設定要搭配使用的環境 AWS CDK - AWS Cloud Development Kit (AWS CDK) V2

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

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

設定要搭配使用的環境 AWS CDK

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

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

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

您可以在其中指定環境

您可以在認證和組態檔案中指定環境,或使用「建構程式庫」中Stack建構的env屬性來 AWS 指定環境。

認證和組態檔

您可以使用 AWS Command Line Interface (AWS CLI) 來建立credentials和儲存、組織和管理 AWS 環境資訊的config檔案。若要深入瞭解這些檔案,請參閱AWS Command Line Interface 使用者指南中的組態和認證檔案設定

儲存在這些檔案中的值是依設定檔組織的。根據您設定程式設計存取的方式,為這些檔案中的設定檔和鍵值配對命名方式會有所不同。若要深入瞭解不同方法,請參閱設定安全登入資料 AWS CDKCLI

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

設定好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_ACCOUNT以及使用Stack建構env屬性指定的AWS_DEFAULT_REGION環境變數。

  3. 與您credentials和檔案的設定config檔相關聯的環境資訊,並CLI使用--profile選項傳送至 CDK。

  4. 來自您credentialsconfig文件的配default置文件。

何時指定環境

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

在模板合成指定環境

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

如果您在env屬性中使用環境變數,則必須搭配 CDK CLI 指令使用--profile選項,從認證和組態檔傳入包含環境資訊的設定檔。然後,此信息將在模板合成應用以生成特定於環境的模板。

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

當您以這種方式提供環境資訊時,您可以在 CDK 應用程式中使用與環境相關的程式碼和邏輯。這也意味著合成的模板可能會有所不同,根據其合成的機器,用戶或會話。這種方法通常在開發過程中可以接受或理想,但不建議用於生產使用。

在堆疊部署時指定環境

如果您不使用Stack構造的env屬性指定環境,CDK CLI 將在合成時生成與環 CloudFormation 境無關的模板。然後,您可以使用指定要部署的環境cdk deploy --profile profile

如果您在部署與環境無關的範本時未指定設定檔,CDK CLI 會在部署時嘗試使用來自您和檔案之設定default檔的環境值。credentials config

如果部署時無法使用環境資訊, 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對象訪問環境變量。

注意

您需要在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 代碼可以合成不同的模板,具體取決於它在其下合成的機器,用戶或會話。

使用 CDK 從您的認證和配置文件指定環境 CLI

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

$ cdk deploy myStack --profile prod

若要取得有關--profile選項的更多資訊,以及其他 CDK CLI 指令和選項,請參閱〈〉AWS CDKCLI指令參考

設定環境時的考量 AWS CDK

您在堆疊中使用建構所定義的服務,必須支援您要部署的目標區域。如需 AWS 服務 每個區域的支援清單,請參閱按地區分類的AWS 服務

您必須擁有有效的 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, 'myBucket', { 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, 'myBucket', { 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, 'myBucket', 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, "myBucket") .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, "myBucket", 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("myBucket"), &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 }

該腳本的視窗版本用於 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 %*