Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cfn-include): allow passing Parameters to the included template #9543

Merged
merged 81 commits into from
Aug 13, 2020
Merged
Show file tree
Hide file tree
Changes from 72 commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
db60c27
doc: added slack link to readme
comcalvi Jun 4, 2020
5924f3b
Merge branch 'master' into master
comcalvi Jun 5, 2020
f0c85a3
Update README.md
comcalvi Jun 5, 2020
f37e60e
Merge branch 'master' into master
mergify[bot] Jun 5, 2020
83ed743
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jun 15, 2020
c6664af
added support for Fn::Select, Fn::FindInMap, Fn::Cidr, Fn::GetAZs, Fn…
comcalvi Jun 15, 2020
d0f64d2
added support for the 'Fn::Transform' cloudformation intrinsic function.
comcalvi Jun 16, 2020
d69e46d
added support for the Fn::Base64 Intrinsic Function
comcalvi Jun 16, 2020
df1446a
tested more complex combinations of conditional and non-conditional i…
comcalvi Jun 16, 2020
132cb4d
fixed linter issues
comcalvi Jun 16, 2020
ae7c570
implmented Adam's requests and fixed additional linter issues
comcalvi Jun 17, 2020
7ca707e
updated README to reflect the newly supported cloudformation functions
comcalvi Jun 17, 2020
63c27a7
removed quotes from the type of Transform's parameter argument, modif…
comcalvi Jun 17, 2020
4179271
fixed teseting issue related to Fn::Select
comcalvi Jun 18, 2020
117ae63
Merge branch 'master' into CfnFunctions
comcalvi Jun 18, 2020
dbb9ef8
fixing merge conflicts
comcalvi Jun 18, 2020
bdab761
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jun 18, 2020
d390580
Merge branch 'master' of https://github.com/aws/aws-cdk into CfnFunct…
comcalvi Jun 18, 2020
14a0d64
merge conflict resolution
comcalvi Jun 18, 2020
dfb42b9
Merge branch 'CfnFunctions' of github.com:comcalvi/aws-cdk into CfnFu…
comcalvi Jun 18, 2020
9f1b2d9
Merge branch 'master' of https://github.com/aws/aws-cdk into CfnFunct…
comcalvi Jun 18, 2020
4c9d1ec
fixed typo in condition name
comcalvi Jun 18, 2020
e15c187
Merge branch 'CfnFunctions'
comcalvi Jun 18, 2020
82c4317
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jun 18, 2020
42c0228
removed parameters from _toCloudFormation()
comcalvi Jun 18, 2020
6a2df1e
added support for parameters in templates
comcalvi Jun 19, 2020
43198b7
fixed merge conflict
comcalvi Jun 19, 2020
cd27ff6
updated documentation
comcalvi Jun 19, 2020
1e72465
updated readme
comcalvi Jun 19, 2020
070f902
incorporated adam's comments
comcalvi Jun 19, 2020
b10a1ed
fixed spacing
comcalvi Jun 19, 2020
68d2fbc
fixed merge conflicts
comcalvi Jun 22, 2020
225d1ce
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jun 25, 2020
badeae8
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jun 26, 2020
5bf4760
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jun 29, 2020
479931e
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jun 29, 2020
c3fa10e
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 2, 2020
685d57d
added outputs array
comcalvi Jun 29, 2020
e334814
added support for retrieving and modifying outputs
comcalvi Jun 30, 2020
34d5c34
fixed linter issues
comcalvi Jun 30, 2020
95badbe
updated README
comcalvi Jun 30, 2020
fa39d72
updated documentation
comcalvi Jun 30, 2020
a3940e3
removed unneeded line in tests
comcalvi Jun 30, 2020
fbf17f2
added newline
comcalvi Jun 30, 2020
c719e85
incorporated PR requests
comcalvi Jul 1, 2020
f05aae1
updated the example in the readme
comcalvi Jul 1, 2020
69223d2
added support for common-named outputs. Fixed a bug in the export nam…
comcalvi Jul 1, 2020
0c55180
added a negative test case and a new error message if an output refer…
comcalvi Jul 1, 2020
7557a00
incorporated changes to PR
comcalvi Jul 6, 2020
356fc8f
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 16, 2020
6c62755
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 17, 2020
783e1f4
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 17, 2020
0e59c33
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 19, 2020
98498d1
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 21, 2020
8d5deff
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 22, 2020
59abb94
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 23, 2020
3b902af
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 27, 2020
bdc9fd1
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 29, 2020
c86cc12
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 29, 2020
93509d3
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 30, 2020
32a241a
fixed the CfnOutput comment docs
comcalvi Jul 31, 2020
576c818
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 31, 2020
711d8dc
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Jul 31, 2020
cfd58af
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Aug 3, 2020
94737a7
Merge branch 'master' of https://github.com/aws/aws-cdk
comcalvi Aug 3, 2020
0cef4b9
added the ability to replace parameters invoked in resources at compi…
comcalvi Aug 4, 2020
f8f6885
added support for replacing parameters in fn-sub expressions
comcalvi Aug 5, 2020
a319204
Merge branch 'master' of https://github.com/aws/aws-cdk into compile-…
comcalvi Aug 8, 2020
c5c1fdf
cfn-inlude can now pass parameters at compile time
comcalvi Aug 8, 2020
7354dda
updated README
comcalvi Aug 8, 2020
f84bccf
incorporated review comments
comcalvi Aug 11, 2020
1c511f0
fixed linter issues
comcalvi Aug 11, 2020
e49c836
incorporated review comments
comcalvi Aug 12, 2020
b6d443f
removed unneeded import
comcalvi Aug 12, 2020
548018f
removed commented code
comcalvi Aug 12, 2020
9f90801
incorporated review comments
comcalvi Aug 12, 2020
79c6ff3
import order fixed
comcalvi Aug 12, 2020
4598c6e
incorporated more review comments
comcalvi Aug 12, 2020
4923d72
fixed from-cfn issue
comcalvi Aug 12, 2020
36b731c
cosmetic fixes
comcalvi Aug 13, 2020
d281c23
Merge branch 'master' into compile-time-parameters
mergify[bot] Aug 13, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions packages/@aws-cdk/cloudformation-include/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,20 @@ and any changes you make to it will be reflected in the resulting template:
param.default = 'MyDefault';
```

You can also provide values for them:
comcalvi marked this conversation as resolved.
Show resolved Hide resolved

```typescript
new inc.CfnInclude(stack, 'includeTemplate', {
templateFile: 'path/to/my/template'
parameterValues: {
comcalvi marked this conversation as resolved.
Show resolved Hide resolved
MyParam: 'my-value',
comcalvi marked this conversation as resolved.
Show resolved Hide resolved
},
});
```

This will replace all references to `MyParam` with the string 'my-value',
and `MyParam` will be removed from the Parameters section of the template.

## Conditions

If your template uses [CloudFormation Conditions](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/conditions-section-structure.html),
Expand Down
69 changes: 63 additions & 6 deletions packages/@aws-cdk/cloudformation-include/lib/cfn-include.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,18 @@ export interface CfnIncludeProps {
* If you include a stack here with an ID that isn't in the template,
* or is in the template but is not a nested stack,
* template creation will fail and an error will be thrown.
* @default {}
comcalvi marked this conversation as resolved.
Show resolved Hide resolved
comcalvi marked this conversation as resolved.
Show resolved Hide resolved
*/
readonly nestedStacks?: { [stackName: string]: CfnIncludeProps };

/**
* Specifies parameters to be replaced by the values in this mapping.
* Any parameters in the template that aren't specified here will be left unmodified.
* If you include a parameter here with an ID that isn't in the template,
* template creation will fail and an error will be thrown.
* @default {}
comcalvi marked this conversation as resolved.
Show resolved Hide resolved
comcalvi marked this conversation as resolved.
Show resolved Hide resolved
*/
readonly parameters?: { [parameterName: string]: any };
}

/**
Expand Down Expand Up @@ -55,6 +65,7 @@ export class CfnInclude extends core.CfnElement {
private readonly conditionsScope: core.Construct;
private readonly resources: { [logicalId: string]: core.CfnResource } = {};
private readonly parameters: { [logicalId: string]: core.CfnParameter } = {};
private readonly parameterValues: { [parameterName: string]: any };
comcalvi marked this conversation as resolved.
Show resolved Hide resolved
private readonly outputs: { [logicalId: string]: core.CfnOutput } = {};
private readonly nestedStacks: { [logicalId: string]: IncludedNestedStack } = {};
private readonly nestedStacksToInclude: { [name: string]: CfnIncludeProps };
Expand All @@ -64,12 +75,21 @@ export class CfnInclude extends core.CfnElement {
constructor(scope: core.Construct, id: string, props: CfnIncludeProps) {
super(scope, id);

this.parameterValues = props.parameters || {};

// read the template into a JS object
this.template = futils.readYamlSync(props.templateFile);

// ToDo implement preserveLogicalIds=false
this.preserveLogicalIds = true;

// check if all user specified parameter values exist in the template
for (const logicalId of Object.keys(this.parameterValues)) {
if (!(logicalId in (this.template.Parameters || {}))) {
throw new Error(`Parameter with logical ID '${logicalId}' was not found in the template`);
}
}

// instantiate all parameters
for (const logicalId of Object.keys(this.template.Parameters || {})) {
this.createParameter(logicalId);
Expand Down Expand Up @@ -204,16 +224,27 @@ export class CfnInclude extends core.CfnElement {

for (const section of Object.keys(this.template)) {
// render all sections of the template unchanged,
// except Conditions, Resources, Parameters, and Outputs which will be taken care of by the created L1s
if (section !== 'Conditions' && section !== 'Resources' && section !== 'Parameters' && section !== 'Outputs') {
// except Conditions, Resources, Parameters, and Outputs, which will be taken care of by the created L1s
// Metadata and Transform are handled below
comcalvi marked this conversation as resolved.
Show resolved Hide resolved
if (section !== 'Conditions' && section !== 'Resources' && section !== 'Parameters' && section !== 'Outputs'
&& section !== 'Metadata' && section !== 'Transform') {
comcalvi marked this conversation as resolved.
Show resolved Hide resolved
ret[section] = this.template[section];
}
}

// Parameters cannot be referenced from the Mappings, Description, or AWSTemplateFormatVersion sections.
const metaTransform = this.createTransformAndMetadata();
comcalvi marked this conversation as resolved.
Show resolved Hide resolved
ret.Metadata = metaTransform.Metadata;
ret.Transform = metaTransform.Transform;

return ret;
}

private createParameter(logicalId: string): void {
if (logicalId in (this.parameterValues)) {
comcalvi marked this conversation as resolved.
Show resolved Hide resolved
return;
}

const expression = new cfn_parse.CfnParser({
finder: {
findResource() { throw new Error('Using GetAtt expressions in Parameter definitions is not allowed'); },
Expand Down Expand Up @@ -253,6 +284,7 @@ export class CfnInclude extends core.CfnElement {
return undefined;
},
},
parameters: this.parameterValues,
}).parseValue(this.template.Outputs[logicalId]);
const cfnOutput = new core.CfnOutput(scope, logicalId, {
value: outputAttributes.Value,
Expand Down Expand Up @@ -294,6 +326,7 @@ export class CfnInclude extends core.CfnElement {
},
},
context: cfn_parse.CfnParsingContext.CONDITIONS,
parameters: this.parameterValues,
});
const cfnCondition = new core.CfnCondition(this.conditionsScope, conditionName, {
expression: cfnParser.parseValue(this.template.Conditions[conditionName]),
Expand Down Expand Up @@ -348,6 +381,7 @@ export class CfnInclude extends core.CfnElement {
};
const cfnParser = new cfn_parse.CfnParser({
finder,
parameters: this.parameterValues,
});

let l1Instance: core.CfnResource;
Expand All @@ -356,13 +390,10 @@ export class CfnInclude extends core.CfnElement {
} else {
const l1ClassFqn = cfn_type_to_l1_mapping.lookup(resourceAttributes.Type);
if (l1ClassFqn) {
const options: core.FromCloudFormationOptions = {
finder,
};
comcalvi marked this conversation as resolved.
Show resolved Hide resolved
const [moduleName, ...className] = l1ClassFqn.split('.');
const module = require(moduleName); // eslint-disable-line @typescript-eslint/no-require-imports
const jsClassFromModule = module[className.join('.')];
l1Instance = jsClassFromModule.fromCloudFormation(this, logicalId, resourceAttributes, options);
l1Instance = jsClassFromModule._fromCloudFormation(this, logicalId, resourceAttributes, cfnParser);
} else {
l1Instance = new core.CfnResource(this, logicalId, {
type: resourceAttributes.Type,
Expand Down Expand Up @@ -416,4 +447,30 @@ export class CfnInclude extends core.CfnElement {

return nestedStackResource;
}

private createTransformAndMetadata(): { [element: string]: any } {
comcalvi marked this conversation as resolved.
Show resolved Hide resolved
const ret: { [element: string]: any } = {};
const self = this;
const finder: core.ICfnFinder = {
findResource(lId): core.CfnResource | undefined {
return self.resources[lId];
},
findRefTarget(elementName: string): core.CfnElement | undefined {
return self.resources[elementName] ?? self.parameters[elementName];
},
findCondition(conditionName: string): core.CfnCondition | undefined {
return self.conditions[conditionName];
},
};

const cfnParser = new cfn_parse.CfnParser({
finder,
parameters: this.parameterValues,
});

ret.Metadata = cfnParser.parseValue(this.template.Metadata);
ret.Transform = cfnParser.parseValue(this.template.Transform);

return ret;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
comcalvi marked this conversation as resolved.
Show resolved Hide resolved
"Parameters": {
"MyParam": {
"Type": "String"
}
},
"Resources": {
"Bucket": {
"Type": "AWS::S3::Bucket",
"Properties": {
"BucketName": {
"Fn::Sub": [
"${MyParam}",
{
"MyParam": { "Ref" : "MyParam" }
}
]
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"Parameters": {
"MyParam": {
"Type": "String"
}
},
"Resources": {
"Bucket": {
"Type": "AWS::S3::Bucket",
"Properties": {
"BucketName": {
"Fn::Sub": [
"${MyParameter}-${MyParam}",
{
"MyParameter": { "Ref" : "MyParam" }
comcalvi marked this conversation as resolved.
Show resolved Hide resolved
}
]
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"Transform" : {
"Name" : "AWS::Include",
comcalvi marked this conversation as resolved.
Show resolved Hide resolved
"Parameters" : {
"Location" : {
"Ref": "MyParam"
}
}
},
"Parameters": {
"MyParam": {
"Type": "String",
"Default": "MyValue"
}
},
"Conditions": {
"AlwaysFalse": {
"Fn::Equals": [ { "Ref": "MyParam" }, "Invalid?BucketName"]
}
},
"Metadata": {
"Field": {
"Fn::If": [
"AlwaysFalse",
"AWS::NoValue",
{
"Ref": "MyParam"
}
]
}
},
"Resources": {
"Bucket": {
"Type": "AWS::S3::Bucket",
"Metadata": {
"Field": {
"Ref": "MyParam"
}
},
"Properties": {
"BucketName": {
"Ref": "MyParam"
}
}
}
},
"Outputs": {
"MyOutput": {
"Value": {
"Ref": "MyParam"
}
}
}
}