Terraform Cloud で複数の環境を構成する

 [QualiArts Advent Calendar 2019](https://qiita.com/advent-calendar/2019/qualiarts)、5日目担当の8kkaです。
今回は [Terraform Cloud](https://www.terraform.io/docs/cloud/index.html) を使って複数環境を管理する方法について書いていきます。

# Terraform Cloud

Terraform Cloud は Terraform をチーム運用する際、安全に状態を共有しつつ変更管理を行えるアプリケーションです。
2019年9月10日行われたアップデートにより、機能が大幅に拡張されました。
同じチームで作業する場合は5人まで無償で使用でき、tfstateの管理、GitHub連携、planやapplyなどの基本コマンド実行などが可能です。

# 複数環境のTerraform運用

業務でTerraformを使う場合、production、staging、developmentなど複数の環境を管理する必要があります。
今回は Terraform Cloud を複数環境で運用するための設定をまとめて行きます。
構成は、共通の network 内で環境毎に subnetwork を作成し、 gce インスタンスを1つずつ配置する想定で進めます。

**Terraformのディレクトリ構成**

```
terraform-dev
├── environments
│   ├── common            # 共通リソースを作成する (network)
│   │   ├── backend.tf
│   │   ├── main.tf
│   │   └── provider.tf
│   ├── dev               # development用のリソースを作成する (subnetwork, gce)
│   │   ├── backend.tf
│   │   ├── main.tf
│   │   └── provider.tf
│   ├── prd               # production用のリソースを作成する (subnetwork, gce)
│   │   ├── backend.tf
│   │   ├── main.tf
│   │   └── provider.tf
│   └── stg               # staging用のリソースを作成する (subnetwork, gce)
│       ├── backend.tf
│       ├── main.tf
│       └── provider.tf
└── modules
    ├── gce
    │   ├── main.tf
    │   └── variables.tf
    ├── network
    │   ├── main.tf
    │   └── variables.tf
    └── subnetwork
        ├── main.tf
        ├── output.tf
        └── variables.tf
```

# Workspace の作成

まずは Workspace を作成しましょう。
「Workspaces」 > 「New workspace」 を選択すると、新しい Workspace を作成できるので、 Terraform を管理しているリポジトリを選択します。
最初は共通で使用するリソースを管理するため、 Workspace Name を 「common」 とし、 Terraform Working Directory を 「./environments/common」 に設定します。
<img width="1680" alt="スクリーンショット 2019-12-03 0.16.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66083/34551c05-f9e7-38a1-d1a9-6315dc531463.png">

作成が完了すると、 Workspaces のページに 「common」 の Workspace が作成されます。
<img width="1680" alt="スクリーンショット 2019-12-03 0.18.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66083/9d7b6d81-17cf-25bd-038e-36b1707bc658.png">

試しに 「Queue plan」 を実行してみましょう。
Plan コマンドが走り、実行ログが出力されます。
ログを確認すると、変更されるリソースが無いことが確認できます。
<img width="1680" alt="スクリーンショット 2019-12-03 1.03.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66083/65d06938-db0c-0ff9-56e3-4aa138cb1cc8.png">


# 各環境の Workspace を作成

「common」 の Workspace が動いたら、「dev」「stg」「prd」 の Workspace も同様に作成します。
作成する際は、 Terraform Working Directory を環境毎合わせて以下のように設定します。

```
dev: 「./environments/dev」 
stg: 「./environments/stg」 
prd: 「./environments/prd」 
```

Workspace が出来たら、各環境毎にtfファイルを編集し、リソースを作成します。
まずは dev 環境用のリソースから作成して行きましょう。
<img width="1680" alt="スクリーンショット 2019-12-03 1.21.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66083/27eec379-3b2d-10b0-3216-41615246537e.png">

ちなみに Plan が失敗した場合はこんな表示になり、 Apply することが出来なくなります。
（たまたま失敗したのでここに差し込んでおります。）
<img width="1680" alt="スクリーンショット 2019-12-03 1.25.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66083/4f6c77f2-7e45-25a9-e893-9872e1df701f.png">

また、 Plan が失敗するかどうかはプルリクを送ったタイミングでも検知してくれます。
「Details」 を押すと Terraform Cloud のページに遷移し、詳細なログを見ることが出来ます。
<img width="1680" alt="スクリーンショット 2019-12-03 1.30.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66083/aed5b5a6-8460-1e0d-e5e4-7876d4b18386.png">

Plan が通ってプルリクがマージされると、 対象　Workspace で Apply の実行確認を求められます。
問題なければ 「Confirm & Apply」 ボタンを押して反映させます。
<img width="1680" alt="スクリーンショット 2019-12-03 1.44.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66083/0f7ff194-e884-a6c7-1550-18b47ac20425.png">

Apply が反映されました。
「RUN STATUS」 の項目を見ると、 今回は 「dev」 の Workspace だけに影響があったことが分かります。
(「common」 が APPLED になったのは1時間前)
<img width="1680" alt="スクリーンショット 2019-12-03 1.52.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66083/4343b357-2ddf-0220-d6d1-8779199077ed.png">

同様に他の環境のリソースも作成します。
これらの手法を取ることで、自分の環境に変化があった時だけ Apply を実行することが出来ます。
<img width="1680" alt="スクリーンショット 2019-12-03 2.30.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66083/f0ce3dc4-363f-9d41-845a-1a6bab48c752.png">

# まとめ
Terraform Cloud を使用することで、tfstateの管理やGitHub連携を簡単に設定できます。
また、tfファイルを環境毎のディレクトリで分け、それぞれの Workspace を作成することで複数環境を同時に管理できるようになります。
9月のアップデートにより、 Terraform Cloud はかなり使いやすくなったので、チームで Terraform を使用する際は是非お試しください！