この記事は AWS Advent Calendar 2019 16日目の記事でした。
2020/7/21 に AWS SAM CLI が General Available となっため、v1.0.0 時点の情報に更新しました。
2021/8/24 に v1.29.0 時点の情報に更新しました。
はじめに
2018年の5月にaws-sam-local 改め aws-sam-cli の新機能 sam init を試すという記事を投稿しました。
AWS SAM CLI は GitHub 上で開発が行われていますが、リリースのペースが早く日々機能追加や改善が行われています。結果として上記の記事の内容は一部古いものとなっています。本記事では2021年8月22日時点の最新バージョンである v1.29.0 までのリリースを踏まえた使い方をご紹介します。
AWS SAM と AWS SAM CLI
Serverless Application Model(SAM)は Lambda や API Gateway, DynamoDB のようなサービスを活用したサーバーレスアプリケーションのデプロイに特化した、AWS CloudFormation の拡張機能です。通常の CloudFormation テンプレートと同様に YAML/JSON でテンプレートを定義しますが、素のテンプレートより簡潔に記載できるのが特徴です。
AWS SAM CLI は SAM を使用したサーバーレスアプリケーションの作成と管理を簡単に行うことができるコマンドラインツールです。
SAM CLI で利用される Docker イメージについて
後述の sam local invoke 等のコマンドでは AWS Lmabda の実行環境をエミュレートするためのコンテナイメージが使用され、起動するコンテナ内で Lambda 関数がローカル実行されます。(あくまでエミュレートなので、完全な再現環境ではありません。)
GA 以前は lambci/docker-lambda で公開されているコンテナイメージが利用されていましたが、v1.0.0 のリリースを機に AWS からオフィシャルにイメージも提供されるようになりました。
AWS SAM CLI のインストール
AWS SAM CLI のすべての機能を活用するには、前提として AWS CLI と Git, Docker のインストールが必要ですが、本記事ではこれらのインストール手順は割愛します。
macOS
Homebrew を使用して AWS SAM CLI をインストールすることができます。
$ brew tap aws/tap
$ brew install aws-sam-cli
$ sam --version
SAM CLI, version 1.29.0
Linux
以下の URL からインストーラーをダウンロードできます。
https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip
$ unzip aws-sam-cli-linux-x86_64.zip -d sam-installation
$ sudo ./sam-installation/install
$ sam --version
SAM CLI, version 1.29.0
Windows
以下の URL からインストーラーをダウンロードできます。
https://github.com/awslabs/aws-sam-cli/releases/latest/download/AWS_SAM_CLI_64_PY3.msi
> sam --version
SAM CLI, version 1.29.0
その他の環境など
公式ドキュメントでは案内されていませんが、pip でもインストールできます。
$ pip install -U aws-sam-cli
$ sam --version
SAM CLI, version 1.29.0
ローカルでの開発とテスト
sam init
sam init コマンドを使用すると、アプリケーションのプロジェクトを初期化できます。v0.30.0 以降では対話型にサンプルアプリケーションをセットアップしたり、GitHubやローカル上のテンプレートを読み込んで初期化することもできるようになっています。
以下は対話型で node.js14.x
のランタイムを指定したサンプルアプリケーションを作成している例です。
$ sam init
Which template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice: 1
What package type would you like to use?
1 - Zip (artifact is a zip uploaded to S3)
2 - Image (artifact is an image uploaded to an ECR image repository)
Package type: 1
Which runtime would you like to use?
1 - nodejs14.x
2 - python3.9
3 - ruby2.7
4 - go1.x
5 - java11
6 - dotnetcore3.1
7 - nodejs12.x
8 - nodejs10.x
9 - python3.8
10 - python3.7
11 - python3.6
12 - python2.7
13 - ruby2.5
14 - java8.al2
15 - java8
16 - dotnetcore2.1
Runtime: 1
Project name [sam-app]:
Cloning from https://github.com/aws/aws-sam-cli-app-templates
AWS quick start application templates:
1 - Hello World Example
2 - Step Functions Sample App (Stock Trader)
3 - Quick Start: From Scratch
4 - Quick Start: Scheduled Events
5 - Quick Start: S3
6 - Quick Start: SNS
7 - Quick Start: SQS
8 - Quick Start: Web Backend
Template selection: 1
-----------------------
Generating application:
-----------------------
Name: sam-app
Runtime: nodejs14.x
Dependency Manager: npm
Application Template: hello-world
Output Directory: .
v1.13.1 以降は AWS Lambda のコンテナイメージによるデプロイをサポートしています。こちらについては別記事を書いているので参照いただければと思います。
その他のバリエーション
# すべてのパラメータを指定
$ sam init --runtime nodejs14.x --dependency-manager npm --app-template hello-world --name sam-app
# GitHub 上のプロジェクトを指定
$ sam init --location gh:aws-samples/cookiecutter-aws-sam-python
# ZIP ファイルやローカルのテンプレートフォルダを指定
$ sam init --location /path/to/template.zip
$ sam init --location https://example.com/path/to/template.zip
$ sam init --location /path/to/template/folder
nodejs14.x でのサンプルアプリケーションの場合以下のようなファイル構成となります。
sam-app
│ .gitignore
│ README.md
│ template.yaml # SAM テンプレート
│
├─events
│ event.json # イベントソース (API Gateway) が Lambda 関数に送信するサンプルペイロード
│
└─hello-world # Lambda関数本体
│ .npmignore
│ app.js
│ package.json
│
└─tests # ユニットテストファイル
└─unit
test-handler.js
sam build
Lambda 関数のソースコードをビルドし、デプロイ用のアーティファクトを作成することができます。
$ sam build
Building resource 'HelloWorldFunction'
Running NodejsNpmBuilder:NpmPack
Running NodejsNpmBuilder:CopyNpmrc
Running NodejsNpmBuilder:CopySource
Running NodejsNpmBuilder:NpmInstall
Running NodejsNpmBuilder:CleanUpNpmrc
Build Succeeded
Built Artifacts : .aws-sam\build
Built Template : .aws-sam\build\template.yaml
Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided
--use-container
オプションで、実際の AWS Lambda 環境をエミュレートした Docker コンテナ内でビルドを実行することが可能です。ネイティブバイナリや複数のランタイムバージョンを扱っている場合に重宝します。
$ sam build --use-container
Starting Build inside a \container
Building codeuri: /home/ec2-user/sam-app/hello-world runtime: nodejs14.x metadata: {} functions: ['HelloWorldFunction']
Fetching public.ecr.aws/sam/build-nodejs14.x:latest Docker container image......
Mounting /home/ec2-user/sam-app/hello-world as /tmp/samcli/source:ro,delegated inside runtime container
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided
Running NodejsNpmBuilder:NpmPack
Running NodejsNpmBuilder:CopyNpmrc
Running NodejsNpmBuilder:CopySource
Running NodejsNpmBuilder:NpmInstall
Running NodejsNpmBuilder:CleanUpNpmrc
sam build で Lambda Layers を作成することも可能です。
こちらについても以前に別の記事を書いたので参照いただければと思います。
sam local invoke
前述の公式コンテナイメージをベースに、ローカルで Lambda 関数を起動できます。sam build で作成されたアーティファクトが存在する場合はコンテナ起動時にマウントされ、Lambda 関数の実行がエミュレートされます。
$ sam local invoke
Invoking app.lambdaHandler (nodejs14.x)
Image was not found.
Building image....................................................................................................
Skip pulling image and use local one: public.ecr.aws/sam/emulation-nodejs14.x:rapid-1.29.0.
Mounting /home/ec2-user/sam-app/hello-world as /var/task:ro,delegated inside runtime container
END RequestId: fa0cdfd6-9427-4ced-ba33-878bbb3769ab
REPORT RequestId: fa0cdfd6-9427-4ced-ba33-878bbb3769ab Init Duration: 1.56 ms Duration: 142.24 ms Billed Duration: 200 ms Memory Size: 128 MB Max Memory Used: 128 MB
{"statusCode":200,"body":"{\"message\":\"hello world\"}"}
sam local generate-event
特定のイベントソースのイベント情報を Lambda 関数に渡して処理したい場合、--event
オプションで json ファイルを指定できます。sam local generate-event
コマンドで様々なイベントソースのペイロードを作成することができます。その際、サービスごとに複数のイベントタイプを指定することができます。
DynamoDB Streams の updateイベント情報を生成し、Lambda関数を起動する例
$ sam local generate-event dynamodb update > ./events/dynamodb_event.json
$ sam local invoke HelloWorldFunction --event ./events/dynamodb_event.json
その他 v1.29.0 時点で生成に対応しているイベントソース
$ sam local generate-event --help
~省略~
Commands:
alexa-skills-kit
alexa-smart-home
apigateway
appsync
batch
cloudformation
cloudfront
cloudwatch
codecommit
codepipeline
cognito
config
connect
dynamodb
kinesis
lex
rekognition
s3
sagemaker
ses
sns
sqs
stepfunctions
sam local start-lambda
Lambda 関数の呼び出しをエミュレートするローカルエンドポイントを起動することができます。AWS CLI でローカルエンドポイントを指定したり、DynamoDB Local などの開発ツールと連携させたりすることで開発、テストを便利におこなうことができます。
$ sam local start-lambda
Starting the Local Lambda Service. You can now invoke your Lambda Functions defined in your template through the endpoint.
2019-12-12 14:00:04 * Running on http://127.0.0.1:3001/ (Press CTRL+C to quit)
# AWSCLIから呼び出し
$ aws lambda invoke --function-name HelloWorldFunction --endpoint http://127.0.0.1:3001/ outfile.txt
{
"StatusCode": 200
}
Step Functions Local や Dynamodb Local との連携についても以前に記事を書いたので参照いただければと思います。
sam local start-api
API 呼び出しを含めたサーバーレスアプリケーション全体のテストを行うために API Geteway のローカルインスタンスを起動することができます。起動中に Lambda 関数への変更を 行った場合は自動的にリロードされるため、start-api を再実行する必要はありません。SAM テンプレート自体を変更した場合はリスタートする必要があります。
$ sam local start-api
Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2019-12-12 14:18:08 * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
# 起動したエンドポイントに curl で接続すると正常に応答し、hello worldを返す
$ curl http://127.0.0.1:3000/hello
{"message":"hello world"}
sam validate
SAM テンプレートが SAM の仕様に沿った記述になっているか検証することができます。
$ sam validate
2021-08-23 13:30:33 Loading policies from IAM...
2021-08-23 13:30:37 Finished loading policies from IAM.
/home/ec2-user/sam-app/template.yaml is a valid SAM Template
AWSへのデプロイ
sam deploy
SAM で作成したアプリケーションのデプロイを行うことができます。以前は AWS SAM CLI でデプロイを行うには複数のステップが必要だったのですが、v0.33.1 以降は単一の sam deploy
コマンドでデプロイを操作できるようになりました。
具体的には必要な設定を事前にプロジェクトルートディレクトリに設定ファイル (samconfig.toml
)として保続しておくか、g
, --guided
オプションで対話的にデプロイをすすめることが可能です。初回にこのオプションを使用してデプロイすることで、選択した構成を samconfig.toml
として保存することもできます。Lambda デプロイパッケージ用の S3 バケットも AWS SAM CLI が自動で作成し、管理します。
$ sam deploy -g
Configuring SAM deploy
======================
Looking for samconfig.toml : Not found
Setting default arguments for 'sam deploy'
=========================================
Stack Name [sam-app]: ★CloudFormation スタック名の指定
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]: y ★デプロイ前にCloudformationの変更セットを確認するか
#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]: y ★SAM CLI に IAM ロールの作成を許可するか (CAPABILITY_IAM)
HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y ★API イベントタイプの関数に認証が含まれていない場合、警告される
Save arguments to samconfig.toml [Y/n]: y ★この設定を samconfig.toml として保存するか
SAM configuration file [samconfig.toml]: ★設定ファイル名を変更する場合は入力
SAM configuration environment [default]: ★環境名の指定
Looking for resources needed for deployment: Found!
Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-xxxxxxxxxxxxx
A different default S3 bucket can be set in samconfig.toml
Saved arguments to config file
Running 'sam deploy' for future deployments will use the parameters saved above.
The above parameters can be changed by modifying samconfig.toml
Learn more about samconfig.toml syntax at
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html
Deploying with following values
===============================
Stack name : sam-app
Region : ap-northeast-1
Confirm changeset : True
Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-xxxxxxxxxxxxx
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}
Signing Profiles : {}
Initiating deployment
=====================
Uploading to sam-app/93b0336bb7eaf29265c790583055f1c5.template 1090 / 1090 (100.00%)
Waiting for changeset to be created..
CloudFormation stack changeset
------------------------------------------------------------------------------------------------------------------------------------------------
Operation LogicalResourceId ResourceType
------------------------------------------------------------------------------------------------------------------------------------------------
+ Add HelloWorldFunctionHelloWorldPermissionProd AWS::Lambda::Permission
+ Add HelloWorldFunctionRole AWS::IAM::Role
+ Add HelloWorldFunction AWS::Lambda::Function
+ Add ServerlessRestApiDeployment47fc2d5f9d AWS::ApiGateway::Deployment
+ Add ServerlessRestApiProdStage AWS::ApiGateway::Stage
+ Add ServerlessRestApi AWS::ApiGateway::RestApi
------------------------------------------------------------------------------------------------------------------------------------------------
Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:123456789012:changeSet/samcli-deploy1576228579/a9ee2685-452f-47d0-851f-92e2ff217c9c
Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y ★変更セットを確認し、デプロイ実行
2021-08-23 15:00:33 - Waiting for stack create/update to complete
CloudFormation events from changeset
-------------------------------------------------------------------------------------------------------------------------------------------------
ResourceStatus ResourceType LogicalResourceId ResourceStatusReason
-------------------------------------------------------------------------------------------------------------------------------------------------
CREATE_IN_PROGRESS AWS::IAM::Role HelloWorldFunctionRole -
CREATE_IN_PROGRESS AWS::IAM::Role HelloWorldFunctionRole Resource creation Initiated
CREATE_COMPLETE AWS::IAM::Role HelloWorldFunctionRole -
CREATE_IN_PROGRESS AWS::Lambda::Function HelloWorldFunction -
CREATE_IN_PROGRESS AWS::Lambda::Function HelloWorldFunction Resource creation Initiated
CREATE_COMPLETE AWS::Lambda::Function HelloWorldFunction -
CREATE_IN_PROGRESS AWS::ApiGateway::RestApi ServerlessRestApi -
CREATE_IN_PROGRESS AWS::ApiGateway::RestApi ServerlessRestApi Resource creation Initiated
CREATE_COMPLETE AWS::ApiGateway::RestApi ServerlessRestApi -
CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionHelloWorldPermis Resource creation Initiated
sionProd
CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionHelloWorldPermis -
sionProd
CREATE_IN_PROGRESS AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5 -
f9d
CREATE_IN_PROGRESS AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5 Resource creation Initiated
f9d
CREATE_COMPLETE AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5 -
f9d
CREATE_IN_PROGRESS AWS::ApiGateway::Stage ServerlessRestApiProdStage -
CREATE_IN_PROGRESS AWS::ApiGateway::Stage ServerlessRestApiProdStage Resource creation Initiated
CREATE_COMPLETE AWS::ApiGateway::Stage ServerlessRestApiProdStage -
CREATE_COMPLETE AWS::Lambda::Permission HelloWorldFunctionHelloWorldPermis -
sionProd
CREATE_COMPLETE AWS::CloudFormation::Stack sam-app -
-------------------------------------------------------------------------------------------------------------------------------------------------
Stack sam-app outputs:
-------------------------------------------------------------------------------------------------------------------------------------------------
OutputKey-Description OutputValue
-------------------------------------------------------------------------------------------------------------------------------------------------
HelloWorldFunctionIamRole - Implicit IAM Role created for Hello World arn:aws:iam::123456789012:role/sam-app-
function HelloWorldFunctionRole-1OUZSV1ENAMCB
HelloWorldApi - API Gateway endpoint URL for Prod stage for Hello https://xxxxxxxxxx.execute-api.ap-
World function northeast-1.amazonaws.com/Prod/hello/
HelloWorldFunction - Hello World Lambda Function ARN arn:aws:lambda:ap-northeast-1:123456789012:function:sam-app-
HelloWorldFunction-1IFZY75A4HM3V
-------------------------------------------------------------------------------------------------------------------------------------------------
Successfully created/updated stack - sam-app in ap-northeast-1
作成された samconfig.toml
は以下のようになります。toml とは設定ファイルを定義するためのフォーマットの1種で、CloudWatch Agent などでも採用されています。
[default]
[default.deploy]
[default.deploy.parameters]
stack_name = "sam-app"
s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-xxxxxxxxxxxxx"
s3_prefix = "sam-app"
region = "ap-northeast-1"
confirm_changeset = true
capabilities = "CAPABILITY_IAM"
samconfig.toml
がプロジェクトのルートディレクトリに存在していれば sam deploy
コマンドだけでデプロイを行うことができます。
$ sam deploy
Deploying with following values
===============================
Stack name : sam-app
Region : ap-northeast-1
Confirm changeset : True
Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-xxxxxxxxxxxxx
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}
Initiating deployment
=====================
HelloWorldFunction may not have authorization defined.
Waiting for changeset to be created..
~以下省略~
OutputValue に出力された API Gateway のエンドポイントに接続すると、正常に応答が得られました。
$ curl https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
{"message":"hello world"}
sam package
SAM で作成したアプリケーションをパッケージ化できます。具体的には以下のことを行っています。
- Lambda 関数デプロイ用の ZIP ファイルを作成し、指定した S3 バケットにアップロード
- CodeUri の参照をローカルからアップロードした S3 のパスに書き換え
これらの処理は v0.33.1 以降であれば、sam deploy コマンド内で暗黙的実行されているため、個別に sam package
コマンドを使用する必要はありません。v0.33.1 以前のように sam package
と sam deploy
個別に実行しデプロイすることも可能です。
$ sam package --template-file template.yaml \
--s3-bucket <bucket-name> --output-template-file packaged.yaml
Uploading to 65113397247fb02f6ff4bad985a3240c 2421730 / 2421730.0 (100.00%)
Successfully packaged artifacts and wrote output template to file packaged.yaml.
Execute the following command to deploy the packaged template
sam deploy --template-file /home/ec2-user/sam-app/packaged.yaml --stack-name <YOUR STACK NAME>
$ sam deploy --template-file packaged.yaml --stack-name sam-app --capabilities CAPABILITY_IAM
返されたSAMテンプレートを確認すると CodeUri が S3 のパスに書き換わっていることがわかります。
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
- CodeUri: hello-world/
+ CodeUri: s3://<bucket-name>/65113397247fb02f6ff4bad985a3240c
Handler: app.lambdaHandler
Runtime: nodejs14.x
sam publish
SAM で作成したアプリケーションを AWS Serverless Application Repository に公開できます。publish を実行するには SAM テンプレート内の Metadata に公開のために必要な情報を定義する必要があります。LICENSE.txt
および、README.md
も用意しておく必要があります。
# publish を実行するにはメタデータが必要
Metadata:
AWS::ServerlessRepo::Application:
Name: my-app
Description: hello world
Author: user1
SpdxLicenseId: Apache-2.0
LicenseUrl: LICENSE.txt
ReadmeUrl: README.md
Labels: ['tests']
HomePageUrl: https://github.com/user1/my-app-project
SemanticVersion: 0.0.1
SourceCodeUrl: https://github.com/user1/my-app-project
また Serverless Application Repository がアーティファクトが格納されている S3 バケットを参照することができるように、対象のバケットに以下のようなポリシーの追加が必要です。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "serverlessrepo.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<your-bucket-name>/*"
"Condition" : {
"StringEquals": {
"aws:SourceAccount": "<your-account-id>"
}
}
}
]
}
テンプレートファイル内の LicenseUrl, ReadmeUrl, CodeUri は S3 上のファイルを指定する必要があるため、前述の sam package
コマンドでパッケージ化後に publish を行います。
$ sam package --template-file template.yaml \
--s3-bucket <bucket-name> --output-template-file packaged.yaml
~出力は省略~
LICENSE.txt および README.md も package コマンドにより S3にアップロードされ、各 Urlが書き換わっていることがわかります。
Metadata:
AWS::ServerlessRepo::Application:
Name: my-app
Description: hello world
Author: user1
SpdxLicenseId: Apache-2.0
- LicenseUrl: LICENSE.txt
+ LicenseUrl: s3://<bukcet-name>/d41d8cd98f00b204e9800998ecf8427e
- ReadmeUrl: README.md
+ ReadmeUrl: s3://<bukcet-name>/2a258235395cbaff804bbaab61a6d4ec
~以下略~
パッケージ後のテンプレートとリージョンを指定して publish します。アプリケーションはプライベートアプリケーションとして SAR に登録されます。
$ sam publish --template packaged.yaml --region ap-northeast-1
Created new application with the following metadata:
{
"Name": "my-app",
"Description": "hello world",
"Author": "user1",
"SpdxLicenseId": "Apache-2.0",
"LicenseUrl": "s3://<bucket-name>/d41d8cd98f00b204e9800998ecf8427e",
"ReadmeUrl": "s3://<bucket-name/2a258235395cbaff804bbaab61a6d4ec",
"Labels": [
"tests"
],
"HomePageUrl": "https://github.com/user1/my-app-project",
"SemanticVersion": "0.0.1",
"SourceCodeUrl": "https://github.com/user1/my-app-project"
}
Click the link below to view your application in AWS console:
https://console.aws.amazon.com/serverlessrepo/home?region=ap-northeast-1#/published-applications/arn:aws:serverlessrepo:ap-northeast-1:0123456789012:applications~my-app
SAR のコンソールを確認すると、正常にアプリケーションが登録されてプライベートアプリケーションとして利用可能になっています。
sam delete
v1.29.0 以降で利用可能な SAM アプリケーションを削除するコマンドです。AWS SAM CLI によってデプロイされた CloudFormation スタック、S3 や ECR にパッケージ化およびデプロイされたアーティファクト、SAM テンプレートファイルを削除します。ローカルのファイルは削除されません。--no-prompts
を指定すると確認メッセージなしで削除できます。
$ sam delete
Are you sure you want to delete the stack sam-app in the region ap-northeast-1 ? [y/N]: y
Are you sure you want to delete the folder sam-app in S3 which contains the artifacts? [y/N]: y
- Deleting S3 object with key sam-app/b71fea080e2e2e88f4ef92ab98d33d0a
- Deleting S3 object with key sam-app/93b0336bb7eaf29265c790583055f1c5.template
- Deleting Cloudformation stack sam-app
Deleted successfully
CI/CD パイプラインの作成
AWS SAM Pipelines は 2021/7/21 にアナウンスされたパブリックプレビューの機能です。2021/8/24 時点の情報を記載していますが、将来的に動作が変更になる可能性があるためご注意ください。
AWS SAM Pipelines を使用すると、簡単に CI/CD パイプラインを作成することができます。
sam pipeline bootstrap
CI/CD パイプラインの作成に必要な AWS リソースを作成する設定コマンドです。以下について既存の ARN を指定するか新規に作成することができます。このコマンドによりパイプラインの各ステージに必要なリソースを事前に作成しておくことができます。
- パイプライン用 IAM ユーザー
- パイプライン実行用 IAM ロール
- CloudFormation 実行用ロール
- アーティファクト格納用 S3 バケット
- ECR のイメージレポジトリ (AWS Lambda のコンテナサポートを使用する場合)
設定の入力が完了すると、aws-sam-cli-managed-<ステージ名>-pipeline-resources
という CloudFormation スタックがデプロイされ、上述の各リソースが作成されます。
# sam pipeline bootstrap
sam pipeline bootstrap generates the required AWS infrastructure resources to connect
to your CI/CD system. This step must be run for each deployment stage in your pipeline,
prior to running the sam pipeline init command.
We will ask for [1] stage definition, [2] account details, and
[3] references to existing resources in order to bootstrap these pipeline resources.
[1] Stage definition
Enter a name for this stage. This will be referenced later when you use the sam pipeline init command:
Stage name: dev ★ステージ名を入力
[2] Account details
The following AWS credential sources are available to use:
To know more about configuration AWS credentials, visit the link below:
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html
1 - Environment variables (not available)
2 - default (named profile)
q - Quit and configure AWS credentials
Select a credential source to associate with this stage: 2 ★クレデンシャル情報を選択
Associated account 123456789012 with stage dev.
Enter the region in which you want these resources to be created [ap-northeast-1]: ★リージョンを入力
Enter the pipeline IAM user ARN if you have previously created one, or we will create one for you []: ★パイプライン用 IAM ユーザー名の入力
[3] Reference application build resources
Enter the pipeline execution role ARN if you have previously created one, or we will create one for you []: ★パイプライン実行用 IAM ロールの入力
Enter the CloudFormation execution role ARN if you have previously created one, or we will create one for you []: ★ CloudFormation 実行用 IAM ロールの入力
Please enter the artifact bucket ARN for your Lambda function. If you do not have a bucket, we will create one for you []: ★アーティファクト用 S3 バケットの入力
Does your application contain any IMAGE type Lambda functions? [y/N]: n ★ AWS Lambda でコンテナイメージを使用しているか
[4] Summary
Below is the summary of the answers:
1 - Account: 123456789012
2 - Stage name: dev
3 - Region: ap-northeast-1
4 - Pipeline user: [to be created]
5 - Pipeline execution role: [to be created]
6 - CloudFormation execution role: [to be created]
7 - Artifacts bucket: [to be created]
8 - ECR image repository: [skipped]
Press enter to confirm the values above, or select an item to edit the value:
This will create the following required resources for the 'dev' environment:
- Pipeline IAM user
- Pipeline execution role
- CloudFormation execution role
- Artifact bucket
Should we proceed with the creation? [y/N]: y
Looking for resources needed for deployment: Not found.
Creating the required resources...
Successfully created!
The following resources were created in your account:
- Pipeline IAM user
- Pipeline execution role
- CloudFormation execution role
- Artifact bucket
Pipeline IAM user credential:
AWS_ACCESS_KEY_ID: XXXXXXXXXXXXXXXXXXXX
AWS_SECRET_ACCESS_KEY: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
View the definition in .aws-sam/pipeline/pipelineconfig.toml,
run sam pipeline bootstrap to generate another set of resources, or proceed to
sam pipeline init to create your pipeline configuration file.
Before running sam pipeline init, we recommend first setting up AWS credentials
in your CI/CD account. Read more about how to do so with your provider in
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-generating-example-ci-cd-others.html.
作成されたステージの定義と紐づくリソースの情報は .aws-sam/pipeline/pipelineconfig.toml
に保存されます。
cat pipelineconfig.toml
version = 0.1
[default]
[default.pipeline_bootstrap]
[default.pipeline_bootstrap.parameters]
pipeline_user = "arn:aws:iam::123456789012:user/aws-sam-cli-managed-dev-pipeline-reso-PipelineUser-XXXXXXXXXXXX"
[dev]
[dev.pipeline_bootstrap]
[dev.pipeline_bootstrap.parameters]
pipeline_execution_role = "arn:aws:iam::123456789012:role/aws-sam-cli-managed-dev-pipe-PipelineExecutionRole-XXXXXXXXXXXXX"
cloudformation_execution_role = "arn:aws:iam::123456789012:role/aws-sam-cli-managed-dev-p-CloudFormationExecutionR-XXXXXXXXXXXX"
artifacts_bucket = "aws-sam-cli-managed-dev-pipeline-artifactsbucket-XXXXXXXXXXXX"
image_repository = ""
region = "ap-northeast-1"
sam pipeline init
AWS SAM Pipelines が対応する CI/CD ツールの設定ファイルを生成するコマンドです。対応するツールは以下のとおりです。
- Jenkins (
Jenkinsfile
) - GitLab CI/CD (
.gitlab-ci.yml
) - GitHub Actions (
.github/workflows/pipeline.yaml
) - AWS CodePipeline (CloudFormation テンプレートおよび buildspec ファイル)
以下はクイックスタートのテンプレートを使用して GitHub Actions のワークフロー定義ファイルを作成する例です。クイックスタートテンプレートは 2 ステージ構成となっているため、あらかじめ sam pipeline bootstrap
コマンドで 2 ステージ作成しておくか、sam pipeline init --bootstrap
を実行してください。
--botstrap オプションをつけて sam pipeline init 実行することで必要なステージと紐づく AWS リソースの作成を同時に行うことができます。
$ sam pipeline init
sam pipeline init generates a pipeline configuration file that your CI/CD system
can use to deploy serverless applications using AWS SAM.
We will guide you through the process to bootstrap resources for each stage,
then walk through the details necessary for creating the pipeline config file.
Please ensure you are in the root folder of your SAM application before you begin.
Select a pipeline structure template to get started:
Select template
1 - AWS Quick Start Pipeline Templates
2 - Custom Pipeline Template Location
Choice: 1 ★クイックスタートテンプレートを選択
Cloning from https://github.com/aws/aws-sam-cli-pipeline-init-templates.git
CI/CD system
1 - Jenkins
2 - GitLab CI/CD
3 - GitHub Actions
4 - AWS CodePipeline
Choice: 3 ★GitHub Actions を選択
You are using the 2-stage pipeline template.
_________ _________
| | | |
| Stage 1 |->| Stage 2 |
|_________| |_________|
Checking for existing stages...
This template configures a pipeline that deploys a serverless application to a testing and a production stage.
What is the GitHub secret name for pipeline user account access key ID? [AWS_ACCESS_KEY_ID]: ★pipeline ユーザーのアクセスキーを入力
What is the GitHub Secret name for pipeline user account access key secret? [AWS_SECRET_ACCESS_KEY]: ★pipeline ユーザーのシークレットアクセスキーを入力
What is the git branch used for production deployments? [main]: ★本番環境で指定するブランチ名の指定
What is the template file path? [template.yaml]: ★SAM テンプレートファイルのパスを指定
We use the stage name to automatically retrieve the bootstrapped resources created when you ran `sam pipeline bootstrap`.
Here are the stage names detected in .aws-sam/pipeline/pipelineconfig.toml: ★事前に bootstrap で作成済みのステージを検知
1 - dev
2 - prod
What is the name of stage 1 (as provided during the bootstrapping)?
Select an index or enter the stage name: 1
What is the sam application stack name for stage 1? [sam-app-dev]:
Stage 1 configured successfully, configuring stage 2.
Here are the stage names detected in .aws-sam/pipeline/pipelineconfig.toml:
1 - dev
2 - prod
What is the name of stage 2 (as provided during the bootstrapping)?
Select an index or enter the stage name: 2
What is the sam application stack name for stage 2? [sam-app-prod]:
Stage 2 configured successfully.
SUMMARY
We will generate a pipeline config file based on the following information:
What is the GitHub secret name for pipeline user account access key ID?: XXXXXXXXXXXXXXXXXXXX
What is the GitHub Secret name for pipeline user account access key secret?: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
What is the git branch used for production deployments?: main
What is the template file path?: template.yaml
What is the name of stage 1 (as provided during the bootstrapping)?
Select an index or enter the stage name: 1
What is the sam application stack name for stage 1?: sam-app-dev
What is the pipeline execution role ARN for stage 1?: arn:aws:iam::123456789012:role/aws-sam-cli-managed-dev-pipe-PipelineExecutionRole-XXXXXXXXXXXXX
What is the CloudFormation execution role ARN for stage 1?: arn:aws:iam::123456789012:role/aws-sam-cli-managed-dev-p-CloudFormationExecutionR-XXXXXXXXXXXXX
What is the S3 bucket name for artifacts for stage 1?: aws-sam-cli-managed-dev-pipeline-artifactsbucket-XXXXXXXXXXXXX
What is the ECR repository URI for stage 1?:
What is the AWS region for stage 1?: ap-northeast-1
What is the name of stage 2 (as provided during the bootstrapping)?
Select an index or enter the stage name: 2
What is the sam application stack name for stage 2?: sam-app-prod
What is the pipeline execution role ARN for stage 2?: arn:aws:iam::123456789012:role/aws-sam-cli-managed-prod-pip-PipelineExecutionRole-XXXXXXXXXXXXX
What is the CloudFormation execution role ARN for stage 2?: arn:aws:iam::123456789012:role/aws-sam-cli-managed-prod-CloudFormationExecutionR-XXXXXXXXXXXXX
What is the S3 bucket name for artifacts for stage 2?: aws-sam-cli-managed-prod-pipeline-artifactsbucket-XXXXXXXXXXXXX
What is the ECR repository URI for stage 2?:
What is the AWS region for stage 2?: ap-northeast-1
Successfully created the pipeline configuration file(s):
- .github/workflows/pipeline.yaml
生成された .github/workflows/pipeline.yaml
を GitHub に Push すれば GitHub Actions による CI/CD パイプラインを実行できます。
その他の機能
sam logs
デプロイ済みの Lambda 関数のログを取得できます。
--tail
でログをたれ流したり、--filter "文字列"
でフィルタリングすることもできます。
以下では CloudFormation のスタック名と関数名を指定しています。
$ sam logs -n HelloWorldFunction --stack-name sam-app
2018/07/20/[$LATEST]c1e4c40fbbf2495aa91ecff5b21ce24d 2018-07-20T07:24:37.835000 START RequestId: f5664465-8bed-11e8-994b-8d4b4bdcc800 Version: $LATEST
2018/07/20/[$LATEST]c1e4c40fbbf2495aa91ecff5b21ce24d 2018-07-20T07:24:38.395000 END RequestId: f5664465-8bed-11e8-994b-8d4b4bdcc800
2018/07/20/[$LATEST]c1e4c40fbbf2495aa91ecff5b21ce24d 2018-07-20T07:24:38.395000 REPORT RequestId: f5664465-8bed-11e8-994b-8d4b4bdcc800 Duration: 542.93 ms Billed Duration: 600 ms Memory Size: 128 MB Max Memory Used: 22 MB
もしくは関数名を直接指定してもよいので、AWS SAM CLI や CloudFormation でデプロイされたかどうかは関係なく、全ての Lanmbda 関数に対して実行できます。またフィルタリングした結果を tail するなどの組み合わせもできるのでトラブルシューティングを迅速に行うことができます。
$ sam logs -n ECRScanToSlack --tail --filter "INFO"
2019/12/12/[$LATEST]76c0c056a02541a8bf7b2568e9e8b06d 2019-12-12T08:32:26.793000 [INFO] 2019-12-12T08:32:26.792Z
506de805-fb06-426f-b6b0-e89f2eb23660 Found credentials in environment variables.
2019/12/12/[$LATEST]76c0c056a02541a8bf7b2568e9e8b06d 2019-12-12T08:32:28.411000 [INFO] 2019-12-12T08:32:28.408Z
506de805-fb06-426f-b6b0-e89f2eb23660 Message posted.
2019/12/12/[$LATEST]76c0c056a02541a8bf7b2568e9e8b06d 2019-12-12T08:34:32.572000 [INFO] 2019-12-12T08:34:32.572Z
3dcde807-f150-4056-bb12-b791b77d0731 Message posted.
2019/12/12/[$LATEST]76c0c056a02541a8bf7b2568e9e8b06d 2019-12-12T08:34:35.812000 [INFO] 2019-12-12T08:34:35.811Z
5ac31616-be63-4402-90ab-4d9b0b74a1a6 Message posted.
Lambda Layersへの対応
AWS SAM CLI は Labmda Layers を使用した関数のローカル実行にも対応しています。(v0.8.1以降)
以下は Lambda Layers を含む SAM テンプレートの例です。
# 該当箇所を抜粋
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello_world/
Handler: app.lambda_handler
Runtime: python3.8
Layers:
- arn:aws:lambda:ap-northeast-1:123456789012:layer:python-boto3:1 # Layerの指定
ローカル実行時、AWS SAM CLI は対象の Layer のパッケージをダウンロードし、ローカルにキャッシュします。その後、提供されているコンテナイメージをベースに対象 Layer のキャッシュがオーバーレイされたコンテナイメージが自動でビルドされ、そのイメージを使用して実行が行われます。
$ sam local invoke
Invoking app.lambda_handler (python3.8)
Image was not found.
Building image......................................................
Requested to skip pulling images ...
Mounting C:\test\sam-app2\hello_world as /var/task:ro,delegated inside runtime container
START RequestId: bfee13e1-74be-1953-d236-aa7e0bc13d8e Version: $LATEST
END RequestId: bfee13e1-74be-1953-d236-aa7e0bc13d8e
REPORT RequestId: bfee13e1-74be-1953-d236-aa7e0bc13d8e Init Duration: 310.57 ms Duration: 4.80 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 23 MB
{"statusCode":200,"body":"{\"message\": \"hello world\"}"}
# samcli/lambda が Layer が展開された後のコンテナイメージ
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
samcli/lambda python3.8-a84bc9cd09799899970128014 99ac7e22ab97 13 seconds ago 548MB
amazon/aws-sam-cli-emulation-image-python3.8 latest 0b8397b4f176 36 hours ago 490MB
AWS Toolkit と AWS SAM CLI によるデバッグ
各種 IDE に対応した AWS Toolkit は AWS SAM との親和性が高く、SAM アプリケーションの作成、デバッグ、デプロイを行うことができます。以下は AWS Toolkit for Visual Studio Code 拡張で Node.js ランタイムの Lambda 関数のデバッグを行う例です。
デバッグの起動構成に以下のような構成を追加します。(.vscode/launch.json)
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to SAM CLI",
"type": "node",
"request": "attach",
"address": "localhost",
"port": 5858,
"localRoot": "${workspaceRoot}/hello-world",
"remoteRoot": "/var/task",
"protocol": "inspector",
"stopOnEntry": false
}
]
}
-d, --debug-port オプションを指定し、sam local invoke します。
$ sam local invoke -e ./events/event.json -d 5858
Invoking app.lambdaHandler (nodejs10.x)
Fetching lambci/lambda:nodejs10.x Docker container image......
Mounting C:\vscode\sam-app\hello-world as /var/task:ro,delegated inside runtime container
Debugger listening on ws://0.0.0.0:5858/3e80f80b-bbaa-4a6c-b087-7f2f3fd46b6b
For help, see: https://nodejs.org/en/docs/inspector
Lambda 関数がデバッグモードで起動しますので、Visual Studio Code 側で設定した起動設定からデバッグを開始することができます。
参考
AWS Serverless Application Model - Developer Guide
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html
GitHub - aws-sam-cli Releases
https://github.com/awslabs/aws-sam-cli/releases
以上です。
参考になれば幸いです。