1편에서 말했듯, 이제 나는 인프라를 “PR 기반”으로 관리하고 있다.
그런데 여기서 자연스럽게 드는 질문이 있다.
“PR에서 terraform plan/apply는 누가 실행하지?”
당연하게 들리지만, 이 부분을 제대로 풀어내지 않으면 IaC는 금방 다시 ‘로컬 실행 지옥’으로 돌아간다.
기존 방식의 문제: 로컬 실행은 답이 아니다
초기에 나도 이렇게 했다:
terraform plan
terraform apply
그런데 팀이라면? 아니, 나 혼자인 경우에도 문제는 터진다:
- 각자 다른 Terraform 버전 → 미묘한 차이로 에러 발생
- 로컬 환경 의존성 → OS, CLI 설정, Provider 버전 차이
- State 파일 충돌 → “Lock 걸려있는데요?”
- 누가 apply 했는지 추적 어려움 → CloudTrail 뒤적이는 데 10분
- 배포가 GitHub Actions/PR 흐름과 따로 놀음
결론: PR 기반 인프라를 하고 싶다면 plan/apply도 PR에서 자동화되어야 한다.
여기서 Atlantis가 등장한다.
핵심 해결책: Atlantis
Atlantis는 PR 이벤트를 기반으로 Terraform을 자동 실행해주는 전용 서버다.
구조는 단순하다.
GitHub PR → Atlantis → Terraform → AWS
애매한 CI/CD 트릭 없이, Terraform 전용으로 설계된 워크플로우.
Atlantis가 어떻게 동작하나?
흐름은 이렇게 간단하다.
- PR 생성
- Atlantis가 자동으로 terraform plan 실행
- 결과를 PR 코멘트로 남김
- 리뷰어가 확인
- plan 정상인지, 보안/비용 문제 없는지 체크
- PR 코멘트로 명령
- Atlantis가 자동으로 terraform apply 실행
- 결과도 PR 코멘트로 돌아옴
- Merge
- 모든 변경이 Git 기록에 남고, 재현 가능
Atlantis 인프라 구조 (내가 구축한 구성)
GitHub (PR Webhook)
↓
Application Load Balancer (HTTPS, /events)
↓
ECS Fargate (Atlantis 서버)
↓
Terraform 실행
↓
AWS 리소스 변경
구성 요소 요약
- GitHub App – PR 이벤트를 Atlantis로 전달
- ALB + HTTPS – Webhook 트래픽 처리
- ECS Fargate – 서버리스로 Atlantis 컨테이너 실행
- EFS – Terraform plugin cache + lock 관리
- Secrets Manager – GitHub App 인증 정보 저장
한 번 구축해두면 거의 손댈 일 없다.
PR에 남는 실제 코멘트 예시
1. PR 생성 → 자동 Plan
**Atlantis Plan Results**
```diff
# aws_security_group_rule.api_https will be created
+ resource "aws_security_group_rule" "api_https" {
+ cidr_blocks = ["10.0.0.0/16"]
+ description = "Allow HTTPS from private subnet"
+ from_port = 443
+ to_port = 443
+ protocol = "tcp"
+ type = "ingress"
}
Plan: 1 to add, 0 to change, 0 to destroy.
```
**Validation**
- 보안 스캔: OK
- 비용 변화: +$0
- 정책 검증: OK
👉 적용하려면 코멘트: `atlantis apply`
2. Apply 실행 후
**Atlantis Apply Results**
```
aws_security_group_rule.api_https: Creating...
aws_security_group_rule.api_https: Creation complete after 2s
```
**Apply 완료!**
3. 오류 발생 시
Error: Invalid Security Group ID "sg-invalid"
❌ plan 실패. 변경 후 다시 push하세요.
이 코멘트 형식만으로도 리뷰·검증·적용·히스토리가 모두 해결된다.
Atlantis 설치 요약
너무 복잡해서 사람들이 기피하지만, 한번 만들어두면 끝이다.
Phase 1 — Terraform으로 Atlantis 인프라 배포
ECS, ALB, SG, EFS, CloudWatch Logs 자동 생성.
Phase 2 — GitHub App 설정
Webhook URL, Permission 설정.
Phase 3 — Secrets Manager
AppID / InstallationID / Private key 저장.
Phase 4 — ECS 재배포 + 테스트
테스트 PR 하나 올려서 plan/apply 확인.
총 12분이면 끝난다.
🛡️ 보안 포인트 (중요한 것만)
GitHub App 권한
- 필수: Contents / PR / Issues
- 절대 금지: Admin, Actions, Secrets
Secrets는 무조건 Secrets Manager
HCL에 토큰 박는 건 진짜 위험하다.
네트워크
- ECS Task → Private Subnet
- ALB만 Public
- Security Group으로 ALB → ECS만 허용
IAM 최소 권한
EC2/ELB/ECS 관련 Describe/Create 정도만 허용.
Action = "*" 는 즉시 아웃.
트러블슈팅(내가 실제 겪은 것들)
1. Atlantis가 PR에 코멘트를 안 남긴다
- GitHub App 설치 누락
- Webhook URL 오타
- ALB → ECS SG 미설정
- Private key 잘못 저장
2. plan은 되는데 apply는 안 된다
- apply_requirements 충족 안 됨 (approve 필요)
- Branch protection rule 충돌
- GitHub App Write 권한 부족
3. state lock 충돌
- 강제 unlock 필요할 때 있음 (주의)
4. apply에서 AWS 에러 발생
- IAM 권한 부족
- 리소스 이름 중복
- depends_on 필요
- Rate Limit
거의 여기서 다 걸린다.
실전 예시 – RDS 인스턴스 타입 변경
- instance_class = "db.t3.medium"
+ instance_class = "db.r6g.large"
PR 생성 → Atlantis plan 출력:
- RDS 변경 1건
- 비용: +$41.45 (57% 증가)
- 다운타임 예상: 1~2분
리뷰어 코멘트:
- “다운타임 있으니 새벽에 합시다.”
- “롤백 계획은 어떻게?”
- “Multi-AZ니까 문제 없어요.”
Modify complete after 2m15s
다음 글에서 다룰 내용
- 내가 사용하는 모듈 패턴
- tfsec / checkov / OPA / Infracost로 이루어진 PR 자동 검증 체계
'성장 스택' 카테고리의 다른 글
| AI 를 활용한 개발 (0) | 2025.10.16 |
|---|---|
| 무료 AI 리뷰를 TodoList로: 첫 오픈소스 기여 이야기 (0) | 2025.10.09 |
| AWS Console 클릭 대신 PR로 끝내는 루틴 – Terraform (1) (2) | 2025.08.27 |
| 2025년의 반년을 돌아보며 (0) | 2025.08.25 |
| 토스 Learner's High 1기 - 세션을 듣고 느낀점 (0) | 2024.12.22 |