About

terraform applyは成功したのにAWSに反映されていない — ElastiCacheの保留変更と、provider 6.58からの「No changes」

レプリカはすぐ増えたのに、自動フェイルオーバーだけ日曜に回された。provider 6.57と6.58で同じ状態をplanしてみて、「終わった」を何で判断するか決めた

terraform applyが緑で終わったのに、AWS側の設定が変わっていないことがある。ElastiCacheで自動フェイルオーバーを有効にしたときに踏んだ。この記事を読むと、なぜそうなるのか(AWSの保留変更)、terraform AWS providerのバージョンでplanの見え方が真逆になること、そして本当に反映されたかを確かめるコマンドがわかる。

ElastiCacheはRedis(Valkey)をAWSが代わりに運用してくれるサービスだ。保留変更(pending modification)は、AWSが「受け付けたけど、メンテナンスウィンドウで当てる」と後回しにした変更のこと。

何が起きたか

ノード1台のRedisにレプリカを足して、自動フェイルオーバーを有効にした。terraformでは2行だ。

num_cache_clusters         = 2     # 1 → 2
automatic_failover_enabled = true  # false → true

applyは成功し、レプリカもすぐ作られ始めた。ところが自動フェイルオーバーだけ有効になっていない。

AutomaticFailover       disabled
PendingModifiedValues   { AutomaticFailoverStatus: enabled }

ElastiCacheのModifyReplicationGroupはApplyImmediatelyの既定がfalseだ(APIドキュメント)。falseだと一部の変更はすぐには入らず、PendingModifiedValuesに積まれてメンテナンスのときに入る。このクラスタのウィンドウは日曜で、applyしたのは木曜。3日間「フェイルオーバーは有効にした」と思い込むところだった。

レプリカはなぜすぐ増えたのか

同じapplyなのに、片方は即時、片方は保留。気になってproviderのソース(terraform-provider-aws main、2026-11-13)を読んだ。

理由は単純だった。num_cache_clustersを増やすときはIncreaseReplicaCount APIを別に呼び、そこにはApplyImmediately: trueが直書きされている。残りの属性はModifyReplicationGroup1回にまとめて送られ、こちらにだけ自分で書いたapply_immediatelyの値が乗る。

つまり同じリソースの中でも、その属性がどのAPIを通るかで即時か保留かが分かれる。「ElastiCacheは保留される」とリソース単位で覚えると間違える。

terraform apply apply_immediately = false Apply complete! ElastiCache (real state) replicas 1 → 2: started at once AutomaticFailover: disabled PendingModifiedValues: AutomaticFailoverStatus: enabled waits for the next maintenance window provider 6.57 plan ~ failover false -> true provider 6.58+ plan No changes (still disabled) done = ask AWS, not terraform describe-replication-groups PendingModifiedValues is empty and AutomaticFailover is enabled 6.58+: flip apply_immediately plan: + apply_immediately = true apply: 1 changed ModifyReplicationGroup calls: 0

provider 6.58からはplanが「No changes」と言う

ここからが本当の落とし穴だ。

自分たちが踏んだときは、planにautomatic_failover_enabled = false -> trueが残り続けた。applyは成功したのに差分が消えないので、少なくとも「何かおかしい」というサインにはなった。

provider 6.58.0(2026-08-05)でこれが変わった。#48246「保留変更があると差分が出続ける問題の修正」。ReadがPendingModifiedValuesの値をそのままstateに入れるようになった。保留中のenabledを「もう有効」と見なすわけだ。

本当にそうなるか確かめるため、OpenTofu 1.12.6にprovider 6.57.1と6.58.0を入れた。AWSの代わりにローカルの偽エンドポイントが上の保留状態を返すようにして、import → planを回した。

6.57.1  ~ automatic_failover_enabled = false -> true   (Plan: 0 to add, 1 to change)
6.58.0  No changes. Your infrastructure matches the configuration.

AWSはまだdisabledなのに、6.58.0はきれいだと言う。保留が解けた状態(enabled・保留なし)を返すと、どちらもNo changesだった。6.58以降、planがきれいでも反映済みとは限らない。

自分たちのproviderのバージョンは記録が残っていない。planに差分が残ったので、6.58より前だったと見ている。

apply_immediatelyだけ変えても何も起きない(6.58から)

自分たちはapply_immediately = trueを入れて再applyして解消した。6.57.1で再現すると、実際にこういうリクエストが飛ぶ。

Action=ModifyReplicationGroup
ApplyImmediately=true
AutomaticFailoverEnabled=true

automatic_failover_enabledに差分が残っているので値がもう一度送られ、今度は即時適用になる。

同じことを6.58.0でやると、planに+ apply_immediately = trueの1行が出て、applyも「1 changed」で終わる。なのに偽エンドポイントに記録されたModify呼び出しは0回だった。ソースを見るとModifyReplicationGroupはほかの属性に差分があるときだけ呼ばれ、apply_immediatelyはその一覧にない。stateではもう有効に見えているので、送るものがないのだ。

これは本物のAWSでは試していない。偽エンドポイントとソースコードで確かめたことだ。すでに保留に入ったものを今すぐ当てたいなら、CLIで同じ値を--apply-immediately付きで送り直すのが確実そうだ(推測、実際には流していない)。

aws elasticache modify-replication-group --replication-group-id <id> --automatic-failover-enabled --apply-immediately

「終わった」はAWSに直接聞いて決める

applyの成功も、planがきれいなことも、判断基準にならない。

aws elasticache describe-replication-groups --replication-group-id <id> --query 'ReplicationGroups[0].{now:AutomaticFailover,pending:PendingModifiedValues}'

pendingが空でnowが望む値なら終わり。上の偽エンドポイントにこのコマンドを流すと"now": "disabled"、"pending": {"AutomaticFailoverStatus": "enabled"}が返る。保留がひと目でわかる。

RDSも同じ作りだ。apply_immediatelyの既定はfalseで、後回しになった変更はdescribe-db-instancesのPendingModifiedValuesに積まれる(RDSドキュメント)。providerのaws_db_instanceは今も保留中のエンジンバージョンだけを特別扱いしている。それ以外の保留値はplanに差分として出ることがある、とproviderのドキュメントにある。RDS側は自分では流していない。

選び方

  • すぐ入れたい変更 → 最初からapply_immediately = true。ただしこれを付けると、今回の変更だけでなく、すでに積まれていた保留変更もまとめて即時に入る(APIドキュメント)。ノードタイプ・エンジンバージョンのように再起動を伴うものが紛れていることがあるので、付ける前にPendingModifiedValuesを見る

  • ウィンドウまで待っていい変更 → falseのままにして、PRや作業記録に「日曜のウィンドウで反映予定」と書いておく

  • どちらでも最後の確認はPendingModifiedValuesが空か。providerを6.58以上に上げたならなおさら

terraformで管理しているAWSで「終わったと言われたのに終わっていない」が続くなら、https://www.negabaro.com/contact から聞いてほしい。こういう確認手順を一緒に組む仕事もしている。

動作フロー

1

ElastiCache・RDSはapply_immediatelyの既定がfalse — 一部の変更はPendingModifiedValuesに積まれ、メンテナンスで入る

2

同じリソースでもAPIで違う — レプリカ追加(IncreaseReplicaCount)はproviderが常に即時で送る

3

provider 6.58.0から保留値がstateに入りplanはNo changes — きれいなplanは反映の証拠ではない

4

6.58からapply_immediatelyだけtrueにしてもModifyReplicationGroupは0回(偽エンドポイントで確認)

5

「終わった」はdescribe-replication-groupsでPendingModifiedValuesが空かを見て決める

ユースケース

ElastiCacheのレプリカ・自動フェイルオーバー・Multi-AZをterraformで有効にするとき AWS providerを6.58以上に上げたあと、planの結果を信じていいか迷うとき applyは成功したのにplanの差分が消えない、コンソールの値が違うとき
← AWSでメンテナンスページを出す3つの方法 — ALBルール・WAF・DNS切替を比べて、DNSをやめた理由