Skip to content
isdnetworks
Go back

인프라 정의에서 떼어 놓은 코드

(수정됨)

Terraform 정의 안에 애플리케이션 배포가 들어 있어서 코드를 고칠 때마다 인프라를 건드려야 했다. aws_instance 의 user_data 안에 git pull 과 빌드 명령이 박혀 있었기 때문이다.

Table of contents

Open Table of contents

원인 — 빈도가 다른 두 가지

코드를 배포하려면 terraform apply 로 인스턴스를 다시 만들어야 했고 배포 한 번에 몇 분이 걸리며 그동안 서비스가 끊겼다. 인프라 정의는 한 달에 한두 번 바뀌는데 애플리케이션은 하루에 몇 번 바뀐다.

빈도가 크게 다른 둘이 한자리에 있으니 자주 바뀌는 쪽에 맞춰 전부가 움직이고 있었다. 같이 두면 둘 다 어려워지므로 바뀌는 빈도로 나눴다.

해결 — 나눈 뒤의 배포

Terraform 에는 서버와 VPC 와 S3 와 IAM 을 두고 CodeDeploy 에는 코드 올리기와 composer install 과 migrate 를 뒀다. 배포할 때 인스턴스를 안 건드리게 되면서 시간이 몇 분에서 몇십 초로 줄었다.

경계가 애매한 것도 있었다. 두 가지 방법이 있었는데 데이터베이스 스키마를 인프라 쪽에 두는 것과 배포 쪽에 두는 것이다. 뒤쪽을 골랐다. 이유는 코드가 그 스키마를 전제하므로 코드와 같이 가야 해서다. 대신 migrate 실패가 배포 실패가 되어 롤백 절차에 스키마 되돌리기까지 들어가는 것을 감수했다.

주의 — 드러난 의존과 확인

나누고 나니 서로 의존하는 지점이 드러났다. Terraform 이 aws_security_group 에서 포트를 열고 CodeDeploy 가 그 포트로 붙는 구조라 인프라를 바꾸면서 포트를 닫으면 배포가 깨진다.

Terraform 이 그 값을 output "app_port" 로 내보내고 CodeDeploy 의 BeforeInstall 훅이 그 포트로 접속되는지 확인하게 했다. 나누기 전에는 안 보이던 의존이 나눈 뒤에 드러났고 그것을 확인 절차로 만든 것이 나눈 값이었다.

상태 파일과 드리프트

terraform.tfstate 는 S3 backend 에 두고 Terraform 공식 문서대로 dynamodb_table 을 지정해 상태 잠금을 걸어 두 사람이 동시에 바꾸는 것을 막았다. 상태 파일에 비밀 값이 들어갈 수 있어서 버킷 접근도 좁혔다.

terraform plan 으로 정의와 실제가 다른지도 주기적으로 확인했는데 손으로 추가한 보안 그룹 규칙이 나왔다. 정의에 없으므로 다음에 적용하면 사라질 것이라 필요한 것이면 정의에 넣고 아니면 지웠다.

판단 기준 — 되돌리기의 순서

나누고 나서 되돌리는 방법도 나뉘었다. 배포는 current 심링크를 옛 릴리스로 바꾸면 몇 초이고 인프라는 정의를 옛 커밋으로 되돌려 apply 해야 하므로 몇 분에서 수십 분이 걸린다.

무엇이 문제인지 먼저 갈라야 어느 쪽을 되돌릴지 정해진다. 배포 직후 문제면 배포를 먼저 되돌리고 인프라 변경 직후면 인프라를 보며 둘 다 최근이면 배포를 먼저 되돌린다. 배포를 먼저 되돌리는 것은 그쪽이 빠르고 위험이 적기 때문이다.

정리


Share this post on:

Previous Post
이미 두 겹이던 검증
Next Post
재생성을 막은 스킵 조건