AWS provider 6.x 업그레이드: breaking change 진단과 안전한 전환 순서
테라폼 운영에서 CLI 버전보다 조심해야 하는 것이 provider 메이저 업그레이드입니다. 결론을 먼저 적으면, provider 메이저는 리소스 스키마 자체가 바뀌므로 코드 수정 없이도 plan diff가 발생할 수 있고, 표준 수순은 “최신 5.x 경유 → 공식 업그레이드 가이드 대조 → no-op 또는 설명 가능한 diff 확인 → 스택별 점진 적용"입니다. CLI 업그레이드의 일반 절차는 앞 글에서 다뤘고, 이 글은 AWS provider 6.x를 소재로 메이저 특유의 리스크를 다룹니다. 변경 내역은 2026-08 시점 검증 기준이며, 적용 시점에 공식 가이드를 다시 확인합니다.
provider 메이저가 CLI보다 무거운 이유 #
CLI 마이너 업그레이드는 호환성 약속의 보호를 받지만 provider 메이저는 그 반대로, 호환을 깨기 위해 존재하는 릴리스입니다. 리소스 인수가 제거되고, 기본값이 바뀌고, 리소스 타입 자체가 사라집니다. 스키마가 바뀌면 코드와 인프라가 그대로여도 plan에 diff가 나타나고, 그중 일부는 리소스 교체(destroy 후 재생성)를 뜻합니다. DB 같은 상태 있는 리소스가 교체로 판정되면 그것은 diff가 아니라 사고 예고입니다.
그래서 메이저 업그레이드는 “버전 숫자 바꾸고 plan 한 번"이 아니라, plan 출력을 전수 판독하는 작업입니다. 판독 기준은 뒤에서 정리합니다.
6.0의 주요 변경: 무엇이 깨지는가 #
공식 업그레이드 가이드 기준으로 실무에 걸리기 쉬운 변경은 이렇습니다.
| 변경 | 내용 | 걸리는 코드 |
|---|---|---|
| 리소스 단위 region 인수 | 대부분의 리소스에 region 인수 추가, provider alias 없이 멀티 리전 구성 가능 | 기존 alias 패턴은 유지 가능, 신규 설계의 선택지 확대 |
| OpsWorks 전면 제거 | 리소스 17종 삭제 | OpsWorks 사용 스택은 업그레이드 전 이전 필요 |
| SimpleDB 제거 | aws_simpledb_domain 삭제 | 해당 리소스 사용 코드 |
| aws_eip의 vpc 인수 제거 | domain 인수로 대체 | 오래된 EIP 코드 |
| 불리언 엄격화 | “1”, “0” 문자열을 불리언으로 인정하지 않음 | 초기 시절 작성된 레거시 코드 |
| Redshift 기본값 반전 | publicly_accessible 기본 false, encrypted 기본 true | 인수를 생략한 Redshift 코드에 diff 발생 |
가장 큰 구조 변화는 리소스 단위 region입니다. 지금까지 멀티 리전은 리전마다 provider alias를 만들어 리소스에 붙이는 방식이었는데(실전 #10의 ACM·CloudFront 구성이 그 패턴입니다), 6.x부터는 리소스에 region을 직접 지정할 수 있습니다. 기존 alias 코드는 그대로 동작하므로 업그레이드를 막지는 않지만, 새로 설계하는 스택에서는 alias 수를 줄일 수 있는 선택지가 생겼습니다.
기본값 반전 유형은 조용해서 더 위험합니다. Redshift처럼 인수를 생략했던 코드는 6.x에서 새 기본값과의 차이가 diff로 나타나는데, 이것은 “코드에 의도를 명시하라"는 신호로 읽고 인수를 명시적으로 적어 diff를 없애는 것이 정석입니다.
전환 순서: 5.x 최신 경유가 표준입니다 #
- 현재 5.x의 최신 마이너로 먼저 올립니다: 메이저 직전 버전은 다음 메이저에서 제거될 기능에 deprecation 경고를 냅니다. 이 경고를 먼저 소진하면 6.0 전환에서 만날 깨짐의 대부분이 미리 드러납니다.
- 업그레이드 가이드를 자기 코드와 대조합니다: 위 표 같은 변경 목록을
grep으로 자기 리포지토리에 돌려, 걸리는 리소스·인수를 사전에 수정합니다. - 버전 제약과 잠금 파일을 갱신합니다: required_providers를
~> 6.0으로 바꾸고terraform init -upgrade로 잠금 파일을 갱신합니다. 이 변경은 CLI 업그레이드와 분리된 단독 PR로 만듭니다. - plan을 전수 판독합니다: 통과 기준은 no-op이 이상적이지만, 메이저에서는 “설명 가능한 diff"까지가 허용선입니다. 스키마 정리로 인한 in-place 변경(~ 표시)은 대체로 무해하고, forces replacement가 붙은 항목은 전부 원인을 규명할 때까지 apply하지 않습니다. 특히 데이터 계층 리소스의 교체 판정은 중단 사유입니다.
- 스택별로 점진 적용합니다: 개발 스택에서 apply까지 완주해 실물 영향을 확인한 뒤 프로덕션으로 갑니다. 전 스택이 한 번에 넘어갈 필요는 없지만, 신구 버전 혼재 기간은 짧게 끊습니다.
공유 모듈의 하한: 발목을 잡는 쪽 #
여러 스택이 공유하는 사내 모듈이나 레지스트리 모듈이 있으면 변수 하나가 더 생깁니다. 모듈의 required_providers가 >= 5.0, < 6.0처럼 상한을 걸어 두었다면, 루트가 6.x로 가고 싶어도 모듈이 막습니다. 반대로 모듈이 6.x 전용 문법(리소스 region 등)을 쓰기 시작하면 5.x에 남은 스택이 그 모듈을 못 씁니다.
순서는 모듈이 먼저입니다. 모듈의 provider 제약을 6.x 호환으로 넓히고(가능하면 >= 5.x, < 7.0처럼 과도기 겸용), 루트 스택들이 순차로 넘어간 뒤, 전환이 끝나면 모듈 하한을 6.x로 올려 정리합니다. 서드파티 모듈이 5.x에 고정되어 있다면 그 모듈의 업스트림 대응 여부가 업그레이드 일정 전체의 제약이 되므로, 대조 단계에서 가장 먼저 확인할 항목입니다.
정리 #
- provider 메이저는 스키마를 깨는 릴리스입니다. 코드를 안 바꿔도 diff가 나오고, 그중 교체 판정이 섞일 수 있어 plan 전수 판독이 필수입니다.
- 표준 수순은 5.x 최신 경유입니다. deprecation 경고를 먼저 소진하면 6.0에서 만날 깨짐이 미리 드러납니다.
- 6.0의 핵심 변경은 리소스 단위 region, OpsWorks·SimpleDB 제거, 불리언 엄격화, Redshift 기본값 반전입니다. 기본값 반전은 인수 명시로 diff를 지웁니다.
- 판독 기준: in-place 변경은 대체로 무해, forces replacement는 전건 규명 전 apply 금지, 데이터 계층 교체 판정은 중단 사유입니다.
- 공유 모듈의 provider 제약이 일정의 병목입니다. 모듈 호환을 먼저 넓히고 루트를 옮긴 뒤 하한을 정리하는 순서로 갑니다.