Fusic Tech Blog

Fusion of Society, IT and Culture

【2019年12月】 AWS SAM (version 0.37) のインストール・ローカルテスト・デプロイ・お掃除まで
2019/12/10

【2019年12月】 AWS SAM (version 0.37) のインストール・ローカルテスト・デプロイ・お掃除まで

こちらは、Fusic Advent Calendar 2019 - Qiita の11日目の記事です。
つい先日まで AWS re:Invent 2019 に参加してました。

RDS ProxyLambda Destinations に関する記事を書こうとしたところ、サンプルアプリをSAMで作る段階で使い方が結構変わっていることに気づいたので、自身のメモがてらに最初に必要な操作をまとめていきます。

自分の環境が 0.11 とかだったので...大分変わってました...

インストール・アップグレード

まず、SAMを利用するには Pythonのバージョンが3.6以上である必要があります
この辺は各環境ごとに調整。

公式リンク の通りに各プラットフォームごとにインストールを進めれば問題ありません。

推奨か分かりませんが、 pip で入れる方法もご紹介。
本記事執筆時点(2019/12/10) では、バージョンは 0.37.0 でした。

インストール

# pip をインストール
$ curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
$ sudo python get-pip.py

# aws-cli と SAM をインストール
$ sudo pip install awscli
$ sudo pip install aws-sam-cli

$ sam --version
SAM CLI, version 0.37.0

アップグレード

# pip 自体をアップグレード
$ sudo pip install --upgrade pip

# sam をアップグレード
$ sudo pip install --upgrade aws-sam-cli

$ sam --version
SAM CLI, version 0.37.0

なにはともあれ Hello World

サンプルアプリ作成

$ 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: 1

Project name [sam-app]:

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

-----------------------
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

以前は、引数で runtimeproject name を指定しないとデフォルトで作成されていましたが、インタラクティブになってます。 各項目の詳細は後述

ディレクトリ構成

$ cd sam-app/
$ tree
.
├── README.md
├── events
│   └── event.json
├── hello-world
│   ├── app.js
│   ├── package.json
│   └── tests
│       └── unit
│           └── test-handler.js
└── template.yaml

4 directories, 6 files

ローカルでHelloWorld

$ 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-10 08:53:20  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)

上記コマンドでローカルに起動するので、別のセッションやブラウザで http://127.0.0.1:3000/hello にアクセスしてみる

$ curl http://127.0.0.1:3000/hello
{"message":"hello world"}

hello world できました。 start-api 側にもログが出ていると思います。
初回は、runtimeのdocker- mageをpullしてくるので少し時間がかかります。

AWSにデプロイ

[アップデート]AWS SAMのデプロイが簡単になりました | Developers.IO
クラメソさんが詳細にすごいためになる記事を書いてくれています。

今まで Makefile とか書いて頑張っていたのですが簡単になってます。

# ソースコードをビルド
$ sam build

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]: Y
        Save arguments to samconfig.toml [Y/n]: Y

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
# 初回のみ
$ sam deploy --guided

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

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

Initiating deployment
=====================
Uploading to sam-app/b91229442223577b14c88212507831d2  127523 / 127523.0  (100.00%)
Uploading to sam-app/0e083803483e38989260c839b95ec21a.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:xxxxxxxxxxxx:changeSet/samcli-deploy1575968922/0e4787ac-be3c-4570-b9df-aff104e56e0f

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

2019-12-10 09:09:09 - 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                      HelloWorldFunctionHelloWorldPermissionProd   -
CREATE_IN_PROGRESS                           AWS::Lambda::Permission                      HelloWorldFunctionHelloWorldPermissionProd   Resource creation Initiated
CREATE_IN_PROGRESS                           AWS::ApiGateway::Deployment                  ServerlessRestApiDeployment47fc2d5f9d        -
CREATE_COMPLETE                              AWS::ApiGateway::Deployment                  ServerlessRestApiDeployment47fc2d5f9d        -
CREATE_IN_PROGRESS                           AWS::ApiGateway::Deployment                  ServerlessRestApiDeployment47fc2d5f9d        Resource creation Initiated
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                      HelloWorldFunctionHelloWorldPermissionProd   -
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::xxxxxxxxxxxx:role/sam-app-HelloWorldFunctionRole-CX6RQWJVS01U
HelloWorldApi - API Gateway endpoint URL for Prod stage for Hello World function         https://ttxhqs49p8.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
HelloWorldFunction - Hello World Lambda Function ARN                                     arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxx:function:sam-app-HelloWorldFunction-
                                                                                         XAHE7P7KUXJ8
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

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

インタラクティブな質問に答えていくと、今後のデプロイ時に参照される samconfig.toml が生成され、デプロイまでできます。
terraform みたいに変更箇所と進捗が見えていいですね!
今までCloudFormationの画面で見てたので。

# デプロイ確認
$ curl https://ttxhqs49p8.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
{"message":"hello world"}

deploy時のメッセージのOutputKey-Description > HelloWorldApi に出力されているURLで確認できます。無事デプロイできてますね

hello-world/app.jsmessage: 'hello world' 部分を message: 'hello new world' に書き換えてみます。

$ sam build
$ sam deploy

samconfig.toml があるので sam deploy 呑みで実行でき変更箇所も確認できると思います。
でも、ちゃんとbuildはしないといけません。

# デプロイ確認
$ curl https://ttxhqs49p8.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
{"message":"hello new world"}

簡単ですね!

デプロイしたもののお掃除

デプロイは簡単になったのですが、削除用のコマンドは提供されていないのでここは今まで通り削除が必要です。
dpeloy時のメッセージに Successfully created/updated stack - sam-app in ap-northeast-1 とスタック名が記述されているので該当のstackを削除します

$ aws cloudformation delete-stack --stack-name sam-app

これでデプロイされていたLambdaやApiGatewayは削除されます。
本当にきれいさっぱりしたい場合は、 samconfig.toml に記述されている s3_bucket もコンソールなどで削除しましょう

終わりに

init--location などオプションも増えていたため、そのあたりの紹介もしたかったのですが、コンソール出力の出力内容を張り付けていたら長くなったのでいったんここまで。
アップデートが速いと戸惑うことも多いですが、確実に使いやすくなっておりすごくいいですね!

皆さんもぜひ新しくなった sam でサーバレスライフを満喫してください。

tutida

tutida

福岡でWebエンジニアやってます。PHP, クラウド, インフラあたりが好き。AWS 五冠