Dev Study
AWSサービスの内部原理 コース

120. SAMはCloudFormationの方言である — Transformという『テンプレートを生成するテンプレート』

SAMを「別のデプロイツール」ではなく「CloudFormationのマクロ」として、短い宣言が定型部分ごと展開されていく変換の前後を図で追っていきます。

① SAMは別物ではなく拡張

SAMテンプレートAWS::Serverless::* の短縮構文で書ける
標準のCloudFormationリソースと同じテンプレート内に共存できる
素のCFnスタックデプロイの実体は常にこれ
SAMは「オープンソースの変換仕様」— GitHubで公開(魔法ではなく読めるコード)
  • 公式定義「AWS SAM Template - An extension of CloudFormation that provides simplified syntax for defining serverless resources.」
  • 「SAM resources work alongside standard CloudFormation resources in the same template.」
  • SAM本体は open-source framework、transform仕様は GitHub の aws/serverless-application-model で公開

SAMは独立したデプロイ基盤ではなく、CloudFormationの上に薄く乗った「短縮記法+それを展開する仕様」。だからSAMリソースと生のCloudFormationリソースは同じテンプレートに同居でき、既存スタックへ後付けもできる。

② スイッチはTransform宣言1行

テンプレート冒頭
満たすべき制約は3つ
Transform宣言Transform: AWS::Serverless-2016-10-31
この1行があると
トップレベル必須他セクション埋込×
リテラル文字列のみこの値そのまま
パラメータ/関数不可値を式で組み立て×
SAM構文が有効にAWS::Serverless::* が使えるようになる
  • 公式「you must declare it at the top level of your CloudFormation template. You can't use AWS::Serverless as a transform embedded in any other template section.」
  • 「The declaration must use the literal string AWS::Serverless-2016-10-31 as its value. You can't use a parameter or function to specify a transform value.」
  • 「a standalone declaration with no additional parameters.」

SAM構文を有効にする条件はただ一つ、テンプレート最上位にこのTransform行を書くこと。値は固定の合言葉で、変数や関数で動的に組み立てることはできない。これがマクロを起動する「#include」に当たる1行。

③ 3プロパティが2リソースに展開

Serverless::FunctionHandler: index.handler / Runtime: nodejs20.x / CodeUri: s3://...zip
変換前はこの3プロパティだけ
Lambda::FunctionCodeUri を Code の S3Bucket + S3Key に分解
Role: !GetAtt MyFunctionRole.Arn — この参照で右のロールと繋がる
IAM::Role書いていないのに自動生成(MyFunctionRole)
AWSLambdaBasicExecutionRole 付き
  • 公式の展開例より: CodeUri は s3://amzn-s3-demo-bucket/MySourceCode.zip → S3Bucket: amzn-s3-demo-bucket + S3Key: MySourceCode.zip に分解
  • 自動生成ロールは ManagedPolicyArns に arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole(基本実行権限)
  • 信頼ポリシー(AssumeRolePolicyDocument)は Principal: lambda.amazonaws.com が Action: sts:AssumeRole できる内容
  • 横並びの2リソース = 1つの短い宣言から生成されたもの

3行の宣言が、Lambda関数本体+実行ロールという2リソースに展開される。定型で毎回同じになる部分(ロール、信頼ポリシー、S3の分解)をエンジンが生成してくれる——これがSAMが「少ない記述」で済む正体。

④ 変換は変更セット作成時

テンプレート提出sam deploy など
このタイミングで CloudFormation が SAM構文を展開
変更セット作成change set
展開後テンプレート素のCloudFormation
スタックとして実行コンソール/差分で見えるのは展開後の姿
AWS::Lambda::Function と AWS::IAM::Role が並ぶ
  • 公式「When creating a change set from the template, CloudFormation expands the AWS SAM syntax, as defined by the transform.」
  • 変換はデプロイ側(CloudFormation)で起きるサーバーサイド処理

SAM構文が生のCloudFormationに化けるのは、変更セットを作る瞬間。だからデプロイの実体は常に素のCloudFormationスタックで、コンソールで確認できるのは展開後の姿。基礎への接続: 前レッスンまでに見た変更セット・ロールバック・ドリフトの仕組みは、土台がCloudFormationのまま変わらないのでSAMでもそっくり効く——CのプリプロセッサやTypeScript→JavaScriptのトランスパイルと同じで、高水準の記述を低水準の同等物へ機械変換しても、土台の意味論はそのまま通用する。

⑤ SAM CLIとCloudFormationの分業

sam initプロジェクトを初期化・新規作成する雛形
プロジェクトディレクトリ = SAMテンプレート+コード+設定
sam build次工程(ローカルテスト/デプロイ)に向けて準備
コードと依存をデプロイ可能な形に整える
sam localサブコマンドでローカルにテスト
Lambda関数のローカル実行・API Gatewayのシミュレート
sam deployCloudFormationを使ってAWSクラウドへデプロイ
成果物をS3へアップロードし、CloudFormationに渡す
sam syncローカルの変更をクラウドへ継続的に同期
開発・クラウドテストのループを高速化
  • 公式の "What it does" より — sam init「Provides options to initialize and create a new serverless application.」
  • sam build「Prepares an application for subsequent steps in the developer workflow, such as local testing or deploying to the AWS Cloud.」
  • sam local「Provides subcommands to test your serverless applications locally.」
  • sam deploy「Deploys an application to the AWS Cloud using CloudFormation.」(デプロイ時に成果物をS3バケットへアップロードする)
  • sam sync「Provides options to quickly sync local application changes to the AWS Cloud.」

SAM CLIは開発ライフサイクル(雛形→ビルド→ローカルテスト→デプロイ→継続同期)を担う道具箱だが、最後にインフラを作る実行エンジンはあくまでCloudFormation。締め: 開発体験はSAM CLI、デプロイの実行エンジンはCloudFormation——この役割分担さえ掴めば、SAMは「CloudFormationの前に立つ変換器」として一枚の絵に収まる。基礎への接続: Lambda編で手書きしていた実行ロールの正体は、この変換エンジンが生成する定型リソースだった、という種明かしでもある。

公式ドキュメントで詳しく ↗