いわさです。
AWS SAM ではリソースの実行ポリシーなどの記述を簡略化出来る SAM Connector という機能があり、以前紹介させて頂きました。
本日こちらに関連した次のアップデートがあり、SAM Connector を定義する際に新しい方法が使えるようになっています。
別の SAM リソースではなく、ソースリソースの属性としてインラインで定義出来るように
例えば Lambda から SNS トピックへメッセージを送信する場合だと、Lambda へ SNS への送信許可ポリシーを与えてやる必要があります。
以前までは SAM Connector を使って以下のように定義することが出来ました。ハイライト部分です。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: ---
Resources:
HogeFunction:
Type: AWS::Serverless::Function
Properties:
Runtime: python3.9
Handler: index.lambda_handler
InlineCode: !Sub |
import boto3
client = boto3.client('sns')
def lambda_handler(event, context):
params = {
'TopicArn': '${HogeTopic}',
'Message': 'hoge message from lambda'
}
client.publish(**params)
MemorySize: 128
Timeout: 100
Architectures:
- x86_64
Policies:
- AWSLambdaBasicExecutionRole
HogeTopic:
Type: AWS::SNS::Topic
HogeConnector:
Type: AWS::Serverless::Connector
Properties:
Source:
Id: HogeFunction
Destination:
Id: HogeTopic
Permissions:
- Write
これでカスタムマネージドポリシーが作成されて Lambda の実行ロールにアタッチされます。
この時点で抽象化されているので個人的には最高なのですが、言われてみれば確かに Lambda 関数とちょっと離れて定義してあるので、コードを読む際などにはひとつコンテキストが増えるような印象があります。
今回のアップデートによって次のように、ソースリソースの Connectors プロパティ内に定義することが出来るようになりました。
コネクター内の記述方法は以前と同じですが、Source プロパティは対象リソースになるので記述が不要になっています。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: ---
Resources:
HogeFunction:
Type: AWS::Serverless::Function
Connectors:
HogeConnector:
Properties:
Destination:
Id: HogeTopic
Permissions:
- Write
Properties:
Runtime: python3.9
Handler: index.lambda_handler
InlineCode: !Sub |
import boto3
client = boto3.client('sns')
def lambda_handler(event, context):
params = {
'TopicArn': '${HogeTopic}',
'Message': 'hoge message from lambda'
}
client.publish(**params)
MemorySize: 128
Timeout: 100
Architectures:
- x86_64
Policies:
- AWSLambdaBasicExecutionRole
HogeTopic:
Type: AWS::SNS::Topic
IAM ロールやセキュリティグループなどで、個別のルールやポリシーをインラインで定義するべきか否かみたいなところはあると思いますが、SAM の場合は AWS リソースに対する抽象化度合いが良い感じなのが良い点のひとつだと思っています。
例えば詳細な設定の API Gateway とかを CloudFormation で定義すると様々なリソースを組み合わせる必要があって少し苦労しますが SAM だと楽に定義出来る上に後からコードを読んでもスタック全体の構造が直感的に理解しやすいです。
ちなみに作成されるリソースとしては以前と変わらず、カスタムマネージドポリシーが Lambda 実行ロールにアタッチされています。
今回リソース内に定義出来るので関係するリソースが増えても、例えば次のようにトピックが増えたとしても Connectors 内にまとまるので、コード見るだけでポリシーとして網羅されてるのかもすぐわかるようになりましたね。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: ---
Resources:
HogeFunction:
Type: AWS::Serverless::Function
Connectors:
HogeConnector:
Properties:
Destination:
Id: HogeTopic
Permissions:
- Write
FugaConnector:
Properties:
Destination:
Id: FugaTopic
Permissions:
- Write
Properties:
Runtime: python3.9
Handler: index.lambda_handler
InlineCode: !Sub |
import boto3
client = boto3.client('sns')
def lambda_handler(event, context):
params = {
'TopicArn': '${HogeTopic}',
'Message': 'hoge message from lambda'
}
client.publish(**params)
MemorySize: 128
Timeout: 100
Architectures:
- x86_64
Policies:
- AWSLambdaBasicExecutionRole
HogeTopic:
Type: AWS::SNS::Topic
FugaTopic:
Type: AWS::SNS::Topic
ソース側での定義が必要
以前まではどちらかというと 2 つのリソースの間に存在するコンポーネントの位置づけという印象だったのですが、今回の機能は送信元リソース側での定義となります。
次のように送信先リソースで、以前のように Source プロパティのみを定義して試してみました。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: ---
Resources:
HogeFunction:
Type: AWS::Serverless::Function
Properties:
Runtime: python3.9
Handler: index.lambda_handler
InlineCode: !Sub |
import boto3
client = boto3.client('sns')
def lambda_handler(event, context):
params = {
'TopicArn': '${HogeTopic}',
'Message': 'hoge message from lambda'
}
client.publish(**params)
MemorySize: 128
Timeout: 100
Architectures:
- x86_64
Policies:
- AWSLambdaBasicExecutionRole
HogeTopic:
Type: AWS::SNS::Topic
Connectors:
HogeConnector:
Type: AWS::Serverless::Connector
Properties:
Source:
Id: HogeFunction
Permissions:
- Write
しかし、次のように Destination が必須というエラーが発生します。
今回の機能を使う場合は送信元リソースへの定義が必要です。
早速英語版ドキュメントも更新されていましたので、利用にあたって以下も確認頂くと良いと思います。
さいごに
本日は AWS SAM Connector がリソース属性として定義出来るようになったので使ってみました。
地味ですが使い勝手が良くなりそうで、私は嬉しいですね。
利用はオプションで、従来のようにコネクターリソースを分けたりあるいはポリシーで直接記述する使い方も引き続き出来るので、気の向いた時にでも使ってみてください。