一番簡単な Terraform Apply

# はじめに
前回、AWS CDKでDeployまでの簡単な例として「IAMユーザを作る」のを記事にしました。

https://qiita.com/a_b_/items/15a35108ad4a8a38346f

今回は同じことを、Terraformでやってみました。

# 参考
以下のサイトを参考にしました。

https://anikitech.com/cloud9-terraform/

https://chariosan.com/2018/12/09/terraform_start/

# 用意するもの

- Cloud9
    - t3.smallで作りました
    - デフォルトVPC上
- Terraform用、IAMユーザ

# 手順
## tfenvインストール
Terraformはバージョンがよく変わるようなので、バージョン管理できるtfenvを入れました。

https://github.com/tfutils/tfenv#manual

```
git clone https://github.com/tfutils/tfenv.git ~/.tfenv
sudo ln -s ~/.tfenv/bin/* /usr/local/bin

# シンボリックリンクができているか確認
ll /usr/local/bin/terraform
ll /usr/local/bin/tfenv

```

## Terraformインストール
```
# 使用可能バージョン一覧
tfenv list-remote

# 後日TFLintを入れることを想定して、下記バージョン（今回はTFLintはインストールしない）
tfenv install 1.1.0
tfenv use 1.1.0
tfenv list
```

# 実行の流れ
## プロジェクト用ディレクトリ作成
```
mkdir test-terraform
cd test-terraform/
```

## コード記述
```terraform:/test-terraform/main.tf
# アクセスキーとシークレットキーを扱う変数
# 今回は、環境変数で与える
variable "access_key" {}
variable "secret_key" {}

terraform {
  # AWSプロバイダーのバージョン
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~>4.8.0"
    }
  }
}

# AWSプロバイダを定義
provider "aws" {
  access_key = "${var.access_key}"
  secret_key = "${var.secret_key}"
  region  = "ap-northeast-1"
}

# IAMユーザ作成
resource "aws_iam_user" "lb" {
  name = "Komichi-Akebi"
}

```

フォルダ構成は以下のようになります。
この後のコマンドで色々ファイルが生成されますが、今の時点ではこれだけになります。

```
test-terraform
└── main.tf
```



## 実行

```
# 環境変数にアクセスキーとシークレットキーを代入
# Terraformの変数として扱う場合は、"TF_VAR_"という接頭辞を付ける
export TF_VAR_access_key="<<aws_access_key_id>>"
export TF_VAR_secret_key="<<aws_secret_access_key>>"

# 初期化
terraform init

# コードをフォーマットし、見栄えを揃える
terraform fmt -recursive
terraform fmt -recursive -check

# 構文エラーを確認
terraform validate

# 実行計画確認
terraform plan

# 作成
terraform apply
```

`terraform apply`を実行すると、以下のように確認を求められるので、yesを入力。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/c05de7aa-df89-69c1-718c-1f75808bc84b.png)

以下のように作成されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/580101e4-fa01-55ea-7f84-5a41f0ad144d.png)

AWS CDKとは異なり、CloudFormation上には該当のスタックはありませんでした。

## 構成の変更
コードを修正して`terraform plan`を実行します。
以下のように差分が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/ea002b32-42c0-2809-50a5-c5af6edf8d13.png)

問題なければ、`terraform apply`を実行し変更します。
以下のようにユーザ名が変更されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/538583cd-c4fe-cf4f-c9ff-b506420cc83c.png)

## 構成の削除
削除する場合は以下のコマンドになります。
```
terraform destroy
```

applyの時と同様に確認が求められるので、yesを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/02b30c86-675a-23c8-43aa-0068e1b0d6d8.png)

作成したリソースが削除されます。

# 余談
Cloud9は、コンソールログインユーザと同等の権限を持つ仕組みがあります。

https://dev.classmethod.jp/articles/aws-cloud9-aws-managed-temporary-credentials/

https://dev.classmethod.jp/articles/execute-aws-cli-with-iam-role-on-cloud9/

Terraformのプロバイダに指定したIAMユーザの代わりに、この仕組みで生成されるキーを使うことができないか試してみました。

キーの情報は`cat ~/.aws/credentials`で見れます。（ですがこの情報、ある程度時間が経つと別のキーに置き換わります。この時点でうまくいかなさそう...）

それらを環境変数に指定して`terraform plan`を実行すると、（案の定）エラーとなり、以下のようなメッセージが表示されました。
```
╷
│ Error: error configuring Terraform AWS Provider: error validating provider credentials: error calling sts:GetCallerIdentity: operation error STS: GetCallerIdentity, https response error StatusCode: 403, RequestID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, api error InvalidClientTokenId: The security token included in the request is invalid.
│ 
│   with provider["registry.terraform.io/hashicorp/aws"],
│   on main.tf line 14, in provider "aws":
│   14: provider "aws" {
│ 
╵
```
Cloud9用のキーのためか、Terraformでは使えませんでした。
説明した際に用いたような、専用のIAMユーザを作る必要がありそうです。

# おわりに
今回はTerraformで簡単な構成作成例をまとめてみました。
今までTerraformはとっつきにくそうだな、というイメージがあったのですが、実際使ってみるとそうでもありませんでした。
Terraformをこれから触る方は参考にしていただければ幸いです。


# 参考：TerraformのAWS Providerのリファレンス
いつか使う機会があった場合のメモとして。

https://registry.terraform.io/providers/hashicorp/aws/latest/docs