When Plans Got Slow, People Started Skipping Them
한국어 원문으로 표시합니다.
목표
300 개짜리 상태를 만들어 계획 시간을 직접 재고, 새로 고침·병렬도·대상 좁히기·상태 나누기 네 손잡이가 시간과 계획 내용을 각각 어떻게 바꾸는지 저장된 계획으로 확인한 뒤, 측정 기록을 표와 결론으로 남깁니다.
왜 중요한가
계획이 느려지는 것은 불편함이 아니라 안전 문제입니다. 3분을 기다려야 하면 사람들은 작은 변경에서 계획을 건너뛰고, 그 순간 '적용 전에 무엇이 바뀌는지 본다' 는 규율이 사라집니다. 그런데 느린 계획을 다루는 손잡이는 모두 무언가를 대가로 냅니다. 새로 고침을 끄면 밖에서 생긴 변화를 못 보고, 대상을 좁히면 그 계획은 설정 전체를 대표하지 못하고, 상태를 나누면 층 사이를 출력으로 이어야 합니다. 그래서 순서가 중요합니다 — 먼저 재고, 무엇이 시간을 먹는지 확인한 다음, 잃어도 되는 것을 골라 손잡이를 당깁니다. 이 실습의 절대 시간은 실제 클라우드와 다릅니다(이 파드의 프로바이더는 원격 호출이 없습니다). 배우는 것은 숫자가 아니라 재는 방법과, 각 손잡이가 계획의 내용을 어떻게 바꾸는가입니다.
단계
/root/tfa-perf/main.tf에var.size만큼의random_pet.n과, 각각의 이름을/root/tfa-perf/out/<인덱스>.txt에 쓰는local_file.n을count로 선언하세요./root/tfa-perf/terraform.tfvars에size = 150을 두고 init·apply 합니다. 상태에는 인스턴스가 300 개 들어갑니다./root/tfa-perf/measure.sh를 만드세요. 첫 인자를 이름표로 받고 나머지 인자를tofu plan에 그대로 넘겨 걸린 시간을 밀리초로 재고, 계획은/root/tfa-perf/plans/<이름표>.tfplan에, 출력은/root/tfa-perf/plans/<이름표>.log에 저장하고,/root/tfa-perf/times.tsv에<이름표>·<밀리초>·<실행한 명령>세 칸을 탭으로 적습니다. 같은 이름표를 다시 재면 줄이 늘지 않고 바뀌어야 합니다. 그다음 아무 옵션 없이full이라는 이름표로 한 번 재세요./root/tfa-perf/out/7.txt를 도구 밖에서 지워 드리프트를 만든 뒤,no-refresh이름표로-refresh=false를 붙여 재고, 이어서refresh이름표로 옵션 없이 재세요. 두 계획 파일에 담긴 변경 수가 달라야 합니다. 마지막으로 apply 해서 지운 파일을 되돌립니다.par1이름표로-parallelism=1을 붙여 재세요. 저장된 계획에 담긴 변경 항목 수가full과 같아야 합니다.target이름표로-target=random_pet.n[0]을 붙여 재세요. 저장된 계획에는 항목이 몇 개 안 남아야 하고,/root/tfa-perf/plans/target.log에는 도구가 낸 경고가 들어 있어야 합니다./root/tfa-perf/split/a와/root/tfa-perf/split/b에 같은 설정을 두고 각각size = 75로 init·apply 하세요(합치면 처음과 같은 300 개입니다). 그다음 각 디렉터리에서/root/tfa-perf/measure.sh를split-a·split-b이름표로 한 번씩 돌리세요.stale이름표로 계획 하나를 저장한 뒤,/root/tfa-perf에서tofu apply -replace=random_pet.n[0] -auto-approve로 상태를 바꾸세요. 그다음 저장해 둔plans/stale.tfplan을 적용해 보고 그 출력을/root/tfa-perf/stale.txt에 저장합니다. 마지막에 계획은 깨끗해야 합니다./root/tfa-perf/report.md를 만드세요.| label | ms | command |머리글과 구분선으로 시작하는 표에times.tsv의 모든 줄을 이름표 순서로 넣고, 표 뒤에fastest: <가장 빠른 이름표>한 줄을 적습니다. 숫자는 지어내지 말고 times.tsv 에서 그대로 옮깁니다.
참고
- 파드에는 OpenTofu 1.9.0 과 local·random 프로바이더 미러가 있어 인터넷 없이 돕니다.
- 저장한 계획(-out)은 tofu show -json 으로 열어 변경 항목을 셀 수 있습니다. 시간과 달리 이 숫자는 기계가 달라도 같습니다.
- 흔한 실수: 측정 기록을 append 로만 쌓아 같은 이름표가 여러 줄이 되는 것. 나중에 어느 줄이 최신인지 알 수 없게 됩니다.
- 흔한 실수: 한 번 재고 결론 내리는 것. 첫 실행은 캐시가 비어 있어 느립니다 — 같은 이름표로 두 번 재고 두 번째를 쓰세요.
- Command: plan · Command: apply · Resource Addressing · terraform_remote_state
잴 만한 크기를 만든다
/root/tfa-perf/main.tf 에 var.size 만큼의 random_pet.n 과, 각각의 이름을 /root/tfa-perf/out/<인덱스>.txt 에 쓰는 local_file.n 을 count 로 선언하세요. /root/tfa-perf/terraform.tfvars 에 size = 150 을 두고 init·apply 합니다. 상태에는 인스턴스가 300 개 들어갑니다.
여기서 count 를 쓰는 이유는 인덱스로 서로를 참조해 두 리소스를 짝지어 늘리기 위해서입니다. 실제 인프라라면 이 300 개가 매번 원격 API 로 확인됩니다 — 그 확인이 계획 시간의 대부분입니다.
재는 도구를 먼저 만든다
/root/tfa-perf/measure.sh 를 만드세요. 첫 인자를 이름표로 받고 나머지 인자를 tofu plan 에 그대로 넘겨 걸린 시간을 밀리초로 재고, 계획은 /root/tfa-perf/plans/<이름표>.tfplan 에, 출력은 /root/tfa-perf/plans/<이름표>.log 에 저장하고, /root/tfa-perf/times.tsv 에 <이름표>·<밀리초>·<실행한 명령> 세 칸을 탭으로 적습니다. 같은 이름표를 다시 재면 줄이 늘지 않고 바뀌어야 합니다. 그다음 아무 옵션 없이 full 이라는 이름표로 한 번 재세요.
밀리초는 date 의 %s%3N 형식으로 얻습니다. 같은 이름표의 예전 줄을 지우고 새로 적으면 여러 번 재도 기록이 깨끗합니다 — 측정 기록이 append 로만 쌓이면 나중에 어느 줄이 최신인지 알 수 없습니다. 계획을 -out 으로 저장해 두는 이유는 나중에 '무엇이 들어 있었는지' 를 다시 볼 수 있어서입니다.
새로 고침을 끄면 무엇이 빨라지고 무엇을 잃나
/root/tfa-perf/out/7.txt 를 도구 밖에서 지워 드리프트를 만든 뒤, no-refresh 이름표로 -refresh=false 를 붙여 재고, 이어서 refresh 이름표로 옵션 없이 재세요. 두 계획 파일에 담긴 변경 수가 달라야 합니다. 마지막으로 apply 해서 지운 파일을 되돌립니다.
새로 고침은 상태에 적힌 것이 실제로 아직 그대로인지 하나씩 확인하는 일입니다. 끄면 그 확인을 통째로 건너뛰므로 빨라지지만, 밖에서 생긴 변화를 못 봅니다. 저장한 계획을 tofu show -json 으로 열어 변경 수를 세어 보세요.
병렬도를 낮추면 시간만 달라지고 결과는 같다
par1 이름표로 -parallelism=1 을 붙여 재세요. 저장된 계획에 담긴 변경 항목 수가 full 과 같아야 합니다.
병렬도는 도구가 동시에 몇 개의 작업(주로 원격 호출)을 진행할지 정하는 값입니다. 계획의 내용과는 무관해서 결과는 같고 시간만 달라집니다. 반대로 올리면 언제나 빨라지느냐 하면 그렇지 않습니다 — 상대 API 가 속도 제한을 걸면 재시도가 늘어 오히려 느려집니다.
대상을 좁히면 계획이 그만큼만 남는다
target 이름표로 -target=random_pet.n[0] 을 붙여 재세요. 저장된 계획에는 항목이 몇 개 안 남아야 하고, /root/tfa-perf/plans/target.log 에는 도구가 낸 경고가 들어 있어야 합니다.
대상을 좁히면 도구는 그 리소스와 그것이 의존하는 것만 계획에 넣습니다. 그래서 이 계획은 설정 전체를 대표하지 않고, 도구도 그 사실을 경고로 알려 줍니다. 공식 문서는 이 옵션을 실수 복구 같은 예외적인 상황에서만 쓰라고 적고 있습니다.
상태를 둘로 나눠 같은 수를 다시 잰다
/root/tfa-perf/split/a 와 /root/tfa-perf/split/b 에 같은 설정을 두고 각각 size = 75 로 init·apply 하세요(합치면 처음과 같은 300 개입니다). 그다음 각 디렉터리에서 /root/tfa-perf/measure.sh 를 split-a·split-b 이름표로 한 번씩 돌리세요.
measure.sh 는 자기가 놓인 위치를 기준으로 기록하므로, 어느 디렉터리에서 부르든 기록은 한곳에 모입니다. 나눈 뒤의 두 시간을 더하면 처음 하나보다 크더라도, 사람은 자기 상태 하나만 기다린다는 점이 핵심입니다 — 나누는 것은 전체 시간이 아니라 한 사람의 대기 시간을 줄입니다.
저장한 계획은 상태가 바뀌면 못 쓴다
stale 이름표로 계획 하나를 저장한 뒤, /root/tfa-perf 에서 tofu apply -replace=random_pet.n[0] -auto-approve 로 상태를 바꾸세요. 그다음 저장해 둔 plans/stale.tfplan 을 적용해 보고 그 출력을 /root/tfa-perf/stale.txt 에 저장합니다. 마지막에 계획은 깨끗해야 합니다.
저장한 계획은 '그때 그 상태에서 이 변경을 하겠다' 는 약속입니다. 상태가 그 뒤에 바뀌면 약속의 전제가 깨지므로 도구가 적용을 거절합니다. CI 에서 plan 과 apply 를 나눠 돌릴 때 이 규칙이 바로 안전장치가 됩니다.
측정 기록을 표로 정리하고 결론을 적는다
/root/tfa-perf/report.md 를 만드세요. | label | ms | command | 머리글과 구분선으로 시작하는 표에 times.tsv 의 모든 줄을 이름표 순서로 넣고, 표 뒤에 fastest: <가장 빠른 이름표> 한 줄을 적습니다. 숫자는 지어내지 말고 times.tsv 에서 그대로 옮깁니다.
결론 줄은 여러분이 잰 숫자에서 나와야 합니다 — 채점기도 times.tsv 를 읽어 같은 계산을 합니다. 어느 손잡이가 가장 크게 줄였는지는 기계마다 다를 수 있고, 그것이 바로 '재 보고 고르라' 는 말의 뜻입니다.