terrafomerでの既存のリソースの取り込み手順


最近AWSのリソースをterraformerで取り込むことが多く、その中でいくつかハマりどころがあったので手順をまとめる。

1. terraformerで取り込み

必要なリソースをterraformerで取り込む。

$ terraformer import aws --resources=hoge --profile=fuga --path-pattern ./

2. state mvでresource名を管理しやすい名前に変更

terraformerが生成するresoure名は、既存のリソースのIDから生成したりしてわかりにくかったりするので、state mvで変更する。
全resourceにたいして行う(つらい)

$ terraform state mv aws_s3_bucket.tfer--abcdefghijklmn aws_s3_bucket.fuga

3. 必要に応じてmodule化

既存のresoureをmoduleにして管理しやすくする。
もしくは既にmoduleがあれば、それを利用してresourceを書き直すのでも良い。

4. providerをreplaceする

自分は、手順3でにmoduleに書き直した直後にplanを実行すると、下記のようなエラーが出た。

$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


Error: Provider configuration not present

To work with aws_s3_bucket.hoge its original provider
configuration at provider["registry.terraform.io/-/aws"] is required, but it
has been removed. This occurs when a provider configuration is removed while
objects created by that provider still exist in the state. Re-add the provider
configuration to destroy aws_s3_bucket.hoge, after which you
can remove the provider configuration again.

どうもterraformerがimportする際に、providerとして昔の形式 registry.terraform.io/-/aws で取り込んでしまうっぽい?
なので、terraform v0.13以降で使用される新しいproviderの形式 registry.terraform.io/hashicorp/aws に変更する必要がある。

$ terraform state replace-provider 'registry.terraform.io/-/aws' 'registry.terraform.io/hashicorp/aws'

5. state mvでresourceからmoduleに変更

ただresourceからmoduleに書き換えただけだとterraformは差分を検知できず、destroy & addしようとするので、state mvでresourceとmoduleを紐つけてやる。

$ terraform state mv aws_acm_certificate.hoge module.acm_hoge.aws_acm_certificate.acm

6. terraform planで差分が出ないことを確認

$ terraform plan
...
...
Plan: 0 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

7. backendをs3等に変更

terraformerはデフォルトだとbackendをlocalにしてしまうので、s3等に変更して誰でもいじれるようにする。

backend.tf
terraform {
  backend "s3" {
    bucket                  = "hoge-backend"
    key                     = "tfstate.json"
    region                  = "ap-northeast-1"
  }
}
$ terraform init --reconfigure 

余談

最初、手順4のエラーがわからず悩まされた。
最終的に下記のstackoverflowを参考にして解決。
https://stackoverflow.com/questions/63590836/switch-terraform-0-12-6-to-0-13-0-gives-me-providerregistry-terraform-io-nul

あとterraformerで取り込むと、毎回resourceをmvしなきゃいけないのはつらい。
prefixを事前に与えるとかしていい感じの名前をつけてほしいんだけど、厳密には難しいんだろうなーって思ったり。
terraformerでの取り込みは腕力が必要ですね。はい。