Manage state files on Terraform Cloud

先日発表された Terraform Cloud の Remote State Management 機能、絶対いいやつなので試してみます。

Terraform Cloud とは

Terraform Cloud とは terraform のために作られた SaaS です。

以下のような機能が (今後公開予定の機能も含め) あります。

  • state ファイル管理ストレージ
  • terraform を複数人で運用するためのコラボレーション機能
  • terraform モジュールの共有基盤

展開としては小規模チーム向けの無料プラン、ビジネスプラン、エンタープライズプランと規模に応じた有償枠もできるそうです。

上記将来の機能や展開についての詳細は以下の記事にまとまっていました。

今回公開された機能は state ファイルのためのストレージ機能です。

これは terraform のバックエンドの一つとして利用できます。

バックエンドのおさらい

バックエンドとは terraform の状態管理を行う機構です。

terraform を実行すると作成された実際のリソースの情報 (IP アドレス、インスタンスの ID 等の生の情報) が状態 (state) として保管されます。

バックエンドはこの state の管理を抽象化し、柔軟に扱えるものです。これによりバックエンドはただ作成された実際のリソース情報を保管するにとどまらず、

  • state の更新にロックをかけることができる (誰かが apply 中に多重に apply してしまうことを防ぐ)
  • state というリソースの生情報 (機密情報) をディスクに持たないで済む (メモリ上に展開され利用される)
  • terraform 環境が無くても、遠隔で操作できる

といった機能も使えるようになります。

ただし、バックエンドによって使える機能が異なります。

バックエンドの種類

バックエンドは大きく以下の2つの種類に分けられます。

  • Standard: state の管理、ストレージとロックを提供 (バックエンドによって異なる)
  • Enhanced: Standard の機能に加え、リモート実行が可能 (現在 remote バックエンドと Terraform エンタープライズの組み合わせのみ可能)

Standard ではロックできるかどうかに差があります。例えば S3 バックエンドは Dynamo DB と組み合わせることでロック機能が使えるようになります。一方 artifactory バックエンドは対応していません。 azurerm バックエンドは標準でロックに対応しています。

どの Standard バックエンドがロックに対応しているのかは、個別のページに書いてあります。例えば S3 バックエンドでは以下のように書いてあります。

Kind: Standard (with locking via DynamoDB)

Stores the state as a given key in a given bucket on Amazon S3. This backend also supports state locking and consistency checking via Dynamo DB, which can be enabled by setting the dynamodb_table field to an existing DynamoDB table name.

Backend Type: s3 - Terraform by HashiCorp

今回発表された Terraform Cloud の Remote State Management について

今回発表された Remote State Management はバックエンドの一つであり Enhanced タイプに該当します。名前は remote バックエンドです (そのまんま)。

Enhanced タイプなので標準でロックに対応しています。 terraform 実行中に別の環境から実行しようとすると以下のように怒られます。

$ terraform apply
  Acquiring state lock. This may take a few moments...

Error: Error locking state: Error acquiring the state lock: workspace already locked (lock ID: "lorentzca/prod")

Terraform acquires a state lock to protect the state from being written
by multiple users at the same time. Please resolve the issue above and try
again. For most commands, you can disable locking with the "-lock=false"
flag, but this is not recommended.

設定方法

公式ブログに動画が公開されており、その通りに実行するだけで OK です。

以下の流れで設定できます。

  • Terraform Cloud アカウントを作成 (Atlas のアカウントを持っている人はそれでログインできます)
  • オーガニゼーションを作成
  • 右上のアイコンから User Settings -> Tokens からトークン作成
  • $HOME/.terraformrc ファイルを作成し以下のように作成したトークンを設定
credentials "app.terraform.io" {
  token = "<トークン>"
}
terraform {
  backend "remote" {
    hostname = "app.terraform.io"
    organization = "<作成したオーガニゼーション名>"

    workspaces {
      name = "<prod とか適当な名前>"
    }
  }
}
  • バックエンドを初期化 (実行前に念のためローカルの .terraform/terraform.tfstate をバックアップしておく)
    • $ terraform init

これで移行完了します。簡単。

こんな感じで state が管理されます。履歴が残るのが嬉しいですね。前回との差分も履歴毎に確認できます。

感想

公式の state 管理ストレージは多くの人が求めていた機能だと思うので嬉しいですね!

以前から公式の SaaS として Atlas があり、そこで state の管理が使えたんですが確か月額6000円くらいしてハードルが高かったので助かる。 🙏

以前フリートライアル中に使っていて、それが終了した時の記事がありました。

終了後は S3 バックエンドと Dynamo DB の組み合わせで使っていたのですが、そのためだけに環境変数に別途クレデンシャルを用意していたりしたので、今回のアップデートでよりシンプルにできて嬉しい。