[アップデート]AWS SAMのデプロイが簡単になりました

AWS SAMのデプロイ方法が簡単になりました。少ないコマンドで、かつパラメーターも少なくて済むようになりました。
2019.11.30

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

こんにちは、大阪オフィスのかずえです。今回は、AWS SAMのデプロイ方法が簡単になったことをお伝えします。

これまで

$ aws s3 mb s3://(バケット名)
$ sam package --s3-bucket (バケット名) --output-template-file out.yaml
$ sam deploy --template-file out.yaml --capabilities CAPABILITY_IAM --stack-name (CFnスタック名)

これから

$ sam deploy

コマンド数が少なくなっている上に、パラメーターも無くなってますね!

やってみた

新しくなったdeployコマンドを使って、チュートリアル Deploying a Hello World Application をやってみました。

SAMのバージョンアップデート

※ SAM未インストールの場合は、以下ページを参考にインストールを行なってください。

現在のバージョン

$ sam --version
SAM CLI, version 0.17.0

アップデート

$ brew upgrade aws-sam-cli
(出力内容省略)

アップデートされたことを確認

$ sam --version
SAM CLI, version 0.34.0

Step 1: Download a Sample AWS SAM Application

まずは sam init でアプリケーションの初期化を行ないます。python3.7を使います。

$ sam init
Which template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice: 1

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 - nodejs8.10
9 - nodejs6.10
10 - python3.7
11 - python3.6
12 - python2.7
13 - java8
14 - dotnetcore2.0
15 - dotnetcore1.0
Runtime: 10

Project name [sam-app]:

Quick start templates may have been updated. Do you want to re-download the latest [Y/n]: Y

-----------------------
Generating application:
-----------------------
Name: sam-app
Runtime: python3.7
Dependency Manager: pip
Application Template: hello-world
Output Directory: .

Next steps can be found in the README file at ./sam-app/README.md

Step 2: Build Your Application

次に sam build を実行します。

$ cd sam-app/
$ sam build
Building resource 'HelloWorldFunction'
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource

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

コンソールの出力結果に記載されていますが、カレントディレクトリ下の .aws-sam/build 以下に色々とファイルが作成されます。大きく分けて二種類あります。

$ ls .aws-sam/build/
HelloWorldFunction template.yaml

HelloWorldFunctionディレクトリ以下 = Built Artifacts

hello_world 以下のpythonファイルと、そこで使われるパッケージのファイル群がダウンロードされています。

template.yaml = Built Template

カレントディレクトリ(アプリケーションルートディレクトリ)に存在した template.yaml が変換されたものです。どう変わってるのかなと差分を見てみましたが、大して変わっていないような、、内容次第では大きく変換されるのでしょうか。

左がもとの template.yaml、右が変換後のファイルです。

Step 3: Deploy Your Application to the AWS Cloud

ここが今回アップデートされた部分ですね。

チュートリアルには --guided オプションつけてねとあるのですが一旦ナシで実行してみましょう。

$ sam deploy
Usage: sam deploy [OPTIONS]
Try "sam deploy --help" for help.

Error: Missing option '--stack-name', 'sam deploy --guided' can be used to provide and save needed parameters for future deploys.

「どういうこと? sam deploy だけでデプロイできるんじゃなかったの?」

はい。実は sam deploy だけでデプロイできるのは 2回目から です。

これまでは sam deploy の前に sam package が必要でした。sam package でソースコード(+依存パッケージ)群のZIP化、そのZIPのS3バケットへのアップデートを行ない、そのS3上のソースを参照するようにSAMテンプレートファイルも変換されていました。また sam deploy 時には、使用するテンプレートファイルや、CFnのスタック名をパラメーターによって指定する必要もありました。

今後は、 sam deploy 時にこういった設定がない場合は、samconfig.toml という ファイルが無いか探して、そこに記載されている設定に従ってデプロイが行われる、という仕様になりました。で、前述の--guided (もしくは -g)オプションを添えてsam deployすると、質問に答えていくだけで samconfig.tomlを作ってくれるので、次回以降は sam deployだけで済むというわけです。

※ これまでの sam package と sam deployを使う方法も引き続き使用できます。

では、--guidedを付けて再実行

$ sam deploy --guided

Configuring SAM deploy
======================

Looking for samconfig.toml : Not found

Setting default arguments for 'sam deploy'
=========================================
Stack Name [sam-app]:
AWS Region [us-east-1]: ap-northeast-1
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [y/N]: y
#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]:
Save arguments to samconfig.toml [Y/n]:

Looking for resources needed for deployment: Not found.
Creating the required resources...
Successfully created!

Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-5vaat5cyd7x4
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-5vaat5cyd7x4
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}

Initiating deployment
=====================
Uploading to sam-app/84978d376aaae3a733b4ac10f9c7af26 532293 / 532293.0 (100.00%)
Uploading to sam-app/76145a8c10a8178f06e48cafba84e2f0.template 1089 / 1089.0 (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:047429787746:changeSet/samcli-deploy1575102149/dbcc7649-e72a-4079-a187-95b66803aa95

Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y

2019-11-30 17:22:46 - 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 HelloWorldFunctionHelloWorldPermissionPro Resource creation Initiated
d
CREATE_IN_PROGRESS AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5f9d -
CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionHelloWorldPermissionPro -
d
CREATE_IN_PROGRESS AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5f9d Resource creation Initiated
CREATE_COMPLETE AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5f9d -
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 HelloWorldFunctionHelloWorldPermissionPro -
d
CREATE_COMPLETE AWS::CloudFormation::Stack sam-app -
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Stack sam-app outputs:
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
OutputKey-Description OutputValue
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
HelloWorldFunctionIamRole - Implicit IAM Role created for Hello World function arn:aws:iam::047429787746:role/sam-app-HelloWorldFunctionRole-1OCESGCMVCZLY
HelloWorldApi - API Gateway endpoint URL for Prod stage for Hello World function https://zyk8do4vz4.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
HelloWorldFunction - Hello World Lambda Function ARN arn:aws:lambda:ap-northeast-1:047429787746:function:sam-app-HelloWorldFunction-
RUO13GDC6QR6
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Successfully created/updated stack - sam-app in ap-northeast-1

アクセス確認

OutputValue欄に出力されたAPI Gateway のエンドポイント URLにアクセスしています。

$ curl https://zyk8do4vz4.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
{"message": "hello world"}

生成された samconfig.toml の中身

version = 0.1
[default]
[default.deploy]
[default.deploy.parameters]
stack_name = "sam-app"
s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-5vaat5cyd7x4"
s3_prefix = "sam-app"
region = "ap-northeast-1"
confirm_changeset = true
capabilities = "CAPABILITY_IAM"

S3バケットを作成するCFnスタックも自動で作成される

aws-sam-cli-managed-defaultという名前で、以下テンプレートを使ったCFnスタックが作成されていました。ソースコードのzipファイルと、それを見に行くように変換されたSAM templateファイルが配置されます。

AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Managed Stack for AWS SAM CLI

Metadata:
SamCliInfo: {"version": "0.34.0", "installationId": "3445debb-03f9-440c-ab96-fc24662a1c5f"}

Resources:
SamCliSourceBucket:
Type: AWS::S3::Bucket
Properties:
VersioningConfiguration:
Status: Enabled
Tags:
- Key: ManagedStackSource
Value: AwsSamCli

SamCliSourceBucketBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref SamCliSourceBucket
PolicyDocument:
Statement:
-
Action:
- "s3:GetObject"
Effect: "Allow"
Resource:
Fn::Join:
- ""
-
- "arn:aws:s3:::"
-
!Ref SamCliSourceBucket
- "/*"
Principal:
Service: serverlessrepo.amazonaws.com

Outputs:
SourceBucket:
Value: !Ref SamCliSourceBucket

ソースを修正して今度は --guided なしでdeployしてみる

pythonコード修正

ショボイですが出力内容 「hello world」を「hello world2」にしてみました。

ビルド

最初このステップを忘れていて混乱してしまいました。。

$ sam build
Building resource 'HelloWorldFunction'
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource

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

デプロイ

$ 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-5vaat5cyd7x4
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}

Initiating deployment
=====================

Waiting for changeset to be created..
Error: No changes to deploy. Stack sam-app is up to date
HL00367:sam-app kazue.masaki$ sam build
Building resource 'HelloWorldFunction'
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource

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

HL00367:sam-app kazue.masaki$ sam build
Building resource 'HelloWorldFunction'
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource

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

HL00367:sam-app kazue.masaki$ 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-5vaat5cyd7x4
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}

Initiating deployment
=====================
Uploading to sam-app/62b5328d77b28db25651302d2667dcb8 532286 / 532286.0 (100.00%)
Uploading to sam-app/805fb24556397f5abb3f5a0b1a19d04f.template 1089 / 1089.0 (100.00%)

Waiting for changeset to be created..

CloudFormation stack changeset
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Operation LogicalResourceId ResourceType
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Modify HelloWorldFunction AWS::Lambda::Function
* Modify ServerlessRestApi AWS::ApiGateway::RestApi
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:047429787746:changeSet/samcli-deploy1575103528/244d9da2-84e6-4aac-abb3-f6524fba4495

Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y

2019-11-30 17:46:13 - Waiting for stack create/update to complete

CloudFormation events from changeset
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ResourceStatus ResourceType LogicalResourceId ResourceStatusReason
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
UPDATE_IN_PROGRESS AWS::Lambda::Function HelloWorldFunction -
UPDATE_COMPLETE AWS::Lambda::Function HelloWorldFunction -
UPDATE_COMPLETE_CLEANUP_IN_PROGRESS AWS::CloudFormation::Stack sam-app -
UPDATE_COMPLETE AWS::CloudFormation::Stack sam-app -
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Stack sam-app outputs:
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
OutputKey-Description OutputValue
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
HelloWorldFunctionIamRole - Implicit IAM Role created for Hello World function arn:aws:iam::047429787746:role/sam-app-HelloWorldFunctionRole-1OCESGCMVCZLY
HelloWorldApi - API Gateway endpoint URL for Prod stage for Hello World function https://zyk8do4vz4.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
HelloWorldFunction - Hello World Lambda Function ARN arn:aws:lambda:ap-northeast-1:047429787746:function:sam-app-HelloWorldFunction-
RUO13GDC6QR6
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Successfully created/updated stack - sam-app in ap-northeast-1

結果確認

curl https://zyk8do4vz4.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
{"message": "hello world2"}

無事デプロイできました!

まとめ

SAMのデプロイ方法が簡単になったことをお伝えしました。半年ぶりくらいにSAMを触ったのですが、半年前は毎回 sam packagesam deploy コマンドのパラメーターなんだったけ?となっていたのを思い出しました笑 ですのでこのアップデートはとても使いやすくなった良いアップデートかなと思います。ぜひ一度お試しくださいませ。

参考資料