AWS SAMを使ってみた！感動した！ 

# はじめに
<!-- 発端や概要を記載 -->
AWS SAM CLIのインストールからHello Worldアプリケーションをデプロイしてみます。
デプロイ実行からものの数十秒でリソースが指定通りにできてて感動しました。
マネージメントコンソールでポチポチやっている方は今すぐSAM環境構築しましょう！
これからは『継続的インティグレーション/継続的デリバリー(CI/CD)』必須ですよ（今さら）！

# 動作環境
macOS Monterey 12.6.5

# 前提条件
* AWS アカウントへのサインアップ。
* 管理者 IAM ユーザーを作成する。
* アクセスキー ID とシークレットアクセスキーを作成する。
* AWS CLI のインストール

<!-- 各チャプター -->
# AWS SAM CLI のインストール
* パッケージのダウンロード＆インストール
GUIインストラーもありますが、今回はコマンドラインでインストールします。
[AWS SAM CLI のインストール](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/install-sam-cli.html)からインストールパッケージをダウンロードします。
インストールします。
```
$ sudo installer -pkg [path-to-pkg-installer/name-of-pkg-installer] -target /
```
※[path-to-pkg-installer/name-of-pkg-installer]：ダウンロードしたパッケージのファイルパス
ターゲット
* AWS SAM CLIが正しくインストールされていることを確認します。
```
$ which sam
/usr/local/bin/sam
$ sam --version
SAM CLI, version 1.86.1
```
# Hello World アプリケーションのデプロイ
* 作業前にAWS CLIで複数のアカウントを使い分けている場合、今回デプロイ先となるのAWSアカウントの認証情報を設定しているプロファイルに切り替えます。
* プロファイルリストの表示
```
$ aws configure list-profiles
```
* プロファイルの切り替え(環境変数)
```
export AWS_PROFILE=[プロファイル名]
```
* 利用しているプロファイルの確認(環境変数を参照している場合)
```
$ aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile              awsprofile1              env    ['AWS_PROFILE', 'AWS_DEFAULT_PROFILE']
access_key     ****************ICND shared-credentials-file    
secret_key     ****************yEgO shared-credentials-file    
    region           ap-northeast-1      config-file    ~/.aws/config
```
* プロファイルの認証情報
```
$ cat ~/.aws/credentials 
[awsprofile2]
aws_access_key_id = A*******************
aws_secret_access_key = 6***************************************
[awsprofile3]
aws_access_key_id = A*******************
aws_secret_access_key = 7***************************************

[default]
aws_access_key_id = A*******************
aws_secret_access_key = N***************************************
[awsprofile1]
aws_access_key_id = A*******************
aws_secret_access_key = U***************************************
```
# sam init
sam init=新しいサーバーレスアプリケーションを初期化します。
下記のコマンドを入力します。
```
$ sam init
```
テンプレートソース、アプリケーションテンプレート、ランタイムなど聞かれるので選択していきます。
Project nameは任意です。今回はtodoとしてます。
```
Which template source would you like to use?
	1 - AWS Quick Start Templates
	2 - Custom Template Location
Choice: 1

Choose an AWS Quick Start application template
	1 - Hello World Example
	2 - Data processing
	3 - Hello World Example with Powertools for AWS Lambda
	4 - Multi-step workflow
	5 - Scheduled task
	6 - Standalone function
	7 - Serverless API
	8 - Infrastructure event management
	9 - Lambda Response Streaming
	10 - Serverless Connector Hello World Example
	11 - Multi-step workflow with Connectors
	12 - Full Stack
	13 - Lambda EFS example
	14 - DynamoDB Example
	15 - Machine Learning
Template: 1

Use the most popular runtime and package type? (Python and zip) [y/N]: y

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]: y
X-Ray will incur an additional cost. View https://aws.amazon.com/xray/pricing/ for more details

Would you like to enable monitoring using CloudWatch Application Insights?
For more info, please view https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-application-insights.html [y/N]: y
AppInsights monitoring may incur additional cost. View https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/appinsights-what-is.html#appinsights-pricing for more details

Project name [sam-app]: todo
    -----------------------
    Generating application:
    -----------------------
    Name: todo
    Runtime: python3.9
    Architectures: x86_64
    Dependency Manager: pip
    Application Template: hello-world
    Output Directory: .
    Configuration file: todo/samconfig.toml
    
    Next steps can be found in the README file at todo/README.md
```
Commands you can use next　こんなコマンド使えるよ。
```
Commands you can use next
=========================
[*] Create pipeline: cd todo && sam pipeline init --bootstrap
[*] Validate SAM template: cd todo && sam validate
[*] Test Function in the Cloud: cd todo && sam sync --stack-name {stack-name} --watch
```
作成されるプロジェクトディレクトリ構成はこんな感じになります。
```
$ cd todo
$ tree
.
├── README.md
├── __init__.py
├── events
│   └── event.json
├── hello_world
│   ├── __init__.py
│   ├── app.py
│   └── requirements.txt
├── samconfig.toml
├── template.yaml
└── tests
    ├── __init__.py
    ├── integration
    │   ├── __init__.py
    │   └── test_api_gateway.py
    ├── requirements.txt
    └── unit
        ├── __init__.py
        └── test_handler.py
```
# sam build
プロジェクトディレクトリに移動してビルドします。
template.yaml をもとにビルドされます。
```
$ cd todo/
bash-3.2$ sam build
Starting Build use cache
・・・
Build Succeeded
```
# ローカルでテスト
ローカルでテストができるようなのでやってみる。
```sam local invoke```コマンドを使用して、AWS Lambda関数の1回限りの呼び出しができるとのこと。
```
$ sam local invoke
Error: Running AWS SAM projects locally requires Docker. Have you got it installed and running?
```
ありゃ
Dockerが入っていないとダメみたい。
[AWS SAM CLI で Docker を使用するためのインストール方法](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/install-docker.html)あたりを参考にDocker(Docker Desktop)入れる。
```
$ sam local invoke
Invoking app.lambda_handler (python3.9)                                                       
Local image is up-to-date                                                                     
Using local image: public.ecr.aws/lambda/python:3.9-rapid-x86_64.                             
                                                                                              
Mounting /Users/xxxxxx/workspace/todo/.aws-sam/build/HelloWorldFunction as             
/var/task:ro,delegated, inside runtime container                                              
START RequestId: 6bdc7d24-8afb-46df-b4f8-3f92e4404925 Version: $LATEST
{"statusCode": 200, "body": "{\"message\": \"hello world\"}"}END RequestId: 6bdc7d24-8afb-46df-b4f8-3f92e4404925
REPORT RequestId: 6bdc7d24-8afb-46df-b4f8-3f92e4404925	Init Duration: 0.29 ms	Duration: 132.16 ms	Billed Duration: 133 ms	Memory Size: 128 MB	Max Memory Used: 128 MB	
```
おおお。OKOK。
```sam local invoke```コマンドの詳しい使い方などは[sam local invoke を使用する](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/using-sam-cli-local-invoke.html)
# sam deploy
いよいよデプロイです。
上記までと変わってプロジェクトフォルダがtodo0614になってますが任意です。
```
$ sam deploy --guided

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

	Looking for config file [samconfig.toml] :  Found
	Reading default arguments  :  Success

	Setting default arguments for 'sam deploy'
	=========================================
	Stack Name [todo0614]: todo0614
	AWS Region [ap-northeast-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
	#Preserves the state of previously provisioned resources when an operation fails
	Disable rollback [Y/n]: Y
	HelloWorldFunction has no authentication. Is this okay? [y/N]: y
	Save arguments to configuration file [Y/n]: Y
	SAM configuration file [samconfig.toml]: samconfig.toml
	SAM configuration environment [default]: default

・・・・
```
成功すると、このように出力されます。
（一部情報はマスクしています）
```
CloudFormation outputs from deployed stack
-------------------------------------------------------------------------------------------------
Outputs                                                                                         
-------------------------------------------------------------------------------------------------
Key                 HelloWorldFunctionIamRole                                                   
Description         Implicit IAM Role created for Hello World function                          
Value               arn:aws:iam::xxxxxxxxxxx:role/todo0614-HelloWorldFunctionRole-1xxxxxxxxx 

Key                 HelloWorldApi                                                               
Description         API Gateway endpoint URL for Prod stage for Hello World function            
Value               https://xxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/     

Key                 HelloWorldFunction                                                          
Description         Hello World Lambda Function ARN                                             
Value               arn:aws:lambda:ap-                                                          
northeast-1:xxxxxxxxxx:function:todo0614-HelloWorldFunction-xxxxxxxxxx                      
-------------------------------------------------------------------------------------------------


Successfully created/updated stack - todo0614 in ap-northeast-1
```
# マネジメントコンソールで確認
本当にできてる！感動！
API Gatewayのほか、Lambda関数、CloudFormationスタック、IAMロール、S3にも作業用バケットができていたりします。マネージメントコンソールでみてみましょう。
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309834/d8892ba5-ef00-48c4-6381-644ecde531db.png)
# API動作確認
curlで確認
```
$ curl https://xxxxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello
{"message": "hello world"}
```
OKですね。
# 最後に
数十秒で様々なリソースがAWS上にデプロイできました。感動しました。
これから色々なリソース作成をyamlファイルで書けるようになって、AWS SAMをどんどん使いこなしていきたいです。
# 参考文献
- [AWS CLI の最新バージョンをインストールまたは更新します。](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html)
- [AWS SAM CLI のインストール](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/install-sam-cli.html)
- [チュートリアル: Hello World アプリケーションのデプロイ](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-getting-started-hello-world.html)
- [AWS SAM を用いて Hello World アプリケーションをデプロイしてみる](https://qiita.com/tmasuyama/items/0d8b59522a0bd1859a59)
- [Hello AWS SAM World!!](https://qiita.com/surai/items/f8eafd1adde951408a2d)
- [sam init を使用する](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/using-sam-cli-init.html)