Terraform 도입기 (4): PR과 Plan으로 일하기
리뷰어가 코드가 아니라 Plan을 보고 승인하게 만든 과정과, Apply를 끝내 자동화하지 않은 이유.
시리즈 · Terraform 도입기4 / 5
- Terraform 도입기 (1): 콘솔로 만든 인프라를 코드로 옮기기로 했다
- Terraform 도입기 (2): 구조를 어떻게 잡았나
- Terraform 도입기 (3): 기존 인프라 옮기기
- Terraform 도입기 (4): PR과 Plan으로 일하기
- Terraform 도입기 (5): 15개월 회고
마이그레이션이 끝나자 저장소의 성격이 바뀌었다. 몰아서 작업하는 곳에서 여러 사람이 매일 조금씩 고치는 곳이 됐다. 이때부터는 코드를 어떻게 짜느냐보다 어떤 순서로 일하느냐가 더 중요해졌다.
변경 하나가 거치는 길
브랜치를 따서 코드를 고치고 PR을 올린다. 그러면 CI가 바뀐 스택에서 plan을 돌려 결과를 PR 댓글로 남긴다. 리뷰어가 그걸 읽고 승인하면 머지하고, 담당자가 apply한다.
여기서 제일 신경 쓴 건 리뷰어가 무엇을 보고 승인하느냐였다. 코드만 보고는 알 수 없는 게 많다. 한 줄 고쳤을 뿐인데 서버가 새로 만들어지는 경우가 있고, 그건 plan에 must be replaced라고 나와야 알 수 있다. 그래서 plan 결과가 PR에 붙어 있어야 했다.
Jenkins 콘솔이 아니라 PR 댓글로 남긴 것도 이유가 있다. 리뷰어가 다른 화면으로 넘어가지 않아도 되고, 무엇보다 PR이 그 변경의 기록으로 남는다. 반년 뒤에 “그때 정확히 뭐가 바뀌었지?“를 찾을 때 코드 diff와 plan이 한 페이지에 있다.
파이프라인을 만든 과정은 당시에 따로 적어 뒀다.
설계에서 정한 건 두 가지 정도다. plan은 PR 브랜치가 아니라 main에 머지된 결과를 기준으로 돌린다. 브랜치를 딴 뒤에 main이 바뀌었다면 브랜치 기준의 plan은 머지 후에 실제로 일어날 일과 다르기 때문이다. 그리고 전체가 아니라 바뀐 스택에서만 돌린다. 스택이 수십 개라 전부 돌리면 느리기도 하고, 관계없는 결과가 섞이면 정작 봐야 할 게 묻힌다.
브랜치 이름에 무슨 일이 일어나는지 적는다
브랜치와 커밋에는 접두사를 붙이기로 했다. create는 리소스 생성, fix는 수정, delete는 삭제, feat는 Terraform 자체의 변경이다. create/ec2-app_was-prod처럼 쓴다.
흔히 쓰는 커밋 규칙과 다른 점은 접두사가 코드가 아니라 인프라에 일어나는 일을 가리킨다는 것이다. PR 목록에서 delete로 시작하는 제목이 보이면 자연스럽게 더 꼼꼼히 보게 된다.
Apply는 사람이 한다
머지된다고 자동으로 적용되지 않는다. 담당자가 직접 apply를 실행한다. 자동으로 만들 수도 있었는데 일부러 안 했다.
PR에 달린 plan은 PR을 올린 시점의 결과다. 머지할 때는 실제 인프라가 달라져 있을 수 있다. 적용하는 사람이 그 자리에서 plan을 한 번 더 보고 yes를 누르는 게 마지막 확인이다. 그리고 적용 시점을 골라야 하는 변경이 있다. 인스턴스 타입을 바꾸거나 DB 설정을 고치는 일은 머지된 순간이 아니라 정해진 시간에 해야 한다. 마지막으로, apply는 중간에 실패할 수 있다. 그러면 절반만 적용된 상태가 되는데, 그 순간에는 누군가 터미널 앞에 있는 편이 낫다.
하루에 수십 건씩 변경이 나오는 조직이라면 다르게 판단했을 것이다. 우리 규모에서는 자동화로 아끼는 시간보다 사람이 한 번 더 보는 쪽이 값어치가 있었다.
대가는 있다. 머지와 적용 사이에 틈이 생긴다. 머지만 하고 적용을 잊으면 코드와 실제 인프라가 어긋나고, 다음 사람의 PR에 자기가 만들지도 않은 변경이 plan으로 뜬다. 실제로 몇 번 겪었고, 그때마다 sync라는 커밋으로 맞췄다. 이 방식의 약한 고리라는 건 알고 있다.