これは v2 AWS CDK デベロッパーガイドです。旧版の CDK v1 は 2022 年 6 月 1 日にメンテナンスを開始し、2023 年 6 月 1 日にサポートを終了しました。
翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
コンストラクトライブラリの CDK Pipelines AWS モジュールを使用して、 AWS CDK アプリケーションの継続的な配信を設定します。CDK アプリケーションのソースコードを AWS CodeCommit、GitHub、または にコミットすると AWS CodeStar、CDK Pipelines は新しいバージョンを自動的に構築、テスト、デプロイできます。
CDK Pipelines は自動更新です。アプリケーションステージまたはスタックを追加すると、パイプラインは自動的に再設定され、それらの新しいステージまたはスタックがデプロイされます。
注記
CDK Pipelines は 2 つの API をサポートしています。1 つは、CDK Pipelines 開発者プレビューで利用可能になった元の API です。もう 1 つは、プレビューフェーズで受け取った CDK 顧客からのフィードバックが組み込まれた、最新の API です。このトピックの例では、最新の API を使用しています。2 つのサポートされている API の違いの詳細については、「AWS-CDK GitHub リポジトリ」の「CDK Pipelines オリジナル API
AWS 環境のブートストラップ
CDK Pipelines を使用する前に、スタックをデプロイする AWS 環境をブートストラップする必要があります。
CDK パイプラインには、少なくとも 2 つの環境が含まれます。1 つめの環境は、パイプラインがプロビジョニングされる場所です。2 つめの環境は、アプリケーションのスタックまたはステージをデプロイする場所です (ステージは関連するスタックのグループです)。これらの環境は同じにすることができますが、ベストプラクティスとしては、異なる環境でステージを分離することをおすすめします。
注記
ブートストラップによって作成されるリソースの種類と、ブートストラップスタックをカスタマイズする方法については、「AWS CDK ブートストラップ」を参照してください。
CDK Pipelines での継続的なデプロイでは、CDK Toolkit スタックに以下を含める必要があります。
-
1 つの Amazon Simple Storage Service (Amazon S3) バケット
-
Amazon ECR リポジトリ
-
パイプラインのさまざまな部分に必要なアクセス許可を付与する IAM ロール
CDK Toolkit は、既存のブートストラップスタックをアップグレードするか、必要に応じて新しいブートストラップスタックを作成します。
AWS CDK パイプラインをプロビジョニングできる環境をブートストラップするには、次の例cdk bootstrap
に示すように を呼び出します。npx
コマンドを使用して AWS CDK Toolkit を呼び出すと、必要に応じて一時的にインストールされます。また、現在のプロジェクトにインストールされている Toolkit が存在する場合は、そのバージョンも使用します。
--cloudformation-execution-policies
は、将来の CDK Pipelines デプロイを実行するポリシーの ARN を指定します。デフォルトのAdministratorAccess
ポリシーにより、パイプラインはすべてのタイプの AWS リソースをデプロイできます。このポリシーを使用する場合は、 AWS CDK アプリを構成するすべてのコードと依存関係を信頼してください。
ほとんどの組織は、自動化によってデプロイできるリソースの種類をより厳しく制御することを義務付けています。組織内の適切な部門に問い合わせて、パイプラインが使用するポリシーを決定します。
デフォルトの AWS プロファイルに必要な認証設定と が含まれている場合は、 --profile
オプションを省略できます AWS リージョン。
npx cdk bootstrap aws://
ACCOUNT-NUMBER
/REGION
--profileADMIN-PROFILE
\ --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess
パイプラインによって AWS CDK アプリケーションがデプロイされる追加の環境をブートストラップするには、代わりに次のコマンドを使用します。--trust
オプションは、 AWS CDK アプリケーションをこの環境にデプロイするためのアクセス許可を他のどのアカウントに付与する必要があるかを示します。このオプションでは、パイプラインの AWS アカウント ID を指定します。
ここでも、デフォルトの AWS プロファイルに必要な認証設定と が含まれている場合は、 --profile
オプションを省略できます AWS リージョン。
npx cdk bootstrap aws://
ACCOUNT-NUMBER
/REGION
--profileADMIN-PROFILE
\ --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess \ --trustPIPELINE-ACCOUNT-NUMBER
ヒント
管理認証情報は、ブートストラップと初期パイプラインのプロビジョニングにのみ使用します。その後、ローカルマシンではなくパイプライン自体を使用して変更をデプロイします。
レガシーブートストラップ環境をアップグレードする場合、新しいバケットが作成されると、以前の Amazon S3 バケットは孤立します。これは、Amazon S3 コンソールを使用して手動で削除してください。
ブートストラップスタックの削除からの保護
ブートストラップスタックが削除されると、CDK デプロイをサポートするために環境で最初にプロビジョニングされた AWS リソースも削除されます。これにより、パイプラインの動作が停止します。これが起きると、復旧のための一般的なソリューションはありません。
環境がブートストラップされた後は、環境のブートストラップスタックの削除と再作成は行わないでください。代わりに、cdk bootstrap
コマンドを再度実行して、ブートストラップスタックを新しいバージョンに更新してみてください。
ブートストラップスタックが誤って削除されないように保護するには、終了保護を有効にする --termination-protection
オプションに cdk bootstrap
コマンドを指定することをおすすめします。新規または既存のブートストラップスタックで終了保護を有効にすることができます。このオプションの詳細については、「--termination-protection
」を参照してください。
終了保護を有効にしたら、 AWS CLI または CloudFormation コンソールを使用して検証できます。
終了保護を有効化するには
-
次のコマンドを実行して、新規または既存のブートストラップスタックで終了保護を有効にします。
$
cdk bootstrap --termination-protection
-
AWS CLI または CloudFormation コンソールを使用して確認します。以下に示しているのは、 AWS CLIを使用した例です。ブートストラップスタック名を変更した場合は、
CDKToolkit
をスタック名に置き換えます。$
aws cloudformation describe-stacks --stack-name
" trueCDKToolkit
--query "Stacks[0].EnableTerminationProtection
プロジェクトの初期化
新しい空の GitHub プロジェクトを作成し、my-pipeline
ディレクトリ内のワークステーションにクローンします。(このトピックのコード例ではGitHub を使用しています。 または を使用することもできます AWS CodeStar ) AWS CodeCommit。
git clone
GITHUB-CLONE-URL
my-pipeline cd my-pipeline
注記
アプリのメインディレクトリには、my-pipeline
以外の名前を使用できます。ただし、その場合は、このトピックの後半でファイルとクラス名を調整する必要があります。これは、 AWS CDK Toolkit が一部のファイル名とクラス名をメインディレクトリの名前に基づいているためです。
クローンを作成したら、通常どおりにプロジェクトを初期化します。
$
cdk init app --language typescript
重要
cdk.json
および cdk.context.json
ファイルは必ずソースコントロールにコミットしてください。コンテキスト情報 ( AWS アカウントから取得した機能フラグやキャッシュされた値など) は、プロジェクトの状態の一部です。値は環境ごとに異なる場合があり、結果として予期せぬ変更が生じる可能性があります。詳細については、「コンテキスト値と AWS CDK」を参照してください。
パイプラインを定義する
CDK Pipelines アプリケーションには、少なくとも 2 つのスタックが含まれます。1 つはパイプライン自体を表すスタックで、もう 1 つかそれ以上は、それを通してデプロイされたアプリケーションを表すスタックです。スタックはステージにグループ化することもできます。ステージを使用して、インフラストラクチャスタックのコピーをさまざまな環境にデプロイできます。ひとまずはパイプラインを検討し、後ほどにはデプロイするアプリケーションについて掘り下げていきます。
コンストラクトCodePipeline
は、 がデプロイエンジン AWS CodePipeline として使用する CDK パイプラインを表すコンストラクトです。CodePipeline
をスタックでインスタンス化する場合は、パイプラインのソースの場所 (GitHub リポジトリなど) を定義します。また、アプリケーションを構築するためのコマンドも定義します。
たとえば、ソースが GitHub リポジトリに保存されているパイプラインを以下に示します。これには、TypeScript CDK アプリケーションのビルドステップも含まれています。GitHub リポジトリに関する情報を、指定された場所に入力します。
注記
デフォルトでは、パイプラインは、Secrets Manager に github-token
という名前で保存されている個人用アクセストークンを使用して GitHub を認証します。
また、パイプラインスタックのインスタンス化を更新して、 AWS アカウントとリージョンを指定する必要があります。
lib/my-pipeline-stack.ts
に作成 (プロジェクトフォルダの名前が my-pipeline
ではない場合は、異なる場合があります)
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { CodePipeline, CodePipelineSource, ShellStep } from 'aws-cdk-lib/pipelines';
export class MyPipelineStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const pipeline = new CodePipeline(this, 'Pipeline', {
pipelineName: 'MyPipeline',
synth: new ShellStep('Synth', {
input: CodePipelineSource.gitHub('OWNER
/REPO
', 'main'),
commands: ['npm ci', 'npm run build', 'npx cdk synth']
})
});
}
}
bin/my-pipeline.ts
に作成 (プロジェクトフォルダの名前が my-pipeline
ではない場合は、異なる場合があります)
#!/usr/bin/env node
import * as cdk from 'aws-cdk-lib';
import { MyPipelineStack } from '../lib/my-pipeline-stack';
const app = new cdk.App();
new MyPipelineStack(app, 'MyPipelineStack', {
env: {
account: '111111111111
',
region: 'eu-west-1
',
}
});
app.synth();
パイプラインは 1 度手動でデプロイする必要があります。その後、パイプラインはソースコードリポジトリから自身を最新の状態に保ち続けます。したがって、リポジトリ内のコードが、デプロイしたいコードであることを必ず確認してください。変更を確認して GitHub にプッシュし、デプロイします。
git add --all git commit -m "initial commit" git push cdk deploy
ヒント
最初のデプロイが完了したので、ローカル AWS アカウントは管理アクセスを必要としなくなります。これは、アプリケーションへのすべての変更はパイプラインを介してデプロイされるためです。必要なのは GitHub にプッシュすることだけです。
アプリケーションステージ
パイプラインに一度に追加できるマルチスタック AWS アプリケーションを定義するには、 のサブクラスを定義しますStage
。(これは CDK Pipelines モジュールの CdkStage
とは異なります。)
ステージには、アプリケーションを構成するスタックが含まれています。スタック間に依存関係がある場合、スタックはパイプラインに自動的に正しい順序で追加されます。相互に依存しないスタックは、並列にデプロイされます。stack1.addDependency(stack2)
を呼び出すことで、スタック間に依存関係を追加できます。
ステージはデフォルトの env
引数を受け入れます。これは、その中のスタックのデフォルトの環境になります。(スタックには独自の環境を指定することもできます)。
アプリケーションをパイプラインに追加するには、Stage
のインスタンスで addStage()
を呼び出します。ステージをインスタンス化してパイプラインに複数回追加することで、DTAP またはマルチリージョンアプリケーションパイプラインのさまざまなステージを定義できます。
シンプルな Lambda 関数を含むスタックを作成し、そのスタックをステージに配置します。次に、ステージをパイプラインに追加してデプロイできるようにします。
Lambda 関数を含むアプリケーションスタックを保持する新しいファイル lib/my-pipeline-lambda-stack.ts
を作成します。
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { Function, InlineCode, Runtime } from 'aws-cdk-lib/aws-lambda';
export class MyLambdaStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
new Function(this, 'LambdaFunction', {
runtime: Runtime.NODEJS_18_X,
handler: 'index.handler',
code: new InlineCode('exports.handler = _ => "Hello, CDK";')
});
}
}
ステージを保持する新しいファイル lib/my-pipeline-app-stage.ts
を作成します。
import * as cdk from 'aws-cdk-lib';
import { Construct } from "constructs";
import { MyLambdaStack } from './my-pipeline-lambda-stack';
export class MyPipelineAppStage extends cdk.Stage {
constructor(scope: Construct, id: string, props?: cdk.StageProps) {
super(scope, id, props);
const lambdaStack = new MyLambdaStack(this, 'LambdaStack');
}
}
lib/my-pipeline-stack.ts
を編集して、ステージをパイプラインに追加します。
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { CodePipeline, CodePipelineSource, ShellStep } from 'aws-cdk-lib/pipelines';
import { MyPipelineAppStage } from './my-pipeline-app-stage';
export class MyPipelineStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const pipeline = new CodePipeline(this, 'Pipeline', {
pipelineName: 'MyPipeline',
synth: new ShellStep('Synth', {
input: CodePipelineSource.gitHub('OWNER
/REPO
', 'main'),
commands: ['npm ci', 'npm run build', 'npx cdk synth']
})
});
pipeline.addStage(new MyPipelineAppStage(this, "test", {
env: { account: "111111111111
", region: "eu-west-1
" }
}));
}
}
addStage()
で追加されたすべてのアプリケーションステージは、addStage()
呼び出しで返された StageDeployment インスタンスで表される、対応するパイプラインステージを追加します。デプロイ前アクションまたはデプロイ後アクションは、addPre()
または addPost()
のメソッドを呼び出すことでステージに追加できます。
// import { ManualApprovalStep } from 'aws-cdk-lib/pipelines';
const testingStage = pipeline.addStage(new MyPipelineAppStage(this, 'testing', {
env: { account: '111111111111
', region: 'eu-west-1
' }
}));
testingStage.addPost(new ManualApprovalStep('approval'));
たとえば複数のアカウントやリージョンにステージをデプロイする場合などは、Wave にステージを追加して並列にデプロイできます。
const wave = pipeline.addWave('wave');
wave.addStage(new MyApplicationStage(this, 'MyAppEU', {
env: { account: '111111111111
', region: 'eu-west-1
' }
}));
wave.addStage(new MyApplicationStage(this, 'MyAppUS', {
env: { account: '111111111111
', region: 'us-west-1
' }
}));
デプロイのテスト
CDK Pipeline にステップを追加して、実行しているデプロイを検証できます。たとえば、CDK Pipeline ライブラリの ShellStep
を使用して、以下のようなタスクを実行できます。
-
Lambda 関数にバックアップされた新しくデプロイされた Amazon API Gateway へのアクセスを試みる
-
AWS CLI コマンドを発行してデプロイされたリソースの設定を確認する
最もシンプルな形式では、検証アクションの追加は以下のようになります。
// stage was returned by pipeline.addStage
stage.addPost(new ShellStep("validate", {
commands: ['../tests/validate.sh'],
}));
多くの AWS CloudFormation デプロイでは、予測不可能な名前のリソースが生成されます。このため、CDK Pipelines はデプロイ後に AWS CloudFormation 出力を読み取る方法を提供します。これにより、生成されたロードバランサーの URL を (たとえば) テストアクションに渡すことができます。
出力を使用するには、関心のある CfnOutput
オブジェクトを公開します。次に、ステップの envFromCfnOutputs
プロパティに渡して、そのステップ内の環境変数として使用可能にします。
// given a stack lbStack that exposes a load balancer construct as loadBalancer
this.loadBalancerAddress = new cdk.CfnOutput(lbStack, 'LbAddress', {
value: `https://${lbStack.loadBalancer.loadBalancerDnsName}/`
});
// pass the load balancer address to a shell step
stage.addPost(new ShellStep("lbaddr", {
envFromCfnOutputs: {lb_addr: lbStack.loadBalancerAddress},
commands: ['echo $lb_addr']
}));
ShellStep
で簡単な検証テストを記述することはできますが、テストが数行を超えると、このアプローチは扱いにくくなります。より複雑なテストでは、inputs
プロパティを介して追加のファイル (完全なシェルスクリプト、他の言語のプログラムなど) を ShellStep
に持ち込むことができます。入力は、ソース (GitHub リポジトリなど) や別の ShellStep
など、出力を持つ任意のステップにすることができます。
ソースリポジトリからファイルを取り込むのは、ファイルがテストで直接使用できる場合 (たとえば、ファイル自体が実行可能である場合) に適しています。この例では、GitHub リポジトリを (CodePipeline
の一部としてインラインでインスタンス化するのではなく) source
として宣言します。次に、このファイルセットをパイプラインと検証テストの両方に渡します。
const source = CodePipelineSource.gitHub('OWNER
/REPO
', 'main');
const pipeline = new CodePipeline(this, 'Pipeline', {
pipelineName: 'MyPipeline',
synth: new ShellStep('Synth', {
input: source,
commands: ['npm ci', 'npm run build', 'npx cdk synth']
})
});
const stage = pipeline.addStage(new MyPipelineAppStage(this, 'test', {
env: { account: '111111111111
', region: 'eu-west-1
' }
}));
stage.addPost(new ShellStep('validate', {
input: source,
commands: ['sh ../tests/validate.sh']
}));
合成ステップから追加のファイルを取得することは、合成の一部として行われるテストをコンパイルする必要がある場合に適しています。
const synthStep = new ShellStep('Synth', {
input: CodePipelineSource.gitHub('OWNER
/REPO
', 'main'),
commands: ['npm ci', 'npm run build', 'npx cdk synth'],
});
const pipeline = new CodePipeline(this, 'Pipeline', {
pipelineName: 'MyPipeline',
synth: synthStep
});
const stage = pipeline.addStage(new MyPipelineAppStage(this, 'test', {
env: { account: '111111111111
', region: 'eu-west-1
' }
}));
// run a script that was transpiled from TypeScript during synthesis
stage.addPost(new ShellStep('validate', {
input: synthStep,
commands: ['node tests/validate.js']
}));
セキュリティ上の考慮事項
どのような形の継続的デリバリーにも、固有のセキュリティリスクがあります。責任 AWS 共有モデル
ただし、その性質上、意図した目的を達成するために高レベルのアクセスを必要とするライブラリは、完全なセキュリティを保証することはできません。 AWS と組織の外部には多くの攻撃ベクトルがあります。
特に、次の点に注意してください。
-
使用するソフトウェアに注意してください。パイプラインで実行するすべてのサードパーティーソフトウェアを検証します。これは、デプロイされるインフラストラクチャが変更される可能性があるためです。
-
依存関係ロックを使用して、予期せぬアップグレードを防止します。CDK Pipelines は、依存関係が想定どおりのものであるよう、
package-lock.json
とyarn.lock
を遵守します。 -
CDK Pipelines は、独自のアカウントで作成されたリソースで実行され、それらのリソースの設定は、パイプラインを介してコードを送信する開発者によって制御されます。したがって、CDK Pipelines 自体は、コンプライアンスチェックをバイパスしようとする悪意のある開発者から保護することはできません。脅威モデルに CDK コードを記述するデベロッパーが含まれている場合は、 AWS CloudFormation 実行ロールに無効化するアクセス許可がないAWS CloudFormation フック
(予防) や AWS Config (事後対応) などの外部コンプライアンスメカニズムを設定する必要があります。 -
本番稼働環境の認証情報は、有効期間が短くなければなりません。ブートストラップと初期プロビジョニングの後、開発者がアカウント認証情報を持つ必要はありません。変更はパイプラインを通じてデプロイできます。そもそも認証情報を必要とせず、認証情報が漏洩する可能性を減らします。
トラブルシューティング
CDK Pipelines の使用を開始する際に、一般的に発生する問題は次のとおりです。
- パイプライン: 内部障害
-
CREATE_FAILED | AWS::CodePipeline::Pipeline | Pipeline/Pipeline Internal Failure
GitHub アクセストークンを確認します。欠落しているか、リポジトリにアクセスするアクセス許可がない可能性があります。
- キーポリシーに 1 つ以上の無効なプリンシパルを含むステートメントが含まれています。
-
CREATE_FAILED | AWS::KMS::Key | Pipeline/Pipeline/ArtifactsBucketEncryptionKey Policy contains a statement with one or more invalid principals.
ターゲット環境の 1 つが新しいブートストラップスタックでブートストラップされていません。すべてのターゲット環境がブートストラップされていることを確認します。
- スタックは ROLLBACK_COMPLETE 状態であり、更新できません。
-
Stack
STACK_NAME
is in ROLLBACK_COMPLETE state and can not be updated. (Service: AmazonCloudFormation; Status Code: 400; Error Code: ValidationError; Request ID: ...)スタックは以前のデプロイに失敗し、再試行不可能な状態です。 AWS CloudFormation コンソールからスタックを削除し、デプロイを再試行します。