Terraform 1.17 베타: 대형 state의 minimal-refresh 검증과 적용

대형 state에서 minimal-refresh의 생략 조건과 원격 실행 제약을 검증하고, const 기반 provider 요구사항과 Terraform Policy 변경을 도입할 수 있다.

2026-10-07

느린 plan에서 먼저 확인할 것은 refresh의 선택 기준이다

대형 state의 refresh가 느리다고 parallelism을 올리면 provider의 rate limit에 부딪힐 수 있고, -refresh=false를 사용하면 일관성 문제가 생길 수 있다. state를 나누는 방법에도 부작용이 있다. 이 문제를 배경으로 구현된 -minimal-refresh는 저장된 state와 configuration을 이용해 변경이 제안되는 리소스만 선택적으로 refresh한다.

이 글의 버전 기준은 Terraform v1.17.0-beta2 (2026-09-23), v1.17.0-beta1 (2026-09-09), 현행 안정판 v1.16.4 (2026-09-23)이다. 여기서 안정판과 원격 실행 지원 상태는 2026-09-30에 수집된 자료를 기준으로 한다.

beta2 릴리스노트는 -minimal-refresh를 새로운 planning 옵션으로 소개한다. 실제 도입 판단에는 구현 PR #38953의 선택 기준까지 읽어야 한다. 변경 여부는 configuration의 텍스트 차이만으로 결정되지 않는다. provider가 plan 과정에서 의미 있는 변경인지 판단하므로, 공백 수정처럼 provider가 no-op으로 판단하는 수정은 refresh를 유발하지 않을 수 있다.

일반적인 리소스 인스턴스의 처리 흐름은 다음과 같다. 먼저 초기 plan을 만들고, 변경이 나오면 그 plan을 폐기한다. 이후 refresh를 수행하고 다시 plan한다. 변경이 나오지 않으면 refresh를 생략한다. 리소스 스키마 업그레이드는 항상 refresh하며, 후속 PR #39103은 identity 업그레이드도 강제 refresh 조건에 추가했다.

다음 그림은 일반적인 리소스 인스턴스에서 초기 plan이 refresh 여부를 가르는 경로와 업그레이드 예외를 보여 준다.

⤢✕예아니오없음있음리소스 인스턴스리소스 스키마 또는 identity업그레이드강제 refreshplan저장된 state와configuration으로 초기 plan변경 제안refresh 생략초기 plan 폐기refresh다시 plan

따라서 베타 검증에서는 단순히 configuration을 수정한 사례보다, provider가 실제 변경으로 판단하는 사례와 no-op으로 판단하는 사례를 구분해야 한다. 변경이 있는 리소스에는 초기 plan과 refresh 후 plan이 모두 수행된다. 자료에는 성능 수치가 없으므로, 대형 state라는 이유만으로 일정한 시간 단축을 기대할 근거는 없다. 팀의 state와 configuration으로 실행 시간을 비교하면서 선택 조건도 함께 확인해야 한다.

의존 관계와 삭제 계획을 별도로 검증한다

-minimal-refresh의 판단 단위는 리소스 인스턴스다. 어떤 리소스가 refresh됐다는 이유로 그 리소스에 의존하는 다른 리소스까지 refresh되지는 않는다. 의존 관계가 있는 configuration에서는 이 차이가 검증의 핵심이다.

예를 들어 의존 대상에 변경을 주는 검증 사례를 만들었다면, 그 대상의 refresh 여부와 의존하는 리소스의 refresh 여부를 각각 확인해야 한다. 둘이 함께 refresh될 것이라는 기대를 검증 기준으로 삼으면 구현의 의도와 어긋난다.

삭제를 다루는 경로에는 별도 규칙이 있다. -minimal-refresh를 사용하는 destroy plan과 deposed·orphaned 리소스는 refresh를 생략한다. 구현 PR은 이 경로에서 refresh 필요 여부를 가리킬 plan 신호가 없다고 설명한다. 해당 refresh는 이미 삭제된 리소스를 state에서 제거하는 역할을 할 수 있지만, 이 옵션은 최적화를 위해 생략을 선택한다.

검증 사례는 변경 유무만으로 나누지 말고 다음 경계까지 포함해야 한다.

검증 대상 refresh를 결정하는 근거 자료에 명시된 동작 확인할 내용
일반 리소스, 초기 plan에 변경 없음 저장된 state와 configuration의 초기 plan refresh 생략 provider가 no-op으로 판단한 수정에서도 생략되는가
일반 리소스, 초기 plan에 변경 있음 provider가 제안한 변경 초기 plan 폐기 후 refresh·재plan 최종 plan을 초기 plan과 혼동하지 않는가
다른 리소스에 의존하는 리소스 해당 인스턴스 자신의 plan 의존 대상의 refresh만으로는 refresh되지 않음 의존 관계를 refresh 전파 조건으로 가정하지 않았는가
리소스 스키마 업그레이드 state를 읽을 때 감지한 업그레이드 항상 refresh 업그레이드가 있는 사례를 별도로 확인했는가
identity 업그레이드 state를 읽을 때 감지한 업그레이드 refresh 수행 변경 없는 일반 사례와 구분했는가
destroy plan, deposed·orphaned 리소스 해당 경로의 생략 규칙 refresh 생략 삭제 계획에서 refresh를 기대하는 운영 절차가 있는가

이 옵션을 검증하면서 “변경 없음”을 외부 리소스와 저장된 state가 일치한다는 증거로 사용해서는 안 된다. refresh를 생략한 리소스의 초기 판단 근거는 저장된 state와 configuration이다. 변경 제안이 없는 사례에서 무엇을 확인했고 무엇을 읽지 않았는지까지 기록해야 검증 결과를 운영에 사용할 수 있다.

원격 실행 지원과 열린 PR의 제안을 구분한다

로컬 Core의 지원 여부와 HCP Terraform·Terraform Enterprise 원격 실행의 지원 여부는 별개다. 2026-09-30 기준 열린 상태인 PR #39310은 원격 실행이 현재 다음 오류로 -minimal-refresh를 거부한다고 설명한다.

Minimal refresh mode is currently not supported

원격 실행을 사용하는 팀은 이 오류를 configuration 문제로 보고 provider 요구사항부터 수정할 필요가 없다. 수집 자료 기준으로는 원격 실행 경로 자체의 제약이다. 로컬에서 옵션이 동작했다는 결과만으로 원격 실행 도입까지 승인할 수 없다.

PR #39310이 제안하는 변경은 cloud 블록과 기존 remote backend를 통해 옵션을 전달하는 것이다. -minimal-refresh를 요청하면 run 생성 옵션의 MinimalRefresh를 true로 설정하고, 요청하지 않으면 nil로 둔다.

서버의 TFP-API-Version 검사도 제안에 포함된다. 버전이 2.7 미만이거나 파싱할 수 없으면 run을 생성하기 전에 오류를 반환한다. 오래된 서버는 알 수 없는 run 속성을 조용히 버리기 때문에, 검사 없이 전달하면 사용자는 minimal refresh를 요청했는데 서버는 전체 refresh를 수행하는 상황이 생길 수 있다는 설명이다.

다음 그림은 수집 당시의 거부 동작과 열린 PR이 제안하는 전달 조건을 같은 축에서 비교한다.

⤢✕ 원격 minimal-refresh: 수집 당시 동작과 열린 PR의 제안 비교 축: 옵션 요청 시 동작 · 서버 조건 · run 생성 처리 2026-09-30 수집 당시 원격 실행 -minimal-refresh 요청 오류로 거부 "Minimal refresh mode is currently not supported" VS 열린 PR #39310의 제안 아직 머지되지 않은 제안 cloud 블록 · remote backend에서 옵션 전달 -minimal-refresh 요청 TFP-API-Version 2.7 이상 MinimalRefresh = true로 전달 2.7 미만 또는 파싱 불가 오류 반환 run 생성하지 않음 -minimal-refresh 요청하지 않음 별도 조건 MinimalRefresh = nil 점선 테두리 = 아직 머지되지 않은 제안 (열린 PR #39310) 비교 축 2026-09-30 수집 당시 원격 실행 열린 PR #39310의 제안 (미머지) 옵션 요청 시 동작 서버 조건 run 생성 처리 오류로 거부 "Minimal refresh mode is currently not supported" cloud 블록 · remote backend에서 옵션 전달 — TFP-API-Version 2.7 이상 → MinimalRefresh = true 2.7 미만 또는 파싱 불가 → 오류 반환 — 2.7 미만 또는 파싱 불가이면 run을 생성하지 않음 기준: 2026-09-30 수집 당시 원격 실행 · 열린 PR #39310 (미머지) | Terraform 1.17 베타: 대형 state의 minimal-refresh 검증과 적용

이 PR의 mock 테스트에는 옵션 전달, API 버전 거부, destroy·-target·-replace와의 조합이 포함돼 있다. 다만 본문의 수동 테스트 항목은 추가 예정으로 남아 있다. 따라서 이를 원격 환경에서의 검증 완료 근거로 삼지 말고, 향후 지원을 검증할 때 사용할 조건 목록으로 읽는 편이 맞다.

provider 요구사항은 plan 전에 결정할 수 있는 값으로 구성한다

dynamic provider sources 구현 PR #39153은 required_providers의 source와 version에서 const 변수와 locals를 참조하는 패턴을 제공한다.

terraform {
  required_providers {
    random = {
      source = "app.terraform.io/${var.organization}/random"
      version = local.random_version
    }
  }
}

variable "organization" {
  type  = string
  const = true
}

locals {
  random_version = "3.9.0"
}

이 예시에서 조직명은 const = true인 organization 변수로 받고, provider 버전은 local.random_version으로 지정한다. 3.9.0은 원문 예시에 사용된 값이다. 팀이 채택해야 할 버전을 추천하는 값으로 읽어서는 안 된다.

조직명처럼 실행 환경에 따라 바뀌는 provider source의 일부를 입력으로 분리하려면 이 패턴을 검증할 수 있다. 변수 값은 -var, -var-file, 환경변수 등 plan에서 지원하는 방식으로 전달할 수 있다.

제약은 값의 출처다. provider 요구사항에 참조하는 값은 plan 단계의 동적 결과에 의존할 수 없다. PR은 이를 dynamic module sources와 같은 제약이라고 명시한다. 변수나 local이라는 이름만 보고 허용 여부를 판단하지 말고, 그 값의 의존 경로를 확인해야 한다.

실무 검토에서는 required_providers.source와 required_providers.version에서 출발해 참조하는 변수와 local을 따라가면 된다. 위 예시의 조직명은 외부에서 전달하는 const 입력이고, 버전은 local에 직접 지정한 값이다. plan 결과가 있어야 결정되는 값을 provider 요구사항에 연결하는 설계는 이 기능으로 해결되지 않는다.

Policy GA 전환에서는 교체 작업의 평가 단위를 확인한다

beta2 릴리스노트는 Terraform Policy를 GA로 명시한다. plan, apply, query의 -policies는 실험 빌드나 -allow-experimental-features 없이 사용할 수 있다. 여기서 Policy의 GA 상태와 Terraform 1.17 릴리스 자체의 베타 상태를 구분해야 한다.

beta1 안내를 바탕으로 검증 항목을 작성했다면 명령 목록부터 수정해야 한다. beta1의 해당 문구에는 plan, apply, init이 있었지만, beta2 릴리스노트에는 plan, apply, query가 명시돼 있다.

기존 정책의 의미를 검증할 때는 교체 작업의 평가를 변경한 PR #38970을 확인해야 한다. 이전에는 CreateThenDelete와 DeleteThenCreate 같은 교체 작업을 하나의 UPDATE로 평가했다. 변경 후 policy engine에는 별도의 CREATE와 DELETE 평가가 전달된다. CREATE에는 새 속성값이, DELETE에는 이전 속성값이 들어간다. 이 동작은 plan과 apply에 모두 적용된다.

다음 그림은 교체 작업을 같은 입력으로 두고, policy engine이 받는 작업과 속성값의 차이를 비교한다.

⤢✕ 리소스 교체의 정책 평가 단위 변경 전후 비교 · 공통 입력: CreateThenDelete 또는 DeleteThenCreate인 리소스 교체 변경 전 리소스 교체 CreateThenDelete 또는 DeleteThenCreate UPDATE 평가 하나의 UPDATE 평가로 합쳐짐 VS 변경 후 plan · apply 모두 적용 리소스 교체 CreateThenDelete 또는 DeleteThenCreate CREATE 평가 새 속성값 전달 DELETE 평가 이전 속성값 전달 CREATE 평가와 DELETE 평가로 나뉨 예외 CreateThenForget CreateThenForget CREATE 평가만 전달 잊힌 인스턴스: 정책 관련 destroy 없음 Terraform 1.17 베타: 대형 state의 minimal-refresh 검증과 적용

기존에 교체를 UPDATE 조건으로만 다루던 정책은 재검증 대상이다. 같은 교체 계획을 두고 새 인스턴스의 생성 허용 여부와 기존 인스턴스의 삭제 허용 여부를 각각 확인해야 한다. CreateThenForget은 별도 사례로 둔다. 이 작업에는 정책 관련 destroy가 없으므로 CREATE 평가만 전달된다.

query 정책은 list 블록으로 발견한 리소스를 평가하고 사람이 읽을 수 있는 결과나 JSON 결과를 보고한다. 발견된 리소스의 평가에서 Unknown과 N/A 결과를 보고하는 수정도 릴리스노트에 포함돼 있다. query 결과를 소비하는 절차가 있다면 이 결과를 검증 사례에 넣어야 한다.

beta2에는 terraform query -policies에 디렉터리가 아닌 경로를 넘기면 policy engine에 전달하지 않고 거부하는 수정도 있다. 정책 경로 설정을 검증할 때 정상 디렉터리뿐 아니라 잘못된 경로에 대한 거부 동작까지 확인할 수 있다.

베타 검증 결과는 실행 시간과 동작 경계로 남긴다

대형 state에서의 도입 판단은 “plan이 빨라졌다”만으로 끝낼 수 없다. 팀의 검증 기록에는 실행 환경, 변경 없는 사례, 변경이 제안된 사례, 의존 관계, 업그레이드, 삭제 계획이 어떻게 처리됐는지가 함께 있어야 한다.

로컬 검증에서는 일반 plan과 -minimal-refresh를 사용하는 plan의 실행 시간을 비교하되, 어떤 리소스에서 refresh가 생략됐는지도 확인한다. 변경 리소스는 refresh 후 다시 plan하므로, 변경 없는 사례의 결과를 변경이 많은 사례에 그대로 적용하지 않는다.

원격 실행 팀은 수집 당시의 거부 동작을 별도 제약으로 기록한다. 열린 PR의 TFP-API-Version 조건이나 mock 테스트 결과를 현재 배포된 동작처럼 기록하면 검증 범위가 부풀려진다.

provider 요구사항과 정책 변경은 실행 시간과 분리해 판단한다. provider 입력은 plan의 동적 결과에 의존하지 않는지 확인하고, 정책은 교체 작업의 CREATE·DELETE 평가와 query의 경로 검증을 확인한다.

마지막으로 terraform version의 JSON을 읽는 자동화도 점검 대상이다. beta2에는 format_version 필드가 추가됐다. 릴리스노트는 기존 도구가 알 수 없는 필드를 무시한다는 가정을 밝히고, 향후 릴리스에서 format_version에 주의를 기울이거나 이를 처리하는 최신 hashicorp/terraform-json·hashicorp/terraform-exec 사용을 권고한다. JSON 소비 코드가 필드 집합을 고정해 검사한다면 새 필드를 포함한 출력으로 확인해야 한다.

이 범위를 검증하면 베타 도입 근거를 실행 시간의 변화, refresh 생략 경계, provider 입력 제약, 정책 평가 결과로 설명할 수 있다. 자료에 없는 성능 개선율이나 원격 지원 완료를 전제하지 않고도, 팀의 다음 적용 판단에 필요한 증거를 남길 수 있다.

TerraformIaCminimal-refreshProviderTerraform Policy