TL;DR
terraform管理下にないインフラをterraformingしようとする場合、
いわゆるStagingなどと呼ばれる環境で本番稼働環境を再現してから、本番環境に適用したいと思うわけです。
VPCやSubnetのような、壊すと大変なnot immutableなりソースはterraform importを駆使して、現行環境を壊さないよう、そーーーっとterraform管理下に引き込みます。(いずれQiita書く)
そしていざimmutableなりソースを--targetオプションを使いながら、ひとつひとつ本番環境に適用する際に遭遇しがちな下記エラー
$ terraform plan -out=apply.plan --target=module.compute.hoge.fuga
..(snip)..
Error: Error running plan: 1 error(s) occurred:
* module.compute.var.vpc-xxx-yyy: Resource 'data.terraform_remote_state.not_immutable' does not have attribute 'vpc-xxx-yyy' for variable 'data.terraform_remote_state.not_immutable.vpc-xxx-yyy'
を(強引に)解決するお話。
issueもあがっております。
https://github.com/hashicorp/terraform/issues/12316
環境
$ terraform version
Terraform v0.10.8
ディレクトリ構成
Terraform Best Practices in 2017
immutableなリソースから、VPCなどのnot immutableなリソースのremote stateを参照しています。
data "terraform_remote_state" "not_immutable" {
backend = "s3"
config {
bucket = "bucket_name"
key = "env:/${terraform.env}/tfstate/not_immutable/terraform.tfstate"
region = "ap-northeast-1"
}
}
対処方法
必要なresource定義を、手で書く or Stagingなどのterraform化検証環境のtfstateからコピペして、リソースIDを本番環境のものに書き換える
まずは最新のtfstateをremoteからpull。
$ terraform state pull > ./terraform.tfstate.d/$(terraform workspace show)/terraform.tfstate
./terraform.tfstate.d/$(terraform workspace show)/terraform.tfstate
に必要なリソースを追記。
"resources": {
"data.terraform_remote_state.not_immutable": {
"type": "terraform_remote_state",
"depends_on": [],
"primary": {
"id": "2017-11-15 02:25:07.174946468 +0000 UTC",
"attributes": {
"backend": "s3",
..(snip)..
"config.%": "3",
"config.bucket": "bucket_name",
"config.key": "env:/prod/tfstate/not_immutable/terraform.tfstate",
"config.region": "ap-northeast-1",
"environment": "default",
"id": "2017-11-15 02:25:07.174946468 +0000 UTC",
"vpc-xxx-yyy.%": "5",
### 今回はここから
"vpc-xxx-yyy.subnet-private-a": "subnet-pra",
"vpc-xxx-yyy.subnet-private-c": "subnet-prc",
"vpc-xxx-yyy.subnet-public-a": "subnet-pua",
"vpc-xxx-yyy.subnet-public-c": "subnet-puc",
"vpc-xxx-yyy.vpc_id": "vpc-xxx-yyy-id"
### ここまでのresource idを本番環境のものに書き換えました。
},
"meta": {},
"tainted": false
},
"deposed": [],
"provider": ""
}
},
tfstateをremoteへpush。
$ terraform state push ./terraform.tfstate.d/$(terraform workspace show)/terraform.tfstate
そして再度terraform plan。
$ terraform plan -out=apply.plan --target=module.compute.hoge.fuga
..(snip)..
Plan: X to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
This plan was saved to: apply.plan
To perform exactly these actions, run the following command to apply:
terraform apply "apply.plan"
エラーは消えました。
めでたしめでたし。