AWS Cloud Development Kit(CDK) part1

出典:AWS Blackbelt

CDKとは

  • IaCの一種
  • 宣言的にあるべき状態にリソースを作成、変更する

なぜIaCなのか

従来の課題

  • 手続きの処理の場合、現在の状態がわからずリリースしづらい
  • 人による解釈の違いや操作ミスのリスクがあり
  • 何度も同じ構成を作るのが大変
  • 手順書やスクリプトの作成に時間がかかり、継続的な講師にテストが困難
  • リソースの状態による判断やエラー処理、ロールバックを網羅しづらい

IaCのメリット

  • コスト削減
    • 手順書の作成、メンテナンス、引継ぎコスト、ブラックボックス化防止、作業時間短縮
  • スピードアップ
    • CI/CD自動テスト、デプロイ、頻繁なデプロイ、厚生パターンのベストプラクティスの共有
  • リスク低減
    • 人的ミスの排除、バージョン管理による変更の追跡と承認プロセス、唯一の情報源(Git)、ロールバック容易性

CDKのメリット

  • 開発者体験を改善
    • アプリと同じ言語で記述できる(TypeScript,JavaScript,Python,Java,.NET,Go)
      • TypeScriptで書かれた単一のコードベースをjsiiによって各言語のコードにコンパイルして提供
    • 型付けとバリデーションで素早くフィードバックを得る
    • リソースとスタックの依存関係を自動的に解決
  • アプリ全体をコードで定義
    • クラウドリソースだけでなく、Lambda巻子のコードやコンテナイメージなどをまとめて管理
    • CI/CDパイプラインを自動構築
    • 複数のAWSアカウントにまたがる環境を管理
  • 高レベルの抽象化
    • 複雑な設定を抽象化しコード量と学習コストを削減
    • 抽象化は個別の設定にアクセスも可能
    • ベストプラクティスに基づくデフォルト値を提供
    • チームの構成パターンや、ガードレールを共有・再利用

CloudFormationからのニーズ

  • 複数のチームが独立して開発・デプロイ可能にするためにモジュール化したい
  • 繰り返し複雑なものを作成することを避けるために抽象化したい
  • JSONやYAMLのような設定言語よりも、自分たちのアイデアを表現できる言語を使いたい

CDKの仕組み

  1. プログラミング言語でインフラ構成を定義
  2. $ cdk deploy
  3. AWS CDK Toolkit(CLI)によってCloudFormationテンプレートを合成(Synthesize) ※Node.js
  4. CloudFormationテンプレートが実行される(API呼び出し)
  5. クラウドリソースが目的の状態に収束
  6. AWS CDK Toolkit(CLI)がLambdaやコンテナ、ファイルなどを直接デプロイ

AWS CDK v2を利用する(CDK v1はサポート終了済み)

CDKのコンセプト

構成要素

  • constructs:コアフレームワーク
  • aws-cdk-lib:コンストラクトライブラリ
  • aws-cdk:AWS CDK Toolkit(CLI)

constructsとaws-cdk-libはプログラミング言語ごと、aws-cdkは共通

AWS CDKの概念

  • App
    • アプリケーション全体
    • 複数のAWSアカウント、リージョンにまたがることが可能
  • Stack
    • CloudFormationスタックに対応
    • デプロイ可能な最小単位
  • Construct
    • CDKの最も基本的なビルディングブロック
    • 1つまたは複数のAWSリソースを表現
    • ユーザーにより定義・配布が可能
  • Cloud Assembly
    • CDK Appの出力、デプロイに必要な資材一式
      • CloudFormationテンプレート
      • アセット(ファイル、Dockerイメージなど)

CloudFormationとの比較

AWS CloudFormation

  • スタックを1つずつデプロイ
  • 依存関係を考慮して人がデプロイ順序を決める
  • 複数スタックを一括デプロイするためにScript、Makefile,CodePipelineが必要
  • CloudFormation Moduleによるカプセル化と再利用

AWS CDK

  • 複数スタックをまとめて1つのアプリとしてデプロイ
  • スタック間の依存関係はCDKが解決してデプロイ順序を決定
  • Constructによる抽象化と再利用
  • 複数のStackをまとめるStageを追加することで環境の複製も用意(Dev,Staging,Prod)

AWS Constructs Library

  • Log-level-constructs(L1)
    • CloudFormationリソース及びプロパティと1:1で対応(自動生成)
    • cfnXXXという名前
    • すべてのプロパティを明示的に設定する必要がある
  • High-Level constructs(L2)
    • デフォルト値や便利なメソッドを定義した単一のAWSリソースを表すクラス
    • より特定のシナリオに合わせて単一のリソースを抽象化したL2.5 constructsも存在
  • Patterns(L3)
    • 複数のリソースを含む一般的な越す英パターンを抽象化

Construct Hub

  • 1,000以上のOSSのコンストラクトが公開されている

Construct ツリー

  • Appをルートとして自由にConstructを構造化可能
  • すべてのConstructで明示的にscope(親)を指定して初期化
  • AWSリソースを作成するConstructはStackの子孫でなければならない
    • StackクラスもConstructの一つ
  • NodeクラスでConstructツリーにアクセス
  • Aspectで各Nodeへの捜査を実装可能

Constructツリーの可視化

  • AWS CloudFormationコンソール
  • AWS Toolkit for Visual Studio Code

エスケープハッチ(代替手段)**

  • L2コンストラクトがない場合
    • L1コンストラクトを使う
    • L1コンストラクトもない場合、cdk.CfnResourceを使う(CFnテンプレートとほぼ同等の記述)
  • L2コンストラクトでプロパティが設定できない場合
    • construct.node.defaultChildでL1コンストラクトを取得し、プロパティを変更
  • CloudFormationで対応していない機能の場合
    • Provider Frameworkを使用してカスタムリソースを作成
    • AWSのAPIを呼び出すシンプルなカスタムリソースはAwsCustomResourceコンストラクトを使用することで作成可能

CDKとほかのサービスの連携

AWS SAMでローカルでバックを実行

  • AWS CDKで作成したサーバレスアプリケーションをAWS SAM CLIを使用してローカルでデバック可能
  • sam local invoke,start-api,start-lambdaに対応、デプロイはCDKで行う

AWS AmplifyとCDKの連携

  • $amplify override ... バックエンドリソースをCDKで上書き(カスタマイズ)
  • $amplify add custom ... CDKでカスタムバックエンドを追加(任意のリソースを定義)
  • $amplify export ... バックエンドリソースをCDKでエクスポート(エクスポートしてCDKからデプロイ可能にする)

CDK for Terraform (CDKTF)

  • AWS CDKがコードからCloudFormationテンプレートを作成するのと同様に、TeratermのJSON構成を生成
  • cdktf-cliにより初期化や合成の他、Terraformレジストリのプロバイダをプロジェクトにインポート可能

CDK for Kubernetes (CDK8s)

  • ソースコードからKubernetesマニフェスト作成

TypeScriptでの開発の流れ

  1. Initialize

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # ディレクトリを作成
    $ mkdir cdk-sample
    $ cd cdk-sample

    # CDKプロジェクトを作成(appをsample-appにするとサンプルが追加される)
    $ npx aws-cdk init app --language=typescript

    # CDK Bootstrapping(IAMロール、S3バケット、ECRなどを作成)
    $ npx aws-cdk bootstrap
  2. Code
    cdk initでファイルがディレクトリに生成される

  • binディレクトリ配下にAppを作成し、AppにStrackを追加する
  • libディレクトリ配下でStackを定義してコンストラクト内でConstructを追加
  • testディレクトリ配下にテストが追加される
  1. Test
    CDKアプリをテスト

    1
    2
    3
    4
    5
    # CDKからCloudFormationテンプレートなどを含むCloud Assemblyを合成
    $ npx aws-cdk synth

    # テスト(Jestなどでテストの実装が必要)
    $ npm run test
  2. Deploy

  • CDKアプリをAWSにデプロイ

    1
    2
    3
    4
    5
    # デプロイ済みのCloudFormationテンプレートとの差分を確認
    $ npx aws-cdk diff

    # AWSにCDKアプリをデプロイ
    $ npx aws-cdk deploy --all
  • cdk deploy の代表的なオプション

    1
    2
    3
    4
    5
    $ npx aws-cdk deploy SampleStack # スタックを指定してデプロイ
    $ npx aws-cdk deploy --all --require-approval=neber # デプロイ時の確認を行わない
    $ npx aws-cdk deploy --all --hosswap # Lambda関数などの開発時に変更を高速に反映する
    $ npx aws-cdk deploy --all --no-rollback # スタックの更新失敗時に自動ロールバックしない
    $ npx aws-cdk deploy --all -c key=value # Contextを指定

各言語におけるプロジェクト構成 はそれぞれに異なる

ドキュメント