サービスの違い
AWSでは、インフラ構成をコードで管理する仕組みを IaC(Infrastructure as Code) と呼ぶ。
| サービス | 主な役割 | DVAでの重要ポイント |
|---|---|---|
| CloudFormation | AWSリソースをテンプレートで定義・管理 | Stack、Change Set、Rollback |
| AWS SAM | サーバーレスアプリを簡潔に定義・開発 | sam build、sam local、sam deploy |
| AWS CDK | プログラミング言語でインフラを定義 | Construct、cdk synth、cdk deploy |
3つは完全に独立した仕組みではない。
CloudFormation
↑
├── SAM
│ └── サーバーレス向けの簡潔な記法
│
└── CDK
└── プログラミング言語から
CloudFormationテンプレートを生成
CloudFormationの基本構造
CloudFormationは、YAMLまたはJSONのテンプレートでAWSリソースを定義する。
AWSTemplateFormatVersion: '2010-09-09'
Description: Sample Lambda Stack
Parameters:
Environment:
Type: String
Default: dev
Resources:
SampleFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: !Sub 'sample-${Environment}'
Runtime: python3.12
Handler: index.handler
Role: !GetAtt LambdaExecutionRole.Arn
Code:
S3Bucket: my-deployment-bucket
S3Key: lambda.zip
Outputs:
FunctionArn:
Value: !GetAtt SampleFunction.Arn
※上記はテンプレートの構造を説明するための抜粋。LambdaExecutionRole は別途定義が必要。
主なセクション
| セクション | 用途 |
|---|---|
Parameters |
デプロイ時に渡す値 |
Resources |
作成するAWSリソース |
Outputs |
作成したリソースの情報を出力 |
Conditions |
条件によって作成内容を変更 |
Mappings |
固定的な対応表を定義 |
Transform |
SAMなどの変換処理を指定 |
ResourcesがCloudFormationテンプレートの中心。
CloudFormationの組み込み関数
| 関数 | 役割 |
|---|---|
Ref |
パラメータやリソースの値を参照 |
Fn::GetAtt |
リソースの属性を取得 |
Fn::Sub |
文字列に変数を埋め込む |
Fn::Join |
文字列を結合 |
Fn::ImportValue |
別スタックのExport値を参照 |
Fn::If |
条件によって値を切り替える |
RefとGetAttの違い
Resources:
MyBucket:
Type: AWS::S3::Bucket
Outputs:
BucketName:
Value: !Ref MyBucket
BucketArn:
Value: !GetAtt MyBucket.Arn
この例では:
-
!Ref MyBucket→ バケット名 -
!GetAtt MyBucket.Arn→ バケットARN
ただし、Ref が返す値はリソース種別によって異なる。
「リソースのARNが必要」→ GetAttを確認。
Fn::Sub
BucketArn:
Value: !Sub 'arn:aws:s3:::${MyBucket}'
文字列へ変数を埋め込む場合に利用する。
CloudFormationのスタック更新
CloudFormationでは、関連するAWSリソースをスタック(Stack) として管理する。
CloudFormation Template
|
v
Stack
|
+-- Lambda
+-- API Gateway
+-- DynamoDB
+-- IAM Role
テンプレートを変更し、スタックを更新することでリソース構成を変更できる。
ただし、更新方法はリソースやプロパティによって異なる。
| 更新方法 | 内容 |
|---|---|
| 中断なしの更新 | リソースを置き換えずに更新 |
| 一時的な中断を伴う更新 | 更新中に影響が出る可能性がある |
| Replacement | リソースを置き換える |
テンプレートの変更が、必ず既存リソースのインプレース更新になるとは限らない。
Change Set
Change Setは、スタック更新前に変更内容を確認する仕組み。
テンプレート変更
|
v
Change Set作成
|
v
変更内容を確認
|
+-- Modify
+-- Add
+-- Remove
|
v
Change Set実行
|
v
スタック更新
例えば、更新によってRDSインスタンスが置き換えられる可能性がある場合、実行前に確認するために利用できる。
ただし、Change Setは実行結果を完全に保証するものではない。
Drift Detectionとの違い
| 機能 | 目的 |
|---|---|
| Change Set | これから適用する変更を確認 |
| Drift Detection | テンプレートと実際のリソース状態の差異を検出 |
「更新前の影響確認」→ Change Set。
「手動変更による構成差分を検出」→ Drift Detection。
CloudFormationのロールバック
スタックの作成・更新に失敗した場合、CloudFormationはロールバックを行う。
更新失敗時の例
UPDATE_IN_PROGRESS
|
v
リソース更新失敗
|
v
UPDATE_ROLLBACK_IN_PROGRESS
|
v
UPDATE_ROLLBACK_COMPLETE
重要なステータス
| ステータス | 意味 |
|---|---|
CREATE_COMPLETE |
作成成功 |
UPDATE_COMPLETE |
更新成功 |
ROLLBACK_COMPLETE |
作成失敗後のロールバック完了 |
UPDATE_ROLLBACK_COMPLETE |
更新失敗後のロールバック完了 |
UPDATE_ROLLBACK_FAILED |
更新ロールバック自体が失敗 |
UPDATE_ROLLBACK_FAILED の場合は、原因を解消したうえで ContinueUpdateRollback を利用する場合がある。
作成失敗のROLLBACKと、更新失敗のUPDATE_ROLLBACKは区別する。
DeletionPolicyとUpdateReplacePolicy
CloudFormationでは、リソースを削除・置換する際の扱いを指定できる。
DeletionPolicy
Resources:
MyBucket:
Type: AWS::S3::Bucket
DeletionPolicy: Retain
Retain を指定すると、スタック削除時などにリソースを残せる。
UpdateReplacePolicy
Resources:
MyDatabase:
Type: AWS::RDS::DBInstance
UpdateReplacePolicy: Snapshot
リソース置換時に、古いリソースをどう扱うか指定する。
| 属性 | 対象 |
|---|---|
DeletionPolicy |
スタック削除やテンプレートからの削除 |
UpdateReplacePolicy |
更新によるリソース置換 |
代表的な指定値は Delete、Retain、対応リソースでの Snapshot。
「スタック削除後もデータを残したい」→ DeletionPolicy。
「置換される旧リソースを残したい」→ UpdateReplacePolicy。
CloudFormationのスタック間連携
複数のスタック間で値を共有する場合、Export と Fn::ImportValue を利用できる。
出力側
Outputs:
SharedBucketName:
Value: !Ref MyBucket
Export:
Name: SharedBucketName
参照側
Parameters:
Dummy:
Type: String
Default: sample
Resources:
ExampleParameter:
Type: AWS::SSM::Parameter
Properties:
Type: String
Name: /sample/bucket
Value: !ImportValue SharedBucketName
ただし、クロススタック参照には制約がある。
- 同じAWSアカウント・リージョン内で利用する
- ImportされているExport値は自由に変更・削除できない
「別スタックの出力値を参照」→ Export / ImportValue。
CloudFormationのIAM権限
CloudFormationがIAMリソースを作成・変更する場合、デプロイ時に能力宣言が必要になることがある。
| 宣言 | 主な用途 |
|---|---|
CAPABILITY_IAM |
IAMリソースの作成・変更を承認 |
CAPABILITY_NAMED_IAM |
明示的な名前を持つIAMリソースを含む場合 |
CAPABILITY_AUTO_EXPAND |
特定のマクロ・変換を伴うテンプレートを直接実行する場合など |
CloudFormationサービスロール
CloudFormationにサービスロールを指定すると、そのロールの権限でリソース操作を実行する。
デプロイ実行者
|
v
CloudFormation
|
| サービスロール
v
Lambda / IAM / S3などを作成
デプロイ実行者の権限と、CloudFormationが実際に使用する権限は分けて考える。
AWS SAMとは
AWS SAM(Serverless Application Model)は、サーバーレスアプリケーションを簡潔に定義するためのフレームワーク。
Lambda、API Gateway、DynamoDBなどを組み合わせた構成を扱いやすい。
SAMテンプレートの書き方
SAMテンプレートでは、Transform が重要。
Transform: AWS::Serverless-2016-10-31
Globals:
Function:
Runtime: python3.12
Timeout: 10
MemorySize: 256
Resources:
HelloFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Handler: app.lambda_handler
Events:
HelloApi:
Type: Api
Properties:
Path: /hello
Method: get
※AWS::Serverless-2016-10-31 は、AWSが定義したSAM Transformの固定識別子。任意の名前には変更できず、CloudFormationがSAM構文を変換するために使用する。
各項目の意味
| 項目 | 役割 |
|---|---|
Transform |
SAMテンプレートとして変換 |
Globals |
複数リソースで共通する設定 |
CodeUri |
Lambdaコードの場所 |
Handler |
実行する関数 |
Events |
Lambdaを起動するイベント |
この例では、GET /hello に対応するLambda関数を定義している。
SAMのEventsとIAM Policies
SAMでは、Lambdaを起動するイベントをテンプレートで定義できる。
SQSイベントの例
Resources:
WorkerFunction:
Type: AWS::Serverless::Function
Properties:
Runtime: python3.12
Handler: app.lambda_handler
CodeUri: worker/
Events:
QueueEvent:
Type: SQS
Properties:
Queue: !GetAtt WorkQueue.Arn
BatchSize: 10
WorkQueue:
Type: AWS::SQS::Queue
SAMが必要なイベントソースマッピングなどのCloudFormationリソースを生成する。
ただし、イベントを定義しただけで、アプリケーションが必要とするすべてのIAM権限が自動付与されるわけではない。
Policies
SAMでは、Lambdaの実行ロールに対する権限を簡潔に指定できる。
Policies:
- DynamoDBReadPolicy:
TableName: !Ref OrdersTable
このようなポリシーテンプレートを利用すると、対象リソースに必要な権限を付与しやすい。
「SAMでLambdaのIAM権限を簡潔に定義」→ Policies / Policy Templates。
SAM CLIの基本コマンド
| コマンド | 用途 |
|---|---|
sam init |
SAMプロジェクト作成 |
sam build |
アプリケーションをビルド |
sam validate |
SAMテンプレートを検証 |
sam local invoke |
Lambdaをローカルで実行 |
sam local start-api |
APIをローカルで起動 |
sam deploy |
AWSへデプロイ |
sam sync |
開発中の変更をAWSへ同期 |
基本的な開発フロー
sam init
|
v
コードを書く
|
v
sam build
|
v
sam local invoke
|
v
sam deploy
|
v
CloudFormation Stack
sam build
sam build
依存ライブラリなどを含めてビルドし、通常は .aws-sam/build に成果物を作成する。
sam local invoke
sam local invoke HelloFunction
Dockerを利用し、Lambdaに近い実行環境で関数をローカル実行する。
ただし、AWS上の実行環境を完全に再現するわけではない。
sam local start-api
sam local start-api
ローカルHTTPエンドポイントを起動し、API経由でLambdaをテストできる。
「Lambdaを単体でローカル実行」→ sam local invoke。
「API Gateway経由の処理をローカル確認」→ sam local start-api。
sam deployとsam sync
sam deploy
sam deploy --guided
初回デプロイでは --guided を利用すると、スタック名やリージョンなどを対話形式で設定できる。
設定は samconfig.toml に保存できる。
以降は次のように実行できる。
sam build
sam deploy
SAMは、必要な成果物をS3やECRへアップロードし、CloudFormationを通じてリソースをデプロイする。
sam sync
sam sync --watch
sam sync は、開発中の変更をAWS環境へ同期するためのコマンド。
--watch を指定すると、ファイル変更を監視して同期できる。
ローカルコードを変更
|
v
sam sync --watch
|
v
AWS開発環境へ反映
使い分け
| 要件 | コマンド |
|---|---|
| 正式なデプロイ | sam deploy |
| ローカルでLambda実行 | sam local invoke |
| ローカルAPIテスト | sam local start-api |
| 開発中の変更を迅速に反映 | sam sync --watch |
sam sync は開発環境での反復作業に適している。
本番デプロイでは、検証された成果物を使った管理されたデプロイを優先する。
SAMのデプロイ方式とCanary
SAMでは、Lambdaの段階的デプロイを定義できる。
AutoPublishAlias
Resources:
HelloFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Handler: app.lambda_handler
Runtime: python3.12
AutoPublishAlias: live
DeploymentPreference:
Type: Canary10Percent5Minutes
動作イメージ
Lambda Alias: live
|
+-- 旧Version 90%
|
+-- 新Version 10%
|
v
5分後
|
v
新Version 100%
SAMの DeploymentPreference は、Lambdaのバージョン・エイリアスとCodeDeployを利用した段階的デプロイを構成する。
主な方式
| 方式 | 特徴 |
|---|---|
| Canary | 一部のトラフィックを新バージョンへ流し、後で切り替える |
| Linear | 一定間隔で段階的に増やす |
| AllAtOnce | 一度に切り替える |
「SAMでLambdaのCanaryデプロイ」→ AutoPublishAlias + DeploymentPreference。
CloudFormationのNested StackとStackSets
Nested Stack
Nested Stackは、CloudFormationスタックを別のスタックから呼び出す仕組み。
親Stack
|
+-- Network Stack
|
+-- Database Stack
|
+-- Application Stack
共通の構成を再利用したい場合に便利。
StackSets
StackSetsは、複数アカウント・複数リージョンへスタックを展開する仕組み。
StackSet
|
+-- Account A / 東京
|
+-- Account B / 東京
|
+-- Account C / 大阪
| 要件 | 選択 |
|---|---|
| テンプレートを分割して再利用 | Nested Stack |
| 複数アカウント・リージョンへ展開 | StackSets |
CloudFormationのCustom Resource
CloudFormationの標準リソースでは対応できない処理を、Custom Resourceで実行できる。
例えば、スタック作成時に独自の初期化処理を行いたい場合。
CloudFormation Stack
|
v
Custom Resource
|
v
Lambdaなどで独自処理
|
v
CloudFormationへ結果を返す
重要なのは、Custom Resourceの処理結果をCloudFormationへ返す必要があること。
応答しないと、スタック操作がタイムアウトする原因になる。
また、作成・更新・削除それぞれのイベントに対応した実装が必要になる場合がある。
CloudFormationのDynamic Reference
CloudFormationでは、Secrets ManagerやParameter Storeの値を動的参照できる。
MasterUserPassword: '{{resolve:secretsmanager:my-db-secret:SecretString:password}}'
秘密情報をテンプレートに直接書かずに済む。
ただし、シークレットがローテーションされても、CloudFormationで作成したリソースの設定が自動更新されるわけではない。
さらに、スタック更新を実行しても、対象リソースが更新されなければ動的参照が再取得されない場合がある。
AWS CDKとは
AWS CDK(Cloud Development Kit)は、プログラミング言語でAWSインフラを定義するフレームワーク。
TypeScript、Python、Java、C#などの言語を利用できる。
CDKの構造
CDK App
|
+-- Stack
|
+-- Construct
|
+-- Construct
|
+-- Construct
Constructのレベル
| レベル | 特徴 |
|---|---|
| L1 | CloudFormationリソースに近い低レベル構成 |
| L2 | 使いやすい抽象化と便利なデフォルト設定 |
| L3 | 複数リソースを組み合わせた高レベルパターン |
L1とL2の例
TypeScriptの例:
import * as s3 from 'aws-cdk-lib/aws-s3';
// L1 Construct
new s3.CfnBucket(this, 'RawBucket');
// L2 Construct
new s3.Bucket(this, 'AppBucket', {
versioned: true
});
L1ではCloudFormationに近いプロパティを扱う。
L2では、CDKが提供する便利なAPIやデフォルト設定を利用できる。
「CloudFormationに近い細かな定義」→ L1。
「簡潔にリソースを定義」→ L2。
CDKの基本コマンド
| コマンド | 用途 |
|---|---|
cdk init |
CDKプロジェクト作成 |
cdk bootstrap |
CDKデプロイに必要な環境を準備 |
cdk synth |
CloudFormationテンプレート生成 |
cdk diff |
デプロイ前の変更差分を表示 |
cdk deploy |
スタックをデプロイ |
cdk destroy |
スタックを削除 |
CDKのデプロイフロー
CDKコード
|
| cdk synth
v
CloudFormationテンプレート
|
| cdk deploy
v
CloudFormation Stack
|
v
AWSリソース
cdk bootstrap
cdk bootstrap
CDKのデプロイに必要なS3バケット、IAMロールなどの環境を準備する。
通常は対象のAWSアカウント・リージョンごとに実施する。
cdk synth
cdk synth
CDKコードからCloudFormationテンプレートを生成する。
AWSリソースをデプロイするコマンドではない。
cdk diff
cdk diff
現在デプロイされているスタックと、CDKコードから生成した構成との差分を確認する。
cdk deploy
cdk deploy
CloudFormationを利用してAWSリソースを作成・更新する。
CDKのTokenと環境依存値
CDKでは、デプロイ時まで確定しない値をTokenとして扱う。
例えば、作成予定のリソースのARNなど。
const bucket = new s3.Bucket(this, 'MyBucket');
console.log(bucket.bucketArn);
bucket.bucketArn は、CDKの実行時点では最終的な文字列として確定していない場合がある。
Tokenの注意点
- CDKコード実行時に値が確定しているとは限らない
- CloudFormationで解決される値がある
- 通常の文字列と同じ感覚で加工すると問題になる場合がある
「CDKでARNがまだ確定していない」→ Token。
SAM・CloudFormation・CDKの使い分け
| 要件 | 選択 |
|---|---|
| AWSリソースをYAMLで定義 | CloudFormation |
| サーバーレスアプリを簡潔に定義 | SAM |
| Lambdaをローカル実行 | SAM CLI |
| APIをローカルテスト | SAM CLI |
| プログラミング言語でインフラを定義 | CDK |
| CloudFormationテンプレートを生成 | cdk synth |
| 更新前に変更を確認 | Change Set / cdk diff
|
| 複数アカウントへ同じ構成を展開 | StackSets |