AMI란 무엇이며 EC2 인스턴스에서 어떻게 생성하는가

EC2 인스턴스를 며칠에 걸쳐 완벽하게 세팅했다. 패키지 설치, 환경 변수 설정, 애플리케이션 배포까지 끝냈는데, 이걸 그대로 복제하거나 Auto Scaling에 쓰려면 어떻게 해야 할까? Amazon Machine Image(AMI) 생성이 그 답이다. 이 글은 AMI의 동작 원리부터 실제 생성 절차, 운영 중 자주 마주치는 함정까지 다룬다.

TL;DR — AMI 생성 핵심 요약

단계핵심 내용
1. AMI 개념 이해EBS 스냅샷 + 루트 디바이스 매핑 + 메타데이터의 조합
2. 인스턴스 준비임시 파일 정리, 민감 정보 제거, 로그 초기화
3. AMI 생성콘솔 또는 CLI로 create-image 실행
4. 상태 확인describe-imagesavailable 상태 대기
5. 검증 및 활용테스트 인스턴스 실행 후 Launch Template 또는 Auto Scaling에 연결

AMI가 실제로 무엇인지 — 동작 원리

AMI를 '인스턴스 복사본'이라고 단순하게 생각하면 나중에 반드시 문제가 생긴다. 정확히는 EBS 스냅샷 집합 + 블록 디바이스 매핑 + 부팅 권한 메타데이터로 구성된 리소스다. 인스턴스 자체를 저장하는 게 아니라, 그 인스턴스를 재현하는 데 필요한 청사진을 저장한다.

EBS 기반 인스턴스(현재 대부분의 인스턴스 유형)에서 AMI를 생성하면 다음이 일어난다:

  • 루트 볼륨과 추가 EBS 볼륨 각각에 대해 EBS 스냅샷이 생성된다.
  • AMI는 이 스냅샷들을 참조하는 블록 디바이스 매핑을 포함한다.
  • AMI를 이용해 새 인스턴스를 시작하면, 해당 스냅샷에서 새 EBS 볼륨이 생성되어 인스턴스에 연결된다.

AMI를 삭제(deregister)해도 연결된 EBS 스냅샷은 자동으로 삭제되지 않는다. 스냅샷은 별도로 수동 삭제해야 한다. 이걸 모르면 스냅샷 비용이 조용히 쌓인다.

graph LR A["EC2 인스턴스
루트 EBS 볼륨"] -->|"create-image 호출"| B["EBS 스냅샷 생성"] B --> C["AMI 등록
블록 디바이스 매핑 포함"] C -->|"run-instances 호출"| D["스냅샷에서
새 EBS 볼륨 생성"] D --> E["새 EC2 인스턴스
부팅"] style A fill:#f0f4ff,stroke:#4a6cf7 style C fill:#fff8e1,stroke:#f9a825 style E fill:#e8f5e9,stroke:#43a047
  1. 원본 EC2 인스턴스: 루트 EBS 볼륨이 연결된 실행 중 또는 중지된 인스턴스.
  2. create-image 호출: AMI 생성 요청. AWS가 내부적으로 EBS 스냅샷 생성을 트리거한다.
  3. EBS 스냅샷: 루트 볼륨(및 추가 볼륨)의 특정 시점 복사본. AMI의 실제 데이터 저장소.
  4. AMI(청사진): 스냅샷 참조 + 블록 디바이스 매핑 + 아키텍처/가상화 메타데이터.
  5. 새 인스턴스 시작: AMI를 기반으로 스냅샷에서 새 EBS 볼륨이 생성되고 인스턴스가 부팅된다.
AMI는 집의 설계도면과 같다. 도면(AMI)을 가지고 있으면 같은 구조의 집(인스턴스)을 몇 채든 지을 수 있다. 도면을 버린다고 이미 지어진 집이 사라지지 않고, 집을 허문다고 도면이 사라지지도 않는다.

AMI 생성 전 인스턴스 준비

이 단계를 건너뛰는 경우가 많은데, 나중에 보안 감사나 장애 대응 때 후회한다. AMI는 생성 시점의 디스크 상태를 그대로 굳힌다. 민감한 데이터나 인스턴스 고유 상태가 포함되면 모든 복제 인스턴스에 그게 퍼진다.

정리 권장 항목

  • SSH 호스트 키 재생성 설정: 동일한 호스트 키를 가진 인스턴스가 여러 개 생기면 보안 문제가 된다. cloud-init이 설정된 경우 첫 부팅 시 자동으로 재생성되지만, 설정을 확인해야 한다.
  • 임시 자격증명 및 토큰 제거: ~/.aws/credentials 파일, 하드코딩된 API 키 등.
  • 애플리케이션 로그 정리: 필요에 따라 선택적으로 진행.
  • 인스턴스 고유 식별자 제거: 호스트명, 인스턴스 ID를 하드코딩한 설정 파일.
# SSH 호스트 키 삭제 (새 인스턴스 첫 부팅 시 재생성되도록)
sudo shred -u /etc/ssh/ssh_host_*_key
sudo shred -u /etc/ssh/ssh_host_*_key.pub

# cloud-init 상태 초기화 (Amazon Linux 2 / AL2023 기준)
sudo cloud-init clean --logs

# 임시 파일 정리
sudo rm -rf /tmp/*
sudo rm -rf /var/tmp/*

중지(stopped) 상태에서 AMI를 생성하면 파일시스템 일관성이 보장된다. 실행 중인 인스턴스에서도 생성 가능하지만, AWS는 내부적으로 스냅샷을 찍기 전에 파일시스템을 플러시하려 시도한다. 데이터베이스처럼 메모리 내 상태가 중요한 워크로드라면 중지 후 생성하는 것이 안전하다.

AMI 생성 — CLI와 콘솔 두 가지 방법

방법 1: AWS CLI (권장 — 자동화 가능)

반복 작업이나 CI/CD 파이프라인에 통합할 거라면 CLI가 맞다. 콘솔은 일회성 작업에만 쓰자.

aws ec2 create-image \
  --instance-id i-0abcdef1234567890 \
  --name "my-app-server-v1.0-$(date +%Y%m%d)" \
  --description "Production app server AMI - 2024" \
  --no-reboot \
  --tag-specifications 'ResourceType=image,Tags=[{Key=Name,Value=my-app-server-v1.0},{Key=Environment,Value=production}]' \
  --region us-east-1

--no-reboot 플래그를 명시하지 않으면 AWS가 스냅샷 전에 인스턴스를 재부팅한다. 재부팅을 피하고 싶다면 이 플래그를 사용하되, 파일시스템 일관성은 사용자가 책임진다는 점을 인지해야 한다.

명령 실행 후 AMI ID가 반환된다. 이 ID로 상태를 추적한다:

aws ec2 describe-images \
  --image-ids ami-0example1234567890 \
  --query 'Images[0].State' \
  --output text \
  --region us-east-1

pending에서 available로 바뀔 때까지 대기한다. 볼륨 크기에 따라 수 분에서 수십 분이 걸릴 수 있다.

AMI 생성 완료까지 대기 (CLI 자동화)

aws ec2 wait image-available \
  --image-ids ami-0example1234567890 \
  --region us-east-1
echo "AMI is now available"

방법 2: AWS 콘솔

  1. EC2 콘솔 → Instances에서 대상 인스턴스 선택.
  2. 상단 ActionsImage and templatesCreate image 클릭.
  3. Image name, Description 입력. 필요시 추가 볼륨 설정 조정.
  4. Create image 클릭 후, AMIs 메뉴에서 상태 확인.

생성된 AMI 확인 및 검증

AMI가 available 상태가 됐다고 바로 프로덕션에 쓰면 안 된다. 반드시 테스트 인스턴스를 하나 띄워서 애플리케이션이 정상 동작하는지 확인해야 한다.

# 생성된 AMI 목록 확인 (내 계정 소유)
aws ec2 describe-images \
  --owners self \
  --query 'Images[*].{ID:ImageId,Name:Name,State:State,Created:CreationDate}' \
  --output table \
  --region us-east-1
# AMI로 테스트 인스턴스 시작
aws ec2 run-instances \
  --image-id ami-0example1234567890 \
  --instance-type t3.micro \
  --key-name my-key-pair \
  --security-group-ids sg-0example123 \
  --subnet-id subnet-0example123 \
  --count 1 \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=ami-validation-test}]' \
  --region us-east-1

실제 운영에서 마주친 함정 — 오진과 실제 원인

증상: AMI로 새 인스턴스를 시작했는데 애플리케이션이 뜨지 않는다. 로그를 보면 데이터베이스 연결 실패. 처음엔 보안 그룹 문제라고 생각하고 인바운드 규칙을 열었지만 해결이 안 됐다.

실제 원인은 원본 인스턴스에서 데이터베이스 엔드포인트를 /etc/hosts에 하드코딩해 두었던 것이다. 원본 인스턴스의 프라이빗 IP를 직접 적어놨는데, 새 인스턴스는 다른 IP를 받았고 그 IP로는 DB에 닿지 못했다.

AMI는 파일시스템 상태를 그대로 굳힌다. 인스턴스 고유 설정이 설정 파일에 박혀 있으면 복제 인스턴스 전체에 그 문제가 전파된다. 수정 방법은 두 가지다: 원본 인스턴스에서 하드코딩을 제거하고 AMI를 재생성하거나, user-data 스크립트로 부팅 시 동적으로 설정을 주입하는 구조로 바꾸는 것이다.

AMI 생성은 '지금 이 순간'을 굳히는 작업이다. 좋은 것만 굳히는 게 아니라 나쁜 것도 함께 굳힌다.

AMI 권한 관리 — 공유와 접근 제어

기본적으로 생성된 AMI는 생성한 AWS 계정에서만 사용 가능하다. 다른 계정과 공유하거나 퍼블릭으로 만들 수 있다.

# 특정 AWS 계정과 AMI 공유
aws ec2 modify-image-attribute \
  --image-id ami-0example1234567890 \
  --launch-permission "Add=[{UserId=111122223333}]" \
  --region us-east-1

AMI를 공유할 때 주의할 점: AMI가 참조하는 EBS 스냅샷도 함께 공유해야 공유받은 계정에서 인스턴스를 시작할 수 있다. AMI만 공유하고 스냅샷을 공유하지 않으면 상대방이 인스턴스를 시작할 수 없다.

# AMI가 참조하는 스냅샷 ID 확인
aws ec2 describe-images \
  --image-ids ami-0example1234567890 \
  --query 'Images[0].BlockDeviceMappings[*].Ebs.SnapshotId' \
  --output text \
  --region us-east-1

# 해당 스냅샷도 동일 계정과 공유
aws ec2 modify-snapshot-attribute \
  --snapshot-id snap-0example1234567890 \
  --attribute createVolumePermission \
  --operation-type add \
  --user-ids 111122223333 \
  --region us-east-1

AMI 수명 주기 관리 — 삭제 절차

AMI를 더 이상 사용하지 않는다면 deregister 후 스냅샷을 별도로 삭제해야 한다. AMI deregister만으로는 스냅샷이 삭제되지 않는다.

graph TD A["AMI 삭제 시작"] --> B["1단계: 스냅샷 ID 조회
describe-images"] B --> C["2단계: AMI Deregister
deregister-image"] C --> D{"스냅샷 삭제했나?"} D -->|"아니오"| E["스냅샷 비용 계속 발생 ⚠️"] D -->|"예"| F["3단계: 스냅샷 삭제
delete-snapshot"] F --> G["정리 완료 ✅"] style E fill:#ffebee,stroke:#e53935 style G fill:#e8f5e9,stroke:#43a047 style D fill:#fff8e1,stroke:#f9a825
  1. 스냅샷 ID 확인: AMI 삭제 전에 참조하는 스냅샷 ID를 먼저 기록해 둔다.
  2. AMI Deregister: AMI 등록을 해제한다. 이 시점부터 이 AMI로 새 인스턴스를 시작할 수 없다.
  3. 스냅샷 삭제: 별도 명령으로 스냅샷을 삭제한다. 이 단계를 빠뜨리면 스냅샷 비용이 계속 발생한다.
# 1단계: 스냅샷 ID 먼저 기록
aws ec2 describe-images \
  --image-ids ami-0example1234567890 \
  --query 'Images[0].BlockDeviceMappings[*].Ebs.SnapshotId' \
  --output text \
  --region us-east-1

# 2단계: AMI deregister
aws ec2 deregister-image \
  --image-id ami-0example1234567890 \
  --region us-east-1

# 3단계: 스냅샷 삭제
aws ec2 delete-snapshot \
  --snapshot-id snap-0example1234567890 \
  --region us-east-1

IAM 권한 — AMI 생성에 필요한 최소 권한

EC2 인스턴스에서 AMI를 생성하고 관리하는 역할 또는 사용자에게 필요한 최소 권한이다.

🔽 IAM 정책 예시 펼치기
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowAMICreation",
      "Effect": "Allow",
      "Action": [
        "ec2:CreateImage",
        "ec2:DescribeImages",
        "ec2:DeregisterImage",
        "ec2:DescribeInstances"
      ],
      "Resource": "*"
    },
    {
      "Sid": "AllowSnapshotManagement",
      "Effect": "Allow",
      "Action": [
        "ec2:CreateSnapshot",
        "ec2:DeleteSnapshot",
        "ec2:DescribeSnapshots",
        "ec2:ModifySnapshotAttribute"
      ],
      "Resource": "*"
    },
    {
      "Sid": "AllowTagging",
      "Effect": "Allow",
      "Action": [
        "ec2:CreateTags"
      ],
      "Resource": "*"
    }
  ]
}

ec2:CreateImage, ec2:DescribeImages, ec2:DescribeInstances 등 Read/Describe 계열 액션은 리소스 수준 제한을 지원하지 않아 "Resource": "*"가 필요하다. AWS Service Authorization Reference에서 각 액션의 리소스 수준 지원 여부를 확인하고 적용하는 것을 권장한다.

다음 단계 — AMI를 실제로 활용하는 방법

AMI를 만들었다면 이걸 어디에 쓸지가 진짜 질문이다. 단순히 백업용으로만 두는 건 AMI의 가치를 절반도 못 쓰는 것이다.

  • Launch Template 연결: AMI ID를 Launch Template에 지정해 두면 Auto Scaling Group, Spot Fleet 등에서 일관된 인스턴스를 시작할 수 있다.
  • Auto Scaling Group 업데이트: 새 AMI로 Launch Template 버전을 업데이트하고 인스턴스 갱신(Instance Refresh)을 트리거해 롤링 업데이트를 수행할 수 있다.
  • 다른 리전으로 복사: aws ec2 copy-image 명령으로 AMI를 다른 리전에 복사해 멀티 리전 배포에 활용한다.
  • AMI 빌더 파이프라인: EC2 Image Builder 서비스를 사용하면 AMI 생성, 테스트, 배포를 파이프라인으로 자동화할 수 있다.

AWS 공식 문서: Amazon Machine Images (AMI) — EC2 User Guide

핵심 용어 정리

용어설명
AMI (Amazon Machine Image)EC2 인스턴스를 시작하는 데 필요한 정보를 담은 템플릿. EBS 스냅샷, 블록 디바이스 매핑, 권한 메타데이터로 구성된다.
EBS 스냅샷EBS 볼륨의 특정 시점 복사본. AMI의 실제 데이터 저장소 역할을 한다. S3에 증분 방식으로 저장된다.
블록 디바이스 매핑인스턴스 시작 시 연결할 볼륨과 그 설정(크기, 유형, 삭제 정책 등)을 정의하는 AMI 구성 요소.
DeregisterAMI 등록 해제. 이후 해당 AMI로 새 인스턴스를 시작할 수 없게 되지만, 연결된 스냅샷은 별도로 삭제해야 한다.
Launch Template인스턴스 시작 파라미터(AMI ID, 인스턴스 유형, 보안 그룹 등)를 저장하는 EC2 리소스. Auto Scaling과 연동된다.

Related Posts

댓글

이 블로그의 인기 게시물

EC2 SSH 연결 타임아웃 완전 해결 가이드: Security Group 인바운드 규칙부터 라우팅까지

S3 정적 웹사이트 호스팅 완전 가이드: HTML/CSS 사이트를 무료로 배포하는 법

EC2 SSH 연결 시간 초과: 확인해야 할 보안 그룹(Security Group) 규칙