MENU

terraform import、tfstateとコードは別物だった

terraform import、tfstateとコードは別物だったことを説明する画像

おはようございます、YASUです。

これまでTerraformで新しくリソースを作る話ばかり扱ってきましたが、実務では「すでにAWSコンソールで手動で作ってしまったリソースを、後からTerraformの管理下に入れたい」という場面がよくあるそうです。今日は、そのためのterraform importについて整理します。

目次

結論

terraform importは、すでに存在するAWSリソースを、Terraformのtfstate(状態を記録する台帳)に登録するコマンドです。ただし、コードの中身は自動生成してくれないため、tfstateとコードの両方を手作業で一致させる必要がある、という地味に手間のかかる作業でした。

なぜこの機能が必要になるのか

実務では、こんな状況がよくあるようです。

  • 最初は急ぎでAWSコンソールから手動でリソースを作ってしまい、後からTerraform管理に切り替えたい
  • 他のチームや前任者が手動で作ったリソースが残っていて、今後はコードで管理したい
  • 一時的に手動で追加した設定を、正式にコード化して残しておきたい

以前紹介した通り、Terraformは「コードの内容」と「tfstateに記録された現状」を見比べて差分を計算する仕組みでした。手動で作られたリソースは、そもそもtfstateに記録がないので、Terraformからは「存在しないもの」として扱われてしまいます。そのままうっかりapplyすると、同じリソースを重複して作ろうとしたり、最悪の場合は既存のリソースを意図せず変更・削除しようとする危険もあります。

importの基本的な流れ

importは、大きく3つのステップで進めます。

# Step 1: コード側に、空の器(リソース定義)を用意しておく
resource "aws_instance" "web" {
  # まだ中身は空でもいい、もしくは仮の値
}
# Step 2: 実際のAWSリソースのIDを指定して、tfstateに取り込む
terraform import aws_instance.web i-0123456789abcdef0
# Step 3: 取り込んだ内容を確認する
terraform plan

terraform importコマンドの後ろにあるi-0123456789abcdef0は、実際のEC2インスタンスのIDです。このIDを指定することで、「このAWS上の実在するリソースを、コード上のaws_instance.webという定義に紐づけてください」とTerraformに伝えています。

ここが一番のハマりポイント

importを実行すると、tfstateには実際の設定内容(AMI、インスタンスタイプ、タグなど)が取り込まれます。しかし、Terraformのコードファイル(.tf)の中身までは自動生成してくれません

つまりimport直後にそのままterraform planを実行すると、コード側がまだ空っぽ(または仮の値)のままなので、「本物の設定と、コード上の設定にズレがあります」という大量の差分が表示されてしまいます。ここで焦ってapplyしてしまうと、意図せず本物のリソースの設定を、コード側の(空っぽの)内容で上書きしてしまう危険があります。

なので、importした後は、planの差分を見ながら、実際の設定内容をコード側に手作業で書き写していく、という地道な作業が必要になります。AWSコンソールの設定画面と、コードを見比べながら、1つずつ値を埋めていくイメージです。

便利な支援ツールもある

近年のTerraformには、この手作業を軽減するための機能も追加されているようです。importブロックという書き方を使うと、コードとして「このリソースをインポートします」という宣言をしておき、terraform plan -generate-config-outのようなオプションと組み合わせることで、ある程度コードの雛形を自動生成できる仕組みも用意されています。ただし完璧に自動化されるわけではなく、最終的な調整は人の目でのチェックが必要とされています。

実務での位置づけ

importは、頻繁に使うコマンドというよりは、「移行のタイミング」で使う特別な作業という位置づけのようです。既存のインフラをTerraform管理に切り替えるプロジェクトでは重要な作業になりますが、日常的な運用の中で毎回使うものではありません。それだけに、いざ必要になった時に「tfstateへの登録」と「コードへの反映」が別々の作業であることを知らないと、思わぬ事故につながりそうです。

まとめ

  • terraform importは、既存のAWSリソースをtfstateに登録するコマンド
  • tfstateには実際の設定が取り込まれるが、コード(.tf)の中身は自動生成されない
  • import直後にそのままapplyすると、コード側の空の内容で上書きしてしまう危険がある
  • importは日常的に使うコマンドではなく、既存インフラの移行時に使う特別な作業

「コードで管理する」ということが当たり前になっていましたが、その前段階として、すでにある現実のインフラを取り込むための地道な作業があると知り、Terraformの理解がまた一段深まった気がします。それでは、また明日!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次