AWS SAMで小さいサービスを作る機会があったので、地味に戸惑ったことを書き残しておく。
前置き
今更ですが一応、AWS SAMとはAWS Serverless Application Modelの略で、AWSでサーバーレスアプリケーションを開発するためのフレームワークである。というといまいち何だか分からないが、少しAWSを分かっている人に極力平たくその一側面を説明すると、CloudFormationの拡張ということになる。
CloudFormationと同じノリで、例えば AWS::Serverless::Function
というリソースタイプを定義すると、LambdaFunctionおよびそれをトリガーするイベントソースとのマッピング、必要なIAMロールなどをまとめて作成してくれる。
ベースはCloudFormationなので、CloudFormationのテンプレートと同じ構文でその他のリソースも定義できる。
本題
例えばCloudFormationで AWS::Lambda::Function
リソースにタグを指定したい場合は以下のように書く。
BenriFunction:
Type: AWS::Lambda::Function
Properties:
....
Tags:
- Key: "service"
Value: "benri-service"
- Key: "environment"
Value: "production"
であれば AWS::Serverless::Function
でタグを指定したい場合、以下のようにしたくなるのが人情である。
BenriFunction:
Type: AWS::Serverless::Function
Properties:
....
Tags:
- Key: "service"
Value: "benri-service"
- Key: "environment"
Value: "production"
しかしこれは間違いで、デプロイ時にエラーとなってしまう。
ここではじめてドキュメントを見ると、SAMのほうは Tags
のTypeはMapであると書いてある。
AWS::Serverless::Function - AWS Serverless Application Model
対してCloudFormationのほうは Tags
のTypeはListである。
AWS::Lambda::Function - AWS CloudFormation
というわけで、AWS::Serverless::Function
のほうは以下のように書く必要がある。
BenriFunction:
Type: AWS::Serverless::Function
Properties:
....
Tags:
service: "benri-service"
environment: "production"
これは AWS::Serverless
配下のリソースで共通の仕様のようだった。
先述の通りSAMはCloudFormationの拡張なので、同じテンプレートにまとめて従来のCloudFormationのリソース定義も書くことができる。すると複数のタグの指定方法が混在することになる。どうしてこんな仕様にしたんだろう。
並のヤムラーは息を吸うようにコピペする習性がある(偏見)ため、私と同じような間違いをおかす方が多いのではないでしょうか。お気をつけください。そしてちゃんとドキュメントは読みましょう(お前が)。
以上です。