TerraformでAWSサービスの情報をコード化する方法

# できること

- AWSサービスの情報をコード化（文書ファイル）にすることができる
- terraformerでコード化できないものに対応できる
    - Lambda、S3が該当する

# 前提条件

- VSCodeが使えること
- AWS CLIが使えること
- Windows端末であること

# Terraformのインストール方法

1. 下記URL内から「Windows」を押下し、「AMD64」の方をダウンロードする。
    - https://developer.hashicorp.com/terraform/downloads
2. ダウンロードしたzipファイルを解凍する。その中の「terraform」アプリを、コード化したファイルを置きたいディレクトリにコピーする。
3. コード化したファイルを置くディレクトリで、「main.tf」ファイルを用意する。ファイルの中身は以下の入力をする。awsに対応するversionは下記URLから抽出する。
    - https://registry.terraform.io/providers/hashicorp/aws/latest

```main.tf
terraform {
	required_providers {
		aws = {
			source = "hashicorp/aws"
			version = "~>5.15.0"
		}
	}
}
```

4.コマンドプロンプト実行環境で「terraform init」コマンドを実行する。このコマンドによってTerraformの初期化ができる。
5.コマンドプロンプト実行環境で「terraform -v」コマンドを実行する。このコマンドでterraformのバージョンが出力されるかどうかで正常に動作しているか確認できる。

# コード化の方法

1. 同じディレクトリに「(AWSサービス名).tf」ファイルを作成する。今回はLambdaをコード化するためのtfファイルを用意する。
    - ファイルの内容はAWSサービスによって異なるため、下記URLのAWSサービス名のResourcesページからresourceのtfファイルのフォーマットを取得する。
    - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function
        - “test_lambda”の箇所は次の工程で使うコマンドと共通の文字列にすれば何でもOK。
        - ファイル名は末尾に.tfが付いていればなんでもOK、だが何のファイルか分かりやすくするためにコード化対象サービスを明記するのがおすすめ。

```lambda_function.tf
resource "aws_lambda_function" "test_lambda" {
	# (resource arguments)
}
```

2.コマンドプロンプト実行環境で下記コマンドを実行する。成功すると「terraform.tfstate」ファイルが実行ディレクトリに作成される。
   - コマンドは各Resoucesページの一番下にあるサンプルコマンドを参考にする。

```
terraform import aws_lambda_function.test_lambda (Lambda関数名)
```

3.先程作成された「terraform.tfstate」ファイルのファイル名を変えて別のフォルダに移動させる。すると2.で実行したコマンドのLambda関数名を別のLambda関数名に変えることで、別のLambdaをコード化できる。

<details><summary>Lambdaのコード化をした場合のtfファイルのサンプル</summary><div>

```terraform.tfstate
{
  "version": 4,
  "terraform_version": "1.5.7",
  "serial": 1,
  "lineage": "58b30f36-b113-2ff7-ea1c-29256ec4c83e",
  "outputs": {},
  "resources": [
    {
      "mode": "managed",
      "type": "aws_lambda_function",
      "name": "test_lambda",
      "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "architectures": [
              "x86_64"
            ],
            "arn": "arn:aws:lambda:ap-northeast-1:657219115014:function:ats-lmd-func-01",
            "code_signing_config_arn": "",
            "dead_letter_config": [],
            "description": "",
            "environment": [
              {
                "variables": {
                  "LOG_LEVEL": "INFO"
                }
              }
            ],
            "ephemeral_storage": [
              {
                "size": 512
              }
            ],
            "file_system_config": [],
            "filename": null,
            "function_name": "ats-lmd-func-01",
            "handler": "lambda_function.lambda_handler",
            "id": "ats-lmd-func-01",
            "image_config": [],
            "image_uri": "",
            "invoke_arn": "arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-northeast-1:657219115014:function:ats-lmd-func-01/invocations",
            "kms_key_arn": "",
            "last_modified": "2023-09-06T02:27:36.455+0000",
            "layers": [],
            "memory_size": 128,
            "package_type": "Zip",
            "publish": null,
            "qualified_arn": "arn:aws:lambda:ap-northeast-1:657219115014:function:ats-lmd-func-01:$LATEST",
            "qualified_invoke_arn": "arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-northeast-1:657219115014:function:ats-lmd-func-01:$LATEST/invocations",
            "replace_security_groups_on_destroy": null,
            "replacement_security_group_ids": null,
            "reserved_concurrent_executions": -1,
            "role": "arn:aws:iam::657219115014:role/ats-lmd-role",
            "runtime": "python3.9",
            "s3_bucket": null,
            "s3_key": null,
            "s3_object_version": null,
            "signing_job_arn": "",
            "signing_profile_version_arn": "",
            "skip_destroy": false,
            "snap_start": [],
            "source_code_hash": "CNGuypKwQ4cwiC0otzQ4FsGU6NalKUvUUTSJ+ynps5U=",
            "source_code_size": 395,
            "tags": {
              "ats": "lmd"
            },
            "tags_all": {
              "ats": "lmd"
            },
            "timeout": 3,
            "timeouts": null,
            "tracing_config": [
              {
                "mode": "PassThrough"
              }
            ],
            "version": "$LATEST",
            "vpc_config": [
              {
                "security_group_ids": [
                  "sg-048f6b35491466018"
                ],
                "subnet_ids": [
                  "subnet-077e7f5b9fe9b08b1",
                  "subnet-09b7406300d35a190"
                ],
                "vpc_id": "vpc-09b8f7a8474546405"
              }
            ]
          },
          "sensitive_attributes": [],
          "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsImRlbGV0ZSI6NjAwMDAwMDAwMDAwLCJ1cGRhdGUiOjYwMDAwMDAwMDAwMH0sInNjaGVtYV92ZXJzaW9uIjoiMCJ9"
        }
      ]
    }
  ],
  "check_results": null
}
```
</div></details>

# Lambda以外のサービスのtfファイルとコマンドサンプル

- CloudWatchメトリクスフィルターのコード化のためのtfファイルとコマンド。
- サービスによってコマンドにARNを指定する場合やロググループ名から指定する場合があるため注意。
```cloudwatch_log_metric_filter.tf
resource "aws_cloudwatch_log_metric_filter" "test_log_metric_filter" {
	# (resource arguments)
}
```

```
terraform import aws_cloudwatch_log_metric_filter.test_log_metric_filter {ロググループ名}:"{メトリクスフィルター名}"
```

- StepFunctionsのステートマシンのコード化のためのtfファイルとコマンド

```stf_state_machine.tf
resource "aws_sfn_state_machine" "test_stf" {
	# (resource arguments)
}
```

```
terraform import aws_sfn_state_machine.test_stf {StepFunctionsのARN}
```

# 参考URL

https://developer.hashicorp.com/terraform/tutorials/aws-get-started/aws-build

https://qiita.com/YK0214/items/9e5975cc3cb50192719e

https://dev.classmethod.jp/articles/kidapan-terraform-install

https://dev.classmethod.jp/articles/cloud9-terraform