큐레이션 요약
코드형 인프라(IaC)로 자동화에서 AI까지: OpenTofu와 ChatOps 도입기
LY Corporation의 LINE Plus SRE 팀은 운영 인프라를 콘솔·스크립트·문서가 아닌 OpenTofu와 Terragrunt 기반의 IaC로 통합했다. 약 1,500개 리소스를 GitOps 방식으로 관리하며, 모든 변경을 PR 리뷰와 CI/CD를 거치게 하고 실제 인프라와 코드의 차이도 자동 감지한다. 핵심은 기존 운영 리소스를 안전하게 import하고, 리소스별 특성과 의존 관계를 반영해 코드·state·실제 인프라를 일치시키는 것이다.
운영 규모 확대로 드러난 기존 방식의 한계
- 팀마다 Verda 대시보드, 자체 스크립트, 위키 매뉴얼 등 서로 다른 방식으로 인프라를 관리했다.
- 설정 정보도 위키, 개인 문서, GitHub 등 여러 곳에 분산되어 있었다.
- 서비스와 리소스가 늘어나면서 다음 문제가 누적됐다.
- 변경 이력과 변경 주체를 일관되게 추적하기 어려움
- 동일한 작업을 반복 수행할 때 실수 가능성 증가
- 환경별 설정 차이와 실제 인프라 상태를 파악하기 어려움
- 변경 전 검토와 변경 후 검증이 체계적이지 않음
- 이를 해결하기 위해 인프라의 원하는 상태를 코드로 선언하고, 변경을 자동화·표준화할 필요가 생겼다.
GitOps로 인프라를 애플리케이션 코드처럼 관리
- 인프라 설정을 Git 저장소에 선언하고 모든 변경을 PR로 진행한다.
- 코드 리뷰, CI/CD, 변경 이력 관리 등 애플리케이션 개발 방식을 인프라에도 적용한다.
- 콘솔에서 직접 클릭하거나 SSH로 수정하는 방식 대신 다음 흐름을 사용한다.
- Git에 코드 변경
- PR 리뷰
- CI/CD를 통한 plan 및 적용
- 실제 인프라와 선언된 상태의 차이 자동 감지
- IaC의 목표는 단순한 자동화가 아니라 인프라를 다음과 같은 엔지니어링 산출물로 만드는 것이다.
- 리뷰 가능
- 버전 관리 가능
- 재현 가능
- 변경 이력 추적 가능
OpenTofu와 Terragrunt 선택
- OpenTofu
- Terraform의 오픈소스 포크다.
- 기존 Terraform과 동일한 HCL 문법과 프로바이더 호환성을 유지한다.
- 기존 Terraform 기반 작성 방식과 모듈 구조를 재사용하기 쉬워 학습 비용이 낮다.
- 모듈화
- VM, 로드밸런서, 모니터링 알림 등을 공통 모듈로 분리했다.
- 팀별로 모듈에 입력값만 전달해 동일한 구조의 인프라를 생성할 수 있다.
- 모듈은 버전으로 관리하며, 새 버전은 필요한 환경에서만 명시적으로 올린다.
- Terragrunt
- OpenTofu의 환경 구성 중복을 줄이는 래퍼다.
- 공통 설정은 상위
root.hcl에 정의한다. - 각 환경에는 서로 다른 입력값만 남긴다.
- 결과적으로 OpenTofu 모듈은 리소스 정의 중복을, Terragrunt는 환경별 설정 중복을 줄였다.
기존 리소스의 단계적 IaC 전환
- 이미 운영 중인 약 300대의 VM, 160개의 LB, 350개의 DNS 레코드를 코드 관리 체계로 옮겨야 했다.
- 리소스를 하나씩 수동 import하면 시간이 오래 걸리고 실수 가능성이 높기 때문에 자동화된 import 스크립트를 작성했다.
- 전환은 두 단계로 진행했다.
- 1단계: 한 서비스를 선정해 import, 모듈, Terragrunt, CI/CD 전체 파이프라인을 검증
- 2단계: 검증된 모듈과 import 스크립트를 나머지 서비스에 확산
- 운영 중인 인프라에 영향을 주지 않는 것이 가장 중요한 원칙이었다.
import 스크립트의 표준 흐름
import 스크립트는 다음 과정을 공통 흐름으로 삼았다.
- 현재 클라우드 리소스를 조회한다.
- IaC로 관리할 대상과 제외할 대상을 구분한다.
- 모듈 구조에 맞게 설정을 변환하고 Terragrunt 파일을 생성한다.
- 실제 리소스를 OpenTofu state에 연결한다.
plan결과를 확인해 불필요한 변경이 없는지 검증한다.
특히 다음 세 요소를 일치시키는 데 집중했다.
- 코드에 선언된 값
- OpenTofu state 파일의 연결 정보
- 실제 클라우드 리소스의 상태
import 후 정규화와 가짜 변경 제거
- import를 완료해도 코드, state, 실제 리소스의 값 표현이 다르면
plan에서 계속 변경 사항이 나타날 수 있었다. - 예를 들어 네트워크 ID나 이미지 ID가 같은 대상을 가리키더라도 표현 방식이 다를 수 있다.
- 이를 방치하면
plan결과를 신뢰하기 어려워지므로 import 후 정규화 과정을 추가했다. - 정규화의 목적은 다음과 같다.
- 동일한 리소스를 표현하는 값의 형식 통일
- 불필요한 diff 제거
- 실제 변경과 표현 차이에 따른 가짜 변경 구분
리소스 특성에 따른 개별 import 전략
모든 리소스를 동일한 방식으로 가져올 수 없었기 때문에 리소스 유형과 의존 관계에 따라 import 단위를 달리했다.
- VM
- 개별 인스턴스를 기준으로 import한다.
- 로드밸런서
- LB뿐 아니라 리스너와 풀 등 함께 동작하는 하위 리소스를 고려한다.
- DNS
- 존과 레코드의 관계를 유지한다.
- 쿠버네티스
- 클러스터와 노드 풀을 어떤 단위로 관리할지 결정한다.
- IMON 알림
- 팀 → 알림 그룹 → 알림 규칙 → 알림 모니터의 계층 관계를 보존한다.
- IMON 리소스는 실제 구조와 유사하게 디렉터리를 구성해 소속 관계를 쉽게 확인할 수 있도록 했다.
운영 리소스와 자동 생성 리소스의 구분
- OpenStack에는 사람이 만든 VM과 쿠버네티스가 자동으로 만든 VM이 함께 존재했다.
- 두 리소스는 외형상 비슷하지만 관리 주체가 다르다.
- 쿠버네티스가 관리하는 VM까지 IaC로 가져오면 클러스터의 기대 상태와 OpenTofu 관리 상태가 충돌할 수 있다.
- 따라서 네이밍 패턴과 메타데이터를 기준으로 쿠버네티스 생성 VM을 import 대상에서 제외했다.
- 모든 리소스를 무조건 코드화하는 것이 아니라, 관리 주체와 생명주기를 먼저 판단하는 것이 중요했다.
프로바이더와 리전 차이 해결
- 실제 클라우드와 OpenTofu 프로바이더의 검증·백엔드 동작이 완전히 일치하지 않는 문제도 발견됐다.
- LB 이름의 하이픈·언더스코어 충돌
- 클라우드는
-와_를 모두 허용했다. - 그러나 프로바이더 백엔드의 검증 로직은
_를 허용하지 않았다. - 기존 LB를 import할 때 오류가 발생했다.
- 프로바이더의 validation 로직을 수정해 해결하고, 해당 변경을 프로바이더에 기여했다.
- 클라우드는
- 리전별 UUID 불일치
- 리전마다
flavor_id,image_id,network_id가 달랐다. - import 이후
plan에서 실제 변경이 아닌 불필요한 diff가 반복됐다. - 사용자는 사람이 읽기 쉬운 이름을 입력하고, 모듈이 리전별 실제 UUID로 변환하도록 매핑 로직을 추가했다.
- 이 방식으로 코드 가독성을 높이고 가짜 변경을 줄였다.
- 리전마다
실용적인 적용 시사점
- 기존 인프라를 IaC로 전환할 때는 단순히 import 명령을 실행하는 것보다 리소스 분류, 정규화, 의존 관계 분석이 중요하다.
- 먼저 하나의 서비스에서 전체 프로세스를 검증한 뒤 다른 서비스로 확산하는 방식이 안전하다.
- 자동 생성 리소스는 관리 주체가 다르므로 무조건 import하지 않아야 한다.
- 프로바이더가 실제 클라우드의 모든 기존 상태를 완벽히 표현하지 못할 수 있으므로, import 후 반드시
plan검증과 예외 처리가 필요하다. - 최종적으로 IaC의 효과는 코드 작성 자체보다 PR 리뷰, 자동 배포, 상태 차이 감지까지 포함한 운영 프로세스 전체를 표준화하는 데 있다.
관련 글
큐레이션 요약을 이어서 읽어보세요.