設定環境以搭配 使用 AWS CDK - AWS Cloud Development Kit (AWS CDK) v2

這是 AWS CDK v2 開發人員指南。較舊的 CDK v1 已於 2022 年 6 月 1 日進入維護,並於 2023 年 6 月 1 日結束支援。

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

設定環境以搭配 使用 AWS CDK

您可以透過多種方式設定 AWS 環境以搭配 使用 AWS Cloud Development Kit (AWS CDK)。根據您的特定需求,管理 AWS 環境的最佳方法會有所不同。

您應用程式中的每個 CDK 堆疊最終都必須與 環境相關聯,以判斷堆疊部署的位置。

如需 AWS 環境的簡介,請參閱 的環境 AWS CDK

您可以從其中指定環境

您可以在登入資料和組態檔案中指定環境,或使用 AWS 建構程式庫中的 Stack 建構env屬性。

登入資料和組態檔案

您可以使用 AWS Command Line Interface (AWS CLI) 來建立 credentialsconfig 檔案,以存放、組織和管理 AWS 環境資訊。若要進一步了解這些檔案,請參閱AWS Command Line Interface 《 使用者指南》中的組態和登入資料檔案設定

存放在這些檔案中的值會依設定檔進行組織。您命名設定檔的方式和這些檔案中的鍵/值對,會根據您設定程式設計存取的方法而有所不同。若要進一步了解不同的方法,請參閱 設定 的安全登入資料 AWS CDKCLI

一般而言, 會 AWS CDK 解析credentials檔案 AWS 帳戶 的資訊,以及config檔案 AWS 區域 的資訊。

設定 credentialsconfig 檔案後,您可以指定要搭配 AWS CDK CLI 和透過環境變數使用的環境。

堆疊建構的 env 屬性

您可以使用 Stack 建構的 env 屬性來指定每個堆疊的環境。此屬性定義要使用的帳戶和區域。您可以將硬式編碼值傳遞至此屬性,或傳遞 CDK 提供的環境變數。

若要傳遞環境變數,請使用 AWS_DEFAULT_ACCOUNTAWS_DEFAULT_REGION 環境變數。這些環境變數可以從 credentialsconfig 檔案傳遞值。您也可以在 CDK 程式碼中使用邏輯來判斷這些環境變數的值。

環境優先順序與 AWS CDK

如果您使用多種方法來指定環境, AWS CDK 會遵循下列優先順序:

  1. 使用 Stack 建構的 env 屬性指定的硬式編碼值。

  2. AWS_DEFAULT_ACCOUNTAWS_DEFAULT_REGION環境變數,以 Stack 建構的 env 屬性指定。

  3. 與來自 credentialsconfig 檔案的設定檔相關聯的環境資訊,並使用 CLI --profile選項傳遞至 CDK。

  4. 來自 credentialsconfig 檔案的default設定檔。

何時指定環境

當您使用 CDK 進行開發時,首先定義 CDK 堆疊,其中包含代表 AWS 資源的建構。接下來,您將每個 CDK 堆疊合成為 AWS CloudFormation 範本。然後,您將 CloudFormation 範本部署到您的環境。您指定環境的方式會決定何時套用環境資訊,並可能影響 CDK 行為和結果。

在範本合成時指定環境

當您使用 Stack 建構的 env 屬性指定環境資訊時,您的環境資訊會套用至範本合成。執行cdk synthcdk deploy產生環境特定的 CloudFormation 範本。

如果您在 env 屬性內使用環境變數,則必須使用 --profile選項搭配 CDK CLI命令,以傳入包含來自登入資料和組態檔案之環境資訊的設定檔。然後,此資訊將在範本合成時套用,以產生環境特定的範本。

CloudFormation 範本中的環境資訊優先於其他方法。例如,如果您使用 提供不同的環境cdk deploy --profile profile,則會忽略設定檔。

當您以這種方式提供環境資訊時,您可以在 CDK 應用程式中使用環境相依程式碼和邏輯。這也表示,合成的範本可能會根據其合成所在的機器、使用者或工作階段而有所不同。這種方法在開發期間通常是可接受的或理想的,但不建議用於生產用途。

在堆疊部署時指定環境

如果您未使用 Stack 建構的 env 屬性指定環境,CDK CLI會在合成時產生與環境無關的 CloudFormation 範本。然後,您可以使用 指定要部署到 的環境cdk deploy --profile profile

如果您在部署環境無關範本時未指定設定檔,CDK CLI會嘗試使用部署時 credentialsconfig 檔案default設定檔中的環境值。

如果部署時無法使用環境資訊, AWS CloudFormation 會嘗試透過環境相關屬性,例如 stack.accountstack.region和 ,在部署時解析環境資訊stack.availabilityZones

對於與環境無關的堆疊,堆疊中的建構無法使用環境資訊,而且您也無法使用需要環境資訊的邏輯。例如,您無法像 一樣編寫程式碼if (stack.region ==== 'us-east-1')或使用需要環境資訊的建構方法,例如 Vpc.fromLookup。若要使用這些功能,您必須使用 env 屬性指定環境。

對於環境無關的堆疊,任何使用可用區域的建構都會看到兩個可用區域,允許將堆疊部署到任何區域。

如何使用 指定環境 AWS CDK

為每個堆疊指定硬式編碼環境

使用 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_ACCOUNTCDK_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 程式碼可以合成不同的範本,取決於其合成所在的機器、使用者或工作階段。

使用 CDK 從登入資料和組態檔案指定環境CLI

部署環境無關範本時,請使用 --profile選項搭配任何 CDK CLI命令,以指定要使用的設定檔。以下是myStack使用 credentialsconfig檔案中定義的prod設定檔來部署名為 之 CDK 堆疊的範例:

$ cdk deploy myStack --profile prod

如需 --profile選項以及其他 CDK CLI命令和選項的詳細資訊,請參閱 AWS CDKCLI 命令參考

使用 設定環境時的考量事項 AWS CDK

您在堆疊中使用建構定義的服務,必須支援您要部署的區域。如需 AWS 服務 每個區域支援的清單,請參閱AWS 依區域提供服務

您必須擁有 valid AWS Identity and Access Management (IAM) 登入資料,才能 AWS CDK 在指定的環境中使用 執行堆疊部署。

範例

從 CDK 堆疊合成與環境無關的 CloudFormation 範本

在此範例中,我們會從 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_ACCOUNTCDK_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: &region, }, })

透過以此方式宣告堆疊的環境,我們可以撰寫簡短指令碼或批次檔案,並從命令列引數設定變數,然後呼叫 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 %*