Terraform の Workspaces 機能は便利ですよね。同一プロジェクトから複数環境(development, qa, staging, prodcution, ...)を切り替えて管理できるので重宝しています。
ワークスペースを変更すると tfstate も別に保存しなければならないため、それぞれ保存される場所が変わるように設定しなければなりません。僕は s3 backend を使っているので、以下のように設定しました。
terraform {
backend "s3" {
region = "ap-northeast-1"
bucket = "my-tfstate"
key = "network/terraform.tfstate"
workspace_key_prefix = "env:"
dynamodb_table = "terraform_backend"
}
}
workspace_key_prefix
がミソで、これにより以下のようにワークスペースごとに異なる key が使われます。
workspace | key |
---|---|
default |
s3://my-tfstate/network/terraform.tfstate |
staging |
s3://my-tfstate/env:/staging/network/terraform.tfstate |
qa |
s3://my-tfstate/env:/qa/network/terraform.tfstate |
default 以外のワークスペースを選択すると workspace_key_prefix
が key の先頭に追加され、env:
の次にワークスペース名が入ることが分かるかと思います。
ちなみに workspace_key_prefix
のデフォルト値は env:
なので、わざわざ書く必要はありません。
terraform {
backend "s3" {
region = "ap-northeast-1"
bucket = "my-tfstate"
key = "network/terraform.tfstate"
dynamodb_table = "terraform_backend"
}
}
これ自体は嬉しい機能なんですが、この tfstate を terraform_remote_state で異なるプロジェクトから参照しようとしたときに超ハマりました。
まず、普通に書くとこうなるかと思います。
data "terraform_remote_state" "network" {
backend = "s3"
config {
region = "ap-northeast-1"
bucket = "my-tfstate"
key = "network/terraform.tfstate"
}
}
backend の設定と同じように、現在のワークスペースによって補完されることを期待しています。
しかし、このリソースの属性を参照しようとすると、属性が見つからないというエラーになるんですね。
* output.aws_aaa: Resource 'data.terraform_remote_state.network' does not have attribute 'vpc_id' for variable 'data.ter
raform_remote_state.network.vpc_id'
どうやら terarform_remote_state
では現在のワークスペースに応じて key を生成してくれるなんてことはなく、backend 設定で補完された key を明示的に書かないといけないようです。
data "terraform_remote_state" "network" {
backend = "s3"
config {
region = "ap-northeast-1"
bucket = "my-tfstate"
key = "env:/${terraform.workspace}/network/terraform.tfstate"
}
}
まぁ異なるワークスペースの tfstate を参照したいケースもありますし、妥当な仕様だと思います。
が、すっかり backend と同じように自動で key が補完されるものと思い込んでおり、ずいぶん見当違いなところを調べ回っていました。
同じ問題にハマっている人の助けになれば幸いです。