Terraformをcontainerで試してみたメモ

## やろうとしていること
- terraformを勉強したい
- ただローカル環境をterraformインストールとかで汚したくない
- そこでcontainer使って汚染されないように環境を作ろうと思い立った
- 全然よくわかってないけどついでにVSCode Remote Containerでファイルをいじれるようにしたい

## 前提
- terraform, container, VSCode Remote Container全てにおいて初心者

## 行ったことを順次記載していく
### terraformの環境を作る(imageからやってみる編)
#### terraformをインストールし動かせる環境を構築するためのDockerFileを作るための調査
- 参考：[Terraformの実行環境](https://blog.naoty.dev/352/)
    - Terraformの環境構築として、Homebrewでインストールする方法と、[hashicorp/terraformのDockerイメージ](https://hub.docker.com/r/hashicorp/terraform/)を使って実行する方法がある
    - おそらく既存のイメージを使う方法が一番簡単だと思うが、AWC CLIとかも全て含めてdocker上で環境を作りたいので、一旦Homebrewで一からインストールする方法を検討する
- docker上でbrewできるように設定する
    - 参考：[Dockerfileで完結 CentOS8でlinuxbrewを使う方法](https://qiita.com/A-Kira/items/e595af54bd275b0cfd36)
    - => エラーになって無理だった。原因を調べている時間もないの **1つ目の参考の既存のイメージを用いる方法にする**

#### terraformイメージから起動するdocker fileの作成
- 一旦動くか確認。この後、ここにAWS CLI等を入れて環境構築をするdocker fileを作る
    - ```FROM hashicorp/terraform:latest``` だけって感じ

#### VSCode Remote Containerを入れて上記docker fileの動作確認
(省略)

#### とりあえずDockerComposeを作っておく
- 今回は不要と思うが常にComposeで作る癖をつけておく(必要ない？)
- terraformとの相性が良くないのか(勉強不足)、compose経由だとcontainerが起動したままにできなかったので致し方なくDockerFile直でやる
    - ```Shell server terminated (code: 1, signal: null)```

#### と思ったのだが、AWS CLIとterraformが入ったローカル環境を作るためにはやっぱり、1からインストールするDockerContainer必要じゃね？と思ったので立ち止まり検討
- 参考：[docker-composeでTerraformのAWS構築環境を作成する 【AWS CLI 2対応】](https://zenn.dev/foolishell/articles/69a9200596560e)
    - zipで持ってきて解凍して使えるようにしている
    - これを見て頑張るのが良さそう

### terraformの環境を作ってEC2作ってみる(dockerfileでRUNで頑張って環境構築する編)
- 参考：[docker-composeでTerraformのAWS構築環境を作成する 【AWS CLI 2対応】](https://zenn.dev/foolishell/articles/69a9200596560e)

#### AWS CLIのインストール

```Dockerfile
FROM ubuntu:20.04

# install comand.
RUN apt-get update && apt-get install -y less vim unzip curl sudo

# install awscli v2
# to see -> https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-linux.html
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && \
    unzip awscliv2.zip && \
    sudo ./aws/install
```

インストールできていることの確認

```ssh
> # aws --version
> aws-cli/2.4.20 Python/3.8.8 Linux/5.10.76-linuxkit exe/x86_64.ubuntu.20 prompt/off
```

#### terraformのインストール

AWS CLIのインストールのDockerFileの下に追記

```dockerfile
# install terraform
# to see -> https://learn.hashicorp.com/tutorials/terraform/install-cli
## check -> > terraform --version
RUN sudo apt-get update && apt-get install -y gnupg software-properties-common

RUN curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add - &&\
    sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main" && \
    sudo apt-get update && sudo apt-get install terraform
```

インストールできていることの確認

```ssh
# terraform --version
> Terraform v1.1.6
> on linux_amd64
```

#### クレデンシャルの設定

- AWSコンソールから「AdministratorAccess」ポリシーがアタッチされたアクセスキーの払い出し
    - 参考：[IAM ユーザーのアクセスキーの管理](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_access-keys.html)
        - 右上のナビゲーションバーで[My Security Credentials (セキュリティ認証情報)] を選択
        - [新しいアクセスキーの作成] を選択
        - Access Key ID と Secret access key をメモ
- 環境変数を設定

```dockerfile
ENV AWS_ACCESS_KEY_ID='xxxxx' \
    AWS_SECRET_ACCESS_KEY='xxxxx' \
    AWS_DEFAULT_REGION='ap-northeast-1' \
    AWS_DEFAULT_OUTPUT='json' 
```

- 正しく設定されていることの確認。この時点でTerraformも設定したくれ電車るを認識してくれるらしい

```ssh
# aws sts get-caller-identity
=> これでエラーになってなければOK
```
#### terraformのコード実装

- DockerFileを配置しているフォルダが実行環境になっているのでそこにsrcファイルを作成し、以下ファイルをmain.tfファイルとして作成する

```terraform
resource "aws_instance" "hello" {
    ami           = "ami-0701e21c502689c31"
    instance_type = "t2.micro"
}

provider "aws" {
    region = "ap-northeast-1"
}
```

- resourceで、インスタンスを定義。amiにAmazonLinux2(ami-0701e21c502689c31)を設定
    - helloはリソースの名前。terraform内で一位に判別するための名前だと思う
- providerで、クラウドプロバイダの設定を記述。省略可能だが、実行環境に依存せず実行できるので常に記述するべき

#### リソースの作成

- 実装したファイルへ移動(cd src)
- 初期化
    - terraformでは最初に初期化が必要

```ssh
terraform init
> ...
> Terraform has been successfully initialized! # これが出たらOK
```

- 実行内容の確認
    - ここではまだ作成しない。実行前に何が起こるか確認することが可能

```ssh
terraform plan
> # aws_instance.hello will be created
>  + resource "aws_instance" "hello" {
>      + ami                                  = "ami-0701e21c502689c31"
>      + instance_type                        = "t2.micro"
>      + availability_zone                    = (known after apply)
>   (色々省略)
```

- 実環境へ反映
    - planの内容に問題なければOK

```ssh
terraform apply
・・・
> Plan: 1 to add, 0 to change, 0 to destroy.
>
> Do you want to perform these actions?
>   Terraform will perform the actions described above.
>   Only 'yes' will be accepted to approve.
> 
>   Enter a value: yes # これが表示されたらyesを入力
・・・
> Apply complete! Resources: 1 added, 0 changed, 0 destroyed. # これが出れば完了
```

- AWSコンソールで確認する
    - 定義したEC2ができていればOK

### Terraformおまけ
- コードフォーマット
    - ``` terraform fmt -recursive ```
        - recursiveオプションをつけることでサブディレクトリ配下も実施される
- よく使われるファイル名
    - main.tf
        - terraformの基本設定を記載する定義ファイル
    - variables.tf
        - 変数を定義するファイル
    - outputs.tf
        - 実行後に出力される変数を定義するファイル
    - リソース名.tf
        - ファイル名ごとにサービスを分けて定義するファイル(network.tfなど)