M15 ‐ IaC 업데이트 및 확장된 인프라 구조 문서화 - 100-hours-a-week/KTB4-4th-wiki GitHub Wiki

V2 IaC 도입

1. 도입 배경

V1에서는 하나의 EC2를 중심으로 서비스를 운영했기 때문에 AWS에서 관리해야 하는 인프라가 비교적 단순했다.

V2에서는 Frontend, Backend, AI Server가 각각 ECS Service로 분리되고, ALB, Service Connect, RDS, Redis, IAM, CloudWatch 등 관리해야 하는 AWS 리소스와 리소스 간 의존 관계가 증가한다.

또한 V2부터 Dev와 Production 환경을 별도로 운영한다. 두 환경은 동일한 서비스 연결 구조를 유지하되 Task 수, CPU / Memory, DB 사양 등 환경별로 필요한 값만 다르게 설정해야 한다.

이러한 환경을 AWS Console에서 각각 관리할 경우 설정 누락이나 환경 간 차이가 발생할 수 있으며, 인프라 변경 과정과 이력을 관리하기 어렵다.

따라서 V2부터 Infrastructure as Code(IaC)를 도입한다.


2. IaC 도입 목적

V2에서 IaC를 도입하는 목적은 다음과 같다.

  • Dev / Production의 동일한 인프라 구조 유지
  • 동일한 인프라 환경의 반복적인 재현
  • 수동 설정에 따른 구성 누락 및 오류 감소
  • Configuration Drift 관리
  • Git을 통한 인프라 변경 이력 관리
  • 적용 전 인프라 변경 사항 검토

인프라 설정을 코드로 관리하고 해당 코드를 실제 인프라 구성의 기준으로 사용한다.


3. IaC 도구 선정

V2의 IaC 도구로 Terraform을 사용한다.

Terraform, CloudFormation, AWS CDK 모두 V2에서 필요한 AWS 리소스를 관리할 수 있기 때문에 단순한 기능 지원 여부만으로 도구를 선정하지 않았다.

Need U에서는 IaC 도구를 선정할 때 다음을 주요 기준으로 두었다.

  • Dev / Production의 동일한 인프라 구조를 재사용할 수 있는가
  • 인프라 변경 내용을 적용 전에 확인하고 팀 단위로 검토할 수 있는가
  • IaC를 처음 도입하는 상황에서 리소스와 설정을 명확하게 관리할 수 있는가
  • V2 이후 인프라 구조가 변경되더라도 기존 IaC 운영 방식을 확장할 수 있는가

3.1 Terraform

Terraform은 공통 인프라를 Module로 구성하고 Dev / Production의 차이만 Variable로 분리할 수 있어, V2에서 Dev로 검증한 인프라 구성을 Production에 동일하게 적용하기 적합하다.

또한 terraform plan을 통해 실제 적용 전에 리소스의 생성·변경·삭제 범위를 확인할 수 있어, 2명의 Cloud 담당자가 Pull Request에서 인프라 변경 사항을 검토한 뒤 적용하는 방식과 잘 맞는다.

HCL을 통해 AWS 리소스와 설정을 선언적으로 관리하므로 IaC를 처음 도입하는 현재 단계에서 실제 인프라와 코드의 관계를 비교적 명확하게 파악할 수 있다.

추가로 Terraform은 Provider 기반으로 관리 대상을 확장할 수 있어, 향후 Kubernetes / Helm 또는 AWS 외부 리소스를 관리하게 되더라도 V2에서 구축한 Terraform 기반의 Plan / Apply 및 Git 관리 방식을 이어갈 수 있다.

3.2 CloudFormation

CloudFormation은 AWS Native 도구이므로 V2에서 사용하는 ECS, ALB, RDS, Redis, IAM 등의 리소스를 관리하기에 충분하며, 별도의 Terraform State를 관리하지 않아도 된다는 장점이 있다.

다만 AWS 리소스 관리에 특화되어 있어 향후 관리 대상이 Kubernetes, Helm 또는 AWS 외부 리소스로 확장될 경우 별도의 도구를 함께 운영해야 할 가능성이 있다.

Need U는 V2 구축뿐 아니라 이후 인프라 관리 범위가 변경될 가능성까지 고려하여 CloudFormation보다 Terraform을 선택하였다.

3.3 AWS CDK

AWS CDK는 TypeScript, Python 등의 프로그래밍 언어를 이용할 수 있어 반복되는 인프라 구성을 추상화하거나 복잡한 로직을 구성하는 데 장점이 있다.

반면 현재 Need U V2에서는 복잡한 인프라 로직을 구현하는 것보다 VPC, ALB, ECS, RDS 등의 리소스와 설정을 명시적으로 정의하고 관리하는 것이 우선이다.

또한 IaC를 처음 도입하는 단계이므로 프로그래밍 언어 기반의 추가적인 추상화보다는 실제 인프라 구성을 선언적으로 확인할 수 있는 Terraform HCL이 현재 운영 방식에 더 적합하다고 판단하였다.

3.4 최종 선정

따라서 Need U에서는 Dev / Production의 공통 인프라 재사용, Plan 기반의 변경 검토, 명시적인 리소스 관리를 V2에서의 주요 선정 기준으로 두고 Terraform을 선택하였다.

또한 향후 Kubernetes / Helm 등으로 인프라 관리 범위가 확대될 경우에도 동일한 IaC 도구와 운영 방식을 유지할 수 있다는 점을 추가적으로 고려하였다.

단, CloudFormation과 CDK가 V2 요구사항을 충족하지 못하기 때문에 제외한 것은 아니며, 현재 Need U의 인프라 운영 방식과 향후 확장 방향을 종합하여 Terraform이 가장 적합하다고 판단하였다.


4. Terraform 적용 범위

Terraform은 Application Version과 독립적으로 지속해서 유지되는 AWS Infrastructure를 관리한다.

주요 관리 대상은 다음과 같다.

  • VPC / Subnet / Route Table
  • Security Group
  • ALB / Listener / Target Group
  • ECS Cluster
  • ECS Service 기본 구성
  • Service Connect
  • RDS MySQL / PostgreSQL
  • Redis
  • IAM
  • Parameter Store 구조 및 접근 권한
  • CloudWatch
  • ECS Service Auto Scaling 정책
  • ECR

ECS Service Auto Scaling의 경우 Terraform이 실제 Task를 실시간으로 증감시키는 것이 아니라, Minimum / Maximum Task 수와 Scaling 정책을 정의한다. 실제 Task 수 조정은 ECS Service Auto Scaling이 수행한다.

Secret의 실제 값은 Terraform 코드에 저장하지 않으며 별도의 보호된 방식으로 관리한다.

Application Version과 관련된 Image Tag, Task Definition Revision 및 Application 배포는 Terraform에서 관리하지 않고 기존 Application CD에서 관리한다.


5. 환경 관리

Dev와 Production은 동일한 Terraform Module을 사용한다.

공통적인 인프라 구조는 Module로 관리하고 다음과 같이 환경에 따라 달라지는 값만 별도로 관리한다.

  • Task 수 및 Auto Scaling 범위
  • CPU / Memory
  • DB 사양
  • Domain
  • Parameter Store Path
  • Monitoring / Alarm 설정

이를 통해 Dev에서 검증한 인프라 구조를 Production에서도 동일하게 사용한다.


6. State 관리

Terraform State는 Local이 아닌 S3 Remote Backend를 사용한다.

Dev와 Production의 State는 S3 Bucket 단위로 분리한다.

하나의 S3 Bucket에서 Prefix와 IAM Policy를 이용해 환경별 접근 권한을 분리할 수도 있지만, IAM Policy 설정 오류가 Production State 접근으로 이어질 가능성을 줄이기 위해 Bucket 자체를 분리한다.

needu-terraform-state-dev
└── terraform.tfstate

needu-terraform-state-prod
└── terraform.tfstate

각 State Bucket에는 다음 설정을 적용한다.

  • S3 Versioning
  • Encryption
  • Public Access Block
  • State Locking
  • 최소 권한 IAM
  • State 파일 Git Commit 금지

환경별 Terraform Role의 접근 권한도 분리한다.

  • Dev Terraform Role → Dev State Bucket만 접근
  • Production Terraform Role → Production State Bucket만 접근

7. 적용 순서

기존 V1 Production 환경 전체를 처음부터 Terraform으로 전환하지 않는다.

새롭게 구축하는 V2 Dev 환경을 첫 IaC 적용 대상으로 한다.

적용 순서는 다음과 같다.

  1. Terraform Provider 및 Remote State 구성
  2. Network 구성
  3. Security Group / IAM 구성
  4. RDS / Redis 구성
  5. ALB / ECS / Service Connect 구성
  6. Parameter Store / CloudWatch 구성
  7. Dev 환경에서 전체 서비스 연결 검증
  8. Dev에서 검증한 Module을 이용해 Production 구성

기존에 생성된 AWS 리소스를 Terraform으로 관리해야 하는 경우에는 신규 생성 여부와 Import 여부를 먼저 결정하고 terraform plan을 통해 변경 내용을 확인한 후 적용한다.


8. 인프라 변경 관리

Terraform 코드를 실제 인프라 구성의 기준으로 관리한다.

Application CI/CD와 Infrastructure IaC Pipeline은 분리한다.

Application 코드의 Build 및 배포 과정에서는 Terraform을 실행하지 않으며, Terraform은 Infrastructure 코드가 변경되는 경우에만 실행한다.

8.1 Dev

Dev 환경에서는 초기 인프라 구축과 검증을 위해 Cloud 담당자의 Local 환경에서 Terraform 실행을 허용한다.

  1. Terraform 코드 수정
  2. terraform fmt
  3. terraform validate
  4. terraform plan
  5. 변경 내용 확인
  6. terraform apply

각 명령어의 역할은 다음과 같다.

명령어 역할
terraform fmt Terraform 코드 형식을 표준 형식으로 정리
terraform validate Terraform 구성의 문법 및 유효성 검사
terraform plan 실제 적용될 인프라 변경 사항 확인
terraform apply 변경 사항을 실제 Infrastructure에 적용

Local에서 변경하더라도 모든 변경 사항은 Terraform 코드에 반영하고 Git을 통해 관리한다.

8.2 Production

Production 환경은 Local에서 직접 terraform apply를 실행하지 않고 GitHub Actions + OIDC를 통해 적용한다.

Terraform 코드 변경
        ↓
Pull Request
        ↓
terraform fmt / validate
        ↓
terraform plan
        ↓
Plan 검토
        ↓
승인
        ↓
GitHub Actions + OIDC
        ↓
terraform apply
        ↓
Production

이를 통해 Production 변경은 개인 PC의 AWS Credential에 의존하지 않고, 검토 및 승인 이력이 남는 경로를 통해 수행한다.

긴급 대응을 위해 AWS Console에서 설정을 변경한 경우에도 이후 Terraform 코드에 동일한 내용을 반영하여 코드와 실제 인프라 상태를 일치시킨다.


9. Terraform 운영 정책

9.1 ECS Task Definition 및 Application 배포 관리

Terraform과 Application CD는 Infrastructure Lifecycle과 Application Release Lifecycle을 분리하여 관리한다.

V2에서는 Frontend, Backend, AI Server가 각각 독립적인 ECS Service로 운영되며, 각 Application의 코드와 Image Version은 서비스별 개발 및 배포 주기에 따라 변경된다.

Application Version 변경까지 Terraform에서 관리할 경우 각 서비스의 코드 배포마다 Terraform Plan / Apply가 필요해지고, Application 배포가 Infrastructure 변경 과정에 종속된다.

따라서 Infrastructure 변경은 Terraform이 관리하고, Application Version 변경 및 배포는 기존 Application CD가 관리한다.

Terraform 관리 범위

Terraform은 Application Version과 독립적으로 유지되는 ECS Infrastructure를 관리한다.

  • ECS Cluster
  • ECS Service 생성 및 기본 구성
  • Fargate Task CPU / Memory
  • Network Configuration
  • Load Balancer / Target Group 연결
  • Service Connect
  • ECS Service Auto Scaling 정책
  • Security Group
  • IAM

Application CD 관리 범위

Application Version 변경과 배포 과정은 기존 Application CD에서 관리한다.

  • Docker Image Build
  • ECR Push
  • Image Tag
  • ECS Task Definition Revision 등록
  • ECS Service가 참조하는 Task Definition Revision 업데이트
  • Deployment Health Check
  • Rollback

이를 통해 Frontend, Backend, AI Server의 Application 배포가 Terraform Apply에 종속되지 않고 각 서비스의 배포 주기에 따라 독립적으로 수행될 수 있도록 한다.

Terraform과 Application CD가 동일한 설정을 동시에 관리하지 않도록 관리 범위를 분리한다.

Application CD가 변경하는 Task Definition Revision은 Terraform의 변경 대상에서 분리하여, Application 배포 이후 Terraform Apply에 의해 이전 Task Definition Revision으로 되돌아가는 충돌이 발생하지 않도록 구성한다.

9.2 관리 원칙

최종적인 관리 주체는 다음과 같이 구분한다.

구분 관리 주체 관리 대상
Application CI GitHub Actions Test, Build, Docker Image Build, ECR Push
Application CD GitHub Actions Task Definition Revision, ECS Service 배포, Health Check, Rollback
Infrastructure Terraform VPC, ALB, ECS 기본 구성, RDS, Redis, IAM, Auto Scaling 정책 등
IaC Pipeline GitHub Actions fmt, validate, plan, 승인, apply

즉, Application 코드 변경은 Application CI/CD에서 처리하고 Infrastructure 변경이 발생하는 경우에만 Terraform을 실행한다.