🔥 AMI: 머신 이미지의 라이프사이클
강의 목차

콘솔에서 EC2 인스턴스를 우클릭해 "Image and templates → Create image"를 눌러 보면, AWS가 그 인스턴스의 디스크 한 장을 통째로 굳혀서 다른 ID로 다시 부를 수 있게 만들어 둔다. 이 굳혀진 한 장이 AMI(Amazon Machine Image)다. 처음 이 메뉴를 눌렀을 때 나는 이게 단순히 디스크 백업 한 부 만드는 동작인 줄 알았는데, 만들고 나서 보니 AMI는 자체 ID를 가지고, 자체 라이프사이클을 따라 움직이고, 다른 계정·다른 리전으로 따로 퍼져 나가는 별도 객체로 존재한다. EC2 인스턴스가 끄고 켜지는 동안에도 AMI는 그 옆에서 따로 살아 있다.
인스턴스 타입: CPU, 메모리, 네트워크 조합에서 m6i.large 같은 사양 묶음을 골랐다면, 다음 단계는 그 타입 위에 어떤 OS와 앱을 올릴지 정하는 일이다. 이 두 단계가 모여야 EC2 한 대가 부팅한다.
AMI는 두 갈래의 상태와 한 가지 시간 속성으로 산다
AMI를 굳히고 나서 운영에서 마주치는 상태 표현은 두 갈래다. 한 갈래는 EC2 API가 돌려주는 imageState 필드로, pending, available, disabled, failed 같은 진짜 상태값이다. 또 한 갈래는 별도의 DeprecationTime 시간 속성으로, "이 AMI는 이 시간 이후 deprecated로 본다"라는 메타데이터다. 나도 이 둘이 같은 줄에 있어야 할 것 같았는데, AWS가 둘을 따로 떼어 둔 데에는 이유가 있다.

pending은 CreateImage API가 호출된 직후 EBS 스냅샷을 만드는 동안의 상태다. 공식 문서는 보통 몇 분 이내라고만 적어 두는데, 디스크가 큰 인스턴스에서는 시간이 더 든다. 그 사이에 인스턴스를 종료하면 스냅샷이 깨지므로 운영 절차서에 "Create image 요청 후 status=available 확인까지는 인스턴스 정지·종료 금지" 한 줄을 넣는 게 안전하다.
available은 RunInstances가 실제로 이 AMI ID를 받아 부팅을 걸 수 있는 정상 상태다. 그래서 콘솔의 AMI 목록은 기본 필터가 available + 내 계정 소유로 잡혀 있다.
DeprecationTime은 상태 필드가 아니라 한 시점을 가리키는 시간 속성이다. AWS가 2021-06에 AMI에 추가한 새 속성으로 (What's New: AMI deprecation property, verified 2026-04-28), AMI 자체는 available로 살아 있지만 콘솔의 기본 목록과 검색에서 콘솔이 노출하지 않는다. AMI ID를 직접 알고 있는 SDK 호출은 그대로 RunInstances로 부팅이 가능하다. 그래서 deprecation은 "더 이상 권장하지 않으니 새 검색 결과에는 노출하지 마"라는 신호이지, 부팅 차단이 아니다. AWS는 2022-03-31부터 2년 이상 된 public AMI에 대해 자동 deprecation 백필을 시작했고, 2022-07-30 시점에 이미 2년 이상 된 public AMI들을 자동 deprecated로 표시했다 (What's New: reduced visibility for public AMIs older than two years, verified 2026-04-28). Amazon Linux 2014 시절 AMI ID를 IaC에 박아 둔 팀들이 콘솔에서 그 AMI를 못 찾아 잠깐 당황했지만 부팅 자체는 멀쩡히 됐다.
disabled는 2023-10-13에 추가된 진짜 상태값이다 (What's New: AMI disabled state, verified 2026-04-28). 이 상태에서는 부팅 차단이 명시적으로 들어간다. disabled 상태에서 RunInstances를 호출하면 실패하고 새 인스턴스가 뜨지 못한다. 다만 이미 그 AMI로 켜져 있는 인스턴스는 영향이 없다. 보안 사고로 지금 이 AMI에서 더 이상 새 인스턴스가 뜨지 못하게 막고 싶은데 기록과 복구 가능성은 남기고 싶을 때 정확히 맞는 도구다. 예를 들어 사내 빌드 파이프라인에서 깨진 골든 이미지가 한 시간 동안 publish됐다가 발견된 경우가 그렇다. 나라면 사고 채널에서 5분 안에 disable, 24시간 안에 EnableImage 또는 deregister로 결론을 짓는다. 단순 정리(공간 비우기)에 disabled를 쓰지는 않는다. 그 작업은 그냥 deregister다.
DeprecationTime 속성 (2021-06 추가): 검색에서 숨김, 부팅 가능
disabled 상태 (2023-10 추가): 부팅 차단, EnableImage로 복구 가능
deregistered : 등록 해제, 복구 불가DeprecationTime 속성 (2021-06 추가): 검색에서 숨김, 부팅 가능
disabled 상태 (2023-10 추가): 부팅 차단, EnableImage로 복구 가능
deregistered : 등록 해제, 복구 불가CreateImage는 AMI 하나가 아니라 스냅샷 N개를 같이 만든다

CreateImage 한 호출이 만드는 건 AMI ID 한 개로 끝이 아니다. 인스턴스에 붙어 있는 EBS 볼륨마다 별도 스냅샷이 자동으로 생성되고, AMI는 그 스냅샷들을 묶는 얇은 manifest다. 그래서 AMI 한 개를 deregister해도 스냅샷은 그대로 남는다. 별도로 DeleteSnapshot을 호출해야 비로소 청소가 끝난다. 청소 스크립트가 AMI만 지우고 스냅샷을 안 지우면 청구서가 조용히 자라는 가장 흔한 함정이다.
작은 시나리오 한 번. m6i.large 한 대에 루트 30GB + 데이터 100GB EBS 볼륨이 붙어 있다고 하자. CreateImage를 한 번 호출하면 AMI 1개 + 스냅샷 2개가 동시에 생긴다. 디스크가 절반쯤 차 있으면 실제로 AWS가 청구하는 스냅샷 양은 약 65GB다. 표준 EBS 스냅샷이 us-east-1 기준 GB-월당 약 $0.05이니까 한 달에 약 $3.25, 1년이면 약 $39다 (EBS pricing, verified 2026-04-28). 별것 아니어 보이지만 골든 이미지를 매주 새로 굳혀 두는 사내 파이프라인이 있다고 치면 1년에 52개로 누적 약 $2,000이다. 이 자동 적립을 잡는 안전망은 Observability 비용 함정: 관찰하는 데 돈이 새는 이유에서 본 retentionInDays 같은 기본값 설정이다. Data Lifecycle Manager의 retention 정책이 그 단계를 채운다. 여기서는 수명 주기 정책 자체는 다루지 않는다.
그리고 NoReboot 옵션을 본다. 기본값은 인스턴스를 재부팅한 뒤 디스크를 굳히는 쪽이다. 메모리에 떠 있던 dirty page를 디스크로 flush한 다음 스냅샷을 뜨면 파일시스템이 일관된 상태로 남아서다. --no-reboot 또는 API의 NoReboot=true를 주면 재부팅 없이 떠 있는 인스턴스 그대로 스냅샷을 뜨는데, AWS가 파일시스템 일관성을 보장하지 않는다고 명시해 둔다 (CreateImage Amazon EC2 API Reference, verified 2026-04-28). 운영 중인 DB 인스턴스에 NoReboot=true로 AMI를 떴다가 그 AMI로 부팅한 후속 인스턴스에서 fsck가 손상 블록을 만나는 사고가 한 케이스다. 나는 production 위 DB는 NoReboot 안 쓴다. 대신 RDS면 자동 스냅샷, EC2 위 DB면 인스턴스를 잠깐 stop했다가 CreateImage하는 길로 간다.
Golden Image: 사내 표준을 굳히는 패턴
Amazon Linux 2023이나 Ubuntu 22.04 같은 base AMI 위에 회사가 매일 깔아야 하는 도구들이 있다. CloudWatch agent, SSM agent, fluent-bit, 사내 보안 에이전트, CIS hardening 스크립트, 회사 표준 언어 런타임(예: Node.js 20, Python 3.12) 같은 것들이다. 이걸 한 번 깔고 굳혀 두는 게 Golden Image 패턴이다. 사내에서 부팅하는 모든 EC2가 이 굳혀진 한 장에서 시작해서 user-data로 앱마다 다른 부분만 추가 설치한다.
이 패턴이 갖는 장점은 부팅 시간 단축과 일관성이다. 50대 인스턴스를 동시에 띄우는 Auto Scaling 이벤트에서 base AMI에 user-data로 매번 50번 같은 패키지를 다시 까는 상황을 떠올려 보자. apt/yum 미러에 50개 동시 요청이 가서 부팅이 5분이 걸리던 게 7분이 된다. 골든 이미지로 굳혀 두면 이게 1분 수준까지 줄어든다. 그리고 사내 보안 에이전트 버전 일관성도 같이 정착한다. 이 항목은 CIS·SOC2 감사에서 가장 자주 묻는 점이다.
언제 Golden Image를 만들지 말아야 하나. 두 갈래로 나는 답한다. (1) 앱을 컨테이너로 패키징할 수 있다면 골든 이미지 대신 컨테이너 이미지로 가는 편이 깨끗하다. ECR에 푸시하고 ECS/EKS에서 받아 가는 길이 cross-region 복제, 권한 모델, 버전 관리 모두 더 단순하다. (2) 앱이 완전히 stateless하고 부팅 횟수가 적다면 그냥 base AMI + user-data로 충분하다. 골든 이미지는 부팅 빈도가 높고 일관성이 비용보다 더 중요한 상황의 답이지, 모든 EC2 워크로드의 답이 아니다.
launchPermission: 다른 계정에 AMI를 빌려주는 길
같은 회사의 dev / prod 두 계정이 같은 골든 이미지를 쓰고 싶은 경우, AMI 자체를 복제할 수도 있고 공유할 수도 있다. 공유는 ModifyImageAttribute --launch-permission Add=... 한 번으로 끝난다. 이 한 호출이 받는 값은 4가지다. 다른 AWS 계정 ID, Organization ARN, OU(Organizational Unit) ARN, 또는 Group=all(public)이다. API는 한 호출에 최대 10,000개 UserId를 받지만, AMI당 공유 대상 수의 기본 쿼터는 리전당 1,000개다 (AMI quotas, verified 2026-04-28). 큰 조직에서 1,000개를 넘으려면 쿼터 증가 요청이 필요하다.
aws ec2 modify-image-attribute \
--image-id ami-0abcdef1234567890 \
--launch-permission "Add=[{UserId=123456789012}]"aws ec2 modify-image-attribute \
--image-id ami-0abcdef1234567890 \
--launch-permission "Add=[{UserId=123456789012}]"여기서 함정 두 갈래. (1) AMI가 기본 KMS 키(aws/ebs, AWS 관리형 키)로 암호화돼 있으면 다른 계정으로 launchPermission을 줘도 그 계정에서 부팅이 안 된다. AWS 관리형 키는 계정 간 공유가 불가능해서다. 해결은 고객 관리형(Customer Managed) KMS 키로 AMI를 다시 굳히고, 그 키의 정책에 대상 계정의 ARN을 추가하는 길이다 (sharingamis-explicit, verified 2026-04-28). (2) 2023-09-13에 추가된 AMI Block Public Access (AMI BPA)는 (What's New: AMI BPA, verified 2026-04-28) 2023-10-20부터 신규 AWS 계정과, 2023-07-15 이후로 public AMI를 가져 본 적 없는 기존 계정에서 기본 ON으로 바뀌었다 (What's New: BPA default-on, verified 2026-04-28). BPA가 켜져 있는 계정에서 Group=all로 launchPermission을 시도하면 API가 그 요청을 거절한다. 이건 한 번이라도 실수로 public AMI를 만들지 않게 막아 주는 안전망인데, 마이그레이션 도중 의도적으로 public AMI를 만들 일이 있다면 BPA를 먼저 OFF해야 한다는 점을 기억해 둬야 한다.
Cross-region 복제: CopyImage가 새 AMI ID를 만든다

서울 리전(ap-northeast-2)에서 굳힌 골든 AMI를 도쿄 리전(ap-northeast-1)으로 옮길 때는 CopyImage를 호출한다. 이 호출이 만드는 결과는 단순한 링크가 아니라 새 AMI ID + 새 스냅샷이다. 즉 같은 디스크 내용을 도쿄 리전에 처음부터 다시 저장한다 (How AMI copy works, verified 2026-04-28). 그래서 비용은 두 배가 든다. 서울에서 한 번, 도쿄에서 다시 한 번.
aws ec2 copy-image \
--source-region ap-northeast-2 \
--source-image-id ami-0abc... \
--region ap-northeast-1 \
--name "golden-base-2026-04-28"aws ec2 copy-image \
--source-region ap-northeast-2 \
--source-image-id ami-0abc... \
--region ap-northeast-1 \
--name "golden-base-2026-04-28"암호화된 AMI를 cross-region 복사할 때 KMS가 만드는 함정이 한 단계 더 있다. KMS 키는 리전별로 분리된 객체라 서울 리전 키로 암호화된 스냅샷을 도쿄 리전 키로 다시 암호화해야 한다. CopyImage가 이 과정을 자동으로 처리하지만, KmsKeyId 파라미터를 명시할 때는 그 키가 대상 리전(도쿄)에 존재하는 활성 키여야 한다 (CopyImage API, verified 2026-04-28). KmsKeyId를 안 주면 기본 동작은 원본 암호화 상태를 보존하는 쪽이고, 내가 소유한 암호화 스냅샷은 같은 KMS 키 거동을 유지한다 (AMIEncryption, verified 2026-04-28). 그래서 cross-account + cross-region을 안전하게 동시에 하려면 양쪽 리전 모두에 customer managed 키를 미리 만들어 두고 양쪽에 대상 계정 권한을 열어 두는 길이 가장 직관적이다.
내가 처음 이 길을 갔을 때 가장 헷갈렸던 대목이 이 KMS의 리전별 분리 구조다. 한 번 만든 customer managed 키가 모든 리전에서 같이 쓰이는 줄 알고 도쿄 리전의 RunInstances가 KMS 관련 오류로 실패할 때까지 30분을 헤맸다. 키도 AMI도 스냅샷도 다 리전 단위 객체라는 사실을 그때 분명히 적어 두었다.
언제 AMI 자체가 답이 아닌가
AMI는 전체 부팅 디스크를 한 장으로 굳히는 강력한 도구지만, 답이 아닌 경우도 분명하다.
서버리스 함수 한 개를 배포하는 거라면 AWS Lambda의 deployment package가 더 단순하다. Lambda는 AMI라는 개념 자체가 없다. 컨테이너로 패키징할 수 있는 앱이라면 ECR + ECS/EKS가 cross-region 복제와 권한 모델 양쪽에서 더 단순한 답이다. ECR replication을 한 번 켜면 자동으로 동작하지만, AMI는 매번 CopyImage를 호출해야 한다. 그리고 인스턴스가 완전히 stateless하고 자주 안 죽는 경우는 base AMI + user-data 한 줄로 충분하다. 골든 이미지를 만들고 갱신하고 deprecate하는 운영 비용이 굳혀 둔 일관성보다 클 수 있다.
거꾸로 AMI가 유일한 답인 상황은 셋이다. (a) 사내 보안 에이전트와 OS 튜닝이 표준화돼야 하는 회사 정책, (b) Auto Scaling으로 분 단위로 인스턴스를 띄우고 죽이는 워크로드(부팅 시간이 곧 비용), (c) 라이센스가 머신에 묶이는 BYOL 워크로드(예: 일부 RHEL Subscription).
그래서 한 인스턴스에서 AMI를 굳힐지 결정하는 한 줄. 이 인스턴스를 한 번 더 만들 일이 있나 묻는다. 있으면 굳혀 두는 게 다음 부팅을 빠르게 해 준다. 없거나 한 번뿐이면 그냥 user-data 또는 컨테이너로 가는 게 깔끔하다.
한 AMI를 만들 때 같이 적어 두면 좋은 세 줄
운영 첫 날에 AMI를 굳히면서 같이 메모해 두면 청구서·보안 사고가 자라지 않는 세 줄.
- 어떤 KMS 키로 암호화돼 있는지 확인한다. 다른 계정으로 공유할 거면 customer managed 키로 다시 빌드한다.
- 몇 개의 EBS 스냅샷이 같이 만들어졌는지 적어 둔다. deregister 시 같이 청소해야 하기 때문이다.
- 어느 리전·어느 계정으로 퍼져 나갈 예정인지 메모한다. cross-region copy를 한다면 KMS 키도 리전마다 미리 만들어 둬야 한다.
EBS 자체는 다음 편에서 본다. AMI 안에서 같이 굳어진 그 스냅샷의 원본이며, 인스턴스에 붙은 디스크가 어디에 붙어 있는가를 두 갈래의 길로 다룬다.













