Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use a CfnParameter in AWS CDK without filling in the value at runtime

I have been attempting to use the AWS CDK to programmatically build a CloudFormation stack template, but am having trouble with using CfnParameters to parameterize the template.

When I write a template manually in json/yaml, I declare ParameterGroups with nested Parameters lists, as well as defining the individual parameters including Type, Description, AllowedPattern, etc. Then in the definition of my resources, I can reference those parameters via Ref values, eg

"CidrBlock": {
  "Ref": "MyVpcCidr"
}

My question is how do I use this feature via the CDK, defining a parameter and referencing it later in the template?

I have tried the following using software.amazon.awscdk.core.CfnParameter, but receive an error

final CfnParameter myVpcCidrParameter =
    CfnParameter.Builder.create(this, "MyVpcCidr")
        .type("String")
        .description("The CIDR block for the VPC")
        .build();

final Vpc vpc =
    Vpc.Builder.create(this, "vpc")
        .cidr(myVpcCidrParameter.getValueAsString()) // <-- error on this line
        .enableDnsSupport(true)
        .enableDnsHostnames(true)
        .build();
...

The error states

JsiiException: 'cidr' property must be a concrete CIDR string, got a Token

which seems reasonable because myVpcCidrParameter.getValueAsString() returns "${Token[TOKEN.10]}".

However I don't see any other method on CfnParameter or the Vpc.Builder to allow me to use a parameter reference to specify the property value as a reference to my parameter.

What is the proper way to use the CDK to build a template with parameters and resources defined using those parameters?

like image 262
wutch Avatar asked Nov 09 '20 23:11

wutch


People also ask

What is a construct in AWS CDK?

Constructs are the basic building blocks of AWS CDK apps. A construct represents a "cloud component" and encapsulates everything AWS CloudFormation needs to create the component.

What is a stack in AWS CDK?

The unit of deployment in the AWS CDK is called a stack. All AWS resources defined within the scope of a stack, either directly or indirectly, are provisioned as a single unit. Because AWS CDK stacks are implemented through AWS CloudFormation stacks, they have the same limitations as in AWS CloudFormation.

What is CDK synthesize?

The cdk synthesize command (almost always abbreviated synth ) synthesizes a stack defined in your app into a CloudFormation template.

Is not assignable to type construct?

In order to solve the "Argument of type is not assignable to parameter of type Construct" error in CDK, we have to: Update our CDK packages in the dependencies section in package. json to the same version. Remove the ^ (caret) symbol prefix from the versions.


1 Answers

Your use of CfnParameters looks correct however there are known issues when used with resources such as:

  • VPCs
  • Load balancers
  • Load balancer targets

Here's an explanation of why this occurs.

A better alternative would be to use CDK context

Here's your example updated using context:

final String myVpcCidr = (String)this.getNode().tryGetContext("myVpcCidr");

final Vpc vpc =
    Vpc.Builder.create(this, "vpc")
        .cidr(myVpcCidr) // <-- Use context value
        .enableDnsSupport(true)
        .enableDnsHostnames(true)
        .build();

Similar to parameters, you can provide the context key/value via CLI:

cdk synth --context myVpcCidr=value MyStack

Context values can also be provided to your AWS CDK app in 5 other ways:

  • Automatically from the current AWS account.
  • In the project's cdk.context.json file.
  • In the context key of the project's cdk.json file.
  • In the context key of your ~/.cdk.json file.
  • In your AWS CDK app using the construct.node.setContext() method.

See the CDK context docs for more info.

like image 71
Ryan Avatar answered Sep 23 '22 18:09

Ryan