これは AWS CDK v2 デベロッパーガイドです。古い v1 CDK は 2022 年 6 月 1 日にメンテナンスを開始し、2023 年 6 月 1 日にサポートを終了しました。
翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
CDK Pipelines を使用した継続的インテグレーションとデリバリー (CI/CD)
構築ライブラリの CDK Pipelines AWS モジュールを使用して、 AWS CDK アプリケーションの継続的な配信を設定します。CDK アプリケーションのソースコードを AWS CodeCommit、GitHub、または にコミットすると AWS CodeStar、CDK Pipelines は新しいバージョンを自動的に構築、テスト、デプロイできます。
CDK Pipelines は自動更新されています。アプリケーションステージまたはスタックを追加すると、パイプラインは自動的に再設定され、それらの新しいステージまたはスタックがデプロイされます。
CDK Pipelines は 2 つの APIsをサポートしています。1 つは CDK Pipelines デベロッパープレビューで利用可能になった元の API です。もう 1 つは、プレビューフェーズで受け取った CDK 顧客からのフィードバックを組み込む最新の API です。このトピックの例では、最新の API を使用しています。サポートされている 2 つの APIs、aws-cdk リポジトリの「CDK Pipelines original API」を参照してください。 GitHub
AWS 環境のブートストラップ
CDK Pipelines を使用する前に、スタックをデプロイする AWS 環境をブートストラップする必要があります。
CDK パイプラインには、少なくとも 2 つの環境が含まれます。最初の環境は、パイプラインがプロビジョニングされる場所です。2 番目の環境は、アプリケーションのスタックまたはステージを にデプロイする場所です (ステージは関連するスタックのグループです)。これらの環境は同じにすることができますが、ベストプラクティスとして、異なる環境でステージを分離することをお勧めします。
ブートストラップによって作成されたリソースの種類と、ブートストラップスタックをカスタマイズする方法AWS CDK ブートストラップの詳細については、「」を参照してください。
CDK Pipelines を使用した継続的なデプロイでは、CDK Toolkit スタックに以下を含める必要があります。
CDK Toolkit は、既存のブートストラップスタックをアップグレードするか、必要に応じて新しいブートストラップスタックを作成します。
AWS CDK パイプラインをプロビジョニングできる環境をブートストラップするには、次の例cdk bootstrap
に示すように を呼び出します。npx
コマンドを使用して AWS CDK Toolkit を呼び出すと、必要に応じて一時的にインストールされます。また、現在のプロジェクトにインストールされている Toolkit が存在する場合は、そのバージョンも使用します。
--cloudformation-execution-policies
は、将来の CDK Pipelines デプロイを実行するポリシーの ARN を指定します。デフォルトのAdministratorAccess
ポリシーにより、パイプラインはすべてのタイプの AWS リソースをデプロイできます。このポリシーを使用する場合は、 AWS CDK アプリを構成するすべてのコードと依存関係を信頼してください。
ほとんどの組織では、自動化によってデプロイできるリソースの種類をより厳密に制御することを義務付けています。組織内の適切な部門に問い合わせて、パイプラインで使用するポリシーを決定します。
デフォルトの AWS プロファイルに必要な認証設定 と が含まれている場合は、 --profile
オプションを省略できます AWS リージョン。
- macOS/Linux
-
npx cdk bootstrap aws://ACCOUNT-NUMBER
/REGION
--profile ADMIN-PROFILE
\
--cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess
- Windows
-
npx cdk bootstrap aws://ACCOUNT-NUMBER
/REGION
--profile ADMIN-PROFILE
^
--cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess
パイプラインによって AWS CDK アプリケーションがデプロイされる追加の環境をブートストラップするには、代わりに次のコマンドを使用します。--trust
オプションは、この環境に AWS CDK アプリケーションをデプロイするアクセス許可を持つ他のアカウントを示します。このオプションでは、パイプラインの AWS アカウント ID を指定します。
デフォルトの AWS プロファイルに必要な認証設定 と が含まれている場合は、 --profile
オプションを省略することもできます AWS リージョン。
- macOS/Linux
-
npx cdk bootstrap aws://ACCOUNT-NUMBER
/REGION
--profile ADMIN-PROFILE
\
--cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess \
--trust PIPELINE-ACCOUNT-NUMBER
- Windows
-
npx cdk bootstrap aws://ACCOUNT-NUMBER
/REGION
--profile ADMIN-PROFILE
^
--cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess ^
--trust PIPELINE-ACCOUNT-NUMBER
管理認証情報は、ブートストラップと初期パイプラインのプロビジョニングにのみ使用します。その後、ローカルマシンではなくパイプライン自体を使用して変更をデプロイします。
レガシーブートストラップ環境をアップグレードする場合、新しいバケットが作成されると、以前の Amazon S3 バケットは孤立します。Amazon S3 コンソールを使用して手動で削除します。
ブートストラップスタックの削除からの保護
ブートストラップスタックが削除されると、CDK デプロイをサポートするために環境に最初にプロビジョニングされた AWS リソースも削除されます。これにより、パイプラインは動作しなくなります。この場合、復旧のための一般的な解決策はありません。
環境がブートストラップされたら、環境のブートストラップスタックを削除して再作成しないでください。代わりに、 cdk bootstrap
コマンドを再度実行して、ブートストラップスタックを新しいバージョンに更新してみてください。
ブートストラップスタックが誤って削除されないように、終了保護を有効にするには、 cdk bootstrap
コマンドで --termination-protection
オプションを指定することをお勧めします。新規または既存のブートストラップスタックで終了保護を有効にできます。このオプションの詳細については、「」を参照してください--termination-protection
。
終了保護を有効にした後、 AWS CLI または CloudFormation コンソールを使用して検証できます。
終了保護を有効にするには
-
次のコマンドを実行して、新規または既存のブートストラップスタックで終了保護を有効にします。
$
cdk bootstrap --termination-protection
-
AWS CLI または CloudFormation コンソールを使用して確認します。以下に示しているのは、 AWS CLIを使用した例です。ブートストラップスタック名を変更した場合は、 をスタック名CDKToolkit
に置き換えます。
$
aws cloudformation describe-stacks --stack-name CDKToolkit
--query "Stacks[0].EnableTerminationProtection
"
true
プロジェクトの初期化
新しい空のGitHubプロジェクトを作成し、 my-pipeline
ディレクトリのワークステーションにクローンを作成します。(このトピックのコード例では、 を使用しています GitHub。 または を使用 AWS CodeStar することもできます) AWS CodeCommit。
git clone GITHUB-CLONE-URL
my-pipeline
cd my-pipeline
アプリのメインディレクトリmy-pipeline
には、 以外の名前を使用できます。ただし、その場合は、このトピックの後半でファイルとクラス名を微調整する必要があります。これは、 AWS CDK Toolkit が一部のファイル名とクラス名をメインディレクトリの名前に基づいているためです。
クローンを作成したら、通常どおりプロジェクトを初期化します。
- TypeScript
-
$
cdk init app --language typescript
- JavaScript
-
$
cdk init app --language javascript
- Python
-
$
cdk init app --language python
アプリを作成したら、次の 2 つのコマンドも入力します。これにより、アプリケーションの Python 仮想環境がアクティブ化され、 AWS CDK コア依存関係がインストールされます。
$
source .venv/bin/activate
# On Windows, run `.\venv\Scripts\activate` instead
$
python -m pip install -r requirements.txt
- Java
-
$
cdk init app --language java
IDE を使用している場合は、プロジェクトを開くかインポートできるようになりました。例えば、Eclipse で、ファイル > インポート > Maven > 既存の Maven プロジェクト を選択します。プロジェクト設定が Java 8 (1.8) を使用するように設定されていることを確認します。
- C#
-
$
cdk init app --language csharp
Visual Studio を使用している場合は、 src
ディレクトリでソリューションファイルを開きます。
- Go
-
$
cdk init app --language go
アプリを作成したら、次のコマンドを入力して、アプリに必要な AWS コンストラクトライブラリモジュールをインストールします。
$
go get
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 使用して を認証しますgithub-token
。
また、パイプラインスタックのインスタンス化を更新して、 AWS アカウントとリージョンを指定する必要があります。
- TypeScript
-
で 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();
- JavaScript
-
で lib/my-pipeline-stack.js
(プロジェクトフォルダの名前が でない場合、異なる場合がありますmy-pipeline
)。
const cdk = require('aws-cdk-lib');
const { CodePipeline, CodePipelineSource, ShellStep } = require('aws-cdk-lib/pipelines');
class MyPipelineStack extends cdk.Stack {
constructor(scope, id, props) {
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']
})
});
}
}
module.exports = { MyPipelineStack }
で bin/my-pipeline.js
(プロジェクトフォルダの名前が でない場合、異なる場合がありますmy-pipeline
)。
#!/usr/bin/env node
const cdk = require('aws-cdk-lib');
const { MyPipelineStack } = require('../lib/my-pipeline-stack');
const app = new cdk.App();
new MyPipelineStack(app, 'MyPipelineStack', {
env: {
account: '111111111111
',
region: 'eu-west-1
',
}
});
app.synth();
- Python
-
で my-pipeline/my-pipeline-stack.py
(プロジェクトフォルダの名前が でない場合、異なる場合がありますmy-pipeline
)。
import aws_cdk as cdk
from constructs import Construct
from aws_cdk.pipelines import CodePipeline, CodePipelineSource, ShellStep
class MyPipelineStack(cdk.Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
pipeline = CodePipeline(self, "Pipeline",
pipeline_name="MyPipeline",
synth=ShellStep("Synth",
input=CodePipelineSource.git_hub("OWNER
/REPO
", "main"),
commands=["npm install -g aws-cdk",
"python -m pip install -r requirements.txt",
"cdk synth"]
)
)
Eclipse app.py
:
#!/usr/bin/env python3
import aws_cdk as cdk
from my_pipeline.my_pipeline_stack import MyPipelineStack
app = cdk.App()
MyPipelineStack(app, "MyPipelineStack",
env=cdk.Environment(account="111111111111
", region="eu-west-1
")
)
app.synth()
- Java
-
で src/main/java/com/myorg/MyPipelineStack.java
(プロジェクトフォルダの名前が でない場合、異なる場合がありますmy-pipeline
)。
package com.myorg;
import java.util.Arrays;
import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.pipelines.CodePipeline;
import software.amazon.awscdk.pipelines.CodePipelineSource;
import software.amazon.awscdk.pipelines.ShellStep;
public class MyPipelineStack extends Stack {
public MyPipelineStack(final Construct scope, final String id) {
this(scope, id, null);
}
public MyPipelineStack(final Construct scope, final String id, final StackProps props) {
super(scope, id, props);
CodePipeline pipeline = CodePipeline.Builder.create(this, "pipeline")
.pipelineName("MyPipeline")
.synth(ShellStep.Builder.create("Synth")
.input(CodePipelineSource.gitHub("OWNER
/REPO
", "main"))
.commands(Arrays.asList("npm install -g aws-cdk", "cdk synth"))
.build())
.build();
}
}
で src/main/java/com/myorg/MyPipelineApp.java
(プロジェクトフォルダの名前が でない場合、異なる場合がありますmy-pipeline
)。
package com.myorg;
import software.amazon.awscdk.App;
import software.amazon.awscdk.Environment;
import software.amazon.awscdk.StackProps;
public class MyPipelineApp {
public static void main(final String[] args) {
App app = new App();
new MyPipelineStack(app, "PipelineStack", StackProps.builder()
.env(Environment.builder()
.account("111111111111
")
.region("eu-west-1
")
.build())
.build());
app.synth();
}
}
- C#
-
で src/MyPipeline/MyPipelineStack.cs
(プロジェクトフォルダの名前が でない場合、異なる場合がありますmy-pipeline
)。
using Amazon.CDK;
using Amazon.CDK.Pipelines;
namespace MyPipeline
{
public class MyPipelineStack : Stack
{
internal MyPipelineStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
{
var pipeline = new CodePipeline(this, "pipeline", new CodePipelineProps
{
PipelineName = "MyPipeline",
Synth = new ShellStep("Synth", new ShellStepProps
{
Input = CodePipelineSource.GitHub("OWNER
/REPO
", "main"),
Commands = new string[] { "npm install -g aws-cdk", "cdk synth" }
})
});
}
}
}
で src/MyPipeline/Program.cs
(プロジェクトフォルダの名前が でない場合、異なる場合がありますmy-pipeline
)。
using Amazon.CDK;
namespace MyPipeline
{
sealed class Program
{
public static void Main(string[] args)
{
var app = new App();
new MyPipelineStack(app, "MyPipelineStack", new StackProps
{
Env = new Amazon.CDK.Environment {
Account = "111111111111
", Region = "eu-west-1
" }
});
app.Synth();
}
}
}
- Go
-
package main
import (
"github.com/aws/aws-cdk-go/awscdk/v2"
codebuild "github.com/aws/aws-cdk-go/awscdk/v2/awscodebuild"
ssm "github.com/aws/aws-cdk-go/awscdk/v2/awsssm"
pipeline "github.com/aws/aws-cdk-go/awscdk/v2/pipelines"
"github.com/aws/constructs-go/constructs/v10"
"github.com/aws/jsii-runtime-go"
"os"
)
// my CDK Stack with resources
func NewCdkStack(scope constructs.Construct, id *string, props *awscdk.StackProps) awscdk.Stack {
stack := awscdk.NewStack(scope, id, props)
// create an example ssm parameter
_ = ssm.NewStringParameter(stack, jsii.String("ssm-test-param"), &ssm.StringParameterProps{
ParameterName: jsii.String("/testparam"),
Description: jsii.String("ssm parameter for demo"),
StringValue: jsii.String("my test param"),
})
return stack
}
// my CDK Application
func NewCdkApplication(scope constructs.Construct, id *string, props *awscdk.StageProps) awscdk.Stage {
stage := awscdk.NewStage(scope, id, props)
_ = NewCdkStack(stage, jsii.String("cdk-stack"), &awscdk.StackProps{Env: props.Env})
return stage
}
// my CDK Pipeline
func NewCdkPipeline(scope constructs.Construct, id *string, props *awscdk.StackProps) awscdk.Stack {
stack := awscdk.NewStack(scope, id, props)
// GitHub repo with owner and repository name
githubRepo := pipeline.CodePipelineSource_GitHub(jsii.String("owner/repo
"), jsii.String("main"), &pipeline.GitHubSourceOptions{
Authentication: awscdk.SecretValue_SecretsManager(jsii.String("my-github-token"), nil),
})
// self mutating pipeline
myPipeline := pipeline.NewCodePipeline(stack, jsii.String("cdkPipeline"), &pipeline.CodePipelineProps{
PipelineName: jsii.String("CdkPipeline"),
// self mutation true - pipeline changes itself before application deployment
SelfMutation: jsii.Bool(true),
CodeBuildDefaults: &pipeline.CodeBuildOptions{
BuildEnvironment: &codebuild.BuildEnvironment{
// image version 6.0 recommended for newer go version
BuildImage: codebuild.LinuxBuildImage_FromCodeBuildImageId(jsii.String("aws/codebuild/standard:6.0")),
},
},
Synth: pipeline.NewCodeBuildStep(jsii.String("Synth"), &pipeline.CodeBuildStepProps{
Input: githubRepo,
Commands: &[]*string{
jsii.String("npm install -g aws-cdk"),
jsii.String("cdk synth"),
},
}),
})
// deployment of actual CDK application
myPipeline.AddStage(NewCdkApplication(stack, jsii.String("MyApplication"), &awscdk.StageProps{
Env: targetAccountEnv(),
}), &pipeline.AddStageOpts{
Post: &[]pipeline.Step{
pipeline.NewCodeBuildStep(jsii.String("Manual Steps"), &pipeline.CodeBuildStepProps{
Commands: &[]*string{
jsii.String("echo \"My CDK App deployed, manual steps go here ... \""),
},
}),
},
})
return stack
}
// main app
func main() {
defer jsii.Close()
app := awscdk.NewApp(nil)
// call CDK Pipeline
NewCdkPipeline(app, jsii.String("CdkPipelineStack"), &awscdk.StackProps{
Env: pipelineEnv(),
})
app.Synth(nil)
}
// env determines the AWS environment (account+region) in which our stack is to
// be deployed. For more information see: https://docs.aws.amazon.com/cdk/latest/guide/environments.html
func pipelineEnv() *awscdk.Environment {
return &awscdk.Environment{
Account: jsii.String(os.Getenv("CDK_DEFAULT_ACCOUNT")),
Region: jsii.String(os.Getenv("CDK_DEFAULT_REGION")),
}
}
func targetAccountEnv() *awscdk.Environment {
return &awscdk.Environment{
Account: jsii.String(os.Getenv("CDK_DEFAULT_ACCOUNT")),
Region: jsii.String(os.Getenv("CDK_DEFAULT_REGION")),
}
}
パイプラインは 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
引数を受け入れ、その中のスタックのデフォルト環境になります。(スタックには、引き続き独自の環境を指定できます)。
アプリケーションをパイプラインに追加するには、 のインスタンスaddStage()
で を呼び出しますStage
。ステージをインスタンス化してパイプラインに複数回追加して、DTAP またはマルチリージョンアプリケーションパイプラインのさまざまなステージを定義できます。
シンプルな Lambda 関数を含むスタックを作成し、そのスタックをステージに配置します。次に、ステージをパイプラインに追加してデプロイできるようにします。
- TypeScript
-
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
" }
}));
}
}
- JavaScript
-
Lambda 関数を含むアプリケーションスタックlib/my-pipeline-lambda-stack.js
を保持する新しい ファイルを作成します。
const cdk = require('aws-cdk-lib');
const { Function, InlineCode, Runtime } = require('aws-cdk-lib/aws-lambda');
class MyLambdaStack extends cdk.Stack {
constructor(scope, id, props) {
super(scope, id, props);
new Function(this, 'LambdaFunction', {
runtime: Runtime.NODEJS_18_X,
handler: 'index.handler',
code: new InlineCode('exports.handler = _ => "Hello, CDK";')
});
}
}
module.exports = { MyLambdaStack }
ステージlib/my-pipeline-app-stage.js
を保持する新しい ファイルを作成します。
const cdk = require('aws-cdk-lib');
const { MyLambdaStack } = require('./my-pipeline-lambda-stack');
class MyPipelineAppStage extends cdk.Stage {
constructor(scope, id, props) {
super(scope, id, props);
const lambdaStack = new MyLambdaStack(this, 'LambdaStack');
}
}
module.exports = { MyPipelineAppStage };
を編集lib/my-pipeline-stack.ts
してステージをパイプラインに追加します。
const cdk = require('aws-cdk-lib');
const { CodePipeline, CodePipelineSource, ShellStep } = require('aws-cdk-lib/pipelines');
const { MyPipelineAppStage } = require('./my-pipeline-app-stage');
class MyPipelineStack extends cdk.Stack {
constructor(scope, id, props) {
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
" }
}));
}
}
module.exports = { MyPipelineStack }
- Python
-
Lambda 関数を含むアプリケーションスタックmy_pipeline/my_pipeline_lambda_stack.py
を保持する新しい ファイルを作成します。
import aws_cdk as cdk
from constructs import Construct
from aws_cdk.aws_lambda import Function, InlineCode, Runtime
class MyLambdaStack(cdk.Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
Function(self, "LambdaFunction",
runtime=Runtime.NODEJS_18_X,
handler="index.handler",
code=InlineCode("exports.handler = _ => 'Hello, CDK';")
)
ステージmy_pipeline/my_pipeline_app_stage.py
を保持する新しい ファイルを作成します。
import aws_cdk as cdk
from constructs import Construct
from my_pipeline.my_pipeline_lambda_stack import MyLambdaStack
class MyPipelineAppStage(cdk.Stage):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
lambdaStack = MyLambdaStack(self, "LambdaStack")
を編集my_pipeline/my-pipeline-stack.py
してステージをパイプラインに追加します。
import aws_cdk as cdk
from constructs import Construct
from aws_cdk.pipelines import CodePipeline, CodePipelineSource, ShellStep
from my_pipeline.my_pipeline_app_stage import MyPipelineAppStage
class MyPipelineStack(cdk.Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
pipeline = CodePipeline(self, "Pipeline",
pipeline_name="MyPipeline",
synth=ShellStep("Synth",
input=CodePipelineSource.git_hub("OWNER
/REPO
", "main"),
commands=["npm install -g aws-cdk",
"python -m pip install -r requirements.txt",
"cdk synth"]))
pipeline.add_stage(MyPipelineAppStage(self, "test",
env=cdk.Environment(account="111111111111
", region="eu-west-1
")))
- Java
-
Lambda 関数を含むアプリケーションスタックsrc/main/java/com.myorg/MyPipelineLambdaStack.java
を保持する新しい ファイルを作成します。
package com.myorg;
import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.lambda.Runtime;
import software.amazon.awscdk.services.lambda.InlineCode;
public class MyPipelineLambdaStack extends Stack {
public MyPipelineLambdaStack(final Construct scope, final String id) {
this(scope, id, null);
}
public MyPipelineLambdaStack(final Construct scope, final String id, final StackProps props) {
super(scope, id, props);
Function.Builder.create(this, "LambdaFunction")
.runtime(Runtime.NODEJS_18_X)
.handler("index.handler")
.code(new InlineCode("exports.handler = _ => 'Hello, CDK';"))
.build();
}
}
ステージsrc/main/java/com.myorg/MyPipelineAppStage.java
を保持する新しい ファイルを作成します。
package com.myorg;
import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.Stage;
import software.amazon.awscdk.StageProps;
public class MyPipelineAppStage extends Stage {
public MyPipelineAppStage(final Construct scope, final String id) {
this(scope, id, null);
}
public MyPipelineAppStage(final Construct scope, final String id, final StageProps props) {
super(scope, id, props);
Stack lambdaStack = new MyPipelineLambdaStack(this, "LambdaStack");
}
}
を編集src/main/java/com.myorg/MyPipelineStack.java
してステージをパイプラインに追加します。
package com.myorg;
import java.util.Arrays;
import software.constructs.Construct;
import software.amazon.awscdk.Environment;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.StageProps;
import software.amazon.awscdk.pipelines.CodePipeline;
import software.amazon.awscdk.pipelines.CodePipelineSource;
import software.amazon.awscdk.pipelines.ShellStep;
public class MyPipelineStack extends Stack {
public MyPipelineStack(final Construct scope, final String id) {
this(scope, id, null);
}
public MyPipelineStack(final Construct scope, final String id, final StackProps props) {
super(scope, id, props);
final CodePipeline pipeline = CodePipeline.Builder.create(this, "pipeline")
.pipelineName("MyPipeline")
.synth(ShellStep.Builder.create("Synth")
.input(CodePipelineSource.gitHub("OWNER
/REPO
", "main"))
.commands(Arrays.asList("npm install -g aws-cdk", "cdk synth"))
.build())
.build();
pipeline.addStage(new MyPipelineAppStage(this, "test", StageProps.builder()
.env(Environment.builder()
.account("111111111111
")
.region("eu-west-1
")
.build())
.build()));
}
}
- C#
-
Lambda 関数を含むアプリケーションスタックsrc/MyPipeline/MyPipelineLambdaStack.cs
を保持する新しい ファイルを作成します。
using Amazon.CDK;
using Constructs;
using Amazon.CDK.AWS.Lambda;
namespace MyPipeline
{
class MyPipelineLambdaStack : Stack
{
public MyPipelineLambdaStack(Construct scope, string id, StackProps props=null) : base(scope, id, props)
{
new Function(this, "LambdaFunction", new FunctionProps
{
Runtime = Runtime.NODEJS_18_X,
Handler = "index.handler",
Code = new InlineCode("exports.handler = _ => 'Hello, CDK';")
});
}
}
}
ステージsrc/MyPipeline/MyPipelineAppStage.cs
を保持する新しい ファイルを作成します。
using Amazon.CDK;
using Constructs;
namespace MyPipeline
{
class MyPipelineAppStage : Stage
{
public MyPipelineAppStage(Construct scope, string id, StageProps props=null) : base(scope, id, props)
{
Stack lambdaStack = new MyPipelineLambdaStack(this, "LambdaStack");
}
}
}
を編集src/MyPipeline/MyPipelineStack.cs
してステージをパイプラインに追加します。
using Amazon.CDK;
using Constructs;
using Amazon.CDK.Pipelines;
namespace MyPipeline
{
public class MyPipelineStack : Stack
{
internal MyPipelineStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
{
var pipeline = new CodePipeline(this, "pipeline", new CodePipelineProps
{
PipelineName = "MyPipeline",
Synth = new ShellStep("Synth", new ShellStepProps
{
Input = CodePipelineSource.GitHub("OWNER
/REPO
", "main"),
Commands = new string[] { "npm install -g aws-cdk", "cdk synth" }
})
});
pipeline.AddStage(new MyPipelineAppStage(this, "test", new StageProps
{
Env = new Environment
{
Account = "111111111111
", Region = "eu-west-1
"
}
}));
}
}
}
によって追加されたすべてのアプリケーションステージは、対応するパイプラインステージを追加addStage()
し、addStage()
呼び出しによって返されるStageDeploymentインスタンスで表されます。デプロイ前またはデプロイ後のアクションをステージに追加するには、 addPre()
または addPost()
メソッドを呼び出します。
- TypeScript
-
// 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'));
- JavaScript
-
// const { ManualApprovalStep } = require('aws-cdk-lib/pipelines');
const testingStage = pipeline.addStage(new MyPipelineAppStage(this, 'testing', {
env: { account: '111111111111
', region: 'eu-west-1
' }
}));
testingStage.addPost(new ManualApprovalStep('approval'));
- Python
-
# from aws_cdk.pipelines import ManualApprovalStep
testing_stage = pipeline.add_stage(MyPipelineAppStage(self, "testing",
env=cdk.Environment(account="111111111111
", region="eu-west-1
")))
testing_stage.add_post(ManualApprovalStep('approval'))
- Java
-
// import software.amazon.awscdk.pipelines.StageDeployment;
// import software.amazon.awscdk.pipelines.ManualApprovalStep;
StageDeployment testingStage =
pipeline.addStage(new MyPipelineAppStage(this, "test", StageProps.builder()
.env(Environment.builder()
.account("111111111111
")
.region("eu-west-1
")
.build())
.build()));
testingStage.addPost(new ManualApprovalStep("approval"));
- C#
-
var testingStage = pipeline.AddStage(new MyPipelineAppStage(this, "test", new StageProps
{
Env = new Environment
{
Account = "111111111111
", Region = "eu-west-1
"
}
}));
testingStage.AddPost(new ManualApprovalStep("approval"));
Wave にステージを追加して、ステージを複数のアカウントやリージョンにhttps://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.pipelines.Wave.htmlデプロイする場合などに、ステージを並行してデプロイできます。
- TypeScript
-
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
' }
}));
- JavaScript
-
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
' }
}));
- Python
-
wave = pipeline.add_wave("wave")
wave.add_stage(MyApplicationStage(self, "MyAppEU",
env=cdk.Environment(account="111111111111
", region="eu-west-1
")))
wave.add_stage(MyApplicationStage(self, "MyAppUS",
env=cdk.Environment(account="111111111111
", region="us-west-1
")))
- Java
-
// import software.amazon.awscdk.pipelines.Wave;
final Wave wave = pipeline.addWave("wave");
wave.addStage(new MyPipelineAppStage(this, "MyAppEU", StageProps.builder()
.env(Environment.builder()
.account("111111111111
")
.region("eu-west-1
")
.build())
.build()));
wave.addStage(new MyPipelineAppStage(this, "MyAppUS", StageProps.builder()
.env(Environment.builder()
.account("111111111111")
.region("us-west-1")
.build())
.build()));
- C#
-
var wave = pipeline.AddWave("wave");
wave.AddStage(new MyPipelineAppStage(this, "MyAppEU", new StageProps
{
Env = new Environment
{
Account = "111111111111
", Region = "eu-west-1
"
}
}));
wave.AddStage(new MyPipelineAppStage(this, "MyAppUS", new StageProps
{
Env = new Environment
{
Account = "111111111111
", Region = "us-west-1
"
}
}));
デプロイのテスト
CDK パイプラインにステップを追加して、実行しているデプロイを検証できます。例えば、CDK Pipeline ライブラリの を使用してShellStep
、次のようなタスクを実行できます。
最も単純な形式では、検証アクションの追加は次のようになります。
- TypeScript
-
// stage was returned by pipeline.addStage
stage.addPost(new ShellStep("validate", {
commands: ['../tests/validate.sh'],
}));
- JavaScript
-
// stage was returned by pipeline.addStage
stage.addPost(new ShellStep("validate", {
commands: ['../tests/validate.sh'],
}));
- Python
-
# stage was returned by pipeline.add_stage
stage.add_post(ShellStep("validate",
commands=[''../tests/validate.sh'']
))
- Java
-
// stage was returned by pipeline.addStage
stage.addPost(ShellStep.Builder.create("validate")
.commands(Arrays.asList("'../tests/validate.sh'"))
.build());
- C#
-
// stage was returned by pipeline.addStage
stage.AddPost(new ShellStep("validate", new ShellStepProps
{
Commands = new string[] { "'../tests/validate.sh'" }
}));
多くの AWS CloudFormation デプロイでは、予測不可能な名前のリソースが生成されます。このため、CDK Pipelines はデプロイ後に AWS CloudFormation 出力を読み取る方法を提供します。これにより、ロードバランサーの生成された URL をテストアクションに渡す (例えば) ことができます。
出力を使用するには、関心のあるCfnOutput
オブジェクトを公開します。次に、ステップの envFromCfnOutputs
プロパティに渡して、そのステップ内の環境変数として利用できるようにします。
- TypeScript
-
// 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']
}));
- JavaScript
-
// 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']
}));
- Python
-
# given a stack lb_stack that exposes a load balancer construct as load_balancer
self.load_balancer_address = cdk.CfnOutput(lb_stack, "LbAddress",
value=f"https://{lb_stack.load_balancer.load_balancer_dns_name}/")
# pass the load balancer address to a shell step
stage.add_post(ShellStep("lbaddr",
env_from_cfn_outputs={"lb_addr": lb_stack.load_balancer_address}
commands=["echo $lb_addr"]))
- Java
-
// given a stack lbStack that exposes a load balancer construct as loadBalancer
loadBalancerAddress = CfnOutput.Builder.create(lbStack, "LbAddress")
.value(String.format("https://%s/",
lbStack.loadBalancer.loadBalancerDnsName))
.build();
stage.addPost(ShellStep.Builder.create("lbaddr")
.envFromCfnOutputs( // Map.of requires Java 9 or later
java.util.Map.of("lbAddr", loadBalancerAddress))
.commands(Arrays.asList("echo $lbAddr"))
.build());
- C#
-
// given a stack lbStack that exposes a load balancer construct as loadBalancer
loadBalancerAddress = new CfnOutput(lbStack, "LbAddress", new CfnOutputProps
{
Value = string.Format("https://{0}/", lbStack.loadBalancer.LoadBalancerDnsName)
});
stage.AddPost(new ShellStep("lbaddr", new ShellStepProps
{
EnvFromCfnOutputs = new Dictionary<string, CfnOutput>
{
{ "lbAddr", loadBalancerAddress }
},
Commands = new string[] { "echo $lbAddr" }
}));
簡単な検証テストは で記述できますがShellStep
、テストが数行を超えると、このアプローチは扱いにくくなります。より複雑なテストでは、 inputs
プロパティShellStep
を介して追加のファイル (完全なシェルスクリプトや他の言語のプログラムなど) を に取り込むことができます。入力は、ソース ( GitHub リポジトリなど) や別の など、出力を持つ任意のステップにすることができますShellStep
。
ファイルがテストで直接使用できる場合 (たとえば、ファイル自体が実行可能である場合)、ソースリポジトリからファイルを取り込むのが適切です。この例では、 GitHub リポジトリを source
( の一部としてインラインでインスタンス化するのではなく) として宣言しますCodePipeline
。次に、このファイルセットをパイプラインと検証テストの両方に渡します。
- TypeScript
-
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']
}));
- JavaScript
-
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']
}));
- Python
-
source = CodePipelineSource.git_hub("OWNER
/REPO
", "main")
pipeline = CodePipeline(self, "Pipeline",
pipeline_name="MyPipeline",
synth=ShellStep("Synth",
input=source,
commands=["npm install -g aws-cdk",
"python -m pip install -r requirements.txt",
"cdk synth"]))
stage = pipeline.add_stage(MyApplicationStage(self, "test",
env=cdk.Environment(account="111111111111
", region="eu-west-1
")))
stage.add_post(ShellStep("validate", input=source,
commands=["sh ../tests/validate.sh"],
))
- Java
-
final CodePipelineSource source = CodePipelineSource.gitHub("OWNER
/REPO
", "main");
final CodePipeline pipeline = CodePipeline.Builder.create(this, "pipeline")
.pipelineName("MyPipeline")
.synth(ShellStep.Builder.create("Synth")
.input(source)
.commands(Arrays.asList("npm install -g aws-cdk", "cdk synth"))
.build())
.build();
final StageDeployment stage =
pipeline.addStage(new MyPipelineAppStage(this, "test", StageProps.builder()
.env(Environment.builder()
.account("111111111111
")
.region("eu-west-1
")
.build())
.build()));
stage.addPost(ShellStep.Builder.create("validate")
.input(source)
.commands(Arrays.asList("sh ../tests/validate.sh"))
.build());
- C#
-
var source = CodePipelineSource.GitHub("OWNER
/REPO
", "main");
var pipeline = new CodePipeline(this, "pipeline", new CodePipelineProps
{
PipelineName = "MyPipeline",
Synth = new ShellStep("Synth", new ShellStepProps
{
Input = source,
Commands = new string[] { "npm install -g aws-cdk", "cdk synth" }
})
});
var stage = pipeline.AddStage(new MyPipelineAppStage(this, "test", new StageProps
{
Env = new Environment
{
Account = "111111111111
", Region = "eu-west-1
"
}
}));
stage.AddPost(new ShellStep("validate", new ShellStepProps
{
Input = source,
Commands = new string[] { "sh ../tests/validate.sh" }
}));
合成ステップから追加のファイルを取得することは、合成の一部として行われるテストをコンパイルする必要がある場合に適しています。
- TypeScript
-
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']
}));
- JavaScript
-
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']
}));
- Python
-
synth_step = ShellStep("Synth",
input=CodePipelineSource.git_hub("OWNER
/REPO
", "main"),
commands=["npm install -g aws-cdk",
"python -m pip install -r requirements.txt",
"cdk synth"])
pipeline = CodePipeline(self, "Pipeline",
pipeline_name="MyPipeline",
synth=synth_step)
stage = pipeline.add_stage(MyApplicationStage(self, "test",
env=cdk.Environment(account="111111111111
", region="eu-west-1
")))
# run a script that was compiled during synthesis
stage.add_post(ShellStep("validate",
input=synth_step,
commands=["node test/validate.js"],
))
- Java
-
final ShellStep synth = ShellStep.Builder.create("Synth")
.input(CodePipelineSource.gitHub("OWNER
/REPO
", "main"))
.commands(Arrays.asList("npm install -g aws-cdk", "cdk synth"))
.build();
final CodePipeline pipeline = CodePipeline.Builder.create(this, "pipeline")
.pipelineName("MyPipeline")
.synth(synth)
.build();
final StageDeployment stage =
pipeline.addStage(new MyPipelineAppStage(this, "test", StageProps.builder()
.env(Environment.builder()
.account("111111111111
")
.region("eu-west-1
")
.build())
.build()));
stage.addPost(ShellStep.Builder.create("validate")
.input(synth)
.commands(Arrays.asList("node ./tests/validate.js"))
.build());
- C#
-
var synth = new ShellStep("Synth", new ShellStepProps
{
Input = CodePipelineSource.GitHub("OWNER
/REPO
", "main"),
Commands = new string[] { "npm install -g aws-cdk", "cdk synth" }
});
var pipeline = new CodePipeline(this, "pipeline", new CodePipelineProps
{
PipelineName = "MyPipeline",
Synth = synth
});
var stage = pipeline.AddStage(new MyPipelineAppStage(this, "test", new StageProps
{
Env = new Environment
{
Account = "111111111111
", Region = "eu-west-1
"
}
}));
stage.AddPost(new ShellStep("validate", new ShellStepProps
{
Input = synth,
Commands = new string[] { "node ./tests/validate.js" }
}));
セキュリティ上の考慮事項
どのような形式の継続的デリバリーでも、固有のセキュリティリスクがあります。 AWS 責任共有モデル では、 AWS クラウド内の情報のセキュリティはお客様の責任となります。CDK Pipelines ライブラリは、安全なデフォルトを組み込み、ベストプラクティスをモデリングすることで、すぐに開始できます。
ただし、本来の目的を達成するために高レベルのアクセスを必要とするライブラリは、完全なセキュリティを保証することはできません。 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 スタックを削除し、デプロイを再試行してください。