这是 AWS CDK v2 开发者指南。较旧的 CDK v1 于 2022 年 6 月 1 日进入维护阶段,并于 2023 年 6 月 1 日终止支持。
本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
您可以通过多种方式配置 AWS 环境,以便与一起使用 AWS Cloud Development Kit (AWS CDK)。根据您的具体需求,管理 AWS
环境的最佳方法会有所不同。
应用程序中的每个CDK堆栈最终都必须与环境相关联,以确定堆栈的部署位置。
有关 AWS 环境的介绍,请参阅的环境 AWS CDK。
可以在凭据和配置文件中指定环境,也可以使用构造库中Stack
构造的env
属性 AWS 来指定环境。
您可以使用 AWS Command Line Interface (AWS CLI) 来创建credentials
和存储、组织和管理您的 AWS 环境信息的config
文件。要了解有关这些文件的更多信息,请参阅《AWS Command Line Interface 用户指南》中的配置和凭据文件设置。
存储在这些文件中的值按配置文件进行组织。您如何命名配置文件以及这些文件中的键值对将因配置编程访问的方法而异。要了解有关不同方法的更多信息,请参阅为配置安全证书 AWS CDKCLI。
通常, AWS CDK 解析credentials
文件中的 AWS 账户 信息以及config
文件中的 AWS 区域 信息。
配置好credentials
和config
文件后,可以指定要与之配合使用的环境 AWS CDK CLI 并通过环境变量。
您可以使用Stack
构造的env
属性为每个堆栈指定环境。此属性定义了要使用的账户和区域。您可以将硬编码值传递给此属性,也可以传递由提供的环境变量。CDK
要传递环境变量,请使用AWS_DEFAULT_ACCOUNT
和AWS_DEFAULT_REGION
环境变量。这些环境变量可以传递credentials
和config
文件中的值。您还可以在CDK代码中使用逻辑来确定这些环境变量的值。
如果您使用多种方法来指定环境,则会 AWS CDK 遵循以下优先级:
-
使用Stack
构造的env
属性指定的硬编码值。
-
AWS_DEFAULT_ACCOUNT
以及使用Stack
构造env
属性指定的AWS_DEFAULT_REGION
环境变量。
-
与您的credentials
和config
文件中的配置文件关联的环境信息并传递到 CDK CLI 使用--profile
选项。
-
来自您的credentials
和config
文件的default
个人资料。
使用开发时CDK,首先要定义CDK堆栈,其中包含代表 AWS 资源的构造。接下来,将每个CDK堆栈合成一个 AWS CloudFormation 模板。然后,将CloudFormation 模板部署到您的环境中。您如何指定环境决定何时应用您的环境信息,并可能影响CDK行为和结果。
当您使用Stack
构造的env
属性指定环境信息时,您的环境信息将在模板合成时应用。运行cdk synth
或cdk
deploy
生成特定于环境 CloudFormation 的模板。
如果在env
属性中使用环境变量,则必须使用带的--profile
选项 CDK CLI 用于传入配置文件的命令,该配置文件包含您的凭据和配置文件中的环境信息。然后,这些信息将应用于模板合成,以生成特定于环境的模板。
CloudFormation 模板中的环境信息优先于其他方法。例如,如果您提供不同的环境cdk deploy --profile profile
,则配置文件将被忽略。
以这种方式提供环境信息时,可以在应用程序中使用与环境相关的代码和逻辑。CDK这也意味着,根据合成模板所在的机器、用户或会话,合成后的模板可能会有所不同。这种方法在开发过程中通常是可以接受或可取的,但不建议用于生产用途。
如果你没有使用Stack
构造的env
属性来指定环境,那么 CDK CLI 将在合成时生成与环境无关 CloudFormation 的模板。然后,您可以使用指定要部署到的环境cdk deploy --profile profile
。
如果您在部署与环境无关的模板时未指定配置文件,则 CDK CLI 将在部署时尝试使用您的credentials
和config
文件default
配置文件中的环境值。
如果部署时没有环境信息,则 AWS CloudFormation 将在部署时尝试通过与环境相关的属性(例如stack.account
stack.region
、和stack.availabilityZones
)来解析环境信息。
对于与环境无关的堆栈,堆栈中的构造不能使用环境信息,也不能使用需要环境信息的逻辑。例如,您不能编写类似的代码,if (stack.region ====
'us-east-1')
也不能使用需要环境信息的构造方法,例如Vpc.fromLookup
。要使用这些功能,必须使用env
属性指定环境。
对于与环境无关的堆栈,任何使用可用区域的构造都将看到两个可用区,从而允许将堆栈部署到任何区域。
使用Stack
构造的env
属性为您的堆栈指定 AWS 环境值。以下是 示例:
- 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 });
- Go
-
env_EU := awscdk.Environment{
Account: jsii.String("8373873873"),
Region: jsii.String("eu-west-1"),
}
env_USA := awscdk.Environment{
Account: jsii.String("2383838383"),
Region: jsii.String("us-west-2"),
}
MyFirstStack(app, "first-stack-us", &awscdk.StackProps{
Env: &env_USA,
})
MyFirstStack(app, "first-stack-eu", &awscdk.StackProps{
Env: &env_EU,
})
我们建议在生产环境中使用这种方法。通过以这种方式明确指定环境,可以确保堆栈始终部署到特定环境中。
AWS CDK 提供了两个可在CDK代码中使用的环境变量:CDK_DEFAULT_ACCOUNT
和CDK_DEFAULT_REGION
。当您在堆栈实例的env
属性中使用这些环境变量时,您可以使用以下命令传递证书和配置文件中的环境信息 CDK CLI --profile
选项。
以下是如何指定这些环境变量的示例:
- TypeScript
-
通过 Node 的process
对象访问环境变量。
您需要在process
中使用该DefinitelyTyped
模块 TypeScript。 cdk
init
为你安装这个模块。但是,如果您使用的是添加之前创建的项目,或者您没有使用来设置项目,则应手动安装此模块cdk
init
。
npm install @types/node
new MyDevStack(app, 'dev', {
env: {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: process.env.CDK_DEFAULT_REGION
}});
- JavaScript
-
通过 Node 的process
对象访问环境变量。
new MyDevStack(app, 'dev', {
env: {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: process.env.CDK_DEFAULT_REGION
}});
- Python
-
使用os
模块的environ
字典来访问环境变量。
import os
MyDevStack(app, "dev", env=cdk.Environment(
account=os.environ["CDK_DEFAULT_ACCOUNT"],
region=os.environ["CDK_DEFAULT_REGION"]))
- Java
-
System.getenv()
用于获取环境变量的值。
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#
-
System.Environment.GetEnvironmentVariable()
用于获取环境变量的值。
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() });
- Go
-
import "os"
MyDevStack(app, "dev", &awscdk.StackProps{
Env: &awscdk.Environment{
Account: jsii.String(os.Getenv("CDK_DEFAULT_ACCOUNT")),
Region: jsii.String(os.Getenv("CDK_DEFAULT_REGION")),
},
})
通过使用环境变量指定环境,可以将相同的CDK堆栈合成到不同环境的 AWS CloudFormation 模板中。这意味着您可以将相同的CDK堆栈部署到不同的 AWS 环境,而无需修改CDK代码。您只需要指定要在运行时使用的配置文件即可cdk synth
。
当将同一个堆栈部署到不同的环境时,这种方法非常适合开发环境。但是,我们不建议在生产环境中使用这种方法,因为相同的CDK代码可以合成不同的模板,具体取决于其合成的机器、用户或会话。
部署与环境无关的模板时,请将该选项与任何 --profile
CDK CLI 命令来指定要使用的配置文件。以下是myStack
使用和文件中定义的prod
配置config
文件部署名为的CDK堆栈credentials
的示例:
$
cdk deploy myStack
--profile prod
有关该--profile
选项的更多信息,以及其他 CDK CLI 命令和选项,请参阅AWS CDK CLI 命令参考。
您在堆栈中使用构造定义的服务必须支持您要部署到的区域。有关 AWS 服务 每个区域支持的列表,请参阅按地区划分的AWS 服务。
您必须拥有有效的 AWS Identity and Access Management (IAM) 凭据才能使用在您的指定环境 AWS CDK 中执行堆栈部署。
在此示例中,我们从堆栈中创建了一个与环境无关的 CloudFormation 模板。CDK然后,我们可以将此模板部署到任何环境。
以下是我们的示例CDK堆栈。此堆栈定义了 Amazon S3 存储桶和存储桶所在区域的 CloudFormation 堆栈输出。在本例中env
,未定义:
- TypeScript
-
export class CdkAppStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Create the S3 bucket
const bucket = new s3.Bucket(this, 'amzn-s3-demo-bucket', {
removalPolicy: cdk.RemovalPolicy.DESTROY,
});
// Create an output for the bucket's Region
new cdk.CfnOutput(this, 'BucketRegion', {
value: bucket.env.region,
});
}
}
- JavaScript
-
class CdkAppStack extends cdk.Stack {
constructor(scope, id, props) {
super(scope, id, props);
// Create the S3 bucket
const bucket = new s3.Bucket(this, 'amzn-s3-demo-bucket', {
removalPolicy: cdk.RemovalPolicy.DESTROY,
});
// Create an output for the bucket's Region
new cdk.CfnOutput(this, 'BucketRegion', {
value: bucket.env.region,
});
}
}
- Python
-
class CdkAppStack(cdk.Stack):
def __init__(self, scope: cdk.Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
# Create the S3 bucket
bucket = s3.Bucket(self, 'amzn-s3-demo-bucket',
removal_policy=cdk.RemovalPolicy.DESTROY
)
# Create an output for the bucket's Region
cdk.CfnOutput(self, 'BucketRegion',
value=bucket.env.region
)
- Java
-
public class CdkAppStack extends Stack {
public CdkAppStack(final Construct scope, final String id, final StackProps props) {
super(scope, id, props);
// Create the S3 bucket
Bucket bucket = Bucket.Builder.create(this, "amzn-s3-demo-bucket")
.removalPolicy(RemovalPolicy.DESTROY)
.build();
// Create an output for the bucket's Region
CfnOutput.Builder.create(this, "BucketRegion")
.value(this.getRegion())
.build();
}
}
- C#
-
namespace MyCdkApp
{
public class CdkAppStack : Stack
{
public CdkAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
{
// Create the S3 bucket
var bucket = new Bucket(this, "amzn-s3-demo-bucket", new BucketProps
{
RemovalPolicy = RemovalPolicy.DESTROY
});
// Create an output for the bucket's Region
new CfnOutput(this, "BucketRegion", new CfnOutputProps
{
Value = this.Region
});
}
}
}
- Go
-
func NewCdkAppStack(scope constructs.Construct, id string, props *CdkAppStackProps) awscdk.Stack {
stack := awscdk.NewStack(scope, &id, &props.StackProps)
// Create the S3 bucket
bucket := awss3.NewBucket(stack, jsii.String("amzn-s3-demo-bucket"), &awss3.BucketProps{
RemovalPolicy: awscdk.RemovalPolicy_DESTROY,
})
// Create an output for the bucket's Region
awscdk.NewCfnOutput(stack, jsii.String("BucketRegion"), &awscdk.CfnOutputProps{
Value: stack.Region(),
})
return stack
}
当我们跑步时cdk synth
,CDKCLI 生成一个 CloudFormation 模板,其中虚拟参数AWS::Region
作为存储桶区域的输出值。此参数将在部署时解析:
Outputs:
BucketRegion:
Value:
Ref: AWS::Region
要将此堆栈部署到我们的凭证和配置文件配置文件中指定的环境中,我们运行以下命令:dev
$
cdk deploy CdkAppStack --profile dev
如果我们不指定配置文件,CDKCLI 将尝试在我们的凭据和配置文件中使用配置文件中的环境信息。default
在此示例中,我们将stack
实例的env
属性配置为使用有效的表达式。我们另外指定了两个环境变量,CDK_DEPLOY_ACCOUNT
和CDK_DEPLOY_REGION
。如果这些环境变量存在,则可以在合成时覆盖默认值:
- 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() });
- Go
-
var account, region string
var b bool
if account, b = os.LookupEnv("CDK_DEPLOY_ACCOUNT"); !b || len(account) == 0 {
account = os.Getenv("CDK_DEFAULT_ACCOUNT")
}
if region, b = os.LookupEnv("CDK_DEPLOY_REGION"); !b || len(region) == 0 {
region = os.Getenv("CDK_DEFAULT_REGION")
}
MyDevStack(app, "dev", &awscdk.StackProps{
Env: &awscdk.Environment{
Account: &account,
Region: ®ion,
},
})
用这种方式声明堆栈的环境后,我们可以编写一个简短的脚本或批处理文件,并从命令行参数中设置变量,然后调用cdk deploy
。示例如下:除前两个参数之外的任何参数都将传递给cdk deploy
以指定命令行选项或参数:
- 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
将脚本另存为cdk-deploy-to.sh
,然后执行chmod +x
cdk-deploy-to.sh
使其可执行。
- 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
}
该脚本的 Windows 版本用于提供 PowerShell 与 macOS/Linux 版本相同的功能。它还包含允许将其作为批处理文件运行的指令,以便可以轻松地从命令行调用。应将其另存为cdk-deploy-to.bat
。该文件cdk-deploy-to.ps1
将在调用批处理文件时创建。
然后,我们可以编写其他脚本,使用该cdk-deploy-to
脚本部署到特定环境。以下是 示例:
- 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 %*
以下是使用cdk-deploy-to
脚本部署到多个环境的示例。如果第一次部署失败,则该过程将停止:
- 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 %*