Terraform 1.5以降では、import
ブロックを使用して構成内でリソースのインポートを管理することができます。この機能により、既存のインフラストラクチャをTerraformの状態にインポートするプロセスが簡素化され、別個のCLI terraform import
コマンドが不要になります。
この記事では、インポートブロックの説明と異なるリソースをインポートする方法を説明します。
テラフォームのインポートブロックとは何ですか?
テラフォームv1.5.0で導入されたimport
ブロックは、既存のインフラストラクチャリソースをTerraform状態ファイルにインポートするための宣言的アプローチを提供します。これにより、リソースのインポートが直接の状態操作として扱われるのではなく、Terraformの計画プロセスの不可欠な部分になります。
その結果、import
ブロックは透明性を向上させ、リソースのインポートをインフラストラクチャのコア原則であるインフラストラクチャコード(IaC)と整合させ、ユーザーがインフラストラクチャを効果的かつ予測可能に管理できるようにします。
Terraformでのimport
ブロックの構文は次の通りです:
import {
to = <resource_address>
id = <resource_identifier>
}
to
:インポートされたリソースがマップされる構成内のリソースアドレスを指定します。id
:提供元のAPIにおける既存リソースの一意の識別子を定義します。 Terraform プロバイダ がリソースにアクセスできるよう正しく構成されていることを確認してください。
一部のリソースタイプでは、インポートに追加の要件や制約がある場合があります。
Import ブロック vs. Terraform インポートコマンド
import
ブロックを使用すると、Terraform で既存インフラストラクチャを設定ファイル内で直接定義できるため、管理が簡素化されます。
一方、terraform import
コマンドを import
ブロックなしで使用すると、既存のリソースを Terraform ステートにリンクしますが、自動的に対応する構成をコードに生成しません。この構成は手動で後から追加する必要があります。インポートコマンドは、単発のインポートやインフラストラクチャを Terraform 管理に移行する際に特に便利です。
両方の方法は、Terraform ステートと実際のインフラストラクチャの整合性を確保するために注意深く取り扱う必要があります。 Import
ブロックは一般的に継続的なリソース管理に適しており、スタンドアロンのコマンドはたまに必要なインポートに適しています。
例1: Terraform Importブロックを使用してS3バケットをインポートする
既存のAWS S3バケット(my-existing-bucket
)をTerraformで管理したいとします。
resource
ブロックはS3バケット(aws_s3_bucket.example
)を指定し、bucket
属性は既存のバケットの名前を定義します。
resource "aws_s3_bucket" "example" {
bucket = "my-existing-bucket"
}
import {
to = aws_s3_bucket.example
id = "my-existing-bucket"
}
import
ブロックは既存のS3バケットをTerraformリソースにリンクします。
to
: インポートされたリソースをresource
ブロックのアドレス(aws_s3_bucket.example
)にマッピングします。id
: バケットのユニークIDを指定します(my-existing-bucket
)。
terraform plan
を実行すると、Terraformはimport
ブロックを読み取り、既存のS3バケットの状態をチェックし、状態ファイルへの変更のプレビューを表示します。その後、terraform apply
を実行すると、Terraformは状態ファイルを更新して既存のバケットを含め、それをaws_s3_bucket.example
リソースにマッピングします。
terraform apply
を実行し、リソースを正常にインポートした後、import
ブロックを削除するのがベストプラクティスです。それを保持していても問題はありませんが、削除することでクリーンな構成を維持し、将来の状態管理中に混乱が生じる可能性を最小限に抑えることができます。
例2:TerraformのImportブロックを使用してEC2インスタンスをインポートする
別の例を考えてみましょう。IDがi-1234567890abcdef0
である既存のEC2インスタンスをTerraformの管理下に置きたいとします。
既存のインスタンスの構成に一致するように、Terraformに管理してもらいたいaws_instance
リソースをresource
ブロックで定義します:
resource "aws_instance" "example" {
ami = "ami-0abcdef1234567890" # Replace with the actual AMI ID
instance_type = "t2.micro"
}
import {
to = aws_instance.example
id = "i-1234567890abcdef0"
}
import
ブロックでは:
to
:構成内のリソース(aws_instance.example
)を既存のリソースにマッピングします。id
:インポートしているEC2インスタンスの固有IDを指定します。
リソースブロックとインポート文をTerraformの構成ファイルに追加したら、terraform plan
を実行して変更をプレビューします。次に、リソースをTerraformの状態ファイルにインポートするためにterraform apply
を実行します。
インポート後、Terraformは既存のEC2インスタンスを管理し、その構成が宣言的であることを確認します。
例3:TerraformのImportブロックを使用してAzureのリソースグループをインポートする
次の例では、Azureのリソースグループをインポートします。
既存のAzureのリソースグループexample-resource-group
がEast US
リージョンにあり、Terraformで管理したいとします。
まず、resource
ブロックで、Terraformが管理するazurerm_resource_group
リソースを定義します:
resource "azurerm_resource_group" "example" {
name = "example-resource-group"
location = "East US"
}
import {
to = azurerm_resource_group.example
id = "/subscriptions/<subscription_id>/resourceGroups/example-resource-group"
}
インポートブロック:
to
:構成内のリソース(azurerm_resource_group.example
)を既存のAzureリソースにマップします。id
:リソースグループの完全修飾AzureリソースIDを指定します。<subscription_id>
はお使いの実際のサブスクリプションIDに置き換えてください。
リソースとインポートブロックをTerraformの構成ファイルに追加します。次に、terraform plan
コマンドを実行して変更をプレビューし、terraform apply
を実行して変更を適用し、リソースをTerraformの状態ファイルにインポートします。
TerraformのImportブロックを条件付きで使用できますか?
Terraformのimportブロックは宣言的であり、プラン時に特定の値が必要です。そのため、Terraformコード内で条件付きで使用することはできません。
importブロックは、条件に基づいてインポートIDを決定するための動的式や変数をサポートしていません。インポートブロック内でcountや変数などの構造を使用しようとすると、Terraformはそのような引数を許可していないためエラーが発生します。
主なポイント
Terraform 1.5以降でのimportブロックの導入により、構成ファイル内でのリソース管理が簡素化され、既存のインフラストラクチャをTerraform構成に直接インポートおよび定義することが可能となりました。これは、複雑さを削減し、既存のインフラストラクチャをTerraform構成に統合しやすくすることで、IaCの原則に合致しています。
Source:
https://dzone.com/articles/how-to-use-terraform-import-block