這是 AWS CDK v2 開發人員指南。較舊的 CDK v1 已於 2022 年 6 月 1 日進入維護,並於 2023 年 6 月 1 日結束支援。
本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
您可以透過多種方式設定 AWS 環境以搭配 使用 AWS Cloud Development Kit (AWS CDK)。根據您的特定需求,管理 AWS 環境的最佳方法會有所不同。
您應用程式中的每個 CDK 堆疊最終都必須與 環境相關聯,以判斷堆疊部署的位置。
如需 AWS 環境的簡介,請參閱 的環境 AWS CDK。
您可以在登入資料和組態檔案中指定環境,或使用 AWS 建構程式庫中的 Stack
建構env
屬性。
您可以使用 AWS Command Line Interface (AWS CLI) 來建立 credentials
和 config
檔案,以存放、組織和管理 AWS 環境資訊。若要進一步了解這些檔案,請參閱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
和 AWS_DEFAULT_REGION
環境變數,以 Stack
建構的 env
屬性指定。
-
與來自 credentials
和 config
檔案的設定檔相關聯的環境資訊,並使用 CLI --profile
選項傳遞至 CDK。
-
來自 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
物件存取環境變數。
您需要 DefinitelyTyped
模組才能在 TypeScript process
中使用。 會為您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
使用 credentials
和 config
檔案中定義的prod
設定檔來部署名為 之 CDK 堆疊的範例:
$
cdk deploy myStack
--profile prod
如需 --profile
選項以及其他 CDK CLI命令和選項的詳細資訊,請參閱 AWS CDKCLI 命令參考。
您在堆疊中使用建構定義的服務,必須支援您要部署的區域。如需 AWS 服務 每個區域支援的清單,請參閱AWS 依區域提供服務。
您必須擁有 valid AWS Identity and Access Management (IAM) 登入資料,才能 AWS CDK 在指定的環境中使用 執行堆疊部署。
在此範例中,我們會從 CDK 堆疊建立與環境無關的 CloudFormation 範本。然後,我們可以將此範本部署到任何環境。
以下是我們的範例 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
,CDK CLI會產生 CloudFormation 範本,並以虛擬參數AWS::Region
做為儲存貯體區域的輸出值。此參數將在部署時解析:
Outputs:
BucketRegion:
Value:
Ref: AWS::Region
若要將此堆疊部署到登入資料和組態檔案dev
設定檔中指定的環境,我們會執行下列動作:
$
cdk deploy CdkAppStack --profile dev
如果我們未指定設定檔,CDK CLI會嘗試使用登入資料和組態檔案中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 %*