こんにちは、ロジカル・アーツの井川です。
今日は Lambda などを作成する際に使う、SAMについてまとめていきます。
SAMとは?
Serverless Application Model の略で、サーバーレスアプリケーションの開発及びデプロイを行うフレームワークです。 全てはYAMLで書くことができます。SAM のシンプルな YAML ファイルを定義することで、複雑な CloudFormation を容易に生成することができます。
SAM の特徴
- CloudFormation からのリソース(例えばOutputs/Mappings/Parameters/Resourcesなど)をサポートします。
- AWSにデプロイする際に使用するコマンドは二つだけです。
- SAMはCodeDeployよりLambda関数へデプロイできます。
- SAMはLambda/API Gateway/DynamoDBの実行を助けることができます。SAMを使えばローカルでデプロイしてテストすることが可能です。
SAM Recipe
- Transform Header indicates it's SAM template:
- Transform: 'AWS::Serverless-2016-10-31'
- アプリケーションのテンプレートを CloudFormation の形式に変換します。
- Code(例)
ハンズオン
前提条件
- Amazon Linux2 AMI を使用した Cloud9 環境
- SAM インストール済み(手順に関しては下記参照)
プロジェクトの作成
SAM を実際にインストールしたら、まず行うことはプロジェクトの作成だと思います。
SAM では sam init コマンドにより、作成することが出来ます。コマンドを入力すると、下記のように幾つか質問され、雛形を作成します。
$ sam init
SAM CLI now collects telemetry to better understand customer needs.
You can OPT OUT and disable telemetry collection by setting the
environment variable SAM_CLI_TELEMETRY=0 in your shell.
Thanks for your help!
Learn More: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-telemetry.html
Which template source would you like to use? // どのテンプレートタイプを使われたいですか?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice: Choice: 1 // 今回はAWS側で既に用意されているテンプレートを使用します
Which runtime would you like to use? // どのランタイムを使用されたいですか?
1 - nodejs12.x
2 - python3.8
3 - ruby2.5
4 - go1.x
5 - java11
6 - dotnetcore2.1
7 - nodejs10.x
8 - python3.7
9 - python3.6
10 - python2.7
11 - java8
12 - dotnetcore2.0
13 - dotnetcore1.0
Runtime: 1 // nodejs12.x
Project name [sam-app]:
Cloning app templates from https://github.com/awslabs/aws-sam-cli-app-templates.git
-----------------------
Generating application:
-----------------------
Name: sam-app
Runtime: nodejs12.x
Dependency Manager: npm
Application Template: hello-world
Output Directory: .
Next steps can be found in the README file at ./sam-app/README.md
一通り入力が終わると上記のようにアプリケーションを新たに生成してくれます。
ディレクトリ構成
今回デプロイするプロジェクトのディレクトリ構成はこのようになっています。

template.yaml
上記のディレクトリにあるファイルの中で、リソースを定義していくファイルが template.yaml になります。
今回の template.yaml は以下の通りです。
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > sam-app Sample SAM Template for sam-app # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst Globals: Function: Timeout: 3 Resources: // 作成するリソースを決定します 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.lambdaHandler Runtime: nodejs12.x Events: HelloWorld: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: Path: /hello Method: get Outputs: // 結果を生成します # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function # Find out more about other implicit resources you can reference within SAM # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api HelloWorldApi: Description: "API Gateway endpoint URL for Prod stage for Hello World function" Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/" 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
Build & Deploy
Build で YAML ファイルをコンパイルして、実行ファイルを新たに生成したのち、実際に実行(デプロイ)していきましょう。コマンドは下記の通りです。
$ sam build $ sam deploy --guided
結果
エラー等発生しなければ、最終的にコマンドラインに以下が表示されるかと思います。
... ... Stack sam-app outputs: --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- OutputKey-Description OutputValue --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- HelloWorldFunctionIamRole - Implicit IAM Role created for Hello World function arn:aws:iam::xxxxxxxxxxxx:role/sam-app-HelloWorldFunctionRole-xxxxxxxxxxxx HelloWorldApi - API Gateway endpoint URL for Prod stage for Hello World function https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/ HelloWorldFunction - Hello World Lambda Function ARN arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxxx:function:sam-app-HelloWorldFunction-xxxxxxxxxxxx --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Successfully created/updated stack - sam-app in ap-northeast-1
上記は Outputs で指定した項目がきちんと表示されていますね。
実際にAWSのコンソール画面でも確認してみましょう。 AWSコンソール->CloudFormation->App名 にて確認できます。

ステータスが無事 CREATE_COMPLETE になっています。
削除
ハンズオンの最後は、お掃除していきましょう。
$ aws cloudformation delete-stack --stack-name sam-app --region ap-northeast-1
きちんと削除されたか確認します。

ステータスが DELETE_COMPLETE になっていますね。ハンズオンは以上となります。
ポリシーテンプレート
ポリシーテンプレートとは、Lambda関数を使用するにあたって必要となるアクセス許可範囲を定義しているテンプレートのことです。
- 様々なテンプレートのリストは以下サイトに載っています。
よく使われるポリシー例
- S3ReadPolicy: S3への読み取り許可を与える
- SQSPollerPolicy: SQSキューにポーリングする許可を与える
- DynamoDBCrudPolicy: CRUD = 作成、読み取り、更新、削除
下記は実際の SQSPollerPolicy を使った Lambda関数の定義テンプレート です。Policies のところに SQSPollerPolicy とあるのが見てわかるかと思います。Policies に記載するだけでSQSを使えるように SAM が自動的に変換を行ってくれます。とても便利なので上記サイトを使って定義することをお勧めします。
MyFunction: Type: 'AWS::Serverless::Function' Properties: CodeUri: ${codeuri} Handler: hello.handler Runtime: python2.7 Policies: - SQSPollerPolicy: QueueName: !GetAtt MyQueue.QueueName
まとめ
今回は、サーバーレスアプリケーションのプロビジョニング、デプロイ、テストを容易にしてくれる SAM についてまとめてみましたがいかがでしたでしょうか。 お役に立てれば幸いです。