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 가 「받아는 뒀고, 메인터넌스 창에 적용하겠다」 며 미뤄 둔 변경이다.

무슨 일이 있었나

노드 하나짜리 Redis 에 레플리카를 붙이고 자동 페일오버를 켰다. terraform 으로는 두 줄이다.

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 한 날은 목요일. 사흘 동안 「페일오버 켰다」 고 믿을 뻔했다.

레플리카는 왜 바로 붙었나

같은 apply 인데 하나는 즉시, 하나는 보류. 이상해서 provider 소스(terraform-provider-aws main, 2026-11-13)를 읽었다.

이유는 단순했다. num_cache_clusters 를 늘리는 건 IncreaseReplicaCount API 를 따로 부르는데, 여기엔 ApplyImmediately: true 가 박혀 있다. 나머지 속성은 ModifyReplicationGroup 한 번에 모아서 보내고, 그때만 우리가 쓴 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 한 줄이 뜨고 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 를 버린 이유