Terraform 入門者向け知識まとめ

# Terraform 概要
* Terraform は Hashicorp 社が開発した Infrastructure as Code (IaC) を実現するためのツール。
* HCL (Hashicorp Configuration Language) と呼ばれる設定言語を用いて設定ファイルを記述することで、その設定に基づいたインフラを構築することができる。
* Terraform の対応範疇はインフラの構成にとどまらず、PaaS や SaaS の設定などもコード化することができる。
* クラウド サービスであれば独自の IaC を実現するためのサービスは用意されているが（GCP であれば Cloud Deployment Manager のように）、Terraform は各インフラサービスに統一した記法を使用できるというメリットがある。

## HCL 概要
JSON 互換の Hashicorp 社開発独自設定言語。

例）

```hcl
resource "google_storage_bucket" "input_data_sources" {
  name          = "input-data-sources"
  location      = "asia-northeast1"
  storage_class = "REGIONAL"
  force_destroy = true

  versioning {
    enabled = false
  }
}
```

そんなに難しいものではなく、雰囲気を覚えれば書ける。
詳細は [GitHub - hashicorp/hcl: HCL is the HashiCorp configuration language.](https://github.com/hashicorp/hcl)

## Terraform 大体の流れ
1. HCL で設定ファイルを書く。
2. `terraform plan` でどのような変更が実際に実施されるかを確認する。
3. `terraform apply` で実際に変更を適用する。

## Terraform を用いてインフラを構成することのメリット

インフラ構成をコード化することによって以下のようなメリットを享受できる。

* コード化された設定ファイルによって GUI を使用することなく、機械的に実行することができる。
* ソフトウェア開発と同じようにバージョン管理およびコラボレーションが行える。
* コードの再利用が可能となる。

これによって例えば以下のような所謂 GitOps 的なフローの実現も可能となる。

* インフラ構成の変更にあたっては GUI を用いた直接の変更は不可とし、設定ファイルを変更して Terraform を実行することを義務付ける。
* 変更した設定ファイルは GitHub 上で PR として提出して有識者からのレビュー受けるものとし、同時にフォーマットチェックやバリデーションを満たすものとする。
* master ブランチにマージされた設定ファイルは自動的に本番環境に適用される。
* この PR を "誰がどのような変更をいつ施したか" という監査証跡として残す。

## 学習リソース
* [Terraform Curriculum - HashiCorp Learn](https://learn.hashicorp.com/terraform)
	* 公式サイトのチュートリアル。初学者にわかりやすく、Step by Step で学習を進めていける。概要を掴むにはちょうど良い。
* [Documentation - Terraform by HashiCorp](https://www.terraform.io/docs/index.html)
	* 公式サイトのドキュメントは割と充実している。

# Terraform 抑えておきたい概念

## Providers
Terraform はメジャーなクラウドベンダーや OpenStack など各種のインフラに対応している。これは Provider と呼ばれる pluggable なアダプターによって実現される。

Provider の一覧は [Providers - Terraform by HashiCorp](https://www.terraform.io/docs/providers/index.html) にあり。

## State & Backends
Terraform は認識している現在のインフラの構成をファイルとして記録する。これを State と呼ぶ。構成ファイルの内容を変更した場合、Terraform はその内容と State とを比較し、実際にインフラに対して行う必要のある変更を判断する。

State はデフォルトではローカルに出力されるが、この場合複数人による同時作業が実施できないため非推奨。State の置き場は Backend と呼ばれ、Hashicorp 社が用意している Terraform Cloud というクラウドサービス上や、GCP Cloud Storage などを指定することができる。これによって State を全員共通のリソースとして扱うことができるので、複数人での同時作業が可能となる。

## Workspace
* 1 つの設定で複数の State を管理することができる Terraform に備わっている仕組み。
* 開発環境と本番環境など環境を分けて同一の構成で構築するときなどに使えるが、小回りは効かないので実際には Workspace を使わずに実現されることも多い。
 
# Terraform Cloud
* Hashicorp 社が Terraform 用に用意しているクラウドサービス。
    * 2019/09 に完全リリースされた。[Announcing Terraform Cloud](https://www.hashicorp.com/blog/announcing-terraform-cloud/)

## Terraform Cloud を使う利点
State は GCS などのパブリックストレージにさえ保管すれば、複数人での同時開発という目的は果たすことができるが、Terraform Cloud を使うことにはそれ以上に以下のメリットがある。

* GitHub などのメジャーなバージョン管理システムサービスと連携している。
* Provider に渡す認証情報などをセキュアに保管することができる。
* プライベートな Terraform モジュールを保管することができる。
* Terraform 実行のアクセス権限管理が行える

## 実行モード
* Terraform Cloud には Terraform の State の保管場所という側面に加えて Terraform を実行する環境としての実行基盤という側面がある。
* 通常、Terraform CLI をローカルで実行した場合には Terraform はローカル上で実行されるが、Backend を Terraform Cloud に設定している場合には Terraform Cloud 上で実行される。
* Terraform Cloud の画面上からも Terraform を実行することが可能。
* ただし、これらの挙動は標準の "Remote" モードの場合。実行モードを "Local" に変更した場合は、Terraform Cloud は State の保管場所としての機能のみを提供するようになる。

## GitHub 連携
Terraform Cloud は主要な VCS サービスとの連携に対応しており、GitHub もその対象の一つ。

GitHub 連携を行うと、PR 作成時に自動的に Terraform Cloud 上で `terraform plan` が Check として動作するようになる。この `plan` は PR がマージされるまでは `apply` することができず、マージすると GUI 上から `apply` することができるようになる。

### Terraform Cloud アクセスに使用する API トークン
Terraform Cloud にプログラムからアクセスする場合は API トークンの発行が必要。これは GUI 上から発行できる。発行した API トークンは、ホームディレクトリの CLI 設定ファイルに記述するのが良いらしい。

[credentials - CLI Configuration - Terraform by HashiCorp](https://www.terraform.io/docs/commands/cli-config.html#credentials)

## Workspace 使用時の注意点

* Terraform Cloud で Terraform の Workspace を使用する場合は Terraform Cloud 上の Workspace と 1 対 1 で対応させることになる。このため、backend では固定のワークスペース名を指定するのではなく、プレフィックスを指定する必要がある。

```hcl
terraform {
  backend "remote" {
    organization = "my-org"

    workspaces {
      # name = "my-app"
      prefix = "my-app-"
    }
  }
}
```

* Terraform を Terraform Cloud 上でリモート実行する場合は interpolation は使用できない（常に "default" が返される）。

# Terraform ハマりポイント

## terraform plan で成功したが、terraform apply で失敗する
`terraform plan` は HCL が正しく書けているかを確認しているに過ぎず、Provider の API を叩いているわけでは無い。`terraform apply` を実行することによって初めて Provider の API が叩かれることになるので、その時点になって記述内容に漏れや認識間違いがあったことが発覚する（例：リソース名は英数字しか使えないがハイフンを使っていた）。このため、`terraform apply` を何度か実行する試行錯誤が必要となる。

### terraform apply 時に内容不明のエラーが発生する
`terraform apply` は基本的には Provider の API を叩いているのでそこでエラーが発生した場合には、そのエラー内容をそのまま表示することになる。が、（少なくとも GCP の Provider を使っている限りにおいては）それがどの API を叩かれたことによって発生したのかは表示されない。これを知るには Terraform のログ出力内容を増やしてデバッグを行う必要がある。ログ出力の内容は`TF_LOG` 環境変数に `INFO` などを指定することで増やすことが可能。

[Debugging - Terraform by HashiCorp](https://www.terraform.io/docs/internals/debugging.html)

また、そもそも先方の Provider の API のエラー内容そもそもが不親切でよくわからない場合もある。これは致し方ない。

# HCL エディター

## VSCode
Hashicorp 社提供の公式プラグインは無し。サードパーティ製のプラグインでは [Terraform - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=mauve.terraform) が最も DL 数が多い。ただし、Terraform 0.12 の記法に非対応のため ([feat: Terraform 0.12 support (was hcl2 support) · Issue #157 · mauve/vscode-terraform](https://github.com/mauve/vscode-terraform/issues/157))、常に文法上の警告が表示されるという難点あり…。

## IntelliJ IDEA
Hashicorp 社公式のプラグインは無いが、JeBrains 社公式のプラグインあり。
[HashiCorp Terraform / HCL language support - Plugins | JetBrains](https://plugins.jetbrains.com/plugin/7808-hashicorp-terraform--hcl-language-support)

補完も効くためなかなか優秀。
ファイル保存時に `terraform fmt` を自動で行うには別途またプラグインの導入が必要。
参考）https://github.com/VladRassokhin/intellij-hcl/issues/71

# 周辺ツール
## Sentinel
Sentinel は Policy as Code を実現するための Hashicorp 社が開発したフレームワーク。
Terraform と統合させて動かすこともできるようなのだが、有料版の使用が必要となる。

## Terragrunt
[Terragrunt | Terraform wrapper](https://terragrunt.gruntwork.io/)
Terraform をさらに便利に使うためのサードパーティー製のラッパーのようだ。

# 参考リンク
* [Index - Terraform Recommended Practices - Terraform by HashiCorp](https://www.terraform.io/docs/cloud/guides/recommended-practices/index.html)
	* 手動管理されているインフラをどのように Terraform で管理するように変えていくかのプラクティスを説明した Hashicorp 社公式のドキュメント。
* [Welcome - Terraform Best Practices](https://www.terraform-best-practices.com/)
	* Terraform を使用する上でのベストプラクティス集。実績のある方が書いているようで参考になりそう。