AWS Cloud Development Kit(CDK) part2
CDKのライフサイクル
AWS CDK -> AWS CloudFormation -> AWS Cloud
AWS CDK
From: Source Code , To: CloudFormation Template- Construct
- Prepare
- Validate
- Symthetize
- リソースのあるべき状態を宣言
- CloudFormationテンプレートにロジックは含めることはできないため、未確定な値はCDKまたは別のプログラムで解決してCloudFormationに渡す必要がある
AWS CloudFormation
Copy: Template , Props: Resources- ユーザーの指示をテンプレートとして受け取ってAPI呼び出し
- スタックに永続化
- テンプレートのコピー
- 管理しているリソースの設定
- Export / Import された値
CDK Appのライフサイクル
- CDK AppはCDK CLIによって実行され、さらに実行は4つの内部フェーズに分かれる
- コードは基本的にConstructionフェーズで実行される
- 後続フェーズでValidateされる例:RestApiにメソッドが一つも含まれない場合にエラーにする
- コードの実行が完了してからCloudFormationやAssetのデプロイが行われる
- コード上でデプロイ時に決定される値を受け取ったり、デプロイ中に処理を実行したりすることはできない
(未決定の値を扱うTokenやCustom Resource, Triggerなどの機能でカバー可能)
- コード上でデプロイ時に決定される値を受け取ったり、デプロイ中に処理を実行したりすることはできない
CDK AppとCDK Toolkit
- CDK AppとCDK Toolkit(CLI)は直接統合しない
- CDK Appをコマンドで実行(別プロセス)
- Contextは環境変数やJSONで渡す(言語非依存)
valueFromLookup
などによって未解決のContext値が参照されるとCDK Appが複数回実行されることがある- CDK AppでSDK呼び出しや副作用のある処理を書く場合はパフォーマンスの劣化や冪等性、権限などに注意が必要
差分の検出
- AWS CDK
cdk diff
コマンド- 合成したテンプレートとすでにデプロイ済みのテンプレートを比較
- リソースの置換が起こるかどうかも仕様から確認
- CDKのスナップショットテスト
- 合成したテンプレートと以前のテンプレート(スナップショット)を比較
- AWS CloudFormation
- CloudFormation変更セット
- 新しいテンプレートをアップロードし保存されているスタックリソースの状態と比較
- UpdateStackが呼ばれると以前の変更セットは削除
- CloudFormationドリフト検出
- 保存されているあスタックリソースの状態と現在のリソースの状態を比較
- CloudFormation変更セット
CDK Appの構成要素
Construct
- クラウドコンポーネントを表現する
- 単一のリソースだけでなく、複数のリソースを含んだConstructを定義可能
- AppやStackなどのクラスもConstructで実装している
- AWS Construct Libraryが標準で提供されるほかユーザーが独自の Constructを定義・配布可能
- Construct Programming Model(CPM)の一部
- クラウドアプリケーションなどの望ましい状態を定義して抽象化するためのプログラミングモデル
- CDKv2からConstructは独立したライブラリとなり、CDKTF,CDK8s,Prohenなどの他のツールでも使用される
Constructのシグネチャ
位置 | 仮引数 | 型 | 説明 |
---|---|---|---|
1 | scope | Construct | Constructツリーの親を指定。通常は現在のスコープを表すthis になる。任意のConstructを渡す場合はIDの重複に注意 |
2 | id | string | Construct IDと呼ばれる。Scope内で一位となる識別子を指定、リソース名や論理IDの一部になる |
3 | props | Constructごとの固有の型 | Constructの初期状態を定義するプロパティ、適切なデフォルト値が用意されており、すべてのプロパティがオプションのこともある |
複数のConstructをまとめる(コンポジション)
- Constructを継承したクラスを定義して複数のConstructをまとめる
- CDKでコンポーネトを構造化する最も一般的な方法
- CloudFormationではStackとテンプレートが1:1対応だが、CDKではStackを複数のConstructから構成可能で、ファイルの分割も自由に行える
- 作成したハイレベルのConstructをライブラリとして共有する場合はProjenの利用を推奨
Construct IDと物理名
- Construct IDはコンストラクトを初期化するときに第二引数に指定する文字列のこと
- スタック名にはConstruct IDがそのまま使われる
- 物理名には
<Stack>ー
が前置され、リソースまでのConstructのパスが統合して使われる - StageでStackをまとめると
<Stage>-
が前置される
App
- エントリーポイント
- 複数のAWSアカウント、リージョンをまたいでStackを一元管理
- Stackの依存関係からデプロイ順序を自動で管理
- CDK CLIから実行され、Cloud Assemblyを作成、CDK CLIによりCloud Assemblyのデプロイが行われる
Stack
- CloudFormationスタックに対応するため、制約も同様に受ける
- StackごとにAWSアカウント、リージョンを指定可能
- tagsプロパティをp指定してStack自身と配下のタグ付け可能なリソースにタグ付けされる
Stage
- 複数のStackをまとめて論理的なアプリ(サービス)のかたまりを表現
- 1つのStageを定義して環境ごとにインスタンスすることで複製が可能
- CDK Pipelines使用時には必須
Environment
- StackやStageを初期化するときにデプロイ先のAWSアカウントとリージョンを指定
- env,account,regionいずれも指定はオプション
- 指定を省略すると、環境に依存しないスタックとみなされる(environment-agnostic)
- この場合
Vpc.fromLookup
やstack.region
などの環境を特定する必要のあるコードは機能しない
- 環境変数
CDK_DEFAULT_ACCOUNT
とCDK_DEFAULT_REGION
がCDK CLIにより提供
Asset
- CDK Appと一緒にデプロイできるファイルやディレクトリ、Dockerイメージ
- zip圧縮またはdocker buildとアップロードはCDK CLIによって実行される
- バンドル時に任意のビルドコマンドを実行可能
Context
- CDK Appから参照できるKey-Valueペア
- cdk.jsonのcontextプロパティとCDK CLIの
-c
,--context
で任意の値を渡せる - CDK CLIは合成中に未解決の値がレポートされるとAWS SDKを使用して解決、
cdk.context.json
にキャッシュ cdk.context.json
は手で編集せず、Gitで管理することを推奨cdk context --reset
でリセット
Feature Flag
- 後方互換性を保ちながらCDKを進化させたり、特定のクラスやメソッドの動作を変更できるようにする
- cdk.jsonにコンテキスト値として指定(
cdk context --reset
ではリセットされない) - cdk initで新しいプロジェクトを作成した場合、推奨されるすべての機能フラグを有効にしたcdk.jsonを生成する
Bootstrapping
- Appをデプロイする前に、ファイル保存するためのS3バケットやECRリポジトリ、IAM Roleなどを作成するプロセス
- AWSアカウントとリージョンごとにBootstrapが必要
- CDK pipelinesを使用する場合など、別のアカウントへのデプロイ許可は
--trust
オプションが使用可能
Token
- Appで未解決の値を扱うためのクラス
- 合成中の後続のコードで決定される値
- Lazy.stringなど
- produce関数で値を返す実装を行う必要がある
- デプロイ時に決定される値
- S3バケット名などのプロパティはTokenを返す
- 合成後にCloudFormationのRef関数に変換される
- Tokenを参照するとプレースホルダが返る
- ほかのリソースに渡せるが、文字列結合以外の演算は不可
Aspect
- 指定されたスコープのすべてのConstructへの捜査を実装可能
- タグをつけたり、削除ポリシーを設定したり、暗号化の有無をチェックすることなどが可能
- Prepareフェーズでvisit関数が呼び出される
- Stageをまたいだ適用はできない
Tags
- 指定されたスコープのすべてのConstructに一括でタグ付け可能
- タグの捜査が競合した場合、priorityの高いものが採用される
- Aspectを使用しているため、Stageをまたいだ適用はできない
- タグ付け可能なリソースのみに付与される
リソースとパラメータの参照
CDK App内のリソース参照
- 組み込み関数で値を解決可能
- CDKアプリのコード内でリソースを参照すると、CloudFormationの組み込み関数に変換される
- CDK App内で値にアクセスするとTokenが返る
参照するリソースの場所に応じてテンプレートを合成
- 同じStack内のリソース
!Ref
または!GetAtt
- 別のStack内のリソース
Export
と!ImportValue
のセット
- 別のリージョンのリソース
Export
とCustomResourceによって消費側のリージョンにSSMParameterを作成し!GetAtt
で取得
- 別のStageのリソース
- 参照不可
AWS CDKのクロスリージョン参照(Preview)
- CDKが自動的にCustomResourceとSSM Parameter Store作成
- 提供側と消費側の両方に指定
crossRegionReferences: true
(※v2.79.0現在)
パラメータ・スークレット参照の使い分け
- シークレット値
1
2const secure1 = SecretValue.ssmSecure('CdkConfSecret1');
const secure1 = SecretValue.secretManager('CdkConfSecret2'); - 平文パラメータ
1
const param1 = StringParameter.valueForStringParameter(stack, 'P1');
- Synth時に値を解決
1
const param1 = StringParameter.valueFromLookup(stack, 'P2');
- パラメータ・シークレットのリソース
1
2
3const param1ref =
StringParameter.fromStringParameterName(stack, 'P1Ref', 'P1');
Tags.of(bucker).add('Param1', param1ref.stringValue);
環境ごとにテンプレートを出しわける方法
- 外部のパラメータを読み込む方法
- スタックを定義する方法
リソースのインポート
CloudFormationへのリソースのインポート
cdk import
- 前提条件:テンプレートとリソースの設定はセット
- 現在のリソースの状態と一致するテンプレートを用意してインポートを実施(OSSのFormer2などを利用する)
インポート手順例
- Former2 で L1 Constructを生成
cdk import
- ドリフトがないことを確認
- Snapshot testを作成
- L2 Constructにリファクタリング
CloudFormation資産の活用
CloudFormationへのリソースのインクルード
CfnInclude
- CloudFormationのテンプレートを再利用
preserveLogicalIds: false
を指定することで論理IDの命名をCDKに任せられる(デフォルトtrue)- インクルードした添付れーどで作成したリソースは
getResource()
などでアクセス可能
CloudFormationスタックをCDKに移行
CfnInclude
を行うスコープのスタック名を合わせる- 通常はConstruct ID(
new Stack()
の第2引数) - Stage配下の場合は
stackName
プロパティを明示的に指定
- 通常はConstruct ID(
cdk diff
でBootstrap関連のパラメータや条件のみが追加されていることを確認
CloudFormationからCDKへの移行方法
- デプロイ済みのスタックを維持して移行
- デプロイ済みのスタックを変更しないため稼働中アプリへの影響を与えづらい
- スタック構成の変更やL2 Constructへのリファクタなどが段階的に行える
- リファクタ時にステート富楼那リソースの論理IDが変更される場合
overrideLogicakId()
で維持 - 移行手順
CfnInclude
で既存のスタック名と合わせてデプロイ- Snapshot testを作成・実行
- デプロイ済みのスタックを削除して移行
- ステートフルなリソースのみインポート対象にする
- 既存リソースの一部だけを利用したい場合に有効
- 移行手順
- CloudFormationで
DeletionPolicy: Retain
を設定 - CloudFormationスタックを削除
- CDKでスタックを作成
- cdk import