Cross-Environment Deployments
Relevant source files
The following files were used as context for generating this wiki page:The AWS Cloud Development Kit (AWS CDK) is a software development framework for defining cloud infrastructure in code. A core capability of the CDK is the ability to define infrastructure once and deploy it to multiple environments, such as development, staging, and production accounts. This is achieved by instantiating stacks with different environment configurations (AWS account and region). The CDK provides mechanisms for both manual, CLI-driven deployments and fully automated deployments through CI/CD pipelines.
Cross-environment deployments often involve sharing resources and configuration between stacks. The CDK facilitates this by automatically managing cross-stack references using AWS CloudFormation exports and imports. This allows a resource defined in one stack (e.g., a VPC) to be consumed by another stack, even if they are deployed at different times or as part of different deployment pipelines.
Sources: packages/@aws-cdk/core/README.md, packages/aws-cdk/README.md
Core Concepts
Cross-Stack References
When a resource from one stack is referenced by another stack within the same AWS account and region, the CDK automatically creates the necessary CloudFormation primitives to enable this communication. It synthesizes a CloudFormation Export in the producing stack and an Fn::ImportValue intrinsic function in the consuming stack. This creates a dependency where the producing stack must be deployed before the consuming stack.
Sources: packages/@aws-cdk/core/README.md:83-93
The following diagram illustrates the automatic creation of a cross-stack reference between two stacks.
To create an explicit dependency between two stacks without an implicit resource reference, you can use the addDependency() method:
stackA.addDependency(stackB);
This ensures that stackB is deployed before stackA.
Sources: packages/@aws-cdk/core/README.md:213-214
Stack Dependencies and Deployment Order
When dependencies exist between stacks, the CDK toolkit handles the deployment order automatically. If stackA depends on stackB, running cdk deploy stackA will also automatically deploy stackB first. This prevents deployment failures caused by missing resources. However, this also means that cyclic dependencies between stacks are not allowed.
Sources: packages/@aws-cdk/core/README.md:216-224
Manual Deployment with the CDK CLI
The CDK Toolkit (cdk command-line interface) provides commands to manage the lifecycle of CDK applications across different environments.
Sources: packages/aws-cdk/README.md
Bootstrapping Environments
Before deploying a CDK application to an environment (an AWS account and region pair) for the first time, the environment must be "bootstrapped". The cdk bootstrap command deploys a CloudFormation stack named CDKToolkit which contains resources required by the CDK for deployment, most notably an S3 bucket for storing file assets and CloudFormation templates.
$ cdk bootstrap
This command needs to be run for each account/region combination you intend to deploy to.
Sources: packages/aws-cdk/README.md:264-267
Deploying Stacks
The cdk deploy command deploys one or more stacks into an AWS account. You can specify which stacks to deploy. Using wildcards like * or ** allows for deploying multiple stacks at once.
$ # Deploy a single stack
$ cdk deploy MyStackName
$ # Deploy all stacks
$ cdk deploy '*'
The target environment for a stack is determined by the env property set during its instantiation in the CDK app.
Sources: packages/aws-cdk/README.md:129-133, 161-166
The following diagram shows the manual workflow for deploying to two separate environments.
Automated Deployments with CI/CD
For robust, repeatable cross-environment deployments, the CDK provides the @aws-cdk/pipelines module. This library allows you to define a continuous delivery pipeline for your CDK applications using AWS CodePipeline.
The @aws-cdk/pipelines module is the current stable solution for CI/CD. It replaced the deprecated @aws-cdk/app-delivery module.
Sources: packages/@aws-cdk/pipelines/package.json:2, 5, packages/@aws-cdk/app-delivery/package.json:3-4
A typical pipeline defined with this module will:
- Fetch source code from a repository (e.g., AWS CodeCommit, GitHub).
- Run a build step using AWS CodeBuild to synthesize the CDK app (
cdk synth). - Deploy the synthesized stacks to various stages (environments), often with manual approval steps between stages like 'Dev' and 'Prod'.
The dependencies of the @aws-cdk/pipelines module indicate its reliance on core CI/CD services:
| Dependency | Purpose |
|---|---|
@aws-cdk/aws-codepipeline | Orchestrates the deployment workflow. |
@aws-cdk/aws-codebuild | Executes build and synthesis commands. |
@aws-cdk/aws-codepipeline-actions | Defines actions within the pipeline stages. |
@aws-cdk/aws-s3 | Stores pipeline artifacts. |
@aws-cdk/aws-iam | Manages permissions for pipeline actions. |
Sources: packages/@aws-cdk/pipelines/package.json:96-113
This sequence diagram shows a common multi-environment pipeline flow.
Asset Handling in Deployments
CDK applications often include local files or directories, known as "assets," which need to be available to the deployed infrastructure (e.g., Lambda function code, website content). The CDK handles the publishing of these assets as part of the deployment process.
The @aws-cdk/aws-s3-deployment construct is a high-level abstraction for deploying assets to an S3 bucket. Under the hood, it uses a custom CloudFormation resource backed by a Lambda function.
Sources: packages/@aws-cdk/aws-s3-deployment/README.md:10-13, 24-30
The deployment process for assets involves two main steps:
- Asset Staging: When
cdk deployis run, the CDK CLI archives the local asset (e.g., zips a directory) and uploads it to the CDK Toolkit's staging bucket (the one created bycdk bootstrap). - Custom Resource Execution: The
BucketDeploymentconstruct creates a custom resource. During the CloudFormation deployment, a Lambda function is invoked. This function downloads the asset from the staging bucket, extracts it, and syncs it to the specified destination bucket using theaws s3 synccommand.
Sources: packages/@aws-cdk/aws-s3-deployment/README.md:24-30, packages/@aws-cdk/aws-s3-deployment/lib/bucket-deployment.ts:285-290
This flowchart illustrates the asset deployment mechanism for BucketDeployment.
Key BucketDeployment Properties
The BucketDeployment construct offers several properties to control its behavior across environments.
| Property | Description |
|---|---|
sources | An array of sources for the deployment, such as Source.asset('./local-dir'). |
destinationBucket | The target S3 bucket for the deployment. This would be different for each environment. |
destinationKeyPrefix | An optional key prefix within the destination bucket. |
distribution | An optional CloudFront distribution to invalidate after the deployment. |
distributionPaths | Specific paths to invalidate in the CloudFront distribution. |
retainOnDelete | If false, contents are deleted from the destination when the resource is removed. Defaults to true. |
prune | If true (default), files in the destination that are not in the source will be deleted. |
memoryLimit | Memory (in MiB) for the deployment Lambda function, useful for large files. |
Sources: packages/@aws-cdk/aws-s3-deployment/lib/bucket-deployment.ts:16-118
Conclusion
The AWS CDK provides a comprehensive framework for managing infrastructure across multiple environments. It supports both simple, manual deployments via the CDK CLI and sophisticated, automated CI/CD pipelines using the @aws-cdk/pipelines module. Core features like automatic cross-stack referencing and managed asset handling abstract away much of the complexity, allowing developers to focus on defining their application's infrastructure in a reusable and environment-agnostic way. By combining these features, teams can build robust and scalable deployment strategies that cater to their specific operational needs.
Sources: packages/@aws-cdk/core/README.md, packages/aws-cdk/README.md, packages/@aws-cdk/pipelines/package.json