Creating Dev and Prod deployments using CDK

Viewed 875

New to AWS CDK, so please bear with me. I am trying to create multi-deployment CDK, wherein the Dev should be deployed to Account A and prod to Acocunt B.

I have created 2 stacks with the respective account numbers and so on.

mktd_dev_stack = Mktv2Stack(app, "Mktv2Stack-dev",

env=cdk.Environment(account='#####', region='us-east-1'),
stack_name = "myStack-Dev",

# For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html
)

the Prod is similar with the Prod account and different name. When I run them I plan on doing

cdk deploy Mktv2Stack-dev

and simiar for prod.

I am using the cdk 2.xx on Python

What my question is, does this setup give me an ability to pass a parameter, say details which is a dict object of names and criteria for resources that will be set up ? Or is there a way for me to pass parameter/dict from app.py to my program_name.py so that I can look up values from the dict and set them to resources accordingly.

Regards Tanmay

1 Answers

TL;DR Use a single stack and pass in the stg/prod as an env var to app.py.

Pass config down from app.py > Stacks > Constructs as Python Parameters (constructor args). Avoid using CDK Parameters* for config, says AWS's CDK Application Best Practices.

Practically speaking, you pass the account or alias as a environment variable, which app.py reads to perform the metadata lookups and set the stack props. Here's a node-flavoured version of this pattern:

AWS_ACCOUNT=123456789012 npx cdk deploy '*' -a 'node ./bin/app' --profile test-account"

Why not 2 stacks in app.py, one for PROD and one for STAGING?

A 2-stack approach can certainly work. The downsides are that you rarely want to deploy both environments at the same time (outside a CI/CD context). And cross-account permissions are trickier to handle safely if mixed in a single cdk deploy.

Customising Constructs for different environments

Within your code, use a dict, class or whatever to return the configuration you want based on an account or region input. Finally, pass the variables to the constructs. Here's an example of code that uses account, region and isProduction props to customise a s3 bucket:

const queriesBucket = new s3.Bucket(this, 'QueriesBucket', {
  bucketName: `${props.appName.toLowerCase()}-queries-${props.env.account}-${
    props.env.region
  }`,
  removalPolicy: props.isProduction
    ? cdk.RemovalPolicy.RETAIN
    : cdk.RemovalPolicy.DESTROY,
  versioned: props.isProduction,
  lifecycleRules: [
    {
      id: 'metadata-rule',
      prefix: 'metadata',
      noncurrentVersionExpiration: props.isProduction
        ? cdk.Duration.days(30)
        : cdk.Duration.days(14),
    },
  ],
});

* "Parameter" has different meaning in Python and CDK. Passing variables between constructs in code using Python Parameters (=method arguments) is a best practice. In CDK-speak a Parameter has the special meaning of a variable value passed to CloudFormation at deploy time. These are not CDK best practice.

Related