概要
先日AWS CDK Conference Japan 2022
でCDK開発にSAMを取り入れている方がいらっしゃいました。SAMはなくなんとなーく知っている程度だったのですが、CDKのローカルテストに使うことができたりと面白そうだなと思ったのでサービスの概要からCDKで作成したテンプレートをSAM CLIでテストするまでの流れについて調べてみました。
AWS SAMとは
結論から言うとSAMはCloudFormationのTransform機能です。これを聞いて納得した方はこの章はスキップしてください。以下ではもう少し噛み砕いて説明します。
AWS SAMとはServerless Application Modelと呼ばれるAWSが提供するIaCサービスです。SAMはサーバーレスサービスに特化したIaCでYAMLとJSON形式をサポートしています。例えばサーバーレスの代表格であるLambdaをデプロイしたいときは次のように書けばOKです。
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Resources:
MyServerlessFunctionLogicalID:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: python3.9
CodeUri: 's3://test-bucket-20220507/sampleLambda.zip'
2行目にも書かれていますが、SAMの実態はCloudFormationのTransform機能です。わざわざTransformを使用するのはCloudFormationで書く場合に比べると書くコード量が減らせるからです。
これを確かめるために先ほどのコードからスタックをデプロイしてみます。
作成されたスタックを見てみるとLambda関数だけでなくIAMロールも作成されています。ロールの中身はLambda関数の実行ロールAWSLambdaBasicExecutionRole
で、作成したLambdaに紐づいていました。
一方、SAMを使わずに生のCloudFormationで記述した場合、次のようになります。
AWSTemplateFormatVersion: 2010-09-09
Resources:
MyServerlessFunctionLogicalID:
Type: 'AWS::Lambda::Function'
Properties:
Code:
S3Bucket: test-bucket-20220507
S3Key: sampleLambda.zip
Handler: index.handler
Role: !GetAtt
- MyServerlessFunctionLogicalIDRole
- Arn
Runtime: python3.9
Tags:
- Key: 'lambda:createdBy'
Value: SAM
MyServerlessFunctionLogicalIDRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Action:
- 'sts:AssumeRole'
Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
Tags:
- Key: 'lambda:createdBy'
Value: SAM
SAMで書いた方がコード量が少ないことがわかりますね。Lambdaの他にもAPI GatewayやDynamoDBもサポートしています。また、SAMは生のCloudFormationと併用して使えるので必要に応じて使い分けることでコード量を節約することができます。
SAM CLI
次にSAM CLIについて説明します。CDKと同じようにSAMにもCLIが存在していてアプリケーションの作成と管理が可能です。各OSごとのインストール手順についてはこちらに記載があります。Macの場合はbrew経由でインストールします。
brew tap aws/tap
brew install aws-sam-cli
# インストールの確認
sam --version
> SAM CLI, version 1.48.0
sam init
を入力するとWhich template source would you like to use?
と聞かれるので1を選択すればクイックスタート可能なテンプレートを選ぶことができます。今回はHello World Example
を選択しました。すでにソースコードは完成しているのでsam build
でビルドすると.aws-sam//build/template.yaml
が作成されます。
またsam local
コマンドを使用することでlocalテストが可能です。
sam local invoke -e events/event.json HelloWorldFunction
> Invoking app.lambda_handler (python3.9)
Skip pulling image and use local one: public.ecr.aws/sam/emulation-python3.9:rapid-1.48.0-x86_64.
Mounting /Users/hogehoge/Documents/sam_test_dir/test_sam/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container
START RequestId: 5310fe15-ae09-4d5a-8c80-b3cc295e9cce Version: $LATEST
END RequestId: 5310fe15-ae09-4d5a-8c80-b3cc295e9cce
REPORT RequestId: 5310fe15-ae09-4d5a-8c80-b3cc295e9cce Init Duration: 0.88 ms Duration: 428.59 ms Billed Duration: 429 ms Memory Size: 128 MB Max Memory Used: 128 MB
{"statusCode": 200, "body": "{\"message\": \"hello world\"}"}%
引数に指定しているevent.json
についてもsam local generate-event
コマンドを使用することで作成することが可能です。例えばS3のputをトリガーとするLambdaのevent.jsonが作成したい場合であれば次のようにリダイレクトすればすぐに作成可能です。
sam local generate-event s3 put > event.json
個人的にこれはとても便利だと思います。他にどのサービスが使用できるかについてはsam local generate-event -h
を参照ください。
SAM CLI with CDK
さていよいよ本題です。CDKで作成したスタックをSAM CLIのlocalテストでテストします。具体的にはsam local invoke
コマンドの-t
オプションの引数にcdk synthなどで生成されるテンプレート(cdk.out/hogehogeStack.template.json
)を指定することでcdkで作成したyamlファイルをsamのcliでテストします。
sam local invoke -e events/event.json -t ./cdk.out/hogehogeStack.template.json CdkFunction