🗂

【Terraform】 既存リソースをTerraform管理下に置くimport blockの使い方

2024/01/16に公開

はじめに

Terraformは、Infrastructure as Code (IaC) ツールとして広く利用されています。その中でも、既存のインフラストラクチャをTerraformで管理する際に重要な機能の一つが「import block」です。この記事では、Terraformのimport blockを使用して、既存のリソースをTerraformのコードに統合する手法について解説します。

import blockとは

既存のインフラストラクチャリソースをTerraformにインポートし、Terraformの管理下に置く機能です。
公式サイト

※通常、Terraformでは .tf ファイルに記述されたコードによってインフラストラクチャを定義しますが、リソースを手動で作成した場合や他のIaCツールで作成した場合には、Terraform管理となりません。

Import blockの構文

import {
  to = aws_instance.example
  id = "i-abcd1234"
}
# to - リソースの識別子
# id - インポート先のリソース定義の識別子を指定

既存リソースをTerraform管理下に置く方法

  • terraform import コマンド
#例:aws のs3をimportする場合
terraform import モジュール名 バケット名
  • terraform import block

import blockの利点

  • Terraformのコード内で記載可能(宣言的)
    • importコマンドは、コマンドラインから実行される一方、import blockは、Terraformのコード内で定義できます。
  • 複数のリソースを一括で取り込める
    • import コマンドでは1つずつリソースを追加する必要がありましたが、import blockでは複数のリソースを一括で取り込むことができます。
  • Terraform planでdry run可能
    • Terraform planを実行することで、実行前に事前チェックが可能です。

実際に使ってみる

  • 事前準備
    • terraformを使わずにs3作成する
aws s3 mb s3://<bucket-name>
  • Terraform コードに追加
    main.tfに追加する
import {
  id = "<bucket-name>" # リソースの識別子
  to = aws_s3_bucket.main         # インポート先のリソース定義の識別子を指定
}

resource "aws_s3_bucket" "main" {
  bucket = "<bucket-name>"
}

公式サイト:s3のimport

  • terraform planを実行して確認すると、Plan: 1 to import,とプランが出力されていることが確認できます。
  # aws_s3_bucket.main will be updated in-place
  # (imported from "import-bulock-tutorial")
  ~ resource "aws_s3_bucket" "main" {
        arn                         = "arn:aws:s3:::<bucket-name>"
        bucket                      = "<bucket-name>"
        bucket_domain_name          = "<bucket-name>.s3.amazonaws.com"
        bucket_regional_domain_name = "<bucket-name>.s3.<リージョン名>"
      + force_destroy               = false
        hosted_zone_id              = "<id>"
        id                          = "<bucket-name>"
        object_lock_enabled         = false
        region                      = "<リージョン名>"
        request_payer               = "BucketOwner"
        tags                        = {}
      ~ tags_all                    = {
          + "Env" = "dev"
        }

        grant {
            id          = "<id>"
            permissions = [
                "FULL_CONTROL",
            ]
            type        = "CanonicalUser"
        }

        server_side_encryption_configuration {
            rule {
                bucket_key_enabled = false

                apply_server_side_encryption_by_default {
                    sse_algorithm = "AES256"
                }
            }
        }

        versioning {
            enabled    = false
            mfa_delete = false
        }
    }

Plan: 1 to import, 0 to add, 1 to change, 0 to destroy.
  • applyを実行して取り込む
terraform apply
  • 取り込めたことを確認する
terraform state list

import blockを使ってIaCを作成する

リソースを取り込むにあたり、IaCを書く必要があるかと思います。

resource "aws_s3_bucket" "main" {
  bucket = "terraform-import-example"
}

但し、取り込むリソースのIaCがすぐに書けないような場合には、下記実行することで、ファイルにIaCを出力することができます。

main.tf

import {
  id = "<bucket-name>" # リソースの識別子
  to = aws_s3_bucket.test         # なんでもOK
}

コマンド

terraform plan -generate-config-out=generated.tf # 出力するファイル名は何でもOK

import実行後

import実行後は import ブロックは削除して大丈夫です。
残しておいても影響はありませんが、無意味なブロックになります。

まとめ

Terraformのimport Blockを利用することで、既存のリソースをTerraformの管理下に統合することができます。また-generate-config-outを利用することで、簡単にIaC化することも可能となります。

Discussion