SAM(AWS Serverless Application Model)とは
YAML形式でAWSリソース(Lambda、API Gateway、DynamoDBなど)を定義するIaCツール。
Resources:
HelloFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs22.x
# 普通のクラウドフォーメーションでAPI Gateway&Lambdaの構成を書こうとすると色々リソース定義しないといけないがSAMなら少ないコードで書ける
Events:
Api:
Type: Api
Properties:
Path: /hello
Method: get
MyApi:
Type: AWS::Serverless::Api
Properties:
Name: my-proxy-api
StageName: dev
EndpointConfiguration: REGIONAL
SAMのインストール方法
下記リンクを参考にCLIインストール
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html
確認
sam --version
デプロイ方法
sam build
sam deploy --guided
--guided
は最初だけで、以降は samconfig.toml
に設定が保存される。
Lambda エイリアスとステージの関連付け
Resources:
HelloFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: hello
MemorySize: 1024
Timeout: 10
Environment:
Variables:
TABLE_NAME: !Ref DynamoTable
Layers:
- !Ref Layer
Handler: index.handler
Runtime: nodejs22.x
# ここが重要
AutoPublishAlias: !Ref StageName
DeploymentPreference:
Type: AllAtOnce
こう書くことで、ステージ別デプロイが可能に。
API Gateway とのバインドも StageName
と AutoPublishAlias
を合わせればOK!
デプロイ後のトラフィック切り替え
-
AWS::Serverless::Function
のリソースで以下のように書けば全部一気に更新、段階的に更新、など設定可能
DeploymentPreference:
Type: AllAtOnce
Type | 意味 |
---|---|
AllAtOnce | 一気に新バージョンへ切替 |
Canary10Percent5Minutes | 10%流して5分様子見、問題なければ残り90% |
Linear10PercentEvery1Minute | 1分ごとに10%ずつ段階的に切替 |
Linear10PercentEvery10Minutes | 10分ごとに10%ずつ |
作成したリソースをコンソールから手でいじったらどうなる?
-
上書きされる。
ただし次回sam deploy
すると テンプレに定義された内容で再構築されるから注意⚠️
デプロイ前に差分確認できる?
sam deploy --guided --no-execute-changeset
で CloudFormation の差分(change set)を確認できる
本番前チェックにおすすめ!
環境変数ファイルみたいなものの作り方
-
parameter_overrides
を使って SAM 側に渡す - samconfig.tomlに以下のように記載することで
sam build --config-env dev
としたときに[dev.deploy.parameters]
が使われるようになる
[dev.deploy.parameters]
stack_name = "hello-app"
s3_bucket = "hello-app-sam-artifact-bucket"
s3_prefix = "hello"
region = "us-west-2"
capabilities = "CAPABILITY_NAMED_IAM"
confirm_changeset = true
parameter_overrides = "StageName=dev Prefix=test"
通常のCloudFormationのリソースも一緒に書ける?
- 書ける
組み込み関数について
- !Subとか!Refとかをよく使う
- !Subは変数展開用
-
FunctionName: !Sub ${Prefix}-test
みたいな感じで使う
-
- !Refはリソース参照用
-
RestApiId: !Ref Api
みたいな感じで使う - Arnを取得したいときは
RestApiId: !Ref Api.Arn
のように書く
-
template.yamlは分割できる?
- 出来ないっぽい?
- シェルスクリプトとかで対応は可能
#!/bin/bash
OUT_FILE="template.yaml"
BASE_FILE="base.yaml"
PARTIALS=(lambda1.yaml lambda2.yaml)
# base.yaml の Resources以外を抽出
awk '
BEGIN {in_resources=0}
/^Resources:/ {in_resources=1; next}
in_resources==0 {print}
' "$BASE_FILE" > "$OUT_FILE"
echo "Resources:" >> "$OUT_FILE"
# 各パーシャルYAMLからResources配下だけ抽出して追加
for f in "${PARTIALS[@]}"; do
awk '
/^Resources:/ {in_resources=1; next}
in_resources==1 && /^[^ ]/ {exit} # 次のトップレベルきたら終了
in_resources==1 {print " " $0}
' "$f" >> "$OUT_FILE"
done