Amazon Web Services ブログ

CDK Pipelinesのmodern APIを使ってCDKアプリケーションをデプロイする

CDK Pipelines は、AWS CodePipelineによって CDK アプリケーションの継続的なデプロイパイプラインを簡単にセットアップできる高レベルのコンストラクトライブラリです。現在のCDK Pipelinesには従来のoriginalバージョンと、新しいmodernバージョンの2つのAPIセットが含まれています。modernバージョンのAPIはより使いやすく改善されており、今後は推奨されるAPIとなります。originalバージョンのAPIは後方互換性のためまだ利用可能ですが、可能であれば新バージョンへの移行をおすすめします。

originalのAPIと比較して、modernのAPIは、より適切なデフォルト値を持ち、より柔軟性があり、並列デプロイメントをサポートし、複数のシンセサイザー入力をサポートし、CodeBuildプロジェクトのより詳細な制御を可能にし、CodePipeline以外のデプロイメントエンジンをサポートしています。original APIのREADMEと移行ガイドは、GitHub にあります。

この記事ではCDK Pipelinesのmodern APIを使ってデプロイを行う基本的な手順について解説します。CDK Pipelinesの使い方についてはAWS CDK Reference Documentation の @aws-cdk/pipelines module のページに詳しく書いてあるため、そちらも合わせて参照してください。

前提条件

今回は以下のシナリオでパイプラインとアプリケーションのデプロイを行うと仮定します。

  • 2つのアカウント、ACCOUNT1(11111111111)ACCOUNT2(222222222222)がある。
  • account1-profile という名前のプロファイルに ACCOUNT1 の認証情報が、account2-profile という名前のプロファイルに ACCOUNT2の認証情報が設定されている。詳細については、 AWS CLI の 名前付きプロファイル を参照してください。
  • ACCOUNT1にパイプラインを、ACCOUNT2にアプリケーションをデプロイする。
  • リージョンはどちらもap-northeast-1にデプロイする。

最終的にデプロイされるイメージは以下の通りになります。レポジトリのソースコードに新しいアプリケーションステージやスタックを追加すると、パイプラインはそれらの新しいステージやスタックをデプロイするように自動的に再構成(self-mutation)されます。パイプラインの開発時には後述する方法で一時的にself-mutationを無効にすることもできます。
また、Roleについては実際にはCDKのBootstrapingとCDK Pipelineによって、用途別にいくつかのRoleが追加でデプロイされます。BootstrappingでデプロイされるRoleについてはDeveloper Guideを参照して下さい。

Deployment image with CDK Pipeline

GitHubへのConnectionを作成する

まずレポジトリにアクセスするための設定を行います。CDK PipelinesによるCI/CDはCodeCommit、GitHub (Enterprise含む)、Bitbucketなど多くのレポジトリに対応しています。今回はGitHubを例に説明します。GitHubとの連携はAWS CodeStarのConnectionsを利用すると簡単です。パイプラインをデプロイするアカウント(ACCOUNT1)でConnectionsのページを開き、GitHubへの接続(Connection)を作成してください。

Create a connection step 1

次のページでは新しいアプリをインストールする をクリックし、レポジトリへの読み取り権限を与えます。

Create a connection step 2

接続の作成が完了したら、表示される画面でarn:aws:codestar-connections:から始まるARNを控えておきます。またGitHubにpushするためのレポジトリを作成しておいて下さい(ここでは my-org/my-app とします)。これらの情報は後で使用します。

CDKアプリケーションにCDK Pipelinesを追加する

まず、CDKプロジェクトにCDK Pipelinesライブラリを追加します。

$ npm install @aws-cdk/pipelines

CDK Pipelinesは2021年9月22日時点でプレリリースのCDKの機能を使用するため、cdk.jsoncontextに以下のフラグを追加します。

{
  // ...
  "context": {
    "@aws-cdk/core:newStyleStackSynthesis": true
  }
}

次に、新しいStackを作成します(例: lib/my-pipeline-stack.ts )。

/**
  * この例ではデプロイするアプリケーションは my-stacks.ts の中で定義されています。
  * 実際にデプロイしたいアプリケーションに置き換えてください。
  * 今回の例ではDatabaseStackは定義したデータベーステーブルを "table"というattributeで公開しており、
  * ComputeStackがこのテーブルへの参照を使用しています。
  */
import { DatabaseStack, ComputeStack } from '../lib/my-stacks';
import { Construct, Stage, Stack, StackProps, StageProps } from '@aws-cdk/core';
import { CodePipeline, CodePipelineSource, ShellStep } from '@aws-cdk/pipelines';

/**
 * パイプラインを定義するStack
 */
export class MyPipelineStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const pipeline = new CodePipeline(this, 'Pipeline', {
      // クロスアカウントを利用する場合に必要です。
      crossAccountKeys: true,
      synth: new ShellStep('Synth', {
        // 事前に作成したレポジトリ名と、ConnectionのARNに置き換えてください。
        input: CodePipelineSource.connection('my-org/my-app', 'main', {
          connectionArn: 'arn:aws:codestar-connections:ap-northeast-1:11111111111:connection/00000000-0000-0000-0000-000000000000',
        }),
        commands: [
          'npm ci',
          'npm run build',
          'npx cdk synth',
        ],
      }),
    });

    // 任意のアカウントとリージョンで、必要な回数だけ`addStage`を呼び出します。
    pipeline.addStage(new MyApplication(this, 'Prod', {
      env: {
        account: '222222222222',
        region: 'ap-northeast-1',
      }
    }));
  }
}

/**
 * `Stage`をextendsして`MyApplication`を定義します。
 * `MyApplication`は1つ以上のStackで構成されます。
 */
class MyApplication extends Stage {
  constructor(scope: Construct, id: string, props?: StageProps) {
    super(scope, id, props);

    const dbStack = new DatabaseStack(this, 'Database');
    new ComputeStack(this, 'Compute', {
      table: dbStack.table,
    });
  }
}

最後にメインファイル(例: bin/cdk-pipelines-demo.ts )にMyPipelineStackを追加します。

new MyPipelineStack(app, 'PipelineStack', {
  env: {
    account: '11111111111',
    region: 'ap-northeast-1',
  }
});

ブートストラップ

パイプラインをデプロイをする前に、デプロイする環境が最新のブートストラッピングスタックでブートストラップされていることを確認します。新しいCDK Pipelinesの機能に対応するために、CDKアプリケーションをデプロイする予定のすべての環境をブートストラップする必要があります。次の環境(アカウントとリージョンの組み合わせ)が対象です。

  • パイプラインをプロビジョニングする環境
  • パイプラインを使用してアプリケーションをデプロイする予定の環境

これは、CDK アプリケーションをデプロイする環境ごとに 1回だけ行う必要があります。環境がすでにブートストラップされているかどうかが不明な場合は、再度コマンドを実行しても問題ありません。

まずは、下記のコマンドでACCOUNT1にパイプラインをデプロイするためのブートストラップをします。

$ npx cdk bootstrap \
  --profile account-profile-1 \
  --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess \ 
  aws://11111111111/ap-northeast-1

次に、ACCOUNT1のパイプラインから、ACCOUNT2にアプリケーションをデプロイするためのブートストラップをします。

$ npx cdk bootstrap \
  --profile account-profile-2 \
  --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess \ 
  --trust 11111111111 \
  aws://222222222222/ap-northeast-1

これでブートストラップは完了です。コマンドについて2点補足をします。

  • cdk.json"@aws-CDK/core:NewStyleStackSynthesis" コンテキストキーを定義し、cdk.jsonファイルが置かれたディレクトリでこのCDK CLI コマンドを実行することによって、ブートストラップリソースは CDK Pipelines が動作するために必要な、新しい(1.46.0 以降の)ものに切り替えられます。この新しいブートストラップリソースは将来的にデフォルトになりますが、この執筆時点(2021年9月22日時点)では、まだオプトインされています。
  • --cloudformation-execution-policies は、CDKデプロイメントが実行すべきマネージドポリシーのARNです。デフォルトではAdministratorAccessですが、—trustフラグを指定して別のアカウントに現在のアカウントへのデプロイの権限を与える場合は、ここに値を指定する必要があります。

デプロイ

ソースコードの編集が終わったらレポジトリにPushしてからcdk deployを行います。

$ git commit -a
$ git push
$ cdk deploy MyPipelineStack

以後、パイプラインはレポジトリにPushされたCDKアプリケーションの構成に合わせて、自動的に再構成(self-mutation)されます。今回のComputeStackDatabaseStackを含む例だと以下のようなパイプラインが作成されます。

Pipeline

Self Mutation を無効にする

パイプラインのself-mutationは、時としてパイプライン開発のワークフローの邪魔になることがあります。パイプラインに変更を加えるたびにgitにPushしなければなりません。そうしないと、cdk deploy を使ってパイプラインを更新した後、自動的にgitにある状態に戻ってしまいます。

開発をより便利にするために、selfMutation: false プロパティを渡すことで、self-mutationを一時的にオフにすることができます。この機能はoriginal APIでも使用できます。

// Modern API
const pipeline = new CodePipeline(this, 'Pipeline', {
  selfMutation: false,
  ...
});

// Original API
const pipeline = new CdkPipeline(this, 'Pipeline', {
  selfMutating: false,
  ...
});

まとめ

この記事では、CodePipelineのmodern APIを使って、CDKアプリケーションをデプロイする基本の手順について説明しました。AWS CDK Reference Documentationの@aws-cdk/pipelines moduleのページではこの記事で紹介した内容に加え、パイプラインをよりカスタマイズする方法や、トラブルシューティングなど、より多くの情報を紹介しています。そちらもぜひ参考にしてください。