Kind of new to these syntax, so not sure if it's achieve-able.
So we have a bunch of CloudFormation template written and we'd like to deploy them via CDK so we write code to construct them using CfnInclude
. The problem is CfnInclude
always require explicit parameters
argument if there are parameters.
Is there a way to write these in a generic way, so we can create a whole bunch of resources via CfnInclude
in just one for loop for all the CF templates, each may or may not have Parameters and the number and content of parameters is different? Cos otherwise, I'll have to supply all possible Parameters to all CF templates and then write them all out during CfnInclude
.
The actual parameters' value are derived from another place and say then are put in a map, so say we know in total these CF templates may need 0, 1, 2 or 3 possible parameters from below list:
let cfnParameters = {
"param1": value1,
"param2": value2,
"param3": value3,
};
Then can we somehow by supplying the template files themselves, write CDK in a way that it figures out how many and what parameters each file has, and then substitute them with proper values by looking up from the map (so that basically I'm passing a dynamically constructed Parameters
list for each different template)? It seems like all those getParameters
API only operate on the already constructed CF template as an object after CfnInclude
is already called?
And I don't think we can first construct a CfnInclude
without passing Parameters
argument and then do GetParameters
and somehow replace them with actual values right? Doc seems to say Parameter Replacement can only be done at construction time?
CodePudding user response:
You are right, CfnInclude
needs the right keys in the parameters prop, or will throw an error. No problem. Make the template's parameter replacement map before constructing CfnInclude
, using language features. Read the template file. Create a map of the template's keys and the desired values. Pass the resulting map to CfnInclude
.
// MyTemplateIncluder.ts
// values we want to apply
const parameters = {
InstanceType: 'm1.large',
KeyName: 'my-key-name',
SSHLocation: '0.0.0.0/0',
AnotherKey: 'anotherValue',
};
// read the template
const templatePath = path.join(__dirname, 'template.json');
const file = fs.readFileSync(templatePath, 'utf-8');
const templateParams = JSON.parse(file)?.['Parameters'] ?? {};
// new object with keys from the template and values from parameters
const replacementParameters = Object.keys(templateParams).reduce((acc, curr) => {
acc[curr] = parameters[curr];
return acc;
}, {});
new include.CfnInclude(this, 'MyTemplate', {
templateFile: templatePath,
parameters: replacementParameters,
});
Encapsulate this logic in a reusable Construct
subclass. Accept parameter values and the template filename as props.