AWS SAM超入門 - 準備からLambda関数のデプロイまで

## 概要
今までLambdaコンソールから手動で関数を書き換えたり設定値を変更してデプロイを行なっていました。
手動作業が多くて危険だったのでAWS SAMを試すことにしました。
動作の理解として超簡単な入門コードでSAMを試してみたので残します。

## 前提
対象AWSアカウントのプロファイルをconfigに設定していること
Node.js 18.x でタイムアウトが3分のLambdaをデプロイしてみます

## 全体図
[![Image from Gyazo](https://i.gyazo.com/2585b8aec1dbaa99787b5e4d76c54b72.png)](https://gyazo.com/2585b8aec1dbaa99787b5e4d76c54b72)


## SAMについて
- Lambda関数コードだけじゃなく、タイムアウト値やトリガーといった設定までテンプレート(SAMファイル)で管理できる
- デプロイパッケージをS3にアップロードしてCloudFormationがLambdaに展開させる

## SAMのインストール
```terminal
$ brew install aws/tap/aws-sam-cli
$ sam --version
SAM CLI, version 1.93.0
```

[AWS SAM CLI のインストール 公式ガイド](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/install-sam-cli.html
)

## デプロイまでの流れ

### S3バケットの準備
コンソールからデプロイパッケージ保存用のS3バケット`test-sam-HOGEHOGE`を作成しておく

### 関数コードとSAMの設定ファイルとSAMファイルを準備する
#### ファイル構成
```terminal
$ tree
.
├── index.mjs
├── samconfig.toml
└── template.yaml
```

```javascript:index.mjs
// テスト用 ただ 'Hello SAM' を出力するコード
export const handler = async (event) => {
  console.log('Hello SAM!!!!')
  const response = {
    statusCode: 200,
    body: JSON.stringify('Hello from SAM!!!!'),
  };
  return response;
};
```

```toml:samconfig.toml
version = 0.1

[default.build.parameters]
use_container = false # Lambda向けコンテナを使用するか

[default]
[default.deploy]
[default.deploy.parameters]
stack_name = "test-sam"
s3_bucket = "test-sam-HOGEHOGE"
s3_prefix = ""
region = "ap-northeast-1"
confirm_changeset = true # 変更セットを確認した上でデプロイする
capabilities = "CAPABILITY_NAMED_IAM" # 固定値 CloudFormationにスタック作成のIAM権限を与える
disable_rollback = false # デプロイ失敗時にスタックをロールバックさせる
tags = [
  "env=\"pro\""
]
```
※参考 [samconfig.tomlのオススメ設定](https://dev.classmethod.jp/articles/recommend-sam-config-toml/)


```yaml:template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: SAM Template for test-sam-app

Resources:
  Function:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: test-sam-app
      CodeUri: .
      Handler: index.handler
      Runtime: nodejs18.x
      Timeout: 180

Outputs:
  Function:
    Description: "test-sam-app Lambda Function ARN"
    Value: !GetAtt Function.Arn
  FunctionIamRole:
    Description: "Implicit IAM Role created for test-sam-app function"
    Value: !GetAtt FunctionRole.Arn

```
※参考 [AWS::Serverless::Function の書き方](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-resource-function.html)

### ビルド
```terminal
$ sam build
Build Succeeded

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

Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided
```

### S3へビルドアーティファクトをアップロード
```terminal
$ sam package --s3-bucket [BuketName] --output-template-file packaged.yaml --profile [Profile]
	Uploading to 6dcab2e2b53f4c7bcd720508d7ce53f1  1660 / 1660  (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 /Users/moriryotaro/projects/CodeCommit/test-sam/packaged.yaml --stack-name <YOUR STACK NAME>

```

### デプロイ
```terminal
$ sam deploy --template-file packaged.yaml --stack-name test-sam --capabilities CAPABILITY_NAMED_IAM --profile [Profile]

Uploading to d14de6bb64d70296a0d45746d137e20e  1195 / 1195  (100.00%)

Deploying with following values
===============================
Stack name                   : test-sam
Region                       : ap-northeast-1
Confirm changeset            : True
Disable rollback             : False
Deployment s3 bucket         : test-sam-HOGEHOGE
Capabilities                 : ["CAPABILITY_NAMED_IAM"]
Parameter overrides          : {}
Signing Profiles             : {}

Initiating deployment
=====================
Waiting for changeset to be created..

CloudFormation stack changeset
-----------------------------------------------------------------------------------------------------------------
Operation                    LogicalResourceId            ResourceType                 Replacement                
-----------------------------------------------------------------------------------------------------------------
+ Add                        FunctionRole                 AWS::IAM::Role               N/A                        
+ Add                        Function                     AWS::Lambda::Function        N/A                        
-----------------------------------------------------------------------------------------------------------------


Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:HOGEHOGE:changeSet/samcli-deploy1690422877/7024a557-8916-4b82-beaa-d9041bf7658a


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

2023-07-27 10:55:06 - Waiting for stack create/update to complete

CloudFormation events from stack operations (refresh every 5.0 seconds)
-----------------------------------------------------------------------------------------------------------------
ResourceStatus               ResourceType                 LogicalResourceId            ResourceStatusReason       
-----------------------------------------------------------------------------------------------------------------
CREATE_IN_PROGRESS           AWS::IAM::Role               FunctionRole                 -                          
CREATE_IN_PROGRESS           AWS::IAM::Role               FunctionRole                 Resource creation          
                                                                                       Initiated                  
CREATE_COMPLETE              AWS::IAM::Role               FunctionRole                 -                          
CREATE_IN_PROGRESS           AWS::Lambda::Function        Function                     -                          
CREATE_IN_PROGRESS           AWS::Lambda::Function        Function                     Resource creation          
                                                                                       Initiated                  
CREATE_COMPLETE              AWS::Lambda::Function        Function                     -                          
CREATE_COMPLETE              AWS::CloudFormation::Stack   test-sam                     -                          
-----------------------------------------------------------------------------------------------------------------

CloudFormation outputs from deployed stack
-----------------------------------------------------------------------------------------------------------------
Outputs                                                                                                         
-----------------------------------------------------------------------------------------------------------------
Key                 Function                                                                                    
Description         test-sam-app Lambda Function ARN                                                            
Value               arn:aws:lambda:ap-northeast-1:HOGEHOGE:function:test-sam-app                            

Key                 FunctionIamRole                                                                             
Description         Implicit IAM Role created for test-sam-app function                                         
Value               arn:aws:iam::HOGEHOGE:role/test-sam-FunctionRole-15JUMOQQQFXT6                          
-----------------------------------------------------------------------------------------------------------------


Successfully created/updated stack - test-sam in ap-northeast-1
```

### デプロイ確認

#### S3
[![Image from Gyazo](https://i.gyazo.com/8da4e20b4166715310ab4081a9a94be7.png)](https://gyazo.com/8da4e20b4166715310ab4081a9a94be7)

#### CloudFormation
[![Image from Gyazo](https://i.gyazo.com/4a29e4f668cac4407afa91b81c6797cc.png)](https://gyazo.com/4a29e4f668cac4407afa91b81c6797cc)

#### Lambda
[![Image from Gyazo](https://i.gyazo.com/5731cc51356b7a8bb20211dcf43bf597.png)](https://gyazo.com/5731cc51356b7a8bb20211dcf43bf597)

[![Image from Gyazo](https://i.gyazo.com/4f5ef204b178a3e554d6be5a829820a6.png)](https://gyazo.com/4f5ef204b178a3e554d6be5a829820a6)




### その他参考
https://www.youtube.com/watch?v=ZDvcCY8QRWA

https://dev.classmethod.jp/articles/sam-lambda-with-library/