LabHub
배우기 러닝패스 코스

Terraform 실전 · 계획 성능 — 재고 나서 고른다 · 이론

느린 계획을 다루는 네 손잡이와 그 대가

LabHub 에서 이어서 보기

한 줄 요약

계획 시간을 줄이는 손잡이는 네 개다 — 새로 고침 끄기·병렬도·대상 좁히기·상태 나누기. 넷 다 무언가를 대가로 내므로, 재 보고 나서 잃어도 되는 것을 골라야 한다.

왜 이게 문제인가 — 느린 계획은 안전 문제다

plan 이 3분 걸리기 시작하면 사람들의 행동이 바뀐다. 한 줄 고치고 3분을 기다리기 싫어서, "이건 뻔한 변경이니까" 하고 바로 apply 를 친다. 그 습관이 자리 잡으면 "적용 전에 무엇이 바뀌는지 본다" 는 규율 자체가 사라진다. 사고는 그다음에 난다.

그래서 계획 성능은 편의 문제가 아니라 규율을 지킬 수 있게 만드는 문제다. 다만 손잡이를 아무거나 당기면 안 된다. 각 손잡이가 정확히 무엇을 포기하는지 알아야 한다.

어떻게 동작하나

계획 한 번은 크게 세 가지 일을 한다. 설정을 읽어 그래프를 만들고(빠름), 상태에 적힌 것이 실제로 아직 그대로인지 하나씩 확인하고(대개 여기가 대부분), 그 결과와 설정을 비교해 변경 목록을 만든다(빠름). 큰 상태에서 느린 이유는 거의 언제나 가운데다.

1. 새로 고침 끄기. 가운데 단계를 통째로 건너뛴다. 가장 크게 줄지만, 밖에서 생긴 변화를 못 본다. 누가 콘솔에서 손으로 고쳐 놓았어도 계획은 "변경 없음" 이라고 말한다. 급히 되돌려야 하는 상황이나, 방금 직접 적용해 상태가 확실히 최신일 때만 쓸 값어치가 있다.

2. 병렬도. 동시에 진행하는 작업 수를 정한다. 계획의 내용은 전혀 바뀌지 않고 시간만 달라진다. 올리면 언제나 빨라지느냐 하면 아니다 — 상대 API 가 속도 제한을 걸면 재시도가 늘어 오히려 느려진다. 낮추는 쪽이 필요한 경우도 있다(제한이 빡빡한 API, 공용 계정).

3. 대상 좁히기. 지정한 주소와 그것이 의존하는 것만 계획에 넣는다. 확실히 빠르지만 그 계획은 설정 전체를 대표하지 않는다. 도구도 계획할 때마다 경고를 낸다. OpenTofu 문서는 이 옵션을 "실수에서 복구하거나 도구의 한계를 우회하는 예외적인 상황에서만" 쓰라고 적는다. 일상 작업에서 이것을 쓰고 있다면, 그건 성능 문제가 아니라 설계 문제라는 신호다.

4. 상태 나누기. 근본적인 해법이다. 매일 바뀌는 층과 거의 안 바뀌는 층을 다른 상태로 두면, 사람은 자기 층만 기다린다. 전체 시간의 합은 오히려 늘 수 있지만 한 사람의 대기 시간이 줄고, 덤으로 잠금 경합과 사고 반경도 줄어든다. 대가는 층 사이를 출력으로 이어야 한다는 것과, 그 연결이 계약이 된다는 것이다.

여기에 저장한 계획(-out)이 얹힌다. CI 에서 계획과 적용을 나눠 돌릴 때 쓰는데, 규칙이 하나 있다. 저장한 계획은 그때 그 상태를 전제로 한다. 그 사이 상태가 바뀌면 적용이 거절된다. 불편해 보이지만 이것이 바로 "리뷰한 그 계획이 적용된다" 를 보장하는 장치다.

현장에서 만나는 모습

가장 흔한 실수는 재지 않고 고르는 것이다. "느리니까 refresh 를 끄자" 로 시작해서, 반년 뒤 드리프트가 쌓인 채 아무도 모르는 상태가 된다. 재 보면 대개 원인이 더 구체적이다 — 특정 데이터 소스 하나가 매번 수천 건을 나열하고 있거나, 한 모듈이 상태의 절반을 차지하고 있다.

두 번째는 한 번 재고 결론 내리는 것이다. 첫 실행은 캐시가 비어 있어 느리다. 같은 조건으로 두 번 재고 두 번째 숫자를 쓰는 습관이 필요하다.

세 번째는 측정 기록을 쌓기만 하는 것이다. 같은 이름표가 여러 줄 쌓이면 나중에 어느 줄이 최신인지 알 수 없다. 기록도 멱등하게 — 같은 이름표는 덮어쓰게 만든다.

그리고 실무에서 자주 놓치는 사실 하나. 시간은 기계마다 다르지만 계획의 내용은 다르지 않다. 저장한 계획을 JSON 으로 열어 변경 항목 수를 세면, 어떤 기계에서 돌려도 같은 숫자가 나온다. 그래서 "대상을 좁히면 계획이 그만큼만 남는다", "새로 고침을 끄면 드리프트를 못 본다" 같은 주장은 시간이 아니라 이 숫자로 증명해야 한다.

네 번째로, 어디까지가 성능 문제이고 어디부터가 설계 문제인지를 가르는 기준이 있으면 대화가 쉬워진다. 손잡이 하나를 당겨 견딜 만해졌다면 성능 문제다. 일상 작업에서 대상을 좁혀야만 일이 되는 상태라면 그건 이미 설계 문제이고, 답은 옵션이 아니라 상태를 나누는 작업이다. 이 구분을 해 두지 않으면 팀은 임시 방편을 표준 절차로 굳히게 된다.

마지막으로 측정 자체의 비용을 잊지 말아야 한다. 계획을 열 번 재면 그만큼 시간이 든다. 그래서 실무에서는 바꾸기 전후 한 쌍만 재고 기록해 둔다. 기록에는 숫자뿐 아니라 그때 쓴 명령을 통째로 남긴다 — 반년 뒤에 "이 숫자는 어떤 조건에서 나온 것이냐" 를 묻게 되는데, 명령이 없으면 그 질문에 답할 수 없어서 다시 재는 수밖에 없다.

다음 실습에서 할 것

/root/tfa-perf 에 300 개짜리 상태를 만들고, 재는 스크립트를 먼저 만듭니다. 그다음 파일 하나를 도구 밖에서 지워 드리프트를 만들고 새로 고침을 껐을 때와 켰을 때 계획에 담긴 변경 수가 어떻게 달라지는지 보고, 병렬도와 대상 좁히기를 재고, 상태를 둘로 나눠 다시 잽니다. 마지막으로 저장한 계획이 상태 변화로 거절되는 것을 확인하고, 잰 숫자를 표와 결론으로 남깁니다.