Cloud その3 - Terraform CloudをTerraformで管理する


おさらい

前回までで、GitHub経由でTerraform CloudのWorkspaceを実行するところまでを手動で設定しました。
ただ、折角Terraformを使っているのにTerraform Cloud自身が手動設定なのはなんだか残念です。
折角なので、Terraform CloudもTerraform管理にしてしまいましょう。

この記事で実現すること

  • Terraform Enterprise Providerの実行
  • Terraform Cloudのコード管理
  • Terraform CloudのSlack通知

この記事がターゲットとする読者層

読者層

  • Terraform Cloudに興味がある人
  • Terraform Cloudの運用に課題を抱えている人
  • いろいろなTerraform Providerに興味がある人

必要スキル

  • 多少のTerraformのコーディング知識

そもそもTerraformは

Qiitaの記事数やコミュニティでの質問から推測して、Terraformを使う場面はパブリッククラウドのインフラのプロビジョニングで使用されることが多いと思います。
実際、公式ページ(Providers - Terraform by HashiCorp)を見ても、パブリッククラウド以外にもHWやIdP, Databaseなどのプロバイダも用意されていることがわかると思います。これらは日夜、世界中の有志たちがこちらで開発していますので、興味のある方は覗いてみるのも面白いと思います。
この他にもさくらクラウド用のプロバイダterraform-provider-sakuracloudなど野良のプロバイダもたくさん開発されています。

今回は公式プロバイダの内の1つ、Terraform Enterprise Providerを使用してTerraform Cloudを管理してみようと思います。

準備

これまでに作成したものとは別に以下のものが必要になります
* Terraform CloudのOrganization操作権限のあるトークン(Organizationトークン、もしくはownersチームに所属するユーザのトークン)
* SlackのWebhook URL

あと、ローカルでも実行できる環境があると便利ですので、過去の記事を参考に設定してください。

構築

terraform initとWorkspaceの作成

まずはプロバイダとバックエンドの設定をコードに記述してterraform initしてWorkspaceを作成します

./main.tf

```
variable tfc_hostname {
type = string
default = "app.terraform.io"
}

variable tfc_token {
type = string
}

terraform {
backend "remote" {
hostname = "app.terraform.io" # Terraform Cloudのホスト名
organization = "kuroseets" # 使用するOrganization

workspaces {
  name = "tfc-test"                # 使用するWorkspace
}

}
}

Terraform Enterprise Provider

provider "tfe" {
hostname = var.hostname
token = var.token
}
```

terraform initを実行すると以下のようにワークスペースが作成されていると思います。

Terraform CloudのWorkspaceの設定

作成されたWorkspaceに、VCSリポジトリと使用するVariableを設定をします
細かい設定は過去の記事
を参考にしていただければと思います。

OrganizationをimportしてTerraform管理に取り込む

まずはOrganizationをimportする準備です。

./organizations.tf

```

管理するOrganization

resource "tfe_organization" "kuroseets" {

}
```

$ terraform import tfe_organization.kuroseets kuroseets

tfe_organization.kuroseets: Importing from ID "kuroseets"...
tfe_organization.kuroseets: Import prepared!
  Prepared tfe_organization for import
tfe_organization.kuroseets: Refreshing state... [id=kuroseets]

Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.

注意

以下のエラーが出る場合はtfeプロバイダでtokenを送るのを一時的に無効にしてみてください
Error: Invalid provider configuration

importが完了したら、stateファイルを参考にしてresource "tfe_organization" 〜を完成させましょう

テスト用Workspace作成

一旦テストでワークスペースを作成してみましょう

./workspaces.tf
resource "tfe_workspace" "test" {
  name         = "test-workspace"
  organization = tfe_organization.kuroseets.name
}


terraform planして問題なければGitHubにCommitしちゃいましょう
そのままTerraform CloudでApplyすれば以下のように新しいWorkspaceが作成されたことが確認できます。

改めてローカルでterraform planを実行したらコードと差分がないことも確認できます。

WorkspaceからSlackへ通知

折角なので、Terraform CloudのワークスペースにアクションがあったときにSlackに通知する設定を追加しましょう

./notifications.tf
variable slack_hook_url {
  type = string
}

data "tfe_workspace" "tfc-test" {
  name = "tfc-test"
  organization = tfe_organization.kuroseets.name
}

resource "tfe_notification_configuration" "test_slack" {
  name             = "test-slack"
  enabled          = true
  destination_type = "slack"
  url              = var.slack_hook_url
  workspace_id     = data.tfe_workspace.tfc-test.id
  triggers = [
    "run:created",
    "run:planning",
    "run:needs_attention",
    "run:applying",
    "run:completed",
    "run:errored"
  ]
}

tfc-testワークスペースのVariablesslack_hook_url変数を作成し、SlackのWebhook URLを指定してください。

そしてApplyしましょう

Applyが完了したら、このようにSlackにTerraform CloudのWorkspaceに処理が入るたびに通知されるようになります。

Terraform Enterprise Providerで管理できるリソース

執筆時での公式サイトによると現在作成できるリソースは以下のようです。

  • Organization
  • チーム
    • 所属メンバー
  • メンバー
  • Workspaces
    • チームのアクセス権
    • 変数
    • 通知
    • 実行トリガー
  • VCS
    • SSH鍵
  • トークン
  • 共通モジュール

フリー版では使うことができないですが、SentinelをWorkspaceに割り当てる機能も実装されているようです。

  • ポリシーセット
    • 変数

まとめ

業務で使う際に、Terraform CloudはSaasで分離なのですが、GUIなのでバージョン管理をどうしようかと悩んでました。
そこで思いついたのがコードでの管理でした。
これでバージョン管理システムと合わせることで版管理ができるようになり、まずは一つの目標が果たせました。
この他Terraform Cloudの権限構成が大雑把なところがあるので、それも線引きをはっきりさせるのにもコード管理は有効に働いています。これについてはまた別にお話しする機会があれば、整理したいな〜と思っています。
さて次回ですが、これまでの記事で公式のプロバイダはTerraform Cloudで使えることはわかりましたが、野良プロバイダをどのようにしてCloudにて使用するのかを中心に記事を書きたいと思います。
※またそれとは別にHashiCorp SentinelPolicy as Codeについての導入用記事も執筆しようと思います。

関連記事

Terraform Cloud その1 - まずは使ってみた(ローカル実行からリモート実行に変更)
Terraform Cloud その2 - Gihubと連携してみた(VCSとWorking Directoryの設定)
Terraform Cloud その3 - Terraform CloudをTerraformで管理する
Terraform Cloud その4 - ワークスペース間で共有する閉じられた空間で使用するModuleについて