Skip to content

feat: Custom AMI에 AWS CLI 설치 및 DB EC2 AMI 갱신 반영 #70

Description

@Hexeong

어떤 기능인가요?

현재 Prod DB EC2에는 S3 백업을 위해 Linux ARM64용 AWS CLI v2를 수동으로 설치했고, binlog 복구를 위해 ARM64 기반 solid-connection/mysql-recovery-tools:8.4.8 Docker 이미지를 수동으로 적재한 상태입니다. 이 설정들은 현재 인스턴스의 루트 볼륨에만 존재하므로 DB EC2를 재생성하면 유실됩니다.

AWS CLI와 MySQL 복구 도구 이미지를 포함한 Custom AMI를 생성하고, 새 AMI ID를 Terraform 운영 입력값에 반영하여 DB EC2가 재생성되어도 S3 백업 및 binlog 복구 실행 환경이 유지되도록 합니다.

관련 이슈: #66, #67, #68

운영 중단을 발생시키지 않기 위한 전제

이 이슈의 목적은 DB EC2가 재생성되는 시점에 실행 환경이 유지되도록 하는 것이며, 지금 당장 운영 중인 DB EC2를 교체하는 것이 아닙니다. 따라서 다음 두 작업을 분리합니다.

  • AMI 생성과 Terraform 입력값 반영: 서비스 영향 없이 진행합니다.
  • DB EC2 인스턴스 교체: 이 이슈에서 수행하지 않고 #67의 EC2 장애 복구 리허설 시점에 함께 진행합니다.

modules/app_stack/db_ec2.tfaws_instance.db_server는 현재 lifecycle.ignore_changesami가 없어, db_ec2_ami_id 변경만으로 인스턴스가 destroy 후 create 됩니다. aws_volume_attachmentstop_instance_before_detaching = true가 적용되어 있어 MySQL이 실행 중인 상태에서 인스턴스가 정지됩니다. 사용자가 있는 상황에서는 이 교체를 수행할 수 없으므로, API EC2(aws_instance.api_server)와 동일하게 amiignore_changes에 추가한 뒤 AMI ID를 반영합니다.

이 구성에서는 새 AMI ID를 반영해도 기존 인스턴스가 유지되며, 이후 어떤 사유로든 인스턴스가 재생성되는 시점에 새 AMI가 적용됩니다. 예기치 않은 EC2 장애로 재생성되는 경우에도 AWS CLI와 복구 도구가 포함된 상태로 기동되므로, 현재보다 백업 파이프라인의 생존성이 높아집니다.

AMI 생성 방식

기존 Custom AMI 생성과 동일하게, public AMI로 별도의 임시 EC2 인스턴스를 생성하고 필요한 구성을 설치한 뒤 해당 인스턴스를 이미지로 생성합니다. 운영 중인 DB EC2에서 이미지를 생성하지 않으므로 이 과정에서 서비스 영향이 발생하지 않습니다.

  • 임시 인스턴스는 운영 DB EC2와 동일한 아키텍처(ARM64)와 OS 버전을 사용합니다.
  • 임시 인스턴스에는 운영 데이터 EBS를 연결하지 않습니다.
  • 이미지 생성이 완료되면 임시 인스턴스를 종료합니다.

작업 상세 내용

1. AMI 빌드 (임시 EC2)

  • public AMI로 임시 EC2 인스턴스를 생성합니다.
  • Linux ARM64용 AWS CLI v2 설치 단계를 추가합니다.
  • AWS CLI 설치 파일의 체크섬 또는 서명을 검증합니다.
  • Linux ARM64 및 MySQL 8.4.8에 맞춘 solid-connection/mysql-recovery-tools:8.4.8 이미지 빌드 절차를 구성합니다.
  • MySQL 공식 client 패키지의 서명 검증을 유지하고 mysqlbinlogmysql 버전이 8.4.8인지 확인합니다.
  • 이미지 생성 전에 복구 도구 이미지를 docker load하여 로컬 Docker 이미지로 적재합니다.
  • 복구 도구 컨테이너는 상시 실행하지 않고 복구 시에만 일회성으로 실행되도록 합니다.
  • AMI에 AWS Access Key 등 정적 자격 증명, DB 비밀번호, 백업 데이터가 포함되지 않도록 확인합니다.
  • 임시 인스턴스에서 이미지를 생성하고 임시 인스턴스를 종료합니다.

2. AMI 검증

  • 생성된 AMI로 검증용 인스턴스를 기동하여 /usr/local/bin/aws --version 실행을 검증합니다.
  • docker run --rm solid-connection/mysql-recovery-tools:8.4.8 --version 실행을 검증합니다.
  • private subnet의 DB EC2가 복구 시점에 외부 레지스트리에서 이미지를 내려받지 않아도 되는지 확인합니다.
  • 검증용 인스턴스를 종료합니다.

3. Terraform 반영 (인스턴스 교체 없음)

  • modules/app_stack/db_ec2.tfaws_instance.db_server lifecycle.ignore_changesami를 추가합니다.
  • 새 Custom AMI ID를 Terraform 운영 입력값(db_ec2_ami_id)에 반영합니다.
  • Terraform plan에서 aws_instance.db_server에 교체가 발생하지 않는지 확인합니다.
  • PR 검토 후 Terraform apply를 통해 입력값을 반영합니다.
  • 현재 운영 DB EC2가 교체되지 않고 그대로 유지되는지 확인합니다.
  • 실제 인스턴스가 사용하는 AMI ID와 코드상의 AMI ID가 달라지는 상태를 운영 문서에 기록합니다.

4. 인스턴스 교체 (#67 리허설 시점에 수행)

이 이슈에서는 수행하지 않으며, #67의 EC2 장애 복구 리허설과 함께 계획된 점검 시간에 진행합니다. 리허설에서 다음 항목을 확인합니다.

  • 기존 데이터 EBS가 보존되고 새 DB EC2에 정상적으로 연결됩니다.
  • mysql_setup.sh가 기존 파일 시스템을 재포맷하지 않고 기존 데이터를 그대로 마운트합니다.
  • 재생성된 DB EC2가 Instance Profile과 S3 Gateway Endpoint를 이용해 백업 버킷에 접근할 수 있습니다.
  • 루트 볼륨에 설치되어 있던 백업 스크립트와 systemd 유닛이 소멸하므로 MySQL Backup Deploy 워크플로우를 install 모드로 재실행합니다.
  • SSH host key가 변경되므로 PROD_DB_SSH_HOST_KEY_ED25519 Repository Variable을 새 fingerprint로 갱신합니다. 갱신 전에는 validate 모드도 실패합니다.
  • Private IP 변경에 따라 애플리케이션의 DB 접속 설정을 확인합니다.
  • 데이터 EBS에 있는 백업 상태 파일과 server_uuid가 보존되어 binlog 체인이 이어지는지 확인합니다.
  • 교체에 소요된 시간을 기록하여 #67의 EC2 장애 시나리오 RTO 실측값으로 사용합니다.

완료 조건

  • Custom AMI에 Linux ARM64용 AWS CLI v2와 MySQL 8.4.8용 복구 도구 이미지가 포함되어 있습니다.
  • AWS CLI가 Instance Profile의 임시 자격 증명만 사용하며 AMI에 정적 자격 증명이 포함되지 않습니다.
  • 복구 도구 이미지는 실행 중인 컨테이너가 아닌 로컬 Docker 이미지로만 AMI에 포함됩니다.
  • 새 AMI ID가 Terraform 운영 입력값에 반영되어 있고, 이 작업으로 운영 DB EC2가 교체되지 않았습니다.
  • 이후 DB EC2가 재생성되면 AWS CLI와 복구 도구를 별도 수동 설치 없이 사용할 수 있습니다.
  • Terraform state를 직접 수정하지 않고 plan/apply를 통해 반영되었습니다.

참고할만한 자료(선택)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions