エンジニャーリング

技術ときどきネコ

terrafrom の backend の設定に 変数を渡してみた(失敗談)

複数人で触れるように terraform で backend を S3 に設定することがある
この時に develop とか staging とか、分けたくなっちゃうことがある
CodeBuild 上で実行するため workspace は使えない

そんな時は backend に出力する tfstate を分けたらなんとかなるはず!
ということで、早速やってみた。

terraform {
  required_version = ">= 0.12.6"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "3.31.0"
    }
  }

  backend "s3" {
    bucket         = "sample-tfstate"
    key            = "sample-${var.XXXX}/main.tfstate"
    region         = "ap-northeast-1"
    dynamodb_table = "terraform_state_lock_sample"
  }
}

このように、書いたとしても var.XXXX のパラメータを渡せなくて init 時にエラーになる。 こんな時は、どうすればいいかというと、init時に引数で渡せばいけるらしい。

こんな感じ

  • tfの設定
  backend "s3" {}
  • init を流す
terraform init \
    -backend-config="key=sample-dev/main.tfstate" \
    -backend-config="backet=sample-tfstate" \
    -backend-config="region=ap-northeast-1" \
    -backend-config="dynamodb_table=terraform_state_lock_sample"

公式にも書いてある
https://www.terraform.io/docs/language/settings/backends/configuration.html

うまくいく・・・はずだった。
devは問題なく立ったんだが、stgを立てるときにdevと混在したような形でcloud watchなどの一部の設定が入り混じる。例えば、XXXX-dev の名前のものが、XXXX-stg に変わってしまったり、同じ tfstate を参照していそうな、そんな感じの動きをしているように見える。

S3の出力先が間違ったのかなどチェックしてみるも、実行時間の通りに tfstate が出力されるし、この tfstate の中身も入り混じってはいない。

正しそうなだけに、謎は深まるばかり・・・

結局、解決には至らず、その部分を sed を使った置換を行うことで対処することにしました。
今回のように terraform を CI/CD っぽく流す時に、この辺の管理はどうするのがベストプラクティスってなんだろう?