【AWS SAM】複数テンプレートで値をエクスポートして共有する「クロススタック参照」の書き方
対象読者: AWS SAMを利用したサーバーレスアプリケーションのデプロイを行ったことがある人
複数のSAMテンプレートで値を共有して利用しよう、という話です。
CloudFormationのクロススタック機能を使っているだけなので、書き方も一緒です。
例えばDynamoDBテーブル名、レイヤー名、S3バケット名などが複数テンプレートで共有したい値になるかと思います。
手順は以下の流れになります。
1. 共有したい値をリソースを作成する側のテンプレートでOutPutで記載する。
2. 共有される側のテンプレートでInportValueを用いて利用する。
※注意点: LayerのARNを共有しようとすると、レイヤーの更新が行えなくなるのでLayerを複数テンプレートで共有したい場合はレイヤー名のみ共有し、バージョンは手入力するなどの対応が必要になります。
それでは、手順について詳しく説明していきます。
【複数テンプレートで値を共有】前提条件
AとBのSAMテンプレートを用意すると仮定します。
A: DynamoDBテーブルをデプロイする
B: LambdaでDynamoDBテーブルにアクセスするのでIAMの権限が欲しい
1. 【複数テンプレートで値を共有】共有したい値をOutPutに記載してSAMデプロイを行う
まず、Aのテンプレート。template.yamlの記載方法を紹介します。
Mappingsにて、環境変数にテーブル名を設定している場合を考えます。
共有したい値はDynamoDBのテーブル名とします。
※簡易的に表示するため、DynamoDBのリソースを宣言する部分等、関係無い部分は省いています。
Parameters:
Environment:
Type: String
AllowedValues:
- dev
Mappings:
EnvironmentMap:
dev:
TableName: UserMasterTable
OutPuts:
MasterTable:
Description: "User info stored table"
Value: !FindInMap [EnvironmentMap, !Ref Environment, TableName]
Export:
Name: UserMasterTableName
さて、ここまで出来たらあとは値を使いたい側のテンプレートでインポートを行うだけです。
同リージョン内のテンプレートであれば、他の設定は必要なくインポート可能です。
2. 【複数テンプレートで値を共有】共有したい値を !ImportValue で記載する
Bのインポートする側のテンプレートを記載します。
!ImportValueという関数を使うことで、同一アカウント同一リージョン内でExportされた他テンプレートの値を使うことが出来ます。
先ほどエクスポートで指定した"Name"の部分を入力してあげましょう。
!ImportValue UserMasterTableName
このように記載してあげれば、Aのテンプレートで指定したDynamoDBのテーブル名を取得することが可能です。
さて、IAMポリシーのリソース部分に記載するには以下のようになります。ついでに !Join 関数の書き方も見てしまいましょう。
LambdaRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service:
- lambda.amazonaws.com
Policies:
- PolicyName: DynamoTableAccess
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- dynamodb:GetItem
Resource:
- !Join
- ""
- - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/"
- !ImportValue UserMasterTableName
最後の部分がImportしている部分ですね。
!Joinの書き方が少し面倒くさいので、確認してください。
特に、インデントがズレるとエラーになってしまうので、注意しましょう。私は何度もJoinのインデントでエラーを起こしました。
!Subを用いてリージョンやアカウントIDを取得することもできます。
これらを用いて、ARNの文字列を生成しているわけです。
まとめ
値をエクスポートすることで、多数のテンプレートで使っている値を全てのテンプレートで変更する必要がなくなります。
今回の場合だと、「DynamoDBのテーブル名を変更したい!」となったときに、一つのテンプレートだけ変えればいいので楽ですね。
今回はこの辺りで終わりにしたいと思います。
為になったら、スキしてください。
この記事が気に入ったらサポートをしてみませんか?