importブロックを使用したリソースのインポート

v1.5 からTerraformに追加された、importブロックでのリソースの追加方法について触れたことがなかったのでやってみた。

import.tfなどでimportブロックを作成する。

import {
 to = (後々つくるAWSリソース名。なので名前は決めておく必要がある。) ex. aws_security_group.testsg
 id = "(AWSリソースID)"
}

importしたいリソースのコードが書かれたファイルをgenerate-config-outの引数で作成する。このとき実施するコマンド自体はterraform planなので、あくまで出力結果が terraform plan のものになる。出力されるファイルのほかに、インポートしたいリソース情報も plan 結果として出力される。

出力された結果を見ると、be imported と表示されている。通常、terraform を介してリソースを作成する場合は、createdと表示されるが今回は異なっていることがわかる。

$ terraform plan --generate-config-out=generate_file.tf
:

Terraform will perform the following actions:

  # aws_security_group.testsg will be imported
  # (config will be generated)
    resource "aws_security_group" "testsg" {
        arn         = "arn:aws:ec2:ap-northeast-1:123456789012:security-group/sg-xxxxxxxxx"
        description = "testsg"
:
:

Plan: 1 to import, 0 to add, 0 to change, 0 to destroy.

:
:

出力されたコードを参照してみる。description等はよいが、例えばvpc_idなどはリソースIDがそのまま記載されているので、必要に応じてリファレンス表記に修正すると良い。

$ cat generate_file.tf

# __generated__ by Terraform
# Please review these resources and move them into your main configuration files.

# __generated__ by Terraform from "sg-xxxxxxxxx"
resource "aws_security_group" "testsg" {
  description = "testsg"

(以下リソースを示すコードが記載されている)

  vpc_id                 = "vpc-abcdefgh" <------
}

なおこのタイミングではまだ state にリソース情報はインポートされていない。

$ terraform state show aws_security_group.testsg
No instance found for the given address!

This command requires that the address references one specific instance.
To view the available instances, use "terraform state list". Please modify
the address to reference a specific instance.

terraform apply を実施することにより実際にリソースがインポートされる。

$ terraform apply

:
:

aws_security_group.testsg: Importing... [id=sg-xxxxxxxxxxxx]
aws_security_group.testsg: Import complete [id=sg-xxxxxxxxxxxx]

Apply complete! Resources: 1 imported, 0 added, 0 changed, 0 destroyed.

なおapplyするディレクトリにimport.tfが存在していない場合、createするリソースとして認識されるため注意が必要。GitHub ActionsなどのCIでapplyまで実行される場合は、import.tfについてもコミットする必要がある。

stateへリソース情報がインポートされたことも確認できた。

$ terraform state show aws_security_group.testsg
# aws_security_group.testsg:
resource "aws_security_group" "testsg" {
  arn         = "arn:aws:ec2:ap-northeast-1:123456789012:security-group/sg-xxxxxxxxxx"
  description = "testsg"
  egress      = [
    {
      cidr_blocks      = [
:
:

インポートが完了したあとのimport.tfは削除しても特に問題なさそうだった。

© てっくらのーと/mkr-note 2024