⚰️

私は AWS SAM を使わなければならない

2021/05/10に公開

はじめに

タイトル名ふざけました。すみません。

技術ブログ等で紹介されていますが、業務で AWS SAM を使う機会があったので備忘録として残しておこうと思います
今回は Lambda を題材に書いていきます

AWS SAM

https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html

公式が提供している サーバーレスアプリケーションの構築に使用できるオープンソースフレームワーク です
使うメリットの詳細については、上記の公式ドキュメントを参照してください(私自身が全てを使えているわけではないので)

個人的には、Lambdaで使うプログラムの テストデバックビルド をローカル環境で出来るのが便利だと思っています

環境

Windows 10 Pro
Windows for Docker (20.10.6, build 370c289)
WSL2

何で Docker? と思うかもしれませんが、テストの際に Docker のコンテナを使うためです
(Dockerのインストール方法は割愛させていただきます)

作業

SAMのインストール

各環境に合わせてインストールしてください
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html

WSL2環境でのやり方を載せておこうと思ったんですが、私がインストールしたときと今のドキュメントの内容が変わっていたため、ドキュメントを参照してください

とりあえず Hello World

どんな感じかを掴み取るには、チュートリアルが一番ですね
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-getting-started-hello-world.html

やることは以下のようです

#Step 1 - Download a sample application
sam init

#Step 2 - Build your application
cd sam-app
sam build

#Step 3 - Deploy your application
sam deploy --guided

Step 1 - Download a sample application

sam init についてのドキュメントは以下になります
https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-init.html

チュートリアルだと、ランタイムを指定していなかったので上記ドキュメントからサポートされているランタイムを調べて指定しました

sam init --runtime go1.x

終わった後に知ったんですが、ランタイムを指定せずとも、どのランタイムを使用するかを問われるため、わざわざ指定する必要はなかったです...
コマンド実行したあとの対話形式について見ていきます

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

今回は、Hello World をするので、手元にテンプレートが無いため 1 を選択しました
使うテンプレートがある場合は、2 を選択しましょう

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

Lambdaを使うので 1 を選択しました
コンテナイメージを使いたい場合は、2 を選択しましょう

Project name [sam-app]: hello-world

わかりやすいように、hello-world としました
プロジェクトで使う名前を指定しましょう

Cloning app templates 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)
Template selection: 1

Hello World をするため、 1 を選択しました
2もサンプルで用意されているAppのようです
(最初の質問で、使用するテンプレートを Quick Start にしたからでしょう)

-----------------------
Generating application:
-----------------------
Name: hello-world
Runtime: go1.x
Dependency Manager: mod
Application Template: hello-world
Output Directory: .

Next steps can be found in the README file at ./hello-world/README.md

入力した結果の情報を出力しています

Output Directory:. と出力されたので、コマンドを実行したディレクトリに Project name [sam-app]: で指定した hello-world のディレクトリが作成されました
(未入力の場合は、デフォルトの sam-app になります)

次に何をすればいいかは、最終行に README を読めと出力されているので確認しましょう
中身は割愛しますが、Zipファイルの中身や必須なパッケージなどが記載されています

Step2 - Build your application

アプリケーションのビルドをするわけですが、sam build が何をしているかは README の中で記載されています

簡単にいうと、依存関係を全部ダウンロードしてパッケージ化してくれます

cd hello-world
sam build
Building codeuri: hello-world/ runtime: go1.x metadata: {} functions: ['HelloWorldFunction']
Running GoModulesBuilder:Build

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

生成されたファイルもありますが、一旦ローカルで動作確認をしちゃいます
Invoke Function: に書かれている sam local invoke を実行しましょう

これを実行することで、ローカルで動作確認(テストやデバック)ができます

Invoking hello-world (go1.x)
Image was not found.
Building image..............

~省略~

REPORT RequestId: 32835243-d58c-4c80-be3f-785411e4350d  Init Duration: 0.21 ms  Duration: 852.08 ms     Billed Duration: 900 ms Memory Size: 128 MB     Max Memory Used: 128 MB
{"statusCode":200,"headers":null,"multiValueHeaders":null,"body":"Hello, マイIP\n"}

ここで Docker の登場です
Dockerイメージがないため (Image was not found.) イメージを作成(Building image)し、そのあと実行しています
サンプルの Hello World の内容を見ていませんでしたが、マイIPが帰ってくるみたいですね

もう一回実行すると、既にDockerイメージがあるため、すぐに結果が返ってくると思います

ちなみに、ローカルAPIゲートウェイ?なるものを起動して確認もできます

sam local start-api

実行すると、http://127.0.0.1:3000/ にアクセスできるようになりますが
関数を実行したいので、http://127.0.0.1:3000/hello にアクセスしましょう

すると、ブラウザ上にマイIPが出力されると思います

build時に生成されたファイルについて

少し脱線しますが、生成されたファイルについて理解しておいた方がいいため記載します

build が成功したときに出力されていたのが以下です

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

中身を確認します

.aws-sam
├── build
│   ├── HelloWorldFunction
│   │   └── hello-world
│   └── template.yaml
└── build.toml

build/HelloWorldFunction/hello-world

Goの場合は、buildによって生成されたバイナリファイルになります
他のはどうなんだろと思い、Pythonで確認してみましたが、プログラムとそれに必要なパッケージがありました

.aws-sam/build/HelloWorldFunction はデプロイ時に使うことが分かりました

build/template.yaml

AWS::Serverless::Function(SAM用のType)を作成するCloudFormationテンプレートです

デプロイすると、AWS上ではスタックを作成しています
一緒にAWSリソースに何か行いたい場合は、このテンプレートに記載すると良いと思います

build.toml

ビルド時に使用する設定ファイルです
このファイルに 関数やruntimeなどの情報が記載されています

Lambda のレイヤーにも対応しているため、layer_build_definitions の項目もあります

ファイルの関係性がなんとなく分かったかなと思います

Step 3 - Deploy your application

最後のデプロイです
初めて実行する際は、--guided オプションをつけて実行しましょう

sam deploy --guided

色々と出力されますが必要だと思う部分だけ記載します

Configuring SAM deploy
======================
Looking for config file [samconfig.toml] :  Not found

デプロイ時に使う設定ファイルです
初回はないので、Not found と言われますが、2回目からはファイルが生成されているため、中身を見てデプロイを行います

Setting default arguments for 'sam deploy'
=========================================
Stack Name [sam-app]: hello-world    
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
HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y
Save arguments to configuration file [Y/n]: Y
SAM configuration file [samconfig.toml]: 
SAM configuration environment [default]: 

設定ファイルの中身を作成するために、対話形式になっています

この中で、特に重要だと思うのが SAM configuration environment [default]: です
environment と見たら直感的に分かるかもしれませんが、環境に応じて使い分けが可能です
例えば、stg環境は default にし、prod環境を prod にするなどが出来ます

出力は省略しますが、先程の対話形式後に色々と出力され、Deployment s3 bucket という項目があり、
CloudFormationで使うテンプレートのアップロード場所が記載されています
これは、デプロイ後に作成されるファイルを修正することで変更が可能です

生成されたファイルについては次回の記事で触れます

結果を見に行く

ap-northeast-1 の CloudFormationを見に行くと、hello-world という名前でスタックが出来上がったと思います
出力タブで作成されたリソースが確認できるので、見るとLambdaも作成されていることが分かります

これで チュートリアル でやることは以上です(ちゃんとドキュメント読んでないです)

削除

sam cli にスタックを削除するコマンドがないっぽいので
通常の aws cli で削除するか、コンソール画面から削除してください

使ってみてどうか

最初にも書きましたが、個人的には、便利なツール だと思います
Lambda の場合は使うプログラムなどをZip化してアップロードし、動作確認を行うという作業が発生します
ローカルでは動いたプログラムが Lambda では動かない...!!!みたいなことが発生すると、またやり直しです
これはエンジニアにとってはストレスです

それを解消してくれるのが、SAMです
アップロードもSAM側でやってくれるし、リソースもCloudFormationのスタックで管理するため、管理上もいいと思います

さいごに

Hello World編はここまでとなります

チュートリアル自体はコマンドをただ実行するだけだったので、そんなに難しいことはなかったと思います
Lambdaを使っている方であれば、使った方がいいツールだと思います!

次は実用的な話ができればと思います

Discussion