EC2 중지 후에도 Elastic IP 요금이 청구되는 이유와 완전 해제 방법

EC2 인스턴스를 중지(Stop)했는데 다음 날 청구서를 확인하니 Elastic IP 요금이 그대로 붙어 있다. 인스턴스를 껐으니 당연히 IP도 멈출 거라 생각했지만, AWS는 그렇게 동작하지 않는다. Elastic IP 요금 청구 구조를 정확히 이해하지 못하면 아무것도 실행되지 않는 인스턴스에 매달 예상치 못한 비용이 쌓인다.

TL;DR — Elastic IP 요금 청구 핵심 정리

상태요금 발생 여부이유
실행 중 인스턴스에 연결됨❌ 무료정상 사용 중
중지된 인스턴스에 연결됨✅ 요금 발생IP가 유휴 상태로 낭비됨
어떤 인스턴스에도 연결 안 됨 (미연결)✅ 요금 발생IP가 유휴 상태로 낭비됨
연결 해제(Disassociate) 후 릴리스(Release) 완료❌ 무료IP가 AWS 풀로 반환됨

결론: 요금을 완전히 멈추려면 Disassociate(연결 해제)Release(릴리스)를 모두 수행해야 한다. Disassociate만 하면 IP가 계정에 남아 있어 여전히 과금된다.

Elastic IP 요금 구조가 작동하는 방식

AWS가 Elastic IP에 요금을 부과하는 핵심 원칙은 단순하다. 퍼블릭 IPv4 주소는 희소 자원이며, AWS는 계정이 해당 IP를 실제로 사용하지 않으면서 점유하고 있을 때 요금을 청구한다. '사용 중'의 정의는 실행 상태(running)의 인스턴스 또는 NAT 게이트웨이에 연결되어 있을 때다.

인스턴스를 중지하면 그 인스턴스에 연결된 Elastic IP는 즉시 '유휴(idle)' 상태가 된다. AWS 입장에서는 이 IP를 다른 고객에게 할당할 수 없는데 계정이 붙잡고 있는 것이므로, 시간당 요금이 발생한다. 요금과 정확한 조건은 변동될 수 있으므로 항상 공식 AWS EC2 요금 페이지에서 확인해야 한다.

stateDiagram-v2 [*] --> 실행중_연결됨 : Elastic IP 할당 및 연결 실행중_연결됨 --> 중지됨_연결됨 : 인스턴스 Stop 중지됨_연결됨 --> 미연결_유휴 : Disassociate 실행중_연결됨 --> 미연결_유휴 : Disassociate 중지됨_연결됨 --> 종료됨_자동해제 : 인스턴스 Terminate 종료됨_자동해제 --> 미연결_유휴 : Association 자동 해제
(IP는 계정 잔류) 미연결_유휴 --> [*] : Release (요금 종료) 실행중_연결됨 : 실행 중 + 연결됨 중지됨_연결됨 : 중지됨 + 연결됨 미연결_유휴 : 미연결 유휴 상태 종료됨_자동해제 : 인스턴스 종료됨
  1. 실행 중 + 연결됨: Elastic IP가 트래픽을 처리하는 정상 상태. 추가 요금 없음.
  2. 중지됨 + 연결됨: IP는 계정에 묶여 있지만 사용되지 않음. 시간당 요금 발생 시작.
  3. 미연결 상태: 인스턴스와 분리됐지만 릴리스하지 않은 경우. 동일하게 시간당 요금 발생.
  4. 릴리스 완료: IP가 AWS 주소 풀로 반환됨. 요금 청구 완전 종료.
주차장 비유가 딱 맞는다. 주차 공간을 예약(할당)해 두고 차를 빼놓으면(인스턴스 중지), 공간은 여전히 당신 것이라 요금이 나온다. 공간 예약 자체를 취소(릴리스)해야 비용이 멈춘다.

Elastic IP 요금 청구를 완전히 중단하는 방법

두 단계가 반드시 순서대로 실행되어야 한다. 인스턴스가 이미 중지된 상태라면 1단계(Disassociate)부터 시작한다. 인스턴스가 실행 중이라면 중지 후 진행하거나, 실행 중 상태에서도 Disassociate는 가능하다 — 단, 연결 해제 즉시 퍼블릭 IP 접근이 끊긴다는 점을 인지해야 한다.

1단계: Disassociate — 인스턴스에서 Elastic IP 연결 해제

Disassociate는 Elastic IP와 인스턴스(또는 네트워크 인터페이스) 사이의 연결을 끊는 작업이다. 이 시점에서 IP는 계정에 남아 있으며, 아직 요금이 발생한다. Disassociate만 하고 멈추는 실수가 가장 흔하다.

먼저 현재 계정의 Elastic IP 목록과 연결 ID(Association ID)를 확인한다.

aws ec2 describe-addresses \
  --query 'Addresses[*].{PublicIp:PublicIp,AllocationId:AllocationId,AssociationId:AssociationId,InstanceId:InstanceId}' \
  --output table \
  --region us-east-1

출력에서 AssociationId 값(예: eipassoc-0abc1234def56789a)을 확인한 후 연결을 해제한다.

aws ec2 disassociate-address \
  --association-id eipassoc-0abc1234def56789a \
  --region us-east-1

성공하면 응답 없이 명령이 종료된다. 다시 describe-addresses를 실행하면 해당 IP의 AssociationIdInstanceId가 비어 있는 것을 확인할 수 있다.

2단계: Release — Elastic IP를 AWS에 반환

Release는 Elastic IP를 계정에서 완전히 제거하고 AWS 주소 풀로 반환하는 작업이다. 이 시점부터 요금이 멈춘다. Release 후에는 동일한 IP를 다시 할당받을 수 없다는 점을 주의해야 한다 — 이 IP를 DNS나 방화벽 화이트리스트에 등록해 두었다면 사전에 정리가 필요하다.

1단계에서 확인한 AllocationId(예: eipalloc-0abc1234def56789a)를 사용한다.

aws ec2 release-address \
  --allocation-id eipalloc-0abc1234def56789a \
  --region us-east-1

릴리스 후 describe-addresses를 다시 실행하면 해당 IP가 목록에서 사라진 것을 확인할 수 있다. 이 시점부터 해당 Elastic IP에 대한 요금 청구는 종료된다.

계정 전체 유휴 Elastic IP 일괄 확인

여러 리전에 걸쳐 Elastic IP를 운영하다 보면 어느 순간 연결되지 않은 IP가 조용히 쌓인다. 특히 인스턴스를 종료(Terminate)할 때 Elastic IP를 릴리스하지 않으면 이런 상황이 발생한다. 아래 명령으로 현재 리전에서 연결되지 않은 Elastic IP만 필터링할 수 있다.

aws ec2 describe-addresses \
  --filters Name=domain,Values=vpc \
  --query 'Addresses[?AssociationId==`null`].{PublicIp:PublicIp,AllocationId:AllocationId}' \
  --output table \
  --region us-east-1

이 명령은 VPC 스코프의 Elastic IP 중 현재 어떤 리소스에도 연결되지 않은 것만 출력한다. 목록에 나타난 IP는 즉시 릴리스 대상이다.

실제 운영에서 마주치는 패턴 — 잘못된 진단과 실제 원인

인스턴스를 종료(Terminate)했는데도 Elastic IP 요금이 계속 나온다는 문의가 종종 있다. 확인해 보면 대부분 두 가지 중 하나다.

첫 번째는 인스턴스 종료 시 Elastic IP가 자동 릴리스되지 않는다는 점을 몰랐던 경우다. 인스턴스를 Terminate하면 연결(Association)은 자동으로 해제되지만, Elastic IP 자체는 계정에 남는다. 콘솔에서 인스턴스가 사라졌으니 IP도 사라졌을 거라 생각하지만, EC2 → Elastic IPs 메뉴를 열면 여전히 살아 있다.

두 번째는 여러 리전에 걸친 Elastic IP를 추적하지 못한 경우다. 비용 탐색기(Cost Explorer)에서 EC2 Other 항목으로 요금이 잡히는데, 어느 리전인지 바로 보이지 않아 찾는 데 시간이 걸린다. AWS Cost Explorer에서 서비스를 'EC2'로, 사용 유형 그룹(Usage Type Group)을 'Elastic IP'로 필터링하면 리전별로 분리해서 볼 수 있다.

graph TD A[인스턴스 Terminate] --> B[Association 자동 해제] B --> C[Elastic IP 계정 잔류
유휴 상태] C --> D{수동 Release 여부} D -- Release 안 함 --> E[시간당 요금 계속 발생] D -- Release 실행 --> F[AWS 주소 풀 반환
요금 청구 종료] style E fill:#ff6b6b,color:#fff style F fill:#51cf66,color:#fff
  1. 인스턴스 Terminate: 연결(Association)은 자동 해제되지만 Elastic IP는 계정에 잔류.
  2. 유휴 상태 진입: 연결 해제된 Elastic IP가 시간당 요금 발생 상태로 전환.
  3. 수동 Release 필요: 명시적으로 Release해야만 요금 청구가 종료됨.

Elastic IP 없이 퍼블릭 IP를 유지하는 대안

Elastic IP가 필요한 이유가 '인스턴스 재시작 후에도 동일한 퍼블릭 IP를 유지하기 위해서'라면, 실제로 고정 IP가 필요한지 먼저 검토할 필요가 있다. 인스턴스에 자동 할당 퍼블릭 IP(Auto-assign Public IP)를 활성화하면 무료로 퍼블릭 IP가 부여되지만, 인스턴스를 중지하고 재시작할 때마다 IP가 바뀐다. 고정 IP가 필요하다면 Elastic IP가 맞지만, 단순히 외부 접근만 필요하다면 Route 53의 동적 DNS 업데이트나 로드 밸런서 DNS 이름을 사용하는 방식이 비용 측면에서 더 효율적일 수 있다.

IAM 권한 — Elastic IP 관리에 필요한 최소 권한

운영 계정에서 Elastic IP 릴리스 작업을 특정 역할에 위임할 때는 아래 최소 권한 정책을 참고한다. ec2:DescribeAddresses는 리소스 수준 제한을 지원하지 않으므로 "Resource": "*"가 필요하다.

🔽 Elastic IP 관리 최소 권한 IAM 정책 (클릭하여 펼치기)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DescribeElasticIPs",
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeAddresses"
      ],
      "Resource": "*"
    },
    {
      "Sid": "ManageElasticIPs",
      "Effect": "Allow",
      "Action": [
        "ec2:DisassociateAddress",
        "ec2:ReleaseAddress"
      ],
      "Resource": "*"
    }
  ]
}

ec2:AllocateAddressec2:AssociateAddress는 새 IP 할당과 연결에만 필요하므로, 릴리스 전용 역할에는 포함하지 않는다.

Elastic IP 요금 청구 중단 — 마무리 및 다음 단계

EC2 인스턴스를 중지하거나 종료할 때 Elastic IP 요금을 멈추려면 반드시 Disassociate → Release 두 단계를 완료해야 한다. Disassociate만으로는 IP가 계정에 남아 계속 과금된다. 정기적으로 describe-addresses로 연결되지 않은 Elastic IP를 점검하는 습관을 들이면 불필요한 비용을 사전에 차단할 수 있다.

핵심 용어 정리

용어설명
Elastic IP (EIP)AWS 계정에 할당되는 고정 퍼블릭 IPv4 주소. 인스턴스와 독립적으로 존재한다.
Allocation IDElastic IP가 계정에 할당될 때 부여되는 고유 식별자 (예: eipalloc-xxx). Release의 기준 단위.
Association IDElastic IP가 특정 인스턴스 또는 네트워크 인터페이스에 연결될 때 생성되는 식별자. Disassociate의 기준 단위.
DisassociateElastic IP와 인스턴스 간의 연결을 해제하는 작업. IP는 계정에 잔류하며 요금이 계속 발생한다.
ReleaseElastic IP를 계정에서 완전히 제거하고 AWS 풀로 반환하는 작업. 이 시점부터 요금 청구가 종료된다.

댓글

이 블로그의 인기 게시물

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

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

IAM User vs IAM Role 차이점 완전 정리 — EC2에서 S3 접근 시 무엇을 써야 하는가