AWS SAM connectors を試してみた
前回と同じく、今回も AWS SAM ネタです。
下記の AWS ブログの記事を読んだので、 AWS SAM connectors を試してみたいと思います。
AWS SAM connectors は、AWS SAM テンプレートで指定するリソースタイプの一種で、サーバーレスアプリケーションを構成するコンポーネント間のアクセス権限設定を容易に指定することができます。
今回は、次のドキュメントの記載内容を少しアレンジして、Node.js の AWS Lambda 関数から Amazon DynamoDB のテーブルにアイテムを Put するシンプルなアプリケーションの権限を AWS SAM connectors を使って設定していきます。
前提として、この記事の内容は、2022年 10月 16日時点のものです。
東京リージョンを使用し、AWS Cloud9 を使用して SAM CLI version 1.52.0 のコマンドを発行します。
また、AWS アカウント ID は12桁すべて 0 で表記します。
ではまず、sam init
を実行します。今回は Node.js 16.x をランタイムに指定します。
sam init --runtime nodejs16.x
その後、対話形式で尋ねられる項目へは、次のように応答しました。今回は AWS X-Ray のトレースは有効化していません。
Which template source would you like to use? 1 - AWS Quick Start Templates 2 - Custom Template Location Choice: 1 Choose an AWS Quick Start application template 1 - Hello World Example 2 - Multi-step workflow 3 - Standalone function 4 - Scheduled task 5 - Data processing 6 - Serverless API Template: 1 Based on your selections, the only Package type available is Zip. We will proceed to selecting the Package type as Zip. Based on your selections, the only dependency manager available is npm. We will proceed copying the template using npm. Select your starter template 1 - Hello World Example 2 - Hello World Example TypeScript Template: 1 Would you like to enable X-Ray tracing on the function(s) in your application? [y/N]: Project name [sam-app]: sam-connectors-test
これで、SAM のリソースを取得できました。
次に、AWS Lambda 関数のコードを書き替えます。
今回だと、sam-connectors-test/hello-world/app.js というファイルが作成されているので、それを開きます。
そして、既存のコードをすべて削除し、次のコードに置換えます。
const AWS = require("aws-sdk"); const docClient = new AWS.DynamoDB.DocumentClient(); exports.handler = async (event, context) => { await docClient.put({ TableName: process.env.TABLE_NAME, Item: { id: context.awsRequestId, event: JSON.stringify(event) } }).promise(); }
このコードでは、環境変数で Amazon DynamoDB のテーブル名を取得して、リクエスト ID をキー属性に、イベントオブジェクトの内容をバリュー属性として Put を行っています。
では、次は SAM テンプレートを編集します。
今回だと、sam-connectors-test/template.yaml というファイルがあるので、それを開きます。
前述の AWS のドキュメントのサンプルの一部を流用、アレンジして、次のような内容にしました。
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > sam-connectors-test Sample SAM Template for sam-connectors-test # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst Globals: Function: Timeout: 3 Resources: MyTable: Type: AWS::Serverless::SimpleTable HelloWorldFunction: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: CodeUri: hello-world/ Handler: app.handler Runtime: nodejs16.x Architectures: - x86_64 Environment: Variables: TABLE_NAME: !Ref MyTable MyConnector: Type: AWS::Serverless::Connector Properties: Source: Id: HelloWorldFunction Destination: Id: MyTable Permissions: - Write Outputs: HelloWorldFunction: Description: "Hello World Lambda Function ARN" Value: !GetAtt HelloWorldFunction.Arn HelloWorldFunctionIamRole: Description: "Implicit IAM Role created for Hello World function" Value: !GetAtt HelloWorldFunctionRole.Arn
このテンプレート内の、MyConnector が AWS SAM connectors になります。
MyConnector: Type: AWS::Serverless::Connector Properties: Source: Id: HelloWorldFunction Destination: Id: MyTable Permissions: - Write
今回だと、HelloWorldFunction 関数から MyTable テーブルへの Write 権限を許可するという指定になります。 IAMポリシーを直接作成するよりは、シンプルな書き方といえますね。
では、ビルドしてデプロイを実行します。
今回は、デプロイで --guided
オプションをつけています。
cd sam-connectors-test sam build sam deploy --guided
--guided
オプション を付けた場合にプロンプトで求められる入力の例を記載しておきます。
Configuring SAM deploy ====================== Looking for config file [samconfig.toml] : Not found Setting default arguments for 'sam deploy' ========================================= Stack Name [sam-app]: sam-connectors-test AWS Region [ap-northeast-1]: #Shows you resources changes to be deployed and require a 'Y' to initiate deploy Confirm changes before deploy [y/N]: #SAM needs permission to be able to create roles to connect to the resources in your template Allow SAM CLI IAM role creation [Y/n]: #Preserves the state of previously provisioned resources when an operation fails Disable rollback [y/N]: Save arguments to configuration file [Y/n]: SAM configuration file [samconfig.toml]: SAM configuration environment [default]:
デプロイが正常に完了すると、次のようなメッセージが出力されます。
Successfully created/updated stack - sam-connectors-test in ap-northeast-1
また、今回の例だと次のような IAM ロールの ARN の Output があります。
これは、AWS Lambda 関数に付与された実行ロールの ARN になります。
Key HelloWorldFunctionIamRole Description Implicit IAM Role created for Hello World function Value arn:aws:iam::000000000000:role/sam-connectors-test-HelloWorldFunctionRole- WB0KUJXSC9YP
この IAM ロールの ARN うち、 arn:aws:iam::000000000000:role/より後のロールの名前の部分をメモします。
今回の例だと、sam-connectors-test-HelloWorldFunctionRole-WB0KUJXSC9YP になります。
そして、次のようにロール名を環境変数で指定して AWS CLI を実行し、ロールにアタッチされているポリシーの内容を表示してみましょう。
ROLE_NAME=sam-connectors-test-HelloWorldFunctionRole-WB0KUJXSC9YP aws iam list-attached-role-policies --role-name ${ROLE_NAME} --query "AttachedPolicies[].[PolicyArn]" --output text
出力例
arn:aws:iam::000000000000:policy/sam-connectors-test-MyConnectorPolicy-1LGRZ5UMK7FFY arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
出力結果のうち、MyConnector という文字を含んでいる ポリシーがあります。
これが、AWS SAM connectors により作成された IAM ポリシーになります。
この IAM ポリシーの ARN をメモして、次のように環境変数で指定して AWS CLI コマンドを実行します。
POLICY_ARN=arn:aws:iam::000000000000:policy/sam-connectors-test-MyConnectorPolicy-1LGRZ5UMK7FFY VERSION_ID=`aws iam get-policy --policy-arn ${POLICY_ARN} --query "Policy.DefaultVersionId" --output text` aws iam get-policy-version --policy-arn ${POLICY_ARN} --version-id ${VERSION_ID}
出力例
{ "PolicyVersion": { "CreateDate": "2022-10-16T01:29:31Z", "VersionId": "v1", "Document": { "Version": "2012-10-17", "Statement": [ { "Action": [ "dynamodb:PutItem", "dynamodb:UpdateItem", "dynamodb:DeleteItem", "dynamodb:BatchWriteItem", "dynamodb:PartiQLDelete", "dynamodb:PartiQLInsert", "dynamodb:PartiQLUpdate" ], "Resource": [ "arn:aws:dynamodb:ap-northeast-1:000000000000:table/sam-connectors-test-MyTable-1ONWBBRN2LWXQ", "arn:aws:dynamodb:ap-northeast-1:000000000000:table/sam-connectors-test-MyTable-1ONWBBRN2LWXQ/index/*" ], "Effect": "Allow" } ] }, "IsDefaultVersion": true } }
AWS SAM connectors により作成された IAM ポリシーの内容が確認できました。PutItem や UpdateItem や DeleteItem など Action として許可されていますね。
今回は、AWS Lambda 関数から、Amazon DynamoDB へのアクセスを例にしましたが、他にも次のようなパターンがサポートされているので、今後は他のパターンも試していきたいです!