Terraform の -minimal-refresh で plan 時間を短縮できるか検証してみた

Terraform の -minimal-refresh で plan 時間を短縮できるか検証してみた

Terraform 1.17 で追加された `-minimal-refresh` オプションを実際に試してみました。3 階層構成で refresh 回数がどれだけ削減され、plan 時間が短くなるかを検証した結果をお伝えします。
2026.10.31

はじめに

クラウド事業本部、あきやまです。

Terraform 1.17 で、計画上変更があるリソースだけを対象に、リモートの現在値を取りに行く -minimal-refresh が追加されました。
通常の terraform plan は、state 上のリソースについて AWS などへ問い合わせて現状を揃えてから差分を出します。
リソース数が多い構成では、この問い合わせの積み重ねが待ち時間の大半になりがちです。
一般的な 3 階層構成を実際にデプロイして、変更 1 件の plan がどれだけ短くなるかを測りました。

環境

項目 値
OS macOS 26.7.2
Terraform v1.17.1
AWS Provider hashicorp/aws v6.71.0
リージョン ap-northeast-1
検証構成 VPC + ALB + ASG(t3.micro×1)+ NAT + RDS(MySQL 8.4 / db.t4g.micro)
state 上のオブジェクト 33(うち、現状確認の対象になる managed リソースは 31)

検証後は terraform destroy 済みです。

結論

リモートへの現状確認の回数は大きく減り、plan の所要時間も短くなりました。ただしこの規模では差は小さめです。

ALB のタグを 1 つだけ変えた plan では、現状確認が 31 回から 1 回になり、所要時間はおおよそ 2.9 秒から 2.2 秒前後になりました。
短縮幅は 0.6〜0.9 秒くらいです。
数百リソースで 1 本あたりの読み取りが重い構成なら差は広がりそうですが、30 本前後の 3 階層では「体感で激変」とは言い切れませんでした。

確認項目 通常 -minimal-refresh
変更 1 件時の現状確認回数 31 1
変更 1 件時の plan 所要時間(2 回計測) 2.81 / 2.96 秒 2.11 / 2.38 秒
変更なし時の現状確認回数 31 0
変更なし時の plan 所要時間 2.97 秒 2.05 秒
plan の内容(変更 1 件) ALB タグ更新 1 件 同じ

※ 現状確認回数は、plan ログの Refreshing state 行数です。所要時間は /usr/bin/time -p で測った経過時間です。

公式どおり、変更が無いと判断したリソースは外部変更を見に行きません。
速さだけ見て常時オン、にはしにくいオプションです。

やってみた

Step 1: 3 階層構成をデプロイする

次の構成を Terraform で作りました。

Public に ALB と NAT、Private に ASG(t3.micro ×1)、DB subnet に RDS MySQL(db.t4g.micro / Single-AZ)です。
計測用に ALB へ ExtraTag を付けてあり、ここだけ後から変えて plan を比較します。

alb.tf
resource "aws_lb" "app" {
  name               = "${var.name_prefix}-alb"
  load_balancer_type = "application"
  security_groups    = [aws_security_group.alb.id]
  subnets            = aws_subnet.public[*].id

  tags = {
    Name     = "${var.name_prefix}-alb"
    ExtraTag = var.alb_extra_tag
  }
}
terraform apply -auto-approve
# Apply complete! Resources: 31 added, 0 changed, 0 destroyed.

Step 2: タグ 1 件だけ変えて plan を比べる

alb_extra_tag を v1 から v2 にして、通常と -minimal-refresh を 2 回ずつ測りました。
計測前に一度ずつ温めています。

現状確認の回数は、ログに出る Refreshing state の行数で数えます。

# 通常
terraform plan -var='alb_extra_tag=v2' -no-color | rg -c 'Refreshing state'
# 31

# minimal-refresh
terraform plan -var='alb_extra_tag=v2' -minimal-refresh -no-color | rg -c 'Refreshing state'
# 1

所要時間は /usr/bin/time -p の経過時間です。

回 通常 -minimal-refresh
1 2.81 秒 2.11 秒
2 2.96 秒 2.38 秒

どちらも plan の中身は同じでした。

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

-minimal-refresh 側のログでは、aws_lb.app だけが Refreshing state になります。
VPC や RDS、ASG などは現状確認をスキップします。

Step 3: 変更なしでも測る

差分が無い plan だと、差がもう少しはっきりします。

条件 現状確認回数 plan 所要時間
通常 31 2.97 秒
-minimal-refresh 0 2.05 秒

現状確認が 0 回でも、plan 自体に約 2 秒かかります。
プロバイダの初期化や設定評価などの固定費が残る、と見てよさそうです。
今回の短縮分は、その上に乗っていた現状確認のコストが削れた分、という感覚です。

Step 4: 片付け

NAT、ALB、EC2、RDS が残るので、計測後すぐ destroy しました。

terraform destroy -auto-approve
# Destroy complete! Resources: 31 destroyed.

注意点・制約

-minimal-refresh は、変更予定が無いリソースの外部変更を無視します。
-refresh=false より狭い範囲ですが、見ないものは見ない、という点は同じ系統です。

次の組み合わせは使えません。

terraform plan -minimal-refresh -refresh=false
# Error: Incompatible refresh options

terraform plan -minimal-refresh -refresh-only
# Error: Incompatible plan mode options

プロバイダのスキーマバージョンが変わったリソースは、plan 結果に関係なく現状確認が走ります。
プロバイダ更新直後は避けた方が安全です。

依存先の現状確認が走っても、依存元まで連鎖では走りません。
公式ドキュメントにも、リソースごとに独立して判断すると書かれています。

参考: terraform plan の Planning Options

今回の 3 階層は「動く最小の完成形」寄りです。
Multi-AZ RDS や NAT 冗長化は入れていません。
それでも managed リソースは 30 本超あり、現状確認回数の差は十分に見えました。

まとめ

  • 3 階層構成で -minimal-refresh を試し、現状確認を 31 回から 1 回に減らせました
  • plan 所要時間はおおよそ 2.9 秒から 2.2 秒前後になり、短縮は確認できました
  • この規模では差は 1 秒未満なので、常時有効にするほどではない、が今の所感です

参考

この記事をシェアする

関連記事