본문 바로가기
프로젝트/핏토링

[핏토링] AWS 계정을 옮겨야 하는데 IaC를 써볼게요

by kim-dev 2025. 12. 1.
반응형

Terraform을 사용하여 AWS에서 가동 중이었던 핏토링 프로젝트 관련 인스턴스들을 모두 새로운 계정으로 이전해야만 했다. 지금부터 Terraform을 사용한 AWS 인프라 이전기를 간단하게 정리해 보려고 한다.

 

인프라를 왜 이전해야 했을까?

핏토링은 우아한테크코스에서 진행한 프로젝트이다. 우아한테크코스에서는 AWS IAM 계정을 빌려주는 형태로 AWS 비용을 지원해주고 있었다. 그래서 우리 팀은 한 달 약 10만원 가량의 AWS 비용을 우아한테크코스로부터 지원받을 수 있었다.

우아한테크코스 활동은 11월 28일까지다. 그 전까지 우아한테크코스 AWS IAM 계정에서 만든 인스턴스들을 모두 삭제해야 했다. 우리 팀은 우아한테크코스 활동이 끝나더라도 프로젝트를 계속 진행하는 것으로 사전에 이미 합의가 된 상황이었기 때문에, 인스턴스를 단순히 삭제하는 게 아니라 새로운 AWS 계정을 만들어서 기존의 인프라 구조를 똑같이 마이그레이션 해야 했다. 그래서 우리는 기존의 우아한테크코스 AWS IAM 계정에서 벗어나, 새로운 핏토링 AWS 계정을 만들어 인프라 구조를 마이그레이션하기로 했다.

 

왜 Terraform을 썼지?

우리는 기존의 인프라 구조를 똑같이 옮겨야만 했다. AWS 인스턴스 간 상호작용이나 보안과 관련된 설정들을 기존과 똑같이 맞춰주지 않으면 기존과 똑같은 방식으로 서버가 동작할 것이라고 확신할 수 없기 때문이다. 가장 간편한 방법은 AWS Management Console에서 각 인스턴스들의 속성을 하나 하나 보면서 똑같은 인스턴스를 만드는 것이다. 아무런 러닝 커브 없이 시간만 들이면 기존과 똑같은 인프라 구조를 만들 수 있다.

그런데 같은 인프라 구조를 수동으로 만들어야 한다는 사실이 굉장히 번거롭게 느껴졌다. 만약 추후에 또 인프라 구조를 다른 곳으로 마이그레이션하는 경우가 발생한다면 또다시 똑같은 작업을 반복해야만 했다. 최근 AWS CCP 자격증 공부를 하고 있는데, 거기서 Terraform과 같은 IaC를 활용하면 인프라를 코드로 관리할 수 있다고 한다. 인프라를 코드로 관리하게 되면 이후 인프라를 옮겨야 하는 상황에서도 같은 작업을 반복할 필요가 없을 것이라 생각했다. 또한 IaC도 일종의 코드이므로 Git을 활용한 버전 관리가 가능하다는 점도 굉장히 큰 매력으로 느껴졌다. 인프라 특성 상 팀원들이 작업한 내용을 한 번에 알기 힘든데, Git을 활용할 수 있다면 커밋 기록을 보고 팀원들과 함께 인프라 작업을 할 수 있기 때문이다.

참고로 Terraform은 인프라를 코드로 다룰 수 있게 해주는 Infrastructure As Code(IaC)의 한 종류이다. 자세한 건 Terraform 공식 문서를 확인해 보자.

 

서비스 마이그레이션 진행 과정

핏토링 서비스의 인프라 구조는 아래와 같았다.

크게 복잡하지는 않은 구조지만 Terraform 코드로 작성하기 힘들 것이라 예상되는 서비스들이 일부 있었는데, 아래와 같았다.

  • CodePipeline, CodeDeploy, CodeBuild: 블루그린 배포 파이프라인 과정이 여러 소스를 참조하고 있었기 때문에, 코드로 작성하는 것이 오히려 Management Console을 사용하는 것보다 더 복잡할 것 같았다.
  • AutoScaling Group과 시작 템플릿: 블루그린 배포에 사용되는 ASG를 만들기 위해서는 배포할 서버와 동일한 상태의 AMI가 필요하다. 기존 계정의 AMI를 새로운 계정으로 옮길 수는 있지만 DB 경로, 환경 변수 등을 새로운 환경에 맞게 바꿔줘야 했기 때문에 당장 AMI와 시작 템플릿, ASG를 코드로 작성할 수는 없을 것이라 생각했다.

위 서비스들은 Management Console을 활용하여 기존과 똑같은 설정으로 손수 새로 생성해 주었고, 나머지 서비스들을 모두 Terraform 코드로 작성해 주었다. Terraform 코드 작성이 처음이었기 때문에 혼자 작성하지는 못했고 Gemini와 함께 한 땀 한 땀 작성했다. 처음에는 생소한 문법 때문에 복잡해 보였지만 코드를 계속 작성해 보니 어느 정도 손에 익어서 Gemini 없이도 기본적인 문법은 작성할 수 있게 되었다. Management Console으로 기존 인스턴스들의 설정을 보면서 똑같은 상태가 되도록 코드를 작성했다.

Terraform 코드 같은 경우는 따로 업로드할 만한 부분이 없다. 일반적인 Terraform 문법을 그대로 사용했기 때문에 공식 문서를 찾아보길 바란다. 간단하게 예시 하나만 작성해 보자면 아래는 기존에 핏토링 인프라에서 사용하던 Dev 서버를 향하는 대상 그룹이다. HTTP 프로토콜 80 포트로 인스턴스와 통신하며, `/health` URI를 통해 헬스 체크한다.

resource "aws_lb_target_group" "fittoring_dev_target_group" {
  name = "fittoring-dev-target-group"
  port = 80
  protocol = "HTTP"
  vpc_id = var.vpc_id

  health_check {
    path = "/health"
    port = "traffic-port"
    protocol = "HTTP"
    healthy_threshold = 5
    unhealthy_threshold = 2
    timeout = 5
    interval = 30
    matcher = "200"
  }
}

이런 식으로 기존 AWS 서비스 설정을 그대로 옮겨 Terraform 코드로 작성했다. Management Console을 사용할 때에는 순서를 지켜서 인스턴스를 생성해야 했는데(VPC를 만들기 전에는 Subnet을 만들 수 없는 것처럼), Terraform을 사용하면 의존성을 기반으로 생성 순서를 자동으로 관리해줘서 편리했다.

 

데이터 옮기기

위 과정을 거쳐 기존 인프라 구조는 똑같이 새로운 계정으로 가져올 수 있었다. 하지만 Terraform은 특정한 설정을 가진 인스턴스를 켜고 끄기만 가능할 뿐, 내부 데이터들까지 그대로 옮길 수는 없다. 그래서 RDS나 S3에 저장되어 있던 데이터들은 직접 다시 넣어줘야 했다.

mysqldump -h [기존 DB 엔드포인트] \
          -u [기존 마스터 계정] \
          -p \
          --single-transaction \
          --routines --triggers \
          --databases [DB 이름] \
          --skip-lock-tables \
          > fittoring_data_dump.sql

우선 위 명령어로 기존 DB의 데이터들을 `fittoring_data_dump.sql`로 덤프해 주었다.

mysql -h [새로운 DB 엔드포인트] \
      -u [새로운 마스터 계정] \
      -p \
      < fittoring_data_dump.sql

그리고 새로운 DB 엔드포인트에 해당 덤프 파일을 적용해 주었다.

S3의 데이터를 옮기는 것은 더 간단했다. S3 버킷의 특정 경로와 로컬 디렉터리를 동기화해주는 `aws s3 sync` 명령어를 사용하여 기존에 S3에 업로드되어 있던 파일들을 Bastion Host 인스턴스에 다운받은 후 Git을 통해 내 컴퓨터로 파일을 옮겨 주었다. 이후 그 파일들을 새로운 S3에 다시 업로드하여 S3 데이터도 성공적으로 옮길 수 있었다.

 

결과 및 다음 과제

위 과정을 진행하여 새로운 계정으로 안전하게 AWS 인프라를 마이그레이션 할 수 있었다. 간단하게 테스트해 보니 별다른 오류는 발생하지 않는 것처럼 보였다. DB에서 사용되는 S3 Url 정도만 새로운 Url로 수정해주면 될 것 같다. S3 Url 같은 경우도 한 번에 바꿀 수 있을 것 같은데 한 번 고민해 봐야 할 것 같다.

그런데 이제 치명적인 문제가 있다. 기존에 월 10만원 가량을 지원받고 있었는데, 이제 AWS를 독립하게 되어 이러한 비용을 전액 부담해야 한다.

이틀만에 32달러가 누적된 상황...

특히 ALB와 RDS 용량이 굉장히 빠르게 증가하는 모습을 보이고 있다. 지금은 RDS의 장점을 별로 누리고 있지 않아서, 그냥 제거하고 DB 전용 EC2 인스턴스를 띄워 비용을 절감하는 방법을 생각하고 있다. 그런데 ALB는 Https 연결부터 무중단 배포까지 우리 인프라에서 상당히 큰 비중을 차지하고 있기 때문에 함부로 제거하지는 못할 것 같다. 그래서 ALB의 존속 여부와 비용 절감 방안에 대해 앞으로 고민을 해봐야 할 것 같다.