S3書き込みするLambda関数のDockerイメージを作成しEventBridgeで定刻実行させる「サーバレスバッチ」をTerraformで自動構築する

忙しくてなかなか時間取れない（ ;  ; ）

掲題のようなニーズってよくありそうなので公開しておきます。

# 概要

https://github.com/yagrush/serverless-scheduled-batch-by-terraform

terraformで以下を自動構築するための一式。

* tfstate管理をS3, tfstate_lock管理をDynamoDBに任せる（のに必要な環境を作成する）
* S3バケットを作る（こちらは業務処理用途のバケット）
* ECRにlambdaのdockerイメージを登録する
* S3にオブジェクトを書き込むlambda関数をdockerイメージから作成する
* EventBridgeで毎分lambda関数を実行するようスケジューリングする

ちなみにlambda関数の中身は `lambda/foo` 以下にpythonプログラム一式があります。
そちらをいじる場合は `lambda/foo` をワークディレクトリとしてVSCodeなどで開いて作業して下さい。

# 自分が試した環境（＆必要なソフトウェア、設定）
* M2, M3 Macbook
* Docker Desktop (or docker & docker-composeコマンド)
* IAMで任意の権限を持ったユーザーを作成できるAWSアカウント

Terraformをインストールする必要はありません。
（Terraform Dockerイメージに実行させるので）

# まずはそのまんまお試しいただく手順
基本はREADME.md通りですが、

## AWSユーザーを作成する
TerraformがAWS上に色々構築するのに必要な権限を持ったAWSユーザーをご用意ください。
（セキュリティなどの心配ご無用なら、オーナーアカウントとかでも良いです）
新たに作成する場合はとりあえず以下の権限を与えておけば動きます。

* AmazonDynamoDBFullAccess
* AmazonS3FullAccess
* AWSLambda_FullAccess
* IAMFullAccess
* CloudWatchLogsFullAccess
* AmazonElasticContainerRegistryPublicFullAccess
* AmazonEventBridgeFullAccess
* ecr.*
```
   {
   "Version": "2012-10-17",
   "Statement": [
       {
           "Sid": "VisualEditor0",
           "Effect": "Allow",
           "Action": [
               "ecr:*"
           ],
           "Resource": "*"
       }
   ]
}
```

## AWSユーザーのアクセスキーを作成する
IAMの画面などからアクセスキーを作成します。
そして以下を控えて下さい。

* Access key ID
* Secret access key

## ホームディレクトリに `.aws/credentials` を作成する
すでに存在するなら以下を追記だけでOK。
`XXXXXXX.....` の部分は、前の工程で控えた各値を入れて下さい。

```shell
[hogehoge]
aws_access_key_id = XXXXXXXXXXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
region = ap-northeast-1
```

## Terraform実行に必要な設定を編集する
以下を各自の状況に応じて編集して下さい。


* `envs/dev/lambda_foo.tfbackend`
`bucket` にはひとまずご自分のハンドルネームなどを書き加えて下さい（S3のバケット名は世界で一意じゃないとダメなので）
* `envs/dev/backend.tfbackend`
`bucket` は上のファイルと一緒にして下さい。
* `envs/dev/config.tfvars`
`bucket_name` にはひとまずご自分のハンドルネームなどを書き加えて下さい（同じ理由）
* [`lambda/foo/src/foo.py`](https://github.com/yagrush/serverless-scheduled-batch-by-terraform/blob/c0f06f956e3c7cfec77e09fd2bc83e5623dddc6c/lambda/foo/src/foo.py#L40C9-L41C9) 40行目
しまったここバケット名ベタ書きしてた・・・
ということで、こちらも上に合わせて書き換えてください。

## Terraformを実行する
コマンドが長いので、Makefileにまとめてmakeコマンドで実行するようにしてあります。
直接コマンドを打つ場合はMakefileの中身を見て下さい。

### Terraformのステート管理用S3バケットとDynamoDBテーブルを作成する。
```shell
make init-p
make plan-p
make apply-p
```

### 業務処理用S3バケットを作成する。
```shell
make init-s3
make plan-s3
make apply-s3
```
`Do you want to perform these actions?` と聞かれたら `yes` と入力する。

### Lambda関数を作成する。
```shell
make init-lambda
make plan-lambda
make apply-lambda
```
`Do you want to perform these actions?` と聞かれたら `yes` と入力する。

具体的にやってること：
* `lambda/foo` 以下一式からLambda関数のDockerイメージを作成。
* ECRにDockerイメージを登録。
* そのDockerイメージからLambda関数を作成。
* EventBridgeに、そのLambda関数を毎分実行するようスケジュールを設定。

あとただのおまけですが

* TerraformでS3にファイルをまとめてアップロードする

を試した痕跡が `lambda/main.tf` に入ってます。

## 動作確認
こけずに全部通ったら、2分後にでも

* CloudWatchログを覗いて、実行ログが出ていること、エラーが出ていないこと
* S3を覗いて、オブジェクト `written_by_foo` が書き込まれていること

が確認できればOK。

## 全て破棄するには
```shell
make destroy-lambda
make destroy-s3
make destroy-p
```
`Do you really want to destroy all resources?` と聞かれたら `yes` と入力する。

これだけ。