※Terraform v1.7.0を使用しています。
importコマンド
terraform importコマンドは、指定した既存リソース及びその設定情報の定義をtfstateファイルに生成するコマンドです。
- 公式ドキュメント
① インポート対象リソースの作成
「manabe-test-instance」というNameタグを付けたEC2インスタンスを作成します。
② resourceブロックの作成
tfファイルに、インポート対象リソース用のresourceブロックを定義します。
この時点では、パラメータの定義は不要です。
例えば、「aws_instance」においては「ami」と「instance_type」が必須パラメータですが未定義で問題ありません。
resource "aws_instance" "sample1" {
}
③ importコマンドの実行
importコマンドの使用方法は以下の通りです。
terraform import [resourceブロックのtype].[resourceブロックのname] [リソースID]
実行します。
$ terraform import aws_instance.sample1 i-0da09fb0d4fe82991
~~ 省略 ~~
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コマンドが成功した後、tfstateファイルを見るとリソースの定義が生成されていることが確認できます。
④ tfファイルの修正
tfファイルのresourceブロックの中身は未定義のままなので、terraform planコマンドで差分を確認しつつ修正していきます。
resource "aws_instance" "sample1" {
// 追記
ami = "ami-0de5b371cbca0edcb"
instance_type = "t2.micro"
tags = {
Name = "manabe-test-instance"
}
}
差分がなくなりました。
$ terraform plan
~~ 省略 ~~
No changes. Your infrastructure matches the configuration.
importブロック
importブロックはTerraform v1.5.0 でリリースされた機能です。
importコマンドではリソースの定義はtfstateファイル上にしか生成されず、tfファイルは手書きで編集する必要がありましたが、importブロックを使用するとtfファイル上にもリソース定義を自動生成することが可能です。
また、importコマンドは1リソースずつ行う必要がありますが、importブロックは複数リソースをまとめて実行することができます。
importブロックの一般的な使用方法として、resourceブロックをimportブロックによって自動生成するパターンと、resourceブロックを事前に作成しておくパターンがあります。
resourceブロックをimportブロックによって自動生成するパターン
① インポート対象リソースの作成
先ほど同様、「manabe-test-instance」というNameタグを付けたEC2インスタンスを作成します。
※先の手順で作成したインスタンスは、terraform destroyコマンドを使用して削除済です。
② importブロックの作成
以下のように定義します。
import {
id = "i-052562f6eee9d60d9"
to = aws_instance.sample1
}
「id」及び「to」は必須パラメータです。
- 「id」:[リソースID]
- 「to」:[resourceブロックのtype].[resourceブロックのname]
③ tfファイルにリソース定義をインポート
以下のように、「-generate-config-out=[任意の名前].tf」というオプションを付けてterraform planコマンドを実行します。
※生成するファイルが存在する場合エラーとなるので、存在しないファイル名を指定しなければなりません。
$ terraform plan -generate-config-out=import.tf
aws_instance.sample1: Preparing import... [id=i-052562f6eee9d60d9]
aws_instance.sample1: Refreshing state... [id=i-052562f6eee9d60d9]
Planning failed. Terraform encountered an error while generating this plan.
╷
│ Warning: Config generation is experimental
│
│ Generating configuration during import is currently experimental, and the generated configuration format may change in future versions.
╵
╷
│ Error: Conflicting configuration arguments
│
│ with aws_instance.sample1,
│ on import.tf line 14:
│ (source code not available)
│
│ "ipv6_address_count": conflicts with ipv6_addresses
╵
╷
│ Error: Conflicting configuration arguments
│
│ with aws_instance.sample1,
│ on import.tf line 15:
│ (source code not available)
│
│ "ipv6_addresses": conflicts with ipv6_address_count
実行後、本オプションで指定したtfファイルが作成され、中にリソース定義が生成されます。
また、import.tfファイルが生成されるのと同時に、terraform planコマンドの実行結果としていくつかエラーが出力されています。
Terraformによって生成されたファイルには共存しないパラメータが存在する可能性があり、存在する場合このようにエラーが出力されます。
本手順の場合、自動生成されたresourceブロック内のパラメータ「ipv6_addresses」と「ipv6_address_count」が競合していました。
「ipv6_address_count」をコメントアウトし、オプションを付けずにterraform planコマンドを実行します。
$ terraform plan
~~ 省略 ~~
Plan: 1 to import, 0 to add, 0 to change, 0 to destroy.
エラーがなくなりました。
④ tfstateファイルにリソース定義をインポート
terraform applyコマンドを実行します。
$ terraform apply
aws_instance.sample1: Preparing import... [id=i-052562f6eee9d60d9]
aws_instance.sample1: Refreshing state... [id=i-052562f6eee9d60d9]
~~ 省略 ~~
Apply complete! Resources: 1 imported, 0 added, 0 changed, 0 destroyed.
実行後、tfstateファイルにリソース定義が自動生成されていることが確認できます。
ここまでの手順が完了したら、importブロックは削除して大丈夫です。
resourceブロックを事前に作成しておくパターン
importブロックの「to」に定義したresourceのアドレスがtfファイル上に既に存在する場合、terraformはtfファイルの自動生成を行わず、既存のresourceブロックと実際のリソースが紐づけられます。
事前にresourceブロックの定義が可能であればこちらのパターンが使用可能です。
① インポート対象リソースの作成
先ほど同様、「manabe-test-instance」というNameタグを付けたEC2インスタンスを作成します。
※先の手順で作成したインスタンスは、terraform destroyコマンドを使用して削除済です。
② importブロック、resourceブロックの作成
以下のようにimportブロック、resourceブロックを定義します。
import {
id = "i-073eddd24e734b1ff"
to = aws_instance.sample1
}
resource "aws_instance" "sample1" {
ami = "ami-0de5b371cbca0edcb"
instance_type = "t2.micro"
tags = {
Name = "manabe-test-instance"
}
}
③ インポートの実行
terraform applyコマンドを実行します。
$ terraform apply
aws_instance.sample1: Preparing import... [id=i-073eddd24e734b1ff]
aws_instance.sample1: Refreshing state... [id=i-073eddd24e734b1ff]
~~ 省略 ~~
Apply complete! Resources: 1 imported, 0 added, 1 changed, 0 destroyed.
実行後、tfstateファイルにリソース定義が生成されていることが確認できます。
ここまでの手順が完了したら、importブロックは削除して大丈夫です。
以上で本手順は終了です。
最後に
importブロックはtfファイルの生成も可能なので非常に便利ですが、本番環境等においてterraform applyコマンドを使用するのは少し怖い気もします。
使用する場合は既存リソースの再生成等が行われないように注意しないといけません。
また、今回はTerraformの標準機能を使用したインポート方法をご紹介しましたが、「Terraformer」や「terracognita」といったツールを使用したインポート方法も存在するようなので、今度そちらも試してみようと思います。