Terraformで、同じ構成を複数プロビジョニングしたい: backend-configオプション編

2022.08.31

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

先日 HashiTalks Japanで「シングルテナント構成のSaaSのIaCにTerraform Workspacesを導入してみた」というビデオ登壇をしました。その中で時間の都合でご紹介できなかった、「Workspacesを使う以外の、同じ構成(リソースセット)を複数個プロビジョニングする方法案」を、複数回に分けてご紹介していきます。

関連エントリ

詳細

terraform.backendブロックの必須attributeを未設定にします。

terraform {
  required_version = "= 1.2.7"

  backend "s3" {
  #   bucket = "hogehoge-terraform"
  #   key    = "dev.tfstate"
  #   region = "us-east-1"
  }

  required_providers {
    aws = {
      version = "~> 4.26.0"
    }
  }
}

そして terraform init時にbackend-configオプションを使って、未設定の分のbackendの設定を指定します。

% terraform init \
 -backend-config="bucket=hogehoge-terraform"\
 -backend-config="key=dev.tfstate"\
 -backend-config="region=us-east-1"

ファイルにまとめてそのパスを指定することも可能です。

config.s3.tfbackend

bucket = "hogehoge-terraform"
key    = "dev.tfstate"
region = "us-east-1"
% terraform init -backend-config="./config.s3.tfbackend"

backend-configオプションに指定する値を切り替えることで、複数の展開先にプロビジョニングすることができます。

一部のattributeはterraform.backendブロックに書いて、書いていないものだけbackend-configオプションで設定することもできます。

keyだけオプションで設定する例

terraform {
  required_version = "= 1.2.7"

  backend "s3" {
    bucket = "hogehoge-terraform"
  #   key    = "dev.tfstate"
    region = "us-east-1"
  }

  required_providers {
    aws = {
      version = "~> 4.26.0"
    }
  }
}

また、一度backendの設定をした後に変更する場合は-reconfigureも指定する必要があります。

% terraform init\
 -backend-config="./config.s3.tfbackend"\
 -reconfigure

もしくはルートモジュールディレクトリの.terraformディレクトリを削除します。 (CI環境のような毎回捨てる環境なら不要です)

この構成の良い点

展開先の情報がコードに出ない、Gitに残らない

Module案などと異なり展開先の情報がコードに現れないので、その情報を隠蔽化したい際には適しています。例えばシングルテナント構成のSaaSを作る際などには向いているでしょう。

backendの設定が自在

Terraform Workspacesに対する優位点です。

Workspacesを使う場合、Stateファイルの格納場所は固定です。S3をbackendに使う場合、Stateファイルはすべて同じバケット内のenv:/(workspace名)/(key名)に格納されます。

例えばWorkspace案でクロスアカウントでプロビジョニングする場合、Stateファイル格納先は1アカウントに集中することになります。展開先のアカウントに別々に格納することはできません。 workspaces-cross-account

対してこの構成だともっと自由にStateファイル格納場所を選ぶことができます。オブジェクトパスはもちろん、バケットを別々にすることも、違うリージョンにすることも、別アカウントにすることもできますね。

この構成のイマイチな点

Terraform単体で使えない

この構成はBackendの設定をTerraformの外に出すことになります。ですので外出し先との連携無しでリソースの管理をすることができません。関係者に使用方法の共有を徹底する必要があるかと思います。

展開先ごとの差分の実現方法が限られる

展開先の情報が全くコードに出てこないので、もし展開先毎にプロビジョニングしたいリソースが異なるような要件があった場合、それを実現する方法は変数ファイル(.tfvars)の値を変えるくらいしかありません。backend-configの設定と併せて、取り違いが起きないように慎重に管理する必要があります。

ユースケース

シングルテナント構成のSaaSのような、展開先毎のプロビジョニング内容にほぼほぼ差分がない、かつ展開先が多い場合に向いていると思います。