Terraform Cloud その2 - Gihubと連携してみた(VCSとWorking Directoryの設定)

## おさらい
前回の記事([Terraform Cloud その1 - まずは使ってみた(ローカル実行からリモート実行に変更)](https://qiita.com/kuroseets/items/be8980a7c9764f28ed11))ではローカルで使用していたTerraformをCloudに移行しました。
今回はGithubと連携してCI/CDっぽく回せるようにみたいと思います。

## この記事で実現すること
* GitHub経由でのTerraform Cloudの実行
* 1つのVCSリポジトリからstateを分離させ複数のWorkspaceで実行
* Terraform CloudのWorkspace間の連携

## この記事がターゲットとする読者層
* Terraform CloudとVCSを連携させたい人
* VCSを使う際のWorkspaceの設定を知りたい人

## 準備
前回まで作成したものとは別に以下のものが必要になります。

* GitHubのアカウント

## 使用するサンプルTerraformコード
今回は[こちら](https://github.com/kuroseets/tfc-aws-test)においているような下記構成にしています。
<details><summary>tree構造</summary><div>

```
.
├── README.md
├── ec2
│   └── main.tf
└── main.tf
```
</div></details>

<details><summary>./main.tf</summary><div>

```
variable "aws_access_key" {}
variable "aws_secret_key" {}
variable "region" {
  default = "ap-northeast-1"
}

terraform {
  backend "remote" {
    hostname     = "app.terraform.io"
    organization = "kuroseets"

    workspaces {
      name = "vpc-test"
    }
  }
}

provider "aws" {
  access_key = var.aws_access_key
  secret_key = var.aws_secret_key
  region     = var.region
}

resource "aws_vpc" "test" {
  cidr_block = "10.0.0.0/16"

  tags = {
    Name = "test"
  }
}

resource "aws_subnet" "test_subnet" {
  vpc_id            = aws_vpc.test.id
  cidr_block        = "10.0.0.0/24"
  availability_zone = "ap-northeast-1a"

  tags = {
    Name = "test-a"
  }
}
```
</div></details>
<details><summary>./ec2/main.tf</summary><div>

```
variable "aws_access_key" {}
variable "aws_secret_key" {}
variable "region" {
  default = "ap-northeast-1"
}

terraform {
  backend "remote" {
    hostname     = "app.terraform.io"
    organization = "kuroseets"

    workspaces {
      name = "ec2-test"
    }
  }
}

provider "aws" {
  access_key = var.aws_access_key
  secret_key = var.aws_secret_key
  region     = var.region
}

data "aws_vpc" "test" {
  tags = {
    Name = "test"
  }
}

data "aws_subnet" "test_subnet" {
  vpc_id = data.aws_vpc.test.id

  tags = {
    Name = "test-a"
  }
}

resource "aws_instance" "test-ec2-1" {
  ami           = "ami-0053d11f74e9e7f52"
  instance_type = "t3.micro"
  subnet_id     = data.aws_subnet.test_subnet.id
  tags = {
    Name = "test-ec2-1"
  }
}
```
</div></details>
ルートディレクトリとec2ディレクトリのソースをローカルで`terraform init`しおけば、Terraform Cloud上では`vpc-test`と`ec2-test`2つのworkspaceが作成されていることでしょう。

## VCS設定
### Terraform CloudでAuthorization callback URLを取得する
Terraform Cloudにログインしてページ上部の`Settings`を選択し、左メニューの`VCS Providers`をクリックしてください
![スクリーンショット 2020-09-05 10.46.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/5aeccdd2-1c1e-7c1e-cfed-b09de8b01f86.png)

`Add a VCS provider`をクリックします
![スクリーンショット 2020-09-05 10.47.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/6604d67f-aa39-9081-83b6-8cbd99d8cf8c.png)

`GitHub`を選択し、表示されたドロップダウンメニューの`GitHub.com(Custom)`を選択します
![スクリーンショット 2020-09-05 10.48.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/e4ac67d5-6e0f-3d65-fa7e-b4de5ee3cff2.png)

表示された赤枠がGithubとの連携で必要になります
また、注意しなければいけないのは、このページを閉じると`Authorization callback URL`が変更されてしまうということです。
ですので、このページを開いたまま、別ブラウザで次はGithubを開いてください。
![スクリーンショット 2020-09-05 10.49.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/92df5e7d-00c2-9809-9a23-2bc390b146b2.png)

### Githubで
右上のアバターをクリックして表示されたメニューから`Settings`を選択します
![スクリーンショット 2020-09-05 10.51.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/c1430f7d-0da2-c49d-b47e-f058032cdaa4.png)

表示されたページの左メニューの`Developer settings`をクリックする
![スクリーンショット 2020-09-05 10.52.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/274366a6-2eaa-4020-e151-d92218fda132.png)

同様に表示された左メニューの`OAuth Apps`を選択します。
![スクリーンショット 2020-09-05 10.52.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/01525d4c-a4a4-a295-2238-ab7dbf7c9fdc.png)

表示されたページの`Register a new application`をクリックします。
![スクリーンショット 2020-09-05 10.53.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/90cbe797-729f-7a3d-7d9e-3b2ac9518b9d.png)

表示された入力フォームにTerraform Cloudで控えている情報を入力し、`Register application`をクリックします。
![スクリーンショット 2020-09-05 10.53.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/0cdbac3c-229b-4c43-099f-dfd5bb5a9979.png)

そして表示されたページの`Client ID`と`Client Secret`をTerraform Cloudで使用するために控えます。
このページも後ほど確認で使用しますので開いたままにしておきましょう。
![スクリーンショット 2020-09-05 10.55.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/d2381694-08b8-b9da-5f86-ae594c0ba747.png)

### TerraformでGithubの情報を入力し連携を完了させる
先ほど入手した`Client ID`と`Client Secret`を入力します。(`Name`は各自で判別しやすい名前を入力して大丈夫です)
![スクリーンショット 2020-09-05 10.59.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/3414e214-0afd-e526-20e9-6d27b5ed50dd.png)

連携を促すOAuth画面が表示された場合ですが、特にGithubの`Organization aceess`は注意してください。
今回は`Organization`へのアクセス権を付与しませんが、`Organization`へのアクセスを許可する場合は`Grant`ボタンをクリックして権限設定してください。
![スクリーンショット 2020-09-05 11.02.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/4fe2bfd1-ad05-196d-e606-d34077eda027.png)

SSH鍵の登録画面が表示されます。サブモジュールを使用する場合は必要になることがありますが、今回は単純な連携ですので設定は不要です。
`Skip and finish`をクリックして設定を完了させましょう。
![スクリーンショット 2020-09-05 11.06.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/257a1cb1-2b5d-2f6c-3817-03d433a53039.png)

`VCS Providers`の画面に戻りますが、新たにVCSが登録されていることが確認できていると思います。
![スクリーンショット 2020-09-05 11.06.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/e54ff8e9-55e1-5d27-b87d-7a901b3138c8.png)

### Githubでも確認
さて、Githubでの確認ですが、設定時に開いたままになっているページをリロードしてください。
`0 user`と表示されていた箇所が`1 user`に変更になっていることが確認できます。
![スクリーンショット 2020-09-05 11.07.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/4d3c019c-7742-0679-6859-3a606ea02ee7.png)

## Workspaceの設定
今回は以下のように連携しようと思います。

|Workspace|Repository|Dirctory|Auto Apply|Run Trigger|
|:---|:---|:---|:--:|:---|
|vpc-test|tfc-aws-test| |false| |
|ec2-test|tfc-aws-test|ec2|true|vpc-test|

ディレクトリやWorkspaceを分けているのは、EC2の追加削除は別stateで管理したいという目的があります。

### Workspaceにリポジトリを設定する
では、まず設定するWorkspaceを選択しましょう
![スクリーンショット 2020-09-05 11.09.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/50dfefe6-6cd9-a2b8-65d4-7ca504e06824.png)

表示されたページの右上にある`Settings`をクリックし表示されたメニューの`Version Control`をクリックします。
![スクリーンショット 2020-09-05 11.09.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/fe25bdc1-b1ff-ddad-ad04-fd7eca945b94.png)

表示されたページの`Connect to version control`をクリックします
![スクリーンショット 2020-09-05 11.09.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/fd1b8a87-0228-a85a-fc1a-1b7b6420fc38.png)

`Version control workflow`をクリックします
![スクリーンショット 2020-09-05 11.09.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/7ff3ea6b-34d4-017f-a122-fe4a14eb170e.png)

`GitHub`をクリックします
![スクリーンショット 2020-09-05 11.10.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/b0502bf3-87eb-c698-b8e5-015bace613cb.png)

`tfc-aws-test`リポジトリを選択します
![スクリーンショット 2020-09-05 11.10.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/8414b3df-2b6d-1b72-c4de-5fb9f0b5c854.png)

内容を確認の上`Update VCS settings`をクリックします
![スクリーンショット 2020-09-05 11.11.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/eaef9818-209b-f821-c1b8-a2ed057ef076.png)

戻ったページで`VCS branch`に変更を適用する際のブランチ名(今回はmaster)を入力し、`Update VCS settings`をクリックします
![スクリーンショット 2020-09-05 11.12.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/9f11e804-a242-d6bc-c2ac-5b0721e9bd26.png)

ここまでを`vpc-test`と`ec2-test`で設定してください。

### 自動ApplyとTerraformを実行するディレクトリ指定
`Settings`メニューの`General`を選択してください。
![スクリーンショット 2020-09-05 12.53.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/21251c83-a951-49f5-71e9-4c84c714f487.png)
表示されたページの`Apply Method`でApplyの実行をマニュアルにするか自動にするかを選択します。
今回は`vpc-test`では`Manual apply`、`ec2-test`では`Auto apply`を選択します。
また、Terraformを実行するディレクトリを指定するには`Terraform Working Directory`にディレクトリを入力します。
`ec2-test`ではec2ディレクトリのmain.tfを実行させたいので、`ec2`と入力します。
入力が完了したら `Save settings`をクリックします。
![スクリーンショット 2020-09-05 11.15.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/d860d196-7322-6cb7-a4f8-03a15c3cf90a.png)

### 他のWorkspace実行をトリガーにする
`Settings`メニューの`Run Triggers`を選択します。
![スクリーンショット 2020-09-05 12.54.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/eb5afc45-3cb0-38eb-3750-0849745ee7b3.png)
`Select item`よりWorkspaceを選択し、`Add workspace`をクリックします
今回は`ec2-test` Workspaceに`vpc-test` Workspaceを設定しました。
警告に読んだところ、このトリガーで実行されたQueueは自動されないのですね。
それには注意が必要です。
![スクリーンショット 2020-09-05 11.27.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/cea23c21-9285-a952-726c-5a0d606570f6.png)

## 確認
githabで変更をmasterにマージしてみましょう
vpc-testのplanでネットワーク周りのみ
![スクリーンショット 2020-09-05 11.21.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/6d54e099-2253-3702-0c13-ed00b8a158f8.png)
ec2-testのplanではec2周りのみが変更されていることが確認できました。
![スクリーンショット 2020-09-05 11.22.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/c55fbb7d-6bf5-e949-2969-914ced5833a2.png)
GithubでもPull Requestで`terraform plan`を実行した結果を表示してくれますので、マージする判断でも使えます
![スクリーンショット 2020-09-05 13.26.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372095/5981b7f9-2382-e1d9-d876-9bbcb40e779e.png)

## まとめ
今回はTerraform CloudとGithubの連携を確認しました。
各WorkspaceやGithub側にもいろいろと細かい設定や配慮が必要でしょうが、
これでインフラにおけるCI/CDが実現できるといっても間違いないでしょう。
今回はAWSの構築コードを使用しましたけど、次回は折角なので、
Terraform CloudでTerraform Cloudを管理する方法実施してみようと思います。


## 関連記事
[Terraform Cloud その1 - まずは使ってみた(ローカル実行からリモート実行に変更)](https://qiita.com/kuroseets/items/be8980a7c9764f28ed11)
[Terraform Cloud その2 - Gihubと連携してみた(VCSとWorking Directoryの設定)](https://qiita.com/kuroseets/items/9104c926b14cd52ffc03)
[Terraform Cloud その3 - Terraform CloudをTerraformで管理する](https://qiita.com/kuroseets/items/bdd160edef10f715c426)
[Terraform Cloud その4 - ワークスペース間で共有する閉じられた空間で使用するModuleについて](https://qiita.com/kuroseets/items/be51dabf7f2ecfb24055)