WorkCASE STUDY 01INFRASTRUCTURE AS CODE

Terraform 기반 인프라 관리와 VPC 이관

기존 AWS 리소스를 Terraform 관리 체계로 편입하고, 환경·리전별 네트워크를 설계해 VPC 전체 이관을 완료했습니다.

주요 작업 기간
2024.12–2025.07
팀
FORCS - eformsign 인프라팀
역할
기획·아키텍처 설계·주요 기능 구현 주도

OUTCOME롤백 경험을 반영해 단계별 적용과 복구 절차를 보완하고, VPC 전체 이관을 완료했습니다.

인프라 관리
기존 리소스의 코드화
네트워크
환경·리전별 VPC 설계
이관
단계별 적용과 복구

배경과 역할

운영 중인 인프라를 이해하는 일부터 코드로 변경을 관리하는 방식까지 설계했습니다.

운영 환경을 코드로 관리

콘솔에서 구성한 AWS 리소스를 Terraform 관리 대상으로 옮겨, 실제 환경과 코드의 관계를 추적할 수 있도록 했습니다. 리소스를 새로 만드는 작업과 기존 리소스를 State에 편입하는 작업을 구분해 운영 환경에 적용했습니다.

설계부터 이관까지

환경·리전별 디렉터리와 모듈 구성, VPC와 연결 리소스의 변경 순서를 설계했습니다. 직접 구성 코드를 작성하고 이관 과정에서 발생한 문제를 분석해 적용·복구 절차에 반영했습니다.

환경과 네트워크 설계

환경과 리전을 기준으로 변경 범위를 나누고, 리소스 간 연결을 모듈 경계에 담았습니다.

환경·리전별 관리 단위

운영·테스트 환경과 리전별로 구성을 분리하고, VPC·컴퓨팅·데이터베이스 등 서비스 단위 모듈을 조합했습니다. 모듈 입력과 출력을 통해 리소스 간 의존성을 명시했습니다.

Public과 Private의 책임

외부 연결과 내부 서비스가 사용하는 네트워크 영역을 분리하고 Subnet, Route Table, Gateway와 보안 그룹을 함께 설계했습니다. 데이터베이스와 파일 스토리지의 연결 경로도 네트워크 이관 범위에 포함했습니다.

DIAGRAMTerraform 관리 범위와 VPC 계층

환경별 Terraform 모듈 구성

환경 루트에서 VPC·컴퓨팅·로드 밸런서·보안 그룹 모듈을 조합합니다. 공통 모듈과 환경별 설정을 분리해 변경 범위를 관리했습니다.

main.tfhcl
module "vpc" {
  source = "./modules/VPC"
}

module "ec2" {
  source = "./modules/EC2"
}

module "eb" {
  source = "./modules/EB"
}

module "elb" {
  source = "./modules/ELB"
}
# ... 다른 모듈 생략 ...
module "sg" {
  source       = "./modules/SG"
  cluster_name = var.cluster_name
}

핵심 구현

네트워크 구성과 Terraform State를 함께 관리해 반복 가능한 변경의 기반을 만들었습니다.

리소스 간 관계를 코드로 표현

Subnet과 라우팅, 보안 그룹을 별도 설정의 집합이 아닌 연결된 구성으로 작성했습니다. VPC 변경 시 영향을 받는 리소스를 모듈의 참조 관계를 따라 확인할 수 있도록 했습니다.

공유 State와 잠금

S3와 DynamoDB를 이용한 State 저장·잠금 구성을 작성했습니다. 여러 작업자가 같은 관리 단위를 수정할 때 변경이 겹치지 않도록 실행의 기준을 정리했습니다.

Terraform Seoul VPC·Public Subnet

VPC의 추가 CIDR과 Public Subnet을 선언하고 Kubernetes 로드 밸런서가 서브넷을 찾도록 태그를 설정했습니다. 네트워크 경계와 서비스 연결 조건을 코드에 함께 남겼습니다.

vpc.tfhcl
resource "aws_vpc" "eformsign-vpc" {
  assign_generated_ipv6_cidr_block = false
  cidr_block                       = "<CIDR>"
  enable_dns_support               = true
  enable_dns_hostnames             = true
  instance_tenancy                 = "default"
  tags = {
    Name = "<VPC_NAME>"
  }
}

resource "aws_vpc_ipv4_cidr_block_association" "secondary_cidr" {
  vpc_id     = aws_vpc.eformsign-vpc.id
  cidr_block = "<CIDR>"
}

resource "aws_vpc_ipv4_cidr_block_association" "third_cidr" {
  vpc_id     = aws_vpc.eformsign-vpc.id
  cidr_block = "<CIDR>"
}

# 퍼블릭 서브넷 4개 생성
resource "aws_subnet" "eformsign_public_subnet" {
  count                   = 4
  vpc_id                  = aws_vpc.eformsign-vpc.id
  cidr_block              = element(["<CIDR>", "<CIDR>", "<CIDR>", "<CIDR>"], count.index)
  availability_zone       = element(["<REGION>", "<REGION>", "<REGION>", "<REGION>"], count.index)
  map_public_ip_on_launch = true

  tags = {
    Name                     = "<SUBNET_NAME>-public${count.index + 1}-${element(["<REGION>", "<REGION>", "<REGION>", "<REGION>"], count.index)}",
    "kubernetes.io/role/elb" = "1"
  }
}

Terraform S3 State·DynamoDB Lock

S3 버전 관리로 이전 상태를 보존하고 DynamoDB 잠금으로 동시에 실행되는 변경을 제어했습니다. 상태 파일을 공유해도 작업자가 서로의 변경을 덮어쓰지 않도록 구성했습니다.

s3_dynamodb_setup.tfhcl
provider "aws" {
  profile = "prod"
  region = "<REGION>"
}

resource "aws_s3_bucket" "tfstate" {
  bucket = "<STATE_BUCKET>"
  versioning {
    enabled = true
  }

  tags = {
    Environment = "prod"
    Name        = "<STATE_BUCKET>"
  }
}
# ... S3 bucket policy와 중간 설정 생략 ...
resource "aws_dynamodb_table" "tfstate_locks" {
  name          = "<LOCK_TABLE>"
  billing_mode  = "PAY_PER_REQUEST"
  hash_key      = "LockID"

  attribute {
    name = "LockID"
    type = "S"
  }

  tags = {
    Environment = "prod"
    Name = "<LOCK_TABLE>"
  }
}

이관과 운영 흐름

기존 리소스 편입, 변경 검토, 단계별 적용과 서비스 확인을 하나의 절차로 구성했습니다.

Import에서 Plan까지

기존 리소스와 코드의 주소를 맞추고 State에 편입한 다음, Plan에서 변경·교체·삭제 대상을 확인했습니다. 운영 리소스의 불필요한 재생성을 피하기 위해 구성 차이를 먼저 조정했습니다.

의존성에 따른 단계별 적용

네트워크와 연결 리소스의 순서를 나누어 적용하고, 각 단계에서 서비스 연결 상태를 확인했습니다. 문제가 발생했을 때 되돌릴 대상과 순서를 함께 준비했습니다.

DIAGRAMplan·review·apply·검증·복구 운영 루프

문제 해결

이관 중의 롤백을 변경 절차를 보완하는 경험으로 연결했습니다.

2025년 7월 롤백

변경이 서비스에 미치는 영향을 확인하며 일부 작업을 되돌렸습니다. 코드 적용 완료와 서비스 동작 확인을 별도의 단계로 다뤄야 한다는 점을 이후 이관 절차에 반영했습니다.

복구 가능한 변경 단위

한 번의 적용 범위를 줄이고 리소스 의존성, 연결 경로와 복구 순서를 재점검했습니다. 실패 상황까지 포함한 작업 흐름을 바탕으로 후속 이관을 진행했습니다.

결과

VPC 전체 이관과 코드 기반의 인프라 관리 체계를 완성했습니다.

전체 이관 완료

롤백 이후 후속 작업을 진행해 전체 이관을 완료했습니다. 네트워크와 연결 리소스를 환경·리전별 코드로 관리할 수 있는 구조를 마련했습니다.

변경 판단의 기준 마련

변경 대상과 리소스 의존성을 코드와 Plan으로 확인하고, 적용 후 서비스 상태와 복구 절차까지 고려하는 운영 방식을 정리했습니다.