This is the AWS CDK v2 Developer Guide. The older CDK v1 entered maintenance on June 1,
2022 and ended support on June 1, 2023.
Environments
An environment is the target AWS account and AWS Region that stacks are deployed to. All
stacks in your CDK app are explicitly or implicitly associated with an environment (env
).
For production stacks, we recommend that you explicitly specify the environment for each stack in your app using
the env
property. The following example specifies different environments for its two different
stacks.
- TypeScript
-
const envEU = { account: '2383838383', region: 'eu-west-1' };
const envUSA = { account: '8373873873', region: 'us-west-2' };
new MyFirstStack(app, 'first-stack-us', { env: envUSA });
new MyFirstStack(app, 'first-stack-eu', { env: envEU });
- JavaScript
-
const envEU = { account: '2383838383', region: 'eu-west-1' };
const envUSA = { account: '8373873873', region: 'us-west-2' };
new MyFirstStack(app, 'first-stack-us', { env: envUSA });
new MyFirstStack(app, 'first-stack-eu', { env: envEU });
- Python
-
env_EU = cdk.Environment(account="8373873873", region="eu-west-1")
env_USA = cdk.Environment(account="2383838383", region="us-west-2")
MyFirstStack(app, "first-stack-us", env=env_USA)
MyFirstStack(app, "first-stack-eu", env=env_EU)
- Java
-
public class MyApp {
// Helper method to build an environment
static Environment makeEnv(String account, String region) {
return Environment.builder()
.account(account)
.region(region)
.build();
}
public static void main(final String argv[]) {
App app = new App();
Environment envEU = makeEnv("8373873873", "eu-west-1");
Environment envUSA = makeEnv("2383838383", "us-west-2");
new MyFirstStack(app, "first-stack-us", StackProps.builder()
.env(envUSA).build());
new MyFirstStack(app, "first-stack-eu", StackProps.builder()
.env(envEU).build());
app.synth();
}
}
- C#
-
Amazon.CDK.Environment makeEnv(string account, string region)
{
return new Amazon.CDK.Environment
{
Account = account,
Region = region
};
}
var envEU = makeEnv(account: "8373873873", region: "eu-west-1");
var envUSA = makeEnv(account: "2383838383", region: "us-west-2");
new MyFirstStack(app, "first-stack-us", new StackProps { Env=envUSA });
new MyFirstStack(app, "first-stack-eu", new StackProps { Env=envEU });
When you hard-code the target account and Region as shown in the preceding example, the stack is always deployed to
that specific account and Region. To make the stack deployable to a different target, but to determine the target at
synthesis time, your stack can use two environment variables provided by the AWS CDK CLI:
CDK_DEFAULT_ACCOUNT
and CDK_DEFAULT_REGION
. These variables are set based on the AWS
profile specified using the --profile option, or the default AWS profile if you don't specify
one.
The following code fragment shows how to access the account and Region passed from the AWS CDK CLI in your
stack.
- TypeScript
-
Access environment variables via Node's process
object.
You need the DefinitelyTyped
module to use process
in TypeScript. cdk
init
installs this module for you. However, you should install this module manually if you are working
with a project created before it was added, or if you didn't set up your project using cdk
init
.
npm install @types/node
new MyDevStack(app, 'dev', {
env: {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: process.env.CDK_DEFAULT_REGION
}});
- JavaScript
-
Access environment variables via Node's process
object.
new MyDevStack(app, 'dev', {
env: {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: process.env.CDK_DEFAULT_REGION
}});
- Python
-
Use the os
module's environ
dictionary to access environment variables.
import os
MyDevStack(app, "dev", env=cdk.Environment(
account=os.environ["CDK_DEFAULT_ACCOUNT"],
region=os.environ["CDK_DEFAULT_REGION"]))
- Java
-
Use System.getenv()
to get the value of an environment variable.
public class MyApp {
// Helper method to build an environment
static Environment makeEnv(String account, String region) {
account = (account == null) ? System.getenv("CDK_DEFAULT_ACCOUNT") : account;
region = (region == null) ? System.getenv("CDK_DEFAULT_REGION") : region;
return Environment.builder()
.account(account)
.region(region)
.build();
}
public static void main(final String argv[]) {
App app = new App();
Environment envEU = makeEnv(null, null);
Environment envUSA = makeEnv(null, null);
new MyDevStack(app, "first-stack-us", StackProps.builder()
.env(envUSA).build());
new MyDevStack(app, "first-stack-eu", StackProps.builder()
.env(envEU).build());
app.synth();
}
}
- C#
-
Use System.Environment.GetEnvironmentVariable()
to get the value of an environment
variable.
Amazon.CDK.Environment makeEnv(string account=null, string region=null)
{
return new Amazon.CDK.Environment
{
Account = account ?? System.Environment.GetEnvironmentVariable("CDK_DEFAULT_ACCOUNT"),
Region = region ?? System.Environment.GetEnvironmentVariable("CDK_DEFAULT_REGION")
};
}
new MyDevStack(app, "dev", new StackProps { Env = makeEnv() });
Specify the AWS Region using a Region code. For a list, see Regional endpoints.
The AWS CDK distinguishes between not specifying the env
property at all and specifying it using
CDK_DEFAULT_ACCOUNT
and CDK_DEFAULT_REGION
. The former implies that the stack should
synthesize an environment-agnostic template. Constructs that are defined in such a stack cannot use any information
about their environment. For example, you can't write code like if (stack.region === 'us-east-1')
or use
framework facilities like Vpc.fromLookup
(Python: from_lookup
), which need to query your AWS account. These features don't work at all until you
specify an explicit environment; to use them, you must specify env
.
When you pass in your environment using CDK_DEFAULT_ACCOUNT
and CDK_DEFAULT_REGION
, the
stack will be deployed in the account and Region determined by the AWS CDK CLI at the time of synthesis. This lets
environment-dependent code work, but it also means that the synthesized template could be different based on the
machine, user, or session that it's synthesized under. This behavior is often acceptable or even desirable during
development, but it would probably be an anti-pattern for production use.
You can set env
however you like, using any valid expression. For example, you might write your stack
to support two additional environment variables to let you override the account and Region at synthesis time. We'll
call these CDK_DEPLOY_ACCOUNT
and CDK_DEPLOY_REGION
here, but you could name them anything
you like, as they are not set by the AWS CDK. In the following stack's environment, alternative environment variables are
used if they're set. If they're not set, they fall back to the default environment provided by the AWS CDK.
- TypeScript
-
new MyDevStack(app, 'dev', {
env: {
account: process.env.CDK_DEPLOY_ACCOUNT || process.env.CDK_DEFAULT_ACCOUNT,
region: process.env.CDK_DEPLOY_REGION || process.env.CDK_DEFAULT_REGION
}});
- JavaScript
-
new MyDevStack(app, 'dev', {
env: {
account: process.env.CDK_DEPLOY_ACCOUNT || process.env.CDK_DEFAULT_ACCOUNT,
region: process.env.CDK_DEPLOY_REGION || process.env.CDK_DEFAULT_REGION
}});
- Python
-
MyDevStack(app, "dev", env=cdk.Environment(
account=os.environ.get("CDK_DEPLOY_ACCOUNT", os.environ["CDK_DEFAULT_ACCOUNT"]),
region=os.environ.get("CDK_DEPLOY_REGION", os.environ["CDK_DEFAULT_REGION"])
- Java
-
public class MyApp {
// Helper method to build an environment
static Environment makeEnv(String account, String region) {
account = (account == null) ? System.getenv("CDK_DEPLOY_ACCOUNT") : account;
region = (region == null) ? System.getenv("CDK_DEPLOY_REGION") : region;
account = (account == null) ? System.getenv("CDK_DEFAULT_ACCOUNT") : account;
region = (region == null) ? System.getenv("CDK_DEFAULT_REGION") : region;
return Environment.builder()
.account(account)
.region(region)
.build();
}
public static void main(final String argv[]) {
App app = new App();
Environment envEU = makeEnv(null, null);
Environment envUSA = makeEnv(null, null);
new MyDevStack(app, "first-stack-us", StackProps.builder()
.env(envUSA).build());
new MyDevStack(app, "first-stack-eu", StackProps.builder()
.env(envEU).build());
app.synth();
}
}
- C#
-
Amazon.CDK.Environment makeEnv(string account=null, string region=null)
{
return new Amazon.CDK.Environment
{
Account = account ??
System.Environment.GetEnvironmentVariable("CDK_DEPLOY_ACCOUNT") ??
System.Environment.GetEnvironmentVariable("CDK_DEFAULT_ACCOUNT"),
Region = region ??
System.Environment.GetEnvironmentVariable("CDK_DEPLOY_REGION") ??
System.Environment.GetEnvironmentVariable("CDK_DEFAULT_REGION")
};
}
new MyDevStack(app, "dev", new StackProps { Env = makeEnv() });
With your stack's environment declared this way, you can write a short script or batch file like the following to
set the variables from command line arguments, then call cdk deploy
. Any arguments beyond the first two
are passed through to cdk deploy
and can be used to specify command line options or stacks.
- macOS/Linux
-
#!/usr/bin/env bash
if [[ $# -ge 2 ]]; then
export CDK_DEPLOY_ACCOUNT=$1
export CDK_DEPLOY_REGION=$2
shift; shift
npx cdk deploy "$@"
exit $?
else
echo 1>&2 "Provide account and region as first two args."
echo 1>&2 "Additional args are passed through to cdk deploy."
exit 1
fi
Save the script as cdk-deploy-to.sh
, then execute chmod +x cdk-deploy-to.sh
to make it executable.
- Windows
-
@findstr /B /V @ %~dpnx0 > %~dpn0.ps1 && powershell -ExecutionPolicy Bypass %~dpn0.ps1 %*
@exit /B %ERRORLEVEL%
if ($args.length -ge 2) {
$env:CDK_DEPLOY_ACCOUNT, $args = $args
$env:CDK_DEPLOY_REGION, $args = $args
npx cdk deploy $args
exit $lastExitCode
} else {
[console]::error.writeline("Provide account and region as first two args.")
[console]::error.writeline("Additional args are passed through to cdk deploy.")
exit 1
}
The Windows version of the script uses PowerShell to provide the same functionality as the macOS/Linux
version. It also contains instructions to allow it to be run as a batch file so it can be easily invoked from a
command line. It should be saved as cdk-deploy-to.bat
. The file
cdk-deploy-to.ps1
will be created when the batch file is invoked.
Then you can write additional scripts that call the "deploy-to" script to deploy to specific environments (even
multiple environments per script):
- macOS/Linux
-
#!/usr/bin/env bash
# cdk-deploy-to-test.sh
./cdk-deploy-to.sh 123457689 us-east-1 "$@"
- Windows
-
@echo off
rem cdk-deploy-to-test.bat
cdk-deploy-to 135792469 us-east-1 %*
When deploying to multiple environments, consider whether you want to continue deploying to other environments
after a deployment fails. The following example avoids deploying to the second production environment if the first
doesn't succeed.
- macOS/Linux
-
#!/usr/bin/env bash
# cdk-deploy-to-prod.sh
./cdk-deploy-to.sh 135792468 us-west-1 "$@" || exit
./cdk-deploy-to.sh 246813579 eu-west-1 "$@"
- Windows
-
@echo off
rem cdk-deploy-to-prod.bat
cdk-deploy-to 135792469 us-west-1 %* || exit /B
cdk-deploy-to 245813579 eu-west-1 %*
Developers could still use the normal cdk deploy
command to deploy to their own AWS environments for
development.
If you don't specify an environment when you instantiate a stack, the stack is said to be
environment-agnostic. AWS CloudFormation templates synthesized from such a stack will try to use deploy-time
resolution on environment-related attributes such as stack.account
, stack.region
, and
stack.availabilityZones
(Python: availability_zones
).
When using cdk deploy to deploy environment-agnostic stacks, the AWS CDK CLI will
use the specified AWS CLI profile to determine where to deploy. If no profile is specified, the default profile is used.
The AWS CDK CLI follows a protocol similar to the AWS CLI to determine which AWS credentials to use when
performing operations in your AWS account. See AWS CDK Toolkit (cdk command) for details.
In an environment-agnostic stack, any constructs that use Availability Zones will see two Availability Zones,
allowing the stack to be deployed to any Region.
Bootstrapping environments
You must bootstrap each environment that you will deploy CDK stacks into. Bootstrapping prepares the
environment for deployment. To learn more, see Bootstrapping.