Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Terraform Import: How the Command Works on One Orphaned Security Group

2026年10月21日に「Dev.to」が公開したITニュース「Terraform Import: How the Command Works on One Orphaned Security Group」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

Terraform Importは、クラウド上に既に存在する資源をTerraformの管理対象に加える機能だ。手動で作成された資源などをStateファイルに登録し、コード管理できるようにする。以前は手動設定が多かったが、自動生成や一括インポート機能で作業は軽減。大規模な未管理資源の発見・コード化にはSGCodeのような専用ツールが有効だ。

ITニュース解説

システムエンジニアがクラウド上のインフラを管理する際、TerraformのようなInfrastructure as Code(IaC)ツールは不可欠だ。Terraformは、コードでインフラを定義し、その状態を「状態ファイル(State File)」に記録することで、クラウド上の実際のリソースとコードの対応関係を管理する。この状態ファイルは、Terraformが次にどのような変更を行うべきかを判断する「地図」の役割を果たす。コード、クラウドの状態、状態ファイル、これら三つが整合していることが、インフラを安定して管理するための鍵である。

しかし、実際の運用では、すべてのインフラがTerraformの管理下にあるわけではない。緊急時にエンジニアが手動でクラウドコンソールからリソースを作成し、Terraformコードへの反映を忘れるケースはよくある。また、引き継いだり買収した会社のインフラには、Terraformの管理外で作成されたリソースが無数に存在する可能性がある。このような「Terraformの管理下にない孤立したリソース」は、状態ファイルに記録がないため、Terraformからは見えない存在だ。もし、後から同じ目的のリソースをTerraformで定義しようとすると、既存リソースを無視して新しいリソースを作成しようとし、二重管理や混乱を招く。

ここで役立つのが、Terraformに既存のクラウド上のリソースを「取り込む」機能、terraform importだ。この機能は、すでに存在するクラウドのリソースを、Terraformの状態ファイルに記録し、その後の管理対象に加えることを目的としている。重要な点は、terraform importを実行しても、クラウド上のリソース自体が変更されることは一切ないということだ。変更されるのは、あくまでTerraformの状態ファイルのみであり、これによりTerraformがそのリソースを認識し、将来的にコードで管理できるようになる。

従来のterraform importコマンドの使い方は、比較的シンプルだ。コマンドラインでterraform import <Terraformでのリソースアドレス> <クラウド上のリソースID>と入力する。例えば、AWSで手動作成されたセキュリティグループを取り込む場合、terraform import aws_security_group.web sg-0a1b2c3d4e5f67890のように実行する。「リソースアドレス」はTerraformコード内でそのリソースに与えたい名前(例: aws_security_group.web)、「リソースID」はクラウドプロバイダが割り当てた一意な識別子(例: sg-0a1b2c3d4e5f67890)である。

ただし、従来のimportコマンドにはいくつかの課題があった。まず、コマンド実行前に、取り込みたいリソースに対応する空のTerraform設定ブロックを手動で記述しておく必要があった。Terraformは、状態を取り込むための「受け皿」を必要としたからだ。そして、最も手間がかかったのは、取り込み後だ。空のブロックでインポートしたリソースは、設定がTerraformコードに記述されていないため、terraform planを実行すると、既存リソースの設定とコードの間に大きな不一致が生じ、大量の変更が提案されてしまう。この不一致を解消するには、エンジニアがクラウドのコンソール画面などからリソースの詳しい設定情報を確認し、一つずつ手動でTerraformの設定ブロックに書き写す作業が必要だった。タグの記述漏れや属性値の不一致は、予期せぬ変更としてプランに表示され、場合によっては既存リソースの「破壊と再作成」につながるリスクもあった。

これらの課題を解決するため、Terraform 1.5からは「importブロック」が導入された。importブロックは、toとidという二つの引数を使い、取り込みたいリソースのアドレスとIDをTerraformの設定ファイル内に記述する。

import {
  to = aws_security_group.web
  id = "sg-0a1b2c3d4e5f67890"
}

このimportブロックは、従来のコマンドのようにすぐに実行されず、次のterraform plan実行時に評価される。これにより、インポートの意図がコードとしてバージョン管理され、プルリクエストを通じてチームメンバーによるレビューが可能になるという大きなメリットが生まれた。さらに、Terraform 1.5では-generate-config-outというフラグが導入され、terraform plan -generate-config-out=generated.tfのように実行することで、既存リソースの属性情報に基づいたTerraformの設定コードを自動的に生成し、指定したファイルに書き出してくれるようになった。これにより、手動での設定書き写し作業が大幅に削減され、エンジニアの作業は自動生成されたコードの確認と修正が中心となる。ただし、この生成機能はまだ「実験的」な位置づけであり、生成される設定が不完全であったり、機密情報や特定のプロバイダに依存する属性がうまく生成されない場合があるため、生成されたコードの丁寧なレビューは依然として不可欠だ。また、S3バケットのバージョン管理や暗号化設定のように、一つのクラウド上のエンティティが複数のTerraformリソースとしてモデル化されている場合、それぞれに対応するimportブロックとIDを記述する必要がある点には注意が必要だ。

Terraform 1.7では、さらにimportブロックにfor_each引数が追加され、複数のリソースを一括で取り込むことが可能になった。これにより、事前にリソースIDのリストを用意しておけば、一つのimportブロックで大量の類似リソースを効率的に管理下に置けるようになる。

locals {
  existing_security_groups = {
    "web" = "sg-0a1b2c3d4e5f67890"
    "db" = "sg-1b2c3d4e5f678901a"
  }
}

import {
  for_each = local.existing_security_groups
  to = aws_security_group.this[each.key]
  id = each.value
}

しかし、terraform importの機能は進化しているものの、特に大規模な環境や、何がクラウドに存在しているかすら不明な状況では、いくつかの限界が残されている。まず、importは常に「リソースID」を必要とするため、クラウドアカウント内にどのようなリソースが存在しているかをimport自身が発見してくれるわけではない。つまり、どのリソースを取り込みたいのか、そのリソースIDは何なのかを、エンジニアが事前に把握している必要がある。また、自動生成された設定コードはレビューが必須であり、完璧ではない場合がある。さらに、複数アカウントにまたがる膨大なリソースや、長年にわたる手動作成インフラを一つずつimportブロックで処理していくのは非常に手間がかかる。そして、最も危険なのは、import直後のplanで設定の不一致が原因で「破壊と再作成」が提案されても、それが通常の更新と見分けがつきにくく、レビュー担当者が気づかずに承認してしまうリスクがあることだ。

import作業中には、いくつかの典型的なエラーに遭遇することがある。「Resource already managed by Terraform」は、指定したアドレスがすでに状態ファイルに存在している場合に発生する。また、import直後のplanで「リソースの破壊と再作成」が提案される場合は、設定ブロックと既存リソースの間に、リソースの再作成を強制するような重大な不一致があることを示している。これはapplyする前に必ず確認し、設定を修正する必要がある。さらに、movedブロックは、すでにTerraformに管理されているリソースの名前や場所を変更したときに状態ファイルを更新するためのものであり、新規リソースを取り込むimportとは役割が異なる点にも注意が必要だ。

このように、terraform importは、少数の既知のリソースをTerraformの管理下に置くという特定のシナリオでは強力なツールだ。しかし、その有効範囲は限定的であり、何がクラウド上に存在しているかすら不明な大規模な環境や、大量の孤立リソースを管理下に置く場合には、より効率的なアプローチが求められる。

そこで登場するのが、terraform importが対応しきれない「インフラの発見」と「コード化」を自動で行うツール、SGCodeだ。SGCodeは、AWS、Azure、GCPといった複数のクラウドアカウントに接続し、そこに存在するすべてのリソースをリアルタイムで検出し、それらがIaCによって管理されているか(Managed)、それとも管理されていないか(Unmanaged)を可視化する「Cloud Inventory」機能を提供する。これにより、システムエンジニアは、どのリソースがTerraformの管理下になく、コード化する必要があるのかを一目で把握できる。

Cloud InventoryでUnmanagedとマークされたリソースの中から、コード化したいものを選び、SGCodeの「Codification」機能を使用すると、選択されたリソースとその関連リソースのTerraform/OpenTofuコードが自動的に生成される。terraform importが一つずつIDを指定し、関連リソースのコードは手動で補完する必要があったのに対し、SGCodeはリソース間の依存関係も考慮してコードを生成してくれるため、手作業を大幅に削減できる。生成されたコードは「Code Workbench」でレビューや編集が可能であり、SGCodeは内部でplanを実行してコードの検証も行う。最終的に、生成されたコードはプルリクエストとしてGitプロバイダに公開され、通常のレビュープロセスを経てマージされる。SGCode自体はプルリクエストをマージしないため、既存のワークフローを維持できる。また、コード化されたインフラに対しても、組織で定義されたセキュリティポリシーが自動的に適用されるため、古い手動作成リソースが現在のセキュリティ基準に適合しているかを確認し、コンプライアンスを強化できる点も大きな利点だ。

terraform importとSGCodeは、異なる状況でそれぞれ最適な役割を果たす。少数の既知の孤立リソースを迅速に管理下に置きたい場合はterraform importが適している。一方で、大量の未知の、あるいは未整理のインフラをまとめて発見し、コード化する必要がある場合は、SGCodeの包括的な機能が非常に有効だ。現実的な運用パターンとしては、まずSGCodeを使って大規模な未知のインフラを検出し、一括でコード化してプルリクエストを発行していく。その後、日常的な運用で偶発的に発生する単発の孤立リソースに対しては、terraform importを使い、必要に応じて手動で調整するというアプローチが効率的である。

まとめると、terraform importは、既知のリソースのIDをTerraformの状態ファイルに記録するという、ある意味で狭く限定された問題を解決するためのツールであり、最近のバージョンアップで設定コードの自動生成機能も加わり、手作業は減った。しかし、リソースの発見はできず、個々のリソースIDの把握が必須となる。これに対し、SGCodeは、クラウド環境全体をスキャンしてTerraformに管理されていないリソースを「発見」し、その関連性まで考慮してTerraformコードを「自動生成」することで、より広範な「ブラウンフィールド」なインフラのコード化問題を解決する。システムエンジニアとして、これらのツールの特性を理解し、現在の状況に応じて適切なツールを選択することが、効率的かつ安全なクラウドインフラ管理には不可欠だ。

関連コンテンツ

関連IT用語

関連ITニュース