Infrastructure as Workflow: 정적인 Terraform을 넘어서

SchemaBridge Team · 2026-01-18 · IaC, DevOps, Cloud Automation

Day 2 클라우드 운영 관리하기. 인프라를 상태를 가진 장기 실행 비즈니스 프로세스로 다루기.

"Infrastructure as Code"의 한계: Day 1 대 Day 2

우리는 Terraform(IaC)을 좋아합니다. Terraform은 "Day 1" 프로비저닝 문제를 해결했습니다. 원하는 상태(EC2 인스턴스 10개, RDS 1개, VPC 1개)를 기술하고 terraform apply를 실행하면 클라우드 제공업체가 그대로 만들어 줍니다. 정적인 리소스에는 완벽합니다. 선언적이고, 멱등적이며, 버전 관리됩니다. 현대 DevOps의 기반입니다.

하지만 클라우드 운영의 현실은 복잡성이 Day 2에 있다는 것입니다. Day 1이 결혼식이라면 Day 2는 결혼 생활입니다. Day 2는 리소스만이 아니라 프로세스에 관한 것입니다. 시간에 따라 변화하는 시스템의 살아 있는 라이프사이클에 관한 것입니다.

중요한 데이터베이스 업그레이드의 라이프사이클을 생각해 봅시다. 이는 정적인 이벤트가 아니라 워크플로입니다.

1. 준비: 안전을 위해 기본 DB의 스냅샷을 S3에 생성합니다.

2. 대기: 스냅샷이 완료될 때까지 기다려야 합니다. 수 TB 규모의 대형 데이터베이스라면 30~45분이 걸릴 수 있습니다.

3. 프로비저닝: 새 엔진 버전을 사용해 스냅샷에서 새 DB 인스턴스를 띄웁니다.

4. 대기: 새 인스턴스가 "Available"과 "Healthy" 상태가 될 때까지 기다립니다.

5. 마이그레이션: 새 인스턴스에 연결해 스키마 마이그레이션 스크립트(Flyway 또는 Liquibase)를 실행합니다. 1시간이 걸릴 수 있습니다.

6. 검증: 데이터 무결성을 확인하기 위해 새 DB를 대상으로 일련의 스모크 테스트를 실행합니다.

7. 전환: 성공하면 DNS CNAME이 새 DB를 가리키도록 업데이트합니다.

8. 롤백: 어느 단계든 실패하면 DNS를 되돌리고 문제가 있는 인스턴스를 제거해야 합니다.

Terraform은 이 일에 잘 맞지 않습니다. Terraform은 명령형이 아니라 선언형입니다. "30분 기다리기"나 "SQL 스크립트를 실행하고 종료 코드 확인하기"를 위한 탈출구로 time_sleep과 local-exec 프로비저너가 있지만, Terraform에는 영속적이고 재개 가능하며 승인으로 제어되는 프로세스 모델이 없습니다. 이를 처리하기 위해 팀들은 보통 Terraform을 Jenkins 파이프라인, CircleCI 잡, Python 스크립트로 감쌉니다. 이 시리즈 앞부분에서 다룬 "Glue Code Crisis"로 되돌아가는 셈인데, 이번에는 인프라 버전입니다. 이런 스크립트는 깨지기 쉽고, 상태가 없으며, 4시간짜리 작업 중간에 실패하면 디버깅이 불가능합니다.

운영을 내구성 있는 워크플로로 다루기

SchemaBridge는 인프라 운영이 곧 비즈니스 워크플로라고 믿습니다. 인프라 운영에는 결제 처리 흐름과 같은 요구사항이 있습니다. 신뢰성, 감사 가능성, 상태 관리, 오류 복구입니다.

Day 2 운영을 SchemaBridge로 옮기면 클라우드를 위한 내구성 있는 오케스트레이터의 힘을 얻게 됩니다.

"컨트롤 플레인" 패턴: AWS, K8s, Terraform과의 통합

SchemaBridge는 Terraform을 대체하지 않고 오케스트레이션합니다. 정적인 세계와 동적인 세계를 통합하기 위해 컨트롤 플레인 패턴을 사용합니다.

1. 트리거: 개발자가 코드를 커밋하거나, 개발자 포털에서 워크플로의 웹훅 URL을 호출해 "Provision Dev Env" 워크플로를 시작합니다.

2. 프로비저닝: SchemaBridge가 Terraform Cloud API(또는 자체 러너의 HTTP 엔드포인트)를 호출해 물리 리소스를 생성하는 실행을 시작합니다. SchemaBridge가 직접 셸로 terraform을 실행하지는 않습니다. 워크플로 스크립트는 설계상 프로세스나 파일 시스템에 접근할 수 없는 GraalVM 샌드박스에서 실행됩니다.

3. 대기: 내구성 있는 Delay 단계가 대기한 다음, Gateway 단계가 Terraform 실행 상태를 확인합니다. 워크플로는 비순환 그래프이므로 무한 폴링 루프 대신 제한된 수의 대기-확인 단계를 연결하거나, Delay 후 워크플로가 자기 자신을 다시 생성(re-spawn)하도록 합니다 — 저희의 점진적 롤아웃 시스템 워크플로가 사용하는 것과 같은 재귀입니다.

4. 프로비저닝 후 처리("로직 계층"): 인프라가 생성되면 SchemaBridge는 DB 마이그레이션 실행, 테스트 데이터 적재, 인수 테스트 시작을 담당하는 엔드포인트를 호출합니다 — CI 시스템의 API나, 새 클러스터 안에서 여러분이 관리하는 작은 운영 서비스입니다.

이 패턴을 사용하면 리소스는 HCL(HashiCorp Configuration Language)로 정의하면서, 운영 로직은 시각적 그래프로 정의할 수 있습니다.

임시 환경: 개발 속도의 성배

모든 현대적인 엔지니어링 팀은 임시(ephemeral) 환경 — 모든 Pull Request(PR)마다 프로덕션의 완전한 복제본 — 을 원합니다. 이를 통해 진정한 격리가 가능해지고, 버그가 main에 병합되기 전에 막을 수 있습니다.

기존 접근 방식은 정리가 어렵기 때문에 실패합니다. PR-123을 위해 리소스를 띄웠지만, 개발자가 PR을 닫는 것을 잊거나 정리 스크립트가 실패합니다. 클라우드 청구서는 "좀비 RDS 인스턴스"와 "고아 로드 밸런서"로 폭증합니다.

SchemaBridge에서 환경은 정의된 라이프사이클을 가진 워크플로입니다.

1. 시작: 프로비저닝 API를 통해 리소스(RDS, 캐시, ECS 서비스)를 띄웁니다.

2. 대기: 내구성 있는 Delay 단계가 생성 시점에 해체를 예약합니다 — 예를 들어 24시간 TTL입니다. 대기 중에는 워커나 컨테이너를 점유하지 않으며, 깨어날 시각은 영속화됩니다.

3. 정리: 타이머가 만료되면 워크플로가 깨어나 프로비저닝 API를 호출해 환경을 제거합니다. "PR이 병합되자마자 해체"하려면 Git 제공업체의 병합 웹훅을 별도의 해체 워크플로로 향하게 하고, 둘 다 실행되어도 문제가 없도록 해체를 멱등적으로 만드세요.

해체 타이머는 환경을 만든 바로 그 실행 안에서 예약되므로 잊기 어렵습니다. SchemaBridge 클러스터 전체가 재시작되더라도 영속화된 타이머는 여전히 실행되고, PR-123의 환경은 일정대로 제거됩니다. 이것이 "클라우드를 위한 가비지 컬렉션"입니다.

예시 시나리오: 지연 시간에 민감한 서비스를 위한 무개입 Blue/Green 배포

지연 시간에 민감한 매칭 엔진을 운영하면서, 단 1마이크로초의 다운타임도 없이 핵심 서비스를 업데이트해야 하는 팀을 생각해 봅시다.

과제

트래픽을 전환하기 전에 새 버전의 정확성을 실시간 데이터로 10분간 검증해야 한다면, 표준 Kubernetes 롤링 업데이트는 충분히 안전하지 않습니다. 복잡한 "Shadow Mode" 배포가 필요할 것입니다.

SchemaBridge 접근 방식

팀은 SchemaBridge에서 "Blue/Green Deployment Workflow"를 구축할 수 있습니다.

1. Green 배포: 새 버전의 엔진을 기존 버전과 나란히 띄웁니다(Green).

2. 섀도 트래픽: API Gateway를 구성해 실시간 트래픽의 일반 사본을 Green으로 보냅니다(fire-and-forget). Green의 응답은 사용자에게 전달되지 않고 수집됩니다.

3. 검증: 10분의 Delay 후, 워크플로는 HTTP로 Green의 수집된 응답과 그에 대응하는 Blue(운영 중) 응답의 샘플을 가져와 JSONata로 비교합니다.

4. 판단 지점: 조건부 엣지가 비교 결과에 따라 라우팅합니다.

5. 전환: 워크플로가 로드 밸런서를 업데이트해 실제 사용자 트래픽을 Green으로 전환합니다.

6. 정리: 한 시간을 더 기다린 뒤(손쉬운 롤백을 위해) Blue를 제거합니다.

결과

이런 워크플로는 배포 위험을 상당히 줄일 수 있습니다. SRE 팀은 배포를 시작한 뒤 자리를 떠날 수 있고, 워크플로가 자신들이 설계한 검증과 명시적인 정리 경로를 실행할 것임을 알고 있습니다 — 위험하고 드문 릴리스를 더 안전하고 일상적인 릴리스로 바꾸는 것입니다.

비용 관리: FinOps의 "워크플로"

클라우드 비용 최적화(FinOps)는 흔히 개발자들에게 리소스를 끄라고 계속 독촉하는 수작업 프로세스입니다. SchemaBridge를 사용하면 이 거버넌스를 자동화할 수 있습니다.

Night Watchman 패턴

매일 저녁 8시에 실행되는 "Night Watchman" 워크플로를 배포할 수 있습니다.

1. 스캔: 운영 API(예: 클라우드 SDK를 감싼 작은 Lambda나 내부 서비스)에 비프로덕션 태그가 붙은 모든 리소스를 요청합니다. SchemaBridge는 HTTP로 이와 통신하며, 네이티브 AWS 커넥터는 없습니다.

2. 활동 확인: 같은 엔드포인트가 지난 1시간의 CPU 사용률을 보고하게 하고, 5% 미만인 리소스만 남깁니다.

3. 중지: 유휴 상태라면 엔드포인트를 호출해 인스턴스를 중지합니다(종료하지 않습니다).

4. 알림: 소유자에게 Slack 메시지를 보냅니다: "비용 절감을 위해 개발 머신을 일시 중지했습니다."

5. 재개: 운영 도구에서 웹훅 URL로 트리거되는 별도의 "start my box" 워크플로가 아침에 인스턴스를 다시 시작합니다.

이처럼 간단한 워크플로로 유휴 개발 환경 지출을 의미 있게 줄이고, 잊힌 채 항상 켜져 있는 비프로덕션 리소스의 지속적인 비용을 절감할 수 있습니다.

비교: Jenkins/GitLab CI 대 SchemaBridge 운영

| 기능 | CI/CD 파이프라인(Jenkins) | SchemaBridge 운영 |

| :--- | :--- | :--- |

| 상태 | 실행기에 묶임. 긴 대기 동안 리소스를 점유 | 내구성 있음(PostgreSQL에 영속화, 재시작에도 유지) |

| 기간 | 분/시간 | 시간/일(내구성 있는 타이머) |

| 로직 | 스크립트(Bash/Groovy) | 시각적(그래프) |

| 승인 | 파이프라인의 input 단계 | Approval 단계(UI 또는 API), 타임아웃 포함 |

| 복구 | 스테이지부터 재시작 | 실패한 단계부터 재시도 |

| 병렬성 | 실행기 수에 제한됨 | 자동 확장되는 워커를 통한 팬아웃(Spawner) |

운영 자동화를 위한 전문가 체크리스트

운영 스택을 현대화하려면 다음 휴리스틱을 따르세요.

1. 대기를 스크립트로 작성하지 마세요: ALB를 기다리려고 bash에 sleep 60을 쓰고 있다면 잘못하고 있는 것입니다. 내구성 있는 Delay 단계와 그 뒤의 상태 확인을 사용하세요.

2. 삭제부터 자동화하세요: 생성 로직 이전에 정리 로직을 작성하세요. 모든 생성 이벤트에 대응하는 제거 경로가 있는지 확인하세요.

3. 승인 게이트를 사용하세요: 위험도가 높은 작업에는 주저하지 말고 사람을 루프에 넣으세요. "Pause for Approval"은 버그가 아니라 기능입니다.

4. 운영자를 감사하세요: 누가 환경을 트리거했고 왜 그랬는지 기록하세요. 트리거가 요청자의 ID를 페이로드에 담아 전달하게 하고, 생성하는 모든 리소스에 그 ID를 기록하세요.

5. 운영을 코드로 다루세요: 운영 워크플로를 애플리케이션 코드처럼 버전 관리하세요. 번들로 내보내 리뷰를 위해 저장소에 보관하고, Deployments 페이지(계획, 검토, 적용)나 구성 가져오기로 배포하세요.

결론: 클라우드는 상태 머신이다

여러분의 인프라는 정적인 서버 더미가 아니라, 비즈니스의 살아 있는 구성 요소입니다. 이를 상태 머신으로 다루면, 지금 SRE 팀의 시간을 잡아먹고 있는 복잡한 다단계 운영 절차를 자동화할 수 있습니다. 안전성과 내구성을 갖춘 채로 "티켓 기반 운영"에서 "셀프서비스 운영"으로 나아갈 수 있습니다.

함께 읽기: 콜드 스타트 신화: 이벤트를 위한 JVM 최적화 — 오래 실행되는 워커가 이벤트별 콜드 스타트보다 나은 이유.

살펴보기