KEIS BLOGは株式会社ケイズ・ソフトウェアが運営しています。

KEIS BLOG

KEIS BLOG

「providerを固定したのになぜ直らない?」Terraform初心者がハマる落とし穴

ある日、既存の AWS リソース(セキュリティグループ)をコード管理下に置くため、terraformer import というツールで .tf ファイルと tfstate を自動生成しました。生成されたコードに対して terraform plan を実行すると、こんなエラーが出ました。

Error: Unsupported argument

  on security_group.tf line 27, in resource "aws_security_group" "example":
  27:   tags_all = {

An argument named "tags_all" is not expected here.

その場は該当箇所を手動で削除して乗り切ったのですが、数ヶ月後に同じリソースを再度 import し直したところ、まったく同じエラーが再発しました。「.terraform.lock.hcl を Git 管理して AWS provider のバージョンを固定したはずなのに、なぜ直らないのか」という疑問が上がったのですが、結論から言うと、この疑問自体が「直すべき場所」を取り違えていました。この記事では、その勘違いが起きた理由を入り口に、Terraform 初心者がつまずきやすいファイル・ツールの役割分担を整理します。

登場人物を整理する

Terraform をちょっと触り始めると、似たような名前のファイルやツールが一気に出てきて混乱します。まず全体像を押さえましょう。

名前役割
Terraform 本体(terraform コマンド)汎用エンジン。.tf を読んで依存関係を解決し、実行計画(plan)を立てて実行(apply)するだけで、クラウド固有の知識は一切持たない
provider(例: terraform-provider-aws)Terraform 本体の指示を実際のクラウド API 呼び出しに翻訳する専用プラグイン。クラウドごとに別バイナリ
.tf ファイルリソース定義。人間が書くこともあれば、ツールが自動生成することもある
.tfstate ファイル「今クラウド上に実際に何が存在するか」の記録
.terraform.lock.hclterraform init 時に生成される、provider のバージョンを固定するためのファイル。Git 管理が公式推奨
terraformerTerraform 本体のエコシステムには含まれない、完全に別の OSS ツール。既存のクラウドリソースを読み取り、.tftfstate を逆生成する(reverse Terraform)
図1: Terraform本体のエコシステムとterraformerの位置づけ
図1: Terraform 本体のエコシステムと terraformer の位置づけ。terraformer だけが外側にある別ツール

ここでの一番の注意点は、terraformer だけ毛色が違うということです。他の要素は全部「Terraform 本体が知っている世界」の話ですが、terraformer は Terraform 本体が存在すら知らない外部のツールです。今回の混乱は、この違いを意識せずに「Terraform まわりの設定を直せば全部直るはず」と思い込んでしまったところから始まっています。

tags_all とは何か

AWS リソースにタグをつける方法には、実は2つの入力元があります。

  • リソースブロックに書く tags
  • provider ブロック全体にかける default_tags
provider "aws" {
  default_tags {
    tags = {
      Environment = "prod"
    }
  }
}

resource "aws_security_group" "example" {
  tags = {
    Name = "example"
  }
}

この2つを AWS provider が自動的に合成した結果が tags_all です。ユーザーが値を書き込むものではなく、Terraform が計算して埋める「Computed(参照専用)属性」という位置づけになっています。だから、そもそも .tf ファイルの中に自分で tags_all = {...} と書くこと自体が想定されておらず、書けばエラーになります。

図2: tagsとdefault_tagsを合成した結果がtags_all
図2: tags と default_tags を合成した結果が tags_all。ユーザーが書けるのは左側まで

なぜ terraformer が tags_all を書き出してしまうのか

terraformer は「AWS の実際の state に含まれる属性を機械的に全部 .tf へダンプする」という作りになっています。その属性が「ユーザーが定義すべきもの」なのか「provider が計算するだけの参照専用(Computed)」なのかを区別せずに全部書き出してしまうため、tags_all もそのまま .tf に紛れ込みます。

さらにややこしいのが、tags_all という属性自体が AWS provider のバージョン 3.38.0(2021年5月ごろ)で導入された比較的新しい概念だという点です。つまり、同じ terraformer コマンドを同じように打っても、「いつ実行したか」によって挙動が変わります。

図3: providerの世代によるterraformerの挙動の違い
図3: 古い provider 時代に import すれば tags_all は出ない。新しい provider 時代に import すれば書き出されてエラーになる
  • 古い provider バージョンの時代に terraformer を実行 → state に tags_all が存在しないので、書き出されない
  • 新しい provider バージョンの時代に terraformer を実行 → state に tags_all が含まれているので、.tf に書き出されてしまう

なぜ「provider を固定」しても直らないのか

ここが今回一番混乱した部分です。.terraform.lock.hcl が固定するのは、「そのプロジェクトが terraform plan/apply を実行するときに使う provider(AWS との通訳担当)のバージョン」です。

一方で tags_all が書き出されるかどうかを決めているのは、terraformer というバイナリ自身が内蔵している「AWS リソースはこういうスキーマだろう」という理解であり、これは terraformer 自身のバージョンに依存します。

図4: lock.hclの固定範囲とterraformerの理解範囲は別レーン
図4: lock.hcl が固定する範囲と、terraformer が内蔵する理解の範囲は別レーン。互いに影響しない

この2つは別のツール・別のタイミングで動いているので、lock.hcl をどれだけ厳密に固定しても terraformer の生成ロジックには一切影響しません。「provider を固定したのになぜ直らないのか」という問いは、そもそも直る見込みのない場所を直そうとしていた、ということになります。

じゃあどう対処すればいいのか

その場しのぎ: エラーになった tags_all = {...} のブロックを手動で削除してから plan/apply する。今回のケースもまずはこれで乗り切りました。

ただしこれだと、次に terraformer で同じリソースを再度 import(再生成)した瞬間に同じ行が復活し、同じエラーが再発します。実際、数ヶ月後にまったく同じ現象が起きました。

恒久対策の方向性:

  • terraformer 実行後、生成された .tf から tags_all のような Computed 専用属性を機械的に取り除く後処理ステップ(sed やスクリプト)を手順に組み込み、手作業に頼らないようにする
  • 手順書に「なぜこの現象が起きるのか」という構造の説明を残しておく。「削除してOK」という結論だけを書き残すと、担当者が変わったときに同じ疑問がまた繰り返される

まとめ

  • Terraform 本体・provider・.tf・.tfstate・.terraform.lock.hcl は同じエコシステム内の話だが、terraformer は完全に別の外部ツール
  • tags_all は AWS provider が自動計算する Computed 属性で、そもそも .tf に手書きするものではない
  • terraformer は「これは書いていい・これは書いてはいけない」の区別をせず、state の中身を無差別にダンプするため、新しい provider 世代の情報を含む state を読むと tags_all も書き出してしまう
  • provider バージョンの固定(lock.hcl)はこの問題の発生レイヤーとは無関係。だから固定しても直らない

Terraform を触っていて「直したはずなのになぜ直らない」と感じたときは、一度「そもそも、その設定は"どのツールのどのレイヤー"に効くものなのか」を疑ってみると、案外あっさり謎が解けることがあります。

エンジニア募集中!

採用情報はこちら

CATEGORY

技術情報

思考

便利サービス

社内イベント

採用担当の戦い

その他

メンバー

LATEST ENTRY

2026.07.08

見慣れないIPアドレスの正体を調べる4つの方法

技術情報

2026.07.08

「providerを固定したのになぜ直らない?」Terraform初心者がハマる落とし穴

技術情報

2026.07.08

【KEISのメンバー #1】入社2年目・若手エンジニアに聞く、未経験からの1年と「続けられるエンジニア」

メンバー

2026.06.21

{% partial %} 文法リファレンス ― 名前・属性・型解決・スコープの全仕様

技術情報

2026.06.21

Liquid に自作タグを足す ― partial タグで見る作り方

技術情報

TAG