【terraform】importコマンドでtfstateファイルを複数モジュールに分割する
「コンテナ時代のWebサービスの作り方」を読みながらTerraformを触ってみている。
その中で、Terraformを使う例としてVPCとEC2を作成する項目があった。本ではまず1つのtfファイルに両方のリソースをまとめて記述した後、ec2とvpcでモジュールを分けた書き方を紹介している。
- パターンA: 1つのtfファイルに両方のリソースを記述する例 (tfstateファイルはS3バケットの
test/
以下に格納)
test |- sample.tf #VPC, Subnet, EC2リソースを定義
# test terraform apply sample.tf ... Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
- パターンB: リソースの種類ごとにモジュールを分ける例(tfstateファイルはS3バケットの
test/vpc/
test/ec2/
以下にそれぞれ格納)
test |- vpc | |- vpc.tf #VPC, Subnetリソースを定義 |- ec2 |- ec2.tf #EC2リソースを定義
ここで疑問に思ったのが、パターンA -> パターンBのように、もし最初に1つのtfファイルをapplyしその後でモジュールを分けたくなった場合どうするのかということ。というのも、パターンAとBでは tfstate
の格納場所が異なっているため、Aのtfファイルをapplyした後にBで分けた2つのtfファイルをapplyしようとしても、既にAで作られたtfstateファイルを検知できず、リソースが二重にapplyされかねない。
# test/vpc terraform plan ... Plan: 2 to add, 0 to change, 0 to destroy.
このような場合、 terraform import
を使って既存リソースの情報を取り込んでおく必要がある。
import
コマンドは ADDRESS
と ID
の2つの引数を必須としている。 ADDRESS
はtfファイル内で定義した resource
のアドレスを指す。例えば test/vpc/vpc.tf
内で my_vpc
という名前でVPCリソースを定義していた場合、 aws_vpc.my_vpc
と指定すればよい。(すなわち、 import
コマンドで既存のリソースを取り込むには、そのリソースに対応するtfファイルをあらかじめ作成しておかなければならない)
ID
の方は、作成済みのリソースを一意に識別できるようにプロバイダ上で割り振られた値を指す。値の確認方法は各プロバイダによるが、AWSのVPCであれば VPC ID
を、EC2であれば Instance ID
を使う。これらはAWSのコンソールやaws cliを使って確認できる。
これらを使って terraform import
を実行する。デフォルトではコマンドを実行したディレクトリにあるtfファイルが参照される。
# test/vpc terraform import aws_vpc.my_vpc vpc-xxxxxxxxxxxxxxxxx aws_vpc.my_vpc: Importing from ID "vpc-xxxxxxxxxxxxxxxxx"... aws_vpc.my_vpc: Import prepared! Prepared aws_vpc for import aws_vpc.my_vpc: Refreshing state... [id=vpc-xxxxxxxxxxxxxxxxx] Import successful! The resources that were imported are shown above. These resources are now in your Terraform state and will henceforth be managed by Terraform. terraform import aws_subnet.my_subnet subnet-xxxxxxxxxxxxxxxxx aws_subnet.my_subnet: Importing from ID "subnet-xxxxxxxxxxxxxxxxx"... aws_subnet.my_subnet: Import prepared! Prepared aws_subnet for import aws_subnet.my_subnet: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxx] Import successful! The resources that were imported are shown above. These resources are now in your Terraform state and will henceforth be managed by Terraform.
import
コマンドを実行するたびに、tfファイルの backend
等で指定された保存場所にtfstateファイルが作成される。直後に terraform plan
を行うと、差分がなくなっている。
# test/vpc
terraform plan
...
No changes. Infrastructure is up-to-date.
後はEC2の方も同様に行えば、余計な差分を生まずにtfstateファイルを移行できる。
import
コマンドは、現時点(terraform v0.12.28 + provider.aws v2.68.0)ではあくまでtfstateファイルを変更するのみで、tfファイルの自動生成はしてくれない。これを補ってくれるOSSツールもあるようだが、 公式ドキュメントには A future version of Terraform will also generate configuration.
と書いてあるので少しだけ期待している。