AWS SAM の新しいリソースタイプ AWS SAM Connector が使えるようになりました

2022.10.08

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

いわさです。

AWS SAM で Connector なるものが発表されましたね。

SAM で使える新しいリソースタイプで、権限周りをうまく抽象化してくれるようです。
さっそく使ってみましょう。

従来

まずは Connector が無い従来はどうなっていたのかをおさらいしてみます。

ここではシンプルに Lambda から SNS へメッセージ発行を行うテンプレートを作ってみます。
権限周りを抜かすと多分最小だとこんな感じでしょう。

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

これをデプロイしてみましょう。

% sam deploy --template-file hoge.yaml --guided --profile hoge                         

:

Waiting for changeset to be created..
CloudFormation stack changeset
-------------------------------------------------------------------------------------------------------------------------
Operation                      LogicalResourceId              ResourceType                   Replacement                  
-------------------------------------------------------------------------------------------------------------------------
+ Add                          HogeFunctionRole               AWS::IAM::Role                 N/A                          
+ Add                          HogeFunction                   AWS::Lambda::Function          N/A                          
+ Add                          HogeTopic                      AWS::SNS::Topic                N/A                          
-------------------------------------------------------------------------------------------------------------------------

:

Successfully created/updated stack - hoge1008sam2 in ap-northeast-1

デプロイされた Lambda 関数の実行ロールを確認してみるとテンプレート上で指定したAWSLambdaBasicExecutionRoleのみが設定されています。
これは Lambda 関数が CloudWatch Logs などへログ出力を行うなどの最低限の実行ロールです。

この Lambda 関数を実行すると以下のように権限不足で失敗します。

そのため、従来の方法であれば追加で Lambda 関数が対象 SNS への Publish するための権限を付与する必要がありました。

Connector を使ってみる

では今回のアップデートで実装された 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

上記ハイライト部分です。
AWS::Serverless::Connectorという新しいリソースタイプを使っています。
プロパティとして設定するのは Source と Destination と Permissions です。
直感的でわかりやすいですね。Lambda 関数 から SNS トピックへの書き込みを許可するコネクターという感じです。

これをデプロイしてみます。

% sam deploy --template-file hoge.yaml --guided --profile hoge

:

Waiting for changeset to be created..
CloudFormation stack changeset
-------------------------------------------------------------------------------------------------------------------------
Operation                      LogicalResourceId              ResourceType                   Replacement                  
-------------------------------------------------------------------------------------------------------------------------
+ Add                          HogeConnectorPolicy            AWS::IAM::ManagedPolicy        N/A                          
+ Add                          HogeFunctionRole               AWS::IAM::Role                 N/A                          
+ Add                          HogeFunction                   AWS::Lambda::Function          N/A                          
+ Add                          HogeTopic                      AWS::SNS::Topic                N/A                          
-------------------------------------------------------------------------------------------------------------------------

:

Successfully created/updated stack - hoge1008sam in ap-northeast-1

先程と異なりAWS::IAM::ManagedPolicyが追加されていますね。
そしてこのマネージドポリシーが以下のように Lambda の実行ロールにアタッチされています。

これによって Lambda 関数から SNS トピックへの送信が出来るようなっています。

いいですね!

使う際に確認しておきたいドキュメント

以下ではAWS::Serverless::ConnectorSourceDestinationに指定出来る組み合わせと、組み合わせごとに設定出来るPermissionsが一覧化されています。
また、今回は Source と Destination に Id を指定しましたが、リソースによってはそれ以外に Role や Type を指定することも出来るのでもう少し許可の範囲を広くしたり柔軟な組み合わせを行うことも出来そうです。

そして、AWS::Serverless::Connectorによって作成される可能性のあるリソースは以下の案内がされています。

Destination が Lambda だったりすると、AWS::Lambda::Permissionが作成されそうですね。

さいごに

本日は AWS SAM の新しいリソースタイプ AWS SAM Connector を使ってみました。

CloudFormation でも SAM でも、権限周りに気をつけなければいけないケース意外に多くかつリソースごとにどの方法で権限を付与するか検討が必要ですが、今後は SAM の場合は適切なレベルのアクセス許可を簡単に設定することが出来そうです。
複雑なシナリオでもカバー出来るのかというのはもう少し確認が必要ですが、抽象化されて直感的に使えるのは SAM っぽくて良いですね。