TerraformからAWSリソースについて知る

# はじめに

本記事は[Progaku Advent Calendar 2022](https://qiita.com/advent-calendar/2022/progaku) 22日目担当です。

[Terraform](https://www.terraform.io/)とは、IaaSを実現するためのツールの1つで、[AWS](https://aws.amazon.com/jp/)や[GCP](https://cloud.google.com/?hl=ja)、[Azure](https://azure.microsoft.com/ja-jp/)だけでなく[snowflake](https://www.snowflake.com/?lang=ja)や[Elasticsearch](https://www.elastic.co/jp/elasticsearch/)などのリソースも構築できます。

私はここ最近、そんなTerraformでAWSを始めとしたいくつかのリソースを作成することを行っていました。その中で、ドキュメントからAWSリソースについて多くの学びを得ることできました。
そこで、本記事ではTerraformのドキュメントからAWSリソースについてを深堀っていきたいと思います。
このアドベントカレンダーを主宰しているProgakuはプログラミング学習コミュニティなので、せっかくですので技術の学習に重きをおいた記事を一筆してみようと思い立った次第です。

# 対象リソース

AWSリソースだけでもいくつあんねん……となるので、リソースを絞ります。
今回は[AWS Lambda](https://aws.amazon.com/jp/lambda/)について深堀っていきます。
そもそもlambdaってなに？　を解説するとそれだけで1記事になりそうなので、われらがクラスメソッドさんの再入門ブログリレーをご参考ください。(いつもお世話になっております)

- [AWS 再入門 AWS Lambda 編](https://dev.classmethod.jp/articles/cm-advent-calendar-2015-aws-re-entering-aws-lambda/)
- [AWS再入門2018 AWS Lambda編](https://dev.classmethod.jp/articles/2018-aws-re-entering-lambda/)

僕の方でもざっくり説明すると、なんらかのイベントをトリガーにプログラムを動作させるサービスです。サッと調べた感じではFaaSやサーバレスの文脈で出てきていそうです。
なんでlambdaかというと、記事をかけそうなリソースがlambdaだったからです。

lambdaのTerraformについてのドキュメントは以下となります。

- [Resource: aws_lambda_function](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function)

それでは見ていきましょう。

# 見てみる

上の方に概要とかサンプルとか、たくさん並んでいてドキュメントとして素晴らしいですが、Terraformについて知っていかないと分からない
んで飛ばします。今回見たいのは[Argument Reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function#argument-reference)です。
必須項目に `function_name` と `role` があり、一度リソースの作成を行ったことがある方はでしょうねとなるはずです。

roleってなに？となった方は[IAM](https://aws.amazon.com/jp/iam/)について調べてみてください。

- [Resource: aws_iam_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role)
- [AWS再入門ブログリレー2022 AWS IAM編](https://dev.classmethod.jp/articles/re-introduction-2022-aws-iam/)

lambdaにもどってオプショナルな引数を見てもたくさんあります。さすがにこれ全部はキツいので強引ながら私の進めたい方向に進ませていただきます。
ザーッと眺めていくと

- `s3_bucket` - (Optional) S3 bucket location containing the function's deployment package. Conflicts with filename and image_uri. This bucket must reside in the same AWS region where you are creating the Lambda function.
- `s3_key` - (Optional) S3 key of an object containing the function's deployment package. Conflicts with filename and image_uri.

と記載があります。
翻訳してみましょう。

- `s3_bucket` - (Optional) 関数のデプロイパッケージを含む S3 バケットの場所。 filename および image_uri と競合します。このバケットは、Lambda 関数を作成しているのと同じ AWS リージョンに存在する必要があります。
- `s3_key` - (Optional) 関数のデプロイ パッケージを含むオブジェクトの S3 キー。 filename および image_uri と競合します。

関数のデプロイパッケージ？　S3リソースへのCRUDイベントをトリガーとしたlambdaの発火はできますが、それとは違いそう。

- S3イベント概要
  - [Amazon S3 イベント通知](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/NotificationHowTo.html)
  - [チュートリアル: Amazon S3 トリガーを使用して Lambda 関数を呼び出す](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/with-s3-example.html)
  - [3分で作る、S3イベントで実行するLambda](https://dev.classmethod.jp/articles/challice-s3event-lambda-made-in-3-minutes/)

では何なのか？　調べてみます。
ソッコー見つかりました。[Lambda デプロイパッケージ](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/gettingstarted-package.html)
ドキュメントを読むに、lambdaへデプロイするプログラムを置くのにS3を用いるみたいです。

> デプロイパッケージのサイズが 50 MB を超える場合は、関数のコードと依存関係を Amazon S3 バケットにアップロードしてください。
> デプロイパッケージを作成し、Lambda 関数を作成する AWS リージョンの Amazon S3 バケットに .zip ファイルをアップロードできます。Lambda 関数を作成する際は、Lambda コンソール上または AWS CLI を使用して S3 バケット名とオブジェクトキー名を指定します。

一番下にこのような記載があり、合点がいきましたね。
私の偏見ではありますが、lambdaに.zipファイルで上げるといえばGoなので、 `terraform s3 go lambda` という浅いワードで検索してみます。
すると以下の記事に当たりました。

- [GolangのLambda関数をTerraformだけでデプロイする](https://dev.classmethod.jp/articles/deploy-golang-lambda-function-with-terraform/)

上記の記事には以下の記載があり、 `source_code_hash` についてもわかりました。

> source_code_hash
> このattributeは関数の再デプロイのトリガーに使われます。この値が更新されると再デプロイされます。
> `Must be set to a base64-encoded SHA256 hash of the package file`
> という要件があります。
> ローカルのデプロイパッケージを使う場合は filebase64sha256("file.zip") とか base64sha256(file("file.zip")) といった方法が使えます。

Terraformのドキュメントを読んでも

> アップデートのトリガーに使用されます。
> filenameまたはs3_keyで指定されたパッケージファイルをbase64エンコードしたSHA256ハッシュを設定する必要があります。
> 通常の設定方法は
> filebase64sha256("file.zip") (Terraform 0.11.12 以降)
> または
> base64sha256(file("file.zip")) (Terraform 0.11.11 以降) 
> で、ここで "file.zip" はラムダ関数ソースアーカイブのローカルファイル名と同じです。

とクラスメソッドさんの記事の内容を小難しくした記載があります。
TerraformはあくまでIaaSであるため、このようにlambdaリソース自体以外の引数もある点に注意です。

# 終わりに

読んで頂きありがとうございました。
AWSリソースを学ぶための1手法としてTerraformを紹介しましたが、Terraformに限らず[AWS SDK](https://aws.amazon.com/jp/developer/tools/)のドキュメントから学んでもいいかと思います。
私はAWSを触るときはPythonとGoを用いるので、

- [boto3](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html)
- [AWS SDK for Go v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2#section-readme)

の2つを紹介しておきます。
以上、[Progaku Advent Calendar 2022](https://qiita.com/advent-calendar/2022/progaku) 22日目の「ここ最近見つけたAWSリソースとの仲よくなり方」でした。