AWS SAM について初心者なりに見えてきたこと

# 背景
一か月ほど、AWS Lambda 周りに取り組んできたので、ここらで一度振り返ってまとめてみよう

想像力とは知識の再構築であることから、自分の理解しているものをまとめるのは役立つので

新しいことを学ぶときは、自身の理解していることを書き留めることは大切なはず、だって忘れるんですもの :hamster: 

# sam command
`sam init` でプロジェクト名でフォルダを作成しつつ初期化
`sam build` で構築して
`sam deploy` でクラウドへ

`sam sync` で、高速デプロイ

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-sync.html

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-sam-cli-command-reference.html

# samconfig.toml
[`sam deploy --guided`](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html#deploy-guided) で、必要な設定を質問形式で入力していった結果。故に二回目以降は --guided は不要だが、stack_name 等の名称は見直した方が無難

`sam build/deploy` といったコマンド実行時、この設定を利用する。Development/Production の切り替えなんかも可能。

ただ、

例えば、
- stack_name
    - Cloud Formation に保存される名前
- s3_bucket
    - S3 上に保存する ARN 
- s3_prefix
    - s3 上に保存する際のフォルダ名
- region
- confirm_changeset
    - deploy 時の確認ダイアログを出すか？

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html

## dev/prod の切り替え例の記事
課題としては、samconfig と、template.yaml との連携？

https://tech.fusic.co.jp/posts/2021-12-09-2021-12-09-aws-sam-samconfig/

## toml 
toml の定義はここに

https://toml.io/ja/v1.0.0-rc.2

# template.yaml
Event から Lambda 関数、Output までここで定義しちゃえば OK な素敵なファイル
Swagger(Open API) 依頼何年振り？と思う yaml ですが、やっぱり便利ですね。


https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-specification-template-anatomy.html

## `Resources:` 
Lambda や、Event に使ったりする リソースを定義をしていく

`Type: AWS::Serverless::Function` を複数定義していくことで、Lambda を複数同時 Deploy 可能

### `Events`
トリガの設定
複数設定可能

```yaml: DynamoDB 例
        DynamoDbEvent:
          Type: DynamoDB
          Properties: 
            BatchSize: 10
            StartingPosition: TRIM_HORIZON # LATEST or TRIM_HORIZON
            Stream: arn:aws:dynamodb:ap-northeast-1:***
            Enabled: true
```

```yaml: SNS 例。以下の場合、SNS Resource を定義している為、 !Ref で参照
        SnsAlarmTopic:
          Type: SNS
          Properties:
            Topic: !Ref TestTopic2
```

```yaml: ルールの例：UTC+0 で設定
        RuleEvent:
          Type: Schedule
          Properties:
            Name: RuleEveryTueSat2120
            # UTC converted to UTC+9:00: am21:34 to pm12:34
            Schedule: cron(34 12 ? * TUE,SAT *)
            Description: Example schedule
            Enabled: True
```

```yaml: スケジュールの例: Timezone 由来で設定
        ScheduleV2Event:
          Type: ScheduleV2
          Properties:
            Name: EveryTueSat1234
            ScheduleExpression: cron(34 12 ? * TUE,SAT *)
            ScheduleExpressionTimezone: "Asia/Tokyo"
            Description: Example schedule2
```

https://qiita.com/baku2san/items/2514ce485731ff7068c5

### `Metadata`
Esbuild 設定の記述

```yaml: 基本は Template のまま
    Metadata: # Manage esbuild properties
      BuildMethod: esbuild
      BuildProperties:
        Minify: true
        Target: "es2020"
        Sourcemap: true
        EntryPoints: 
        - app.ts
        External:
          - "@aws-sdk/lib-dynamodb"
          - "@aws-sdk/client-dynamodb"
```

#### External について
https://qiita.com/baku2san/items/b2161a215e06221b8ca0


## `Outputs`
Lambda の出力先定義
今のところ使ってないけど、SNS Push を利用する際には、SDK で内部からコールするよりは、この接続を使った方が良い気がしているので、そのうち調査したいところ

# 課題
複数の Lambda を定義する場合に、CodeUri を別フォルダ定義して作ることになると思うが・・

- 個別フォルダの 依存関係はどうするのか？
    - 現状、各フォルダにいって、npm コマンドをしてる。`sam build` で `npm install` してそうなので、`script.start/install` などが動くかと思ったけど動かない。とはいえ、package.json/tsconfig.json は必要そう

そもそも、この実装方法が間違っているのかがよくわからない。Sample Code がどこかにあるなら見てみたいが、AWS Sample では見つけられなかった・・。TypeScript に詳しければ解決策があるのかもしれないけれど

- 共通ライブラリのコードの組み込み方法は？
    - これも TypeScript の常識なのかもしれないが・・、現状は、npm scripts で copyfiles でプロジェクトフォルダ外からコピーしてきてる・・。webpack みたいにして固めて取り込み？その辺を学習すればわかるのかも？

```powershell: フォルダイメージ
- src
    - libs
        - ddbClient.ts
        - ddbDocClient.ts
    - lambdaCode1 # ここで npm start して、libs をコピーさせた上で、src 直下で sam build
        - libs copied
        - package.json
        - tsconfig.json
    - LambdaCode2 # ここで npm start
        - libs copied
        - package.json
        - tsconfig.json
```

# あとがき
試行した環境をちゃんと sam delete しないとゴミが残りまくるので、個人環境だと特に注意 :frowning2: 

まだまだわからないことが多いなぁ、というのが正直なところ

今やりたいことは
- DynamoDB 操作の比較
    - 更新式
    - PartiQL
- DynamoDB の Query/Scan 系の速度比較（Best Practice の把握)