본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 20. · 6 Views
VPC 피어링과 엔드포인트 완벽 가이드
VPC 간 안전한 통신을 위한 피어링 연결과 AWS 서비스 접근을 위한 엔드포인트 구성 방법을 실무 중심으로 배워봅니다. 프라이빗한 네트워크 구성의 핵심 개념을 쉽게 이해할 수 있습니다.
목차
1. VPC 피어링 개념
어느 날 김개발 씨는 회사의 개발 환경과 운영 환경을 분리하는 작업을 맡았습니다. 각각 다른 VPC로 분리했는데, 문제가 생겼습니다.
개발 서버에서 운영 데이터베이스에 접근해야 하는데 어떻게 해야 할까요?
VPC 피어링은 서로 다른 VPC를 프라이빗하게 연결하는 네트워킹 기술입니다. 마치 두 개의 독립된 건물 사이에 전용 복도를 만드는 것과 같습니다.
인터넷을 거치지 않고 안전하게 AWS 네트워크 내부에서만 통신할 수 있습니다.
다음 코드를 살펴봅시다.
# VPC 피어링 연결 생성 예제
import boto3
ec2 = boto3.client('ec2')
# VPC 피어링 연결 생성
response = ec2.create_vpc_peering_connection(
VpcId='vpc-12345678', # 요청자 VPC
PeerVpcId='vpc-87654321', # 수락자 VPC
PeerRegion='ap-northeast-2' # 리전이 다른 경우 지정
)
peering_id = response['VpcPeeringConnection']['VpcPeeringConnectionId']
print(f"피어링 연결 생성됨: {peering_id}")
김개발 씨는 입사 6개월 차 인프라 담당 개발자입니다. 오늘 팀장님께서 새로운 미션을 주셨습니다.
"개발 환경과 운영 환경을 완전히 분리해주세요. 하지만 개발팀이 운영 DB에 접근할 수 있어야 합니다." 김개발 씨는 고민에 빠졌습니다.
각각 다른 VPC로 분리하면 격리는 되지만, 서로 통신할 수 없습니다. 그렇다고 인터넷을 통해 연결하자니 보안이 걱정됩니다.
선배 개발자 박시니어 씨가 다가와 힌트를 줍니다. "VPC 피어링을 사용해보는 게 어때요?" 그렇다면 VPC 피어링이란 정확히 무엇일까요?
쉽게 비유하자면, VPC 피어링은 마치 두 개의 독립된 아파트 단지 사이에 전용 지하 통로를 만드는 것과 같습니다. 각 단지는 독립적으로 관리되지만, 허가받은 사람들은 안전한 지하 통로를 통해 다른 단지로 이동할 수 있습니다.
바깥 도로(인터넷)를 거치지 않아도 되는 것입니다. VPC 피어링도 마찬가지입니다.
두 VPC 사이에 프라이빗한 네트워크 연결을 만들어, AWS 내부 네트워크를 통해서만 통신하게 합니다. VPC 피어링이 없던 시절에는 어땠을까요?
개발자들은 VPC 간 통신을 위해 퍼블릭 인터넷을 사용해야 했습니다. 각 리소스에 공인 IP를 할당하고, 보안 그룹을 열어야 했습니다.
이는 보안상 매우 위험했습니다. 더 큰 문제는 인터넷을 거치면서 발생하는 레이턴시와 데이터 전송 비용이었습니다.
또한 VPN 연결을 구성하는 방법도 있었지만, 설정이 복잡하고 유지보수가 어려웠습니다. 프로젝트가 커질수록 관리해야 할 연결이 기하급수적으로 늘어났습니다.
바로 이런 문제를 해결하기 위해 VPC 피어링이 등장했습니다. VPC 피어링을 사용하면 프라이빗한 통신이 가능해집니다.
인터넷 게이트웨이나 NAT 게이트웨이 없이도 VPC 간 직접 통신이 됩니다. 또한 AWS 백본 네트워크를 사용하므로 낮은 레이턴시를 보장합니다.
무엇보다 데이터 전송 비용이 인터넷을 거치는 것보다 저렴하다는 큰 이점이 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 boto3 클라이언트를 생성합니다. 이것이 AWS API를 호출하는 기본 도구입니다.
다음으로 create_vpc_peering_connection 메서드를 호출합니다. VpcId는 요청을 보내는 VPC이고, PeerVpcId는 연결을 수락할 VPC입니다.
PeerRegion 파라미터로 다른 리전의 VPC와도 연결할 수 있습니다. 마지막으로 생성된 피어링 연결의 ID가 반환됩니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 이커머스 회사를 운영한다고 가정해봅시다.
고객 서비스용 VPC, 결제 시스템용 VPC, 데이터 분석용 VPC를 각각 분리해서 운영합니다. VPC 피어링을 활용하면 각 시스템 간 안전하게 데이터를 주고받으면서도 보안 격리를 유지할 수 있습니다.
넷플릭스, 에어비앤비 같은 많은 기업에서 이런 패턴을 적극적으로 사용하고 있습니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 CIDR 블록이 겹치는 VPC를 피어링하려는 것입니다. VPC A가 10.0.0.0/16이고 VPC B도 10.0.0.0/16이면 피어링이 불가능합니다.
IP 주소가 겹쳐서 라우팅할 수 없기 때문입니다. 따라서 VPC 설계 단계부터 CIDR 블록을 서로 겹치지 않게 계획해야 합니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다.
"아, 그래서 VPC를 설계할 때 CIDR 블록을 미리 잘 나눠야 하는군요!" VPC 피어링을 제대로 이해하면 안전하고 효율적인 멀티 VPC 아키텍처를 구성할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - VPC 생성 시 CIDR 블록을 미리 계획하여 겹치지 않게 설계하세요
- 피어링 연결은 양방향이지만, 라우팅 테이블은 각 VPC에서 별도로 설정해야 합니다
- 같은 리전뿐 아니라 다른 리전, 다른 계정의 VPC와도 피어링 가능합니다
2. 피어링 연결 생성
VPC 피어링 개념을 이해한 김개발 씨는 이제 실제로 연결을 만들어야 합니다. AWS 콘솔을 열어보니 생각보다 단계가 많아 보입니다.
"요청하고, 수락하고, 그 다음엔 뭐죠?"
피어링 연결 생성은 요청자가 피어링을 신청하고 수락자가 승인하는 2단계 프로세스입니다. 마치 친구 추가 요청을 보내고 상대방이 수락하는 것과 같습니다.
연결이 생성된 후에도 라우팅 설정이 필요합니다.
다음 코드를 살펴봅시다.
# VPC 피어링 연결 생성 및 수락 전체 과정
import boto3
ec2 = boto3.client('ec2')
# 1단계: 피어링 연결 요청
response = ec2.create_vpc_peering_connection(
VpcId='vpc-dev-12345',
PeerVpcId='vpc-prod-67890',
PeerOwnerId='123456789012' # 다른 계정일 경우
)
peering_id = response['VpcPeeringConnection']['VpcPeeringConnectionId']
# 2단계: 피어링 연결 수락 (수락자 측에서 실행)
ec2.accept_vpc_peering_connection(
VpcPeeringConnectionId=peering_id
)
print(f"피어링 연결 완료: {peering_id}")
김개발 씨는 AWS 콘솔에 로그인했습니다. VPC 대시보드에서 피어링 연결 메뉴를 찾았습니다.
하지만 막상 클릭하니 입력할 항목이 여러 개 나옵니다. "요청자 VPC, 수락자 VPC, 계정 ID...
이게 다 뭐지?" 점심시간에 박시니어 씨와 함께 밥을 먹으면서 질문했습니다. "피어링 연결을 만들려는데, 단계가 좀 복잡해 보여요." 박시니어 씨가 친절하게 설명해줍니다.
그렇다면 피어링 연결 생성 과정은 어떻게 될까요? 쉽게 비유하자면, 피어링 연결은 마치 SNS에서 친구 추가하는 것과 같습니다.
내가 친구 요청을 보내면, 상대방이 수락 버튼을 눌러야 비로소 친구가 됩니다. 한쪽만 원한다고 자동으로 연결되지 않습니다.
이는 보안상 매우 중요한 설계입니다. VPC 피어링도 동일한 방식입니다.
요청자가 먼저 피어링 연결을 신청하고, 수락자가 이를 승인해야 활성화됩니다. 왜 이렇게 복잡한 절차가 필요할까요?
만약 요청만으로 자동 연결된다면 어떻게 될까요? 누군가 악의적으로 우리 VPC에 연결을 시도할 수 있습니다.
우리도 모르는 사이에 네트워크가 노출될 수 있습니다. 더 큰 문제는 잘못된 VPC에 연결되어 프로덕션 환경이 위험에 처할 수 있다는 것입니다.
바로 이런 위험을 방지하기 위해 2단계 승인 프로세스가 필요합니다. 피어링 연결 생성 프로세스를 사용하면 명시적인 승인이 가능합니다.
양쪽 관리자가 모두 동의해야만 연결이 활성화됩니다. 또한 연결 요청 내역이 모두 기록되어 감사 추적이 가능합니다.
무엇보다 잘못된 연결 시도를 사전에 차단할 수 있다는 큰 이점이 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 create_vpc_peering_connection으로 연결을 요청합니다. VpcId는 요청을 보내는 쪽, PeerVpcId는 받는 쪽입니다.
PeerOwnerId는 다른 AWS 계정의 VPC와 연결할 때 필요합니다. 같은 계정이면 생략 가능합니다.
요청이 생성되면 피어링 ID가 반환됩니다. 이 ID를 받아서 수락자 측에서 accept_vpc_peering_connection을 호출하면 연결이 활성화됩니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 대기업의 IT 부서를 생각해봅시다.
마케팅팀, 재무팀, 개발팀이 각각 독립된 AWS 계정을 사용합니다. 개발팀이 마케팅팀의 데이터 웨어하우스에 접근해야 한다면, 개발팀 계정에서 피어링을 요청하고 마케팅팀 계정에서 수락합니다.
이렇게 하면 각 팀의 네트워크 관리자가 명시적으로 승인한 연결만 허용됩니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 피어링 연결만 생성하고 라우팅 테이블을 설정하지 않는 것입니다. 피어링 연결이 Active 상태가 되어도, 라우팅 테이블에 경로를 추가하지 않으면 실제로 통신할 수 없습니다.
마치 전화번호를 교환했지만 전화를 걸지 않는 것과 같습니다. 따라서 피어링 생성 후 반드시 라우팅 설정을 해야 합니다.
또 하나 주의할 점은 보안 그룹 설정입니다. 피어링이 연결되어도 보안 그룹이 트래픽을 막고 있으면 통신이 안 됩니다.
상대방 VPC의 CIDR 블록을 소스로 하는 인바운드 규칙을 추가해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨의 설명을 들은 김개발 씨는 메모장을 꺼냈습니다. "피어링 생성, 수락, 라우팅 설정, 보안 그룹 설정까지 총 4단계네요!" 피어링 연결 생성 과정을 제대로 이해하면 안전하고 체계적인 VPC 간 연결을 구성할 수 있습니다.
여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - 피어링 상태가 pending-acceptance에서 active로 변경되었는지 꼭 확인하세요
- 다른 계정과 피어링할 때는 계정 ID를 정확히 입력해야 합니다
- 피어링 연결은 삭제했다가 다시 만들 수 있지만, ID가 변경되므로 주의하세요
3. 라우팅 설정
피어링 연결이 Active 상태가 된 김개발 씨는 기뻐하며 개발 서버에서 운영 DB에 접속을 시도했습니다. 그런데 연결이 안 됩니다.
"분명히 피어링이 활성화됐는데 왜 안 되는 거죠?"
라우팅 설정은 피어링 연결을 통해 트래픽이 실제로 흐르도록 경로를 지정하는 작업입니다. 마치 지도에 목적지까지의 경로를 표시하는 것과 같습니다.
각 VPC의 라우팅 테이블에 상대방 CIDR로 가는 경로를 추가해야 합니다.
다음 코드를 살펴봅시다.
# 피어링 연결을 위한 라우팅 테이블 설정
import boto3
ec2 = boto3.client('ec2')
# VPC A의 라우팅 테이블에 VPC B로 가는 경로 추가
ec2.create_route(
RouteTableId='rtb-dev-12345',
DestinationCidrBlock='10.1.0.0/16', # VPC B의 CIDR
VpcPeeringConnectionId='pcx-abc123'
)
# VPC B의 라우팅 테이블에 VPC A로 가는 경로 추가
ec2.create_route(
RouteTableId='rtb-prod-67890',
DestinationCidrBlock='10.0.0.0/16', # VPC A의 CIDR
VpcPeeringConnectionId='pcx-abc123'
)
print("라우팅 설정 완료")
김개발 씨는 당황했습니다. 분명히 AWS 콘솔에서 피어링 연결 상태가 Active로 표시되는데, 핑도 안 나가고 SSH 접속도 안 됩니다.
"혹시 제가 뭔가 빠뜨린 게 있나요?" 박시니어 씨가 화면을 보더니 바로 알아챘습니다. "아, 라우팅 테이블 설정 안 하셨네요.
피어링 연결만으로는 부족해요." 그렇다면 라우팅 설정이란 정확히 무엇일까요? 쉽게 비유하자면, 라우팅 설정은 마치 내비게이션에 목적지를 입력하는 것과 같습니다.
두 건물 사이에 복도를 만들었다고 해서 사람들이 자동으로 찾아가지 않습니다. "저쪽 건물로 가려면 이 복도를 이용하세요"라는 안내판이 필요합니다.
라우팅 테이블이 바로 그 안내판 역할을 합니다. VPC의 라우팅 테이블도 마찬가지입니다.
특정 IP 대역으로 가는 패킷을 어느 경로로 보낼지 알려줍니다. 라우팅 설정을 하지 않으면 어떻게 될까요?
피어링 연결이 활성화되어도 VPC는 그 연결을 사용할지 모릅니다. VPC A에서 10.1.0.0/16 대역으로 패킷을 보내려 할 때, 라우팅 테이블에 해당 경로가 없으면 패킷은 버려집니다.
마치 주소를 모르면 편지를 보낼 수 없는 것과 같습니다. 더 큰 문제는 한쪽만 설정하고 반대쪽을 빠뜨리면 단방향 통신만 되는 이상한 상황이 발생한다는 것입니다.
바로 이런 문제를 해결하기 위해 양방향 라우팅 설정이 필요합니다. 라우팅 테이블을 올바르게 설정하면 패킷이 정확한 경로로 전달됩니다.
VPC A에서 B로, B에서 A로 양방향 통신이 가능해집니다. 또한 서브넷별로 다른 라우팅 정책을 적용할 수도 있습니다.
무엇보다 네트워크 트래픽의 흐름을 완전히 제어할 수 있다는 큰 이점이 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 VPC A의 라우팅 테이블 ID를 지정합니다. DestinationCidrBlock에는 목적지인 VPC B의 CIDR 블록을 입력합니다.
VpcPeeringConnectionId는 앞서 생성한 피어링 연결의 ID입니다. 이 경로를 추가하면 "10.1.0.0/16으로 가는 트래픽은 이 피어링 연결을 통해 보내라"는 의미가 됩니다.
같은 방식으로 VPC B의 라우팅 테이블에도 반대 방향 경로를 추가합니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 마이크로서비스 아키텍처를 운영하는 회사를 생각해봅시다. 각 서비스가 별도의 VPC에 있고, API 게이트웨이 VPC에서 각 서비스 VPC로 라우팅해야 합니다.
이때 API 게이트웨이 VPC의 라우팅 테이블에 모든 서비스 VPC로 가는 경로를 추가하고, 각 서비스 VPC에서도 API 게이트웨이로 돌아오는 경로를 설정합니다. 넷플릭스, 우버 같은 대규모 서비스에서 이런 패턴을 사용합니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 모든 서브넷의 라우팅 테이블을 확인하지 않는 것입니다.
VPC 하나에 여러 서브넷이 있을 수 있고, 각 서브넷이 다른 라우팅 테이블을 사용할 수 있습니다. 퍼블릭 서브넷의 라우팅 테이블만 설정하고 프라이빗 서브넷은 빠뜨리면, 프라이빗 서브넷의 리소스는 피어링 연결을 사용할 수 없습니다.
따라서 통신이 필요한 모든 서브넷의 라우팅 테이블을 확인해야 합니다. 또 하나 주의할 점은 가장 구체적인 경로가 우선된다는 것입니다.
예를 들어 0.0.0.0/0과 10.1.0.0/16이 모두 라우팅 테이블에 있으면, 10.1.0.5로 가는 패킷은 더 구체적인 10.1.0.0/16 경로를 따릅니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨의 도움으로 라우팅 테이블을 설정한 김개발 씨는 다시 접속을 시도했습니다. "오, 됩니다!
핑도 나가고 SSH도 되네요!" 라우팅 설정을 제대로 이해하면 복잡한 멀티 VPC 환경에서도 네트워크를 자유자재로 제어할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - 각 VPC의 모든 관련 서브넷 라우팅 테이블을 확인하세요
- 라우팅 우선순위는 가장 구체적인(prefix가 긴) 경로가 높습니다
- AWS 콘솔에서 라우팅 테이블의 "Routes" 탭에서 설정을 확인할 수 있습니다
4. VPC 엔드포인트 종류
며칠 후 김개발 씨는 새로운 과제를 받았습니다. "S3에 저장된 로그 파일을 분석 서버에서 읽어와야 하는데, 보안팀에서 인터넷을 거치지 말라고 하네요." 어떻게 해야 할까요?
VPC 엔드포인트는 AWS 서비스에 프라이빗하게 접근할 수 있는 통로입니다. 인터넷 게이트웨이나 NAT 없이도 S3, DynamoDB 같은 서비스를 사용할 수 있습니다.
게이트웨이 엔드포인트와 인터페이스 엔드포인트 두 가지 종류가 있습니다.
다음 코드를 살펴봅시다.
# VPC 엔드포인트 종류 확인
import boto3
ec2 = boto3.client('ec2')
# 사용 가능한 엔드포인트 서비스 목록 조회
response = ec2.describe_vpc_endpoint_services()
# 게이트웨이 타입 서비스 필터링
gateway_services = [
svc for svc in response['ServiceNames']
if 's3' in svc or 'dynamodb' in svc
]
# 인터페이스 타입 서비스 (나머지 대부분)
interface_services = [
svc for svc in response['ServiceNames']
if svc not in gateway_services
]
print(f"게이트웨이 엔드포인트: {len(gateway_services)}개")
print(f"인터페이스 엔드포인트: {len(interface_services)}개")
김개발 씨는 또 다시 고민에 빠졌습니다. 프라이빗 서브넷의 EC2 인스턴스에서 S3 버킷에 접근해야 하는데, 보안 정책상 인터넷을 거칠 수 없습니다.
"NAT 게이트웨이를 쓰면 되지 않나요?"라고 물었더니, 보안팀에서 거절했습니다. 점심시간에 박시니어 씨를 찾아가 물어봤습니다.
"인터넷 없이 S3를 쓸 수 있는 방법이 있나요?" 박시니어 씨가 웃으며 대답합니다. "VPC 엔드포인트를 사용하면 돼요." 그렇다면 VPC 엔드포인트란 정확히 무엇일까요?
쉽게 비유하자면, VPC 엔드포인트는 마치 백화점의 직원 전용 통로와 같습니다. 고객들은 정문으로 들어가지만, 직원들은 뒷문으로 바로 들어갑니다.
외부로 나갔다 들어올 필요가 없습니다. VPC 엔드포인트도 마찬가지로 VPC 내부에서 AWS 서비스로 바로 연결되는 프라이빗 통로입니다.
인터넷을 거치지 않고 AWS 백본 네트워크를 통해서만 통신합니다. VPC 엔드포인트가 없던 시절에는 어땠을까요?
프라이빗 서브넷의 리소스가 S3에 접근하려면 NAT 게이트웨이를 거쳐 인터넷으로 나가야 했습니다. 이는 보안상 위험했습니다.
데이터가 VPC 밖으로 나갔다 들어오기 때문입니다. 더 큰 문제는 NAT 게이트웨이 비용과 데이터 전송 비용이 만만치 않았다는 것입니다.
대용량 데이터를 주고받으면 비용이 기하급수적으로 늘어났습니다. 바로 이런 문제를 해결하기 위해 VPC 엔드포인트가 등장했습니다.
VPC 엔드포인트를 사용하면 완전한 프라이빗 통신이 가능합니다. 데이터가 절대 인터넷으로 나가지 않습니다.
또한 NAT 게이트웨이가 필요 없어 비용을 절감할 수 있습니다. 무엇보다 AWS 백본 네트워크를 사용하므로 빠르고 안정적이라는 큰 이점이 있습니다.
VPC 엔드포인트에는 두 가지 종류가 있습니다. 첫 번째는 게이트웨이 엔드포인트입니다.
S3와 DynamoDB만 지원합니다. 라우팅 테이블에 경로를 추가하는 방식으로 작동합니다.
추가 비용이 없습니다. 두 번째는 인터페이스 엔드포인트입니다.
대부분의 AWS 서비스를 지원합니다. ENI(Elastic Network Interface)를 VPC에 생성하고, 프라이빗 IP 주소를 할당받습니다.
시간당 요금과 데이터 전송 비용이 발생합니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 describe_vpc_endpoint_services를 호출하여 사용 가능한 모든 엔드포인트 서비스를 조회합니다. 반환된 서비스 목록에서 S3와 DynamoDB를 필터링하면 게이트웨이 타입 서비스입니다.
나머지는 대부분 인터페이스 타입입니다. 이렇게 구분해두면 어떤 엔드포인트를 사용해야 할지 쉽게 판단할 수 있습니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 금융권 시스템을 개발한다고 가정해봅시다.
고객 개인정보가 담긴 데이터를 S3에 저장하고 분석합니다. 규제상 데이터가 절대 인터넷으로 나가면 안 됩니다.
이때 S3 게이트웨이 엔드포인트를 사용하면 완전히 프라이빗한 환경에서 데이터를 처리할 수 있습니다. 많은 은행, 증권사에서 이런 패턴을 필수로 사용합니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 모든 서비스에 게이트웨이 엔드포인트를 쓰려는 것입니다.
게이트웨이 엔드포인트는 S3와 DynamoDB만 지원합니다. EC2, Lambda, SQS 같은 서비스는 인터페이스 엔드포인트를 사용해야 합니다.
따라서 사용하려는 서비스가 어떤 타입을 지원하는지 먼저 확인해야 합니다. 또 하나 주의할 점은 비용 구조가 다르다는 것입니다.
게이트웨이 엔드포인트는 무료지만, 인터페이스 엔드포인트는 시간당 요금이 발생합니다. 꼭 필요한 곳에만 사용하는 것이 좋습니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다.
"아, S3는 게이트웨이 엔드포인트를 쓰면 되겠네요. 무료이기도 하고요!" VPC 엔드포인트의 종류를 제대로 이해하면 보안과 비용 효율을 모두 잡을 수 있습니다.
여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - S3와 DynamoDB는 게이트웨이 엔드포인트(무료), 나머지는 인터페이스 엔드포인트(유료)
- 엔드포인트 정책으로 특정 버킷이나 테이블만 접근하도록 제한할 수 있습니다
- AWS PrivateLink를 사용하면 자체 서비스도 엔드포인트로 제공 가능합니다
5. 게이트웨이 엔드포인트
김개발 씨는 S3 게이트웨이 엔드포인트를 만들기로 했습니다. 콘솔을 열어보니 생각보다 간단해 보입니다.
"그냥 VPC랑 라우팅 테이블만 선택하면 되는 건가요?"
게이트웨이 엔드포인트는 라우팅 테이블에 경로를 추가하는 방식으로 S3나 DynamoDB에 접근합니다. 마치 지도에 지름길을 표시하는 것과 같습니다.
추가 비용 없이 프라이빗하게 서비스를 사용할 수 있습니다.
다음 코드를 살펴봅시다.
# S3 게이트웨이 엔드포인트 생성
import boto3
ec2 = boto3.client('ec2')
# 게이트웨이 엔드포인트 생성
response = ec2.create_vpc_endpoint(
VpcId='vpc-12345678',
ServiceName='com.amazonaws.ap-northeast-2.s3',
RouteTableIds=[
'rtb-private-1',
'rtb-private-2'
],
PolicyDocument='''{
"Statement": [{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": "*"
}]
}'''
)
endpoint_id = response['VpcEndpoint']['VpcEndpointId']
print(f"게이트웨이 엔드포인트 생성됨: {endpoint_id}")
김개발 씨는 AWS 콘솔에서 VPC 엔드포인트 생성 버튼을 클릭했습니다. 서비스 카테고리에서 AWS 서비스를 선택하고, 서비스 목록에서 S3를 찾았습니다.
두 개의 옵션이 보입니다. "게이트웨이"와 "인터페이스".
"게이트웨이가 무료라고 했으니 이걸로 하면 되겠네요." 하지만 다음 화면에서 라우팅 테이블을 선택하라는 메시지가 나왔습니다. "이게 뭐지?
왜 라우팅 테이블을 선택해야 하는 거지?" 김개발 씨는 또 박시니어 씨를 찾아갔습니다. 그렇다면 게이트웨이 엔드포인트는 어떻게 작동할까요?
쉽게 비유하자면, 게이트웨이 엔드포인트는 마치 내비게이션에 즐겨찾기를 추가하는 것과 같습니다. "S3로 가려면 이 지름길을 이용하세요"라고 경로를 미리 저장해둡니다.
차가 목적지로 갈 때 자동으로 그 지름길을 선택합니다. 물리적인 터널이나 장비를 만드는 게 아니라, 단순히 라우팅 규칙을 추가하는 것입니다.
게이트웨이 엔드포인트도 마찬가지입니다. VPC의 라우팅 테이블에 S3로 가는 경로를 자동으로 추가합니다.
게이트웨이 엔드포인트를 사용하지 않으면 어떻게 될까요? 프라이빗 서브넷의 EC2에서 S3에 접근하려면 NAT 게이트웨이를 거쳐야 합니다.
NAT 게이트웨이는 시간당 요금이 발생하고, 데이터를 처리할 때마다 추가 비용이 듭니다. 대용량 로그를 S3에 업로드하는 서비스라면 한 달에 수백 달러가 나올 수 있습니다.
더 큰 문제는 NAT 게이트웨이가 단일 장애점이 될 수 있다는 것입니다. 바로 이런 문제를 해결하기 위해 게이트웨이 엔드포인트를 사용합니다.
게이트웨이 엔드포인트를 사용하면 완전히 무료입니다. 아무리 많은 데이터를 전송해도 추가 비용이 없습니다.
또한 AWS 백본 네트워크를 사용하므로 빠르고 안정적입니다. 무엇보다 설정이 간단하고, 라우팅 테이블만 지정하면 자동으로 작동한다는 큰 이점이 있습니다.
위의 코드를 한 줄씩 살펴보겠습니다. 먼저 VpcId로 엔드포인트를 생성할 VPC를 지정합니다.
ServiceName은 리전에 따라 달라지므로 정확히 입력해야 합니다. RouteTableIds는 엔드포인트를 사용할 라우팅 테이블의 ID 목록입니다.
보통 프라이빗 서브넷의 라우팅 테이블을 지정합니다. PolicyDocument는 접근 권한을 제어하는 IAM 정책입니다.
위 예제는 모든 접근을 허용하지만, 실무에서는 특정 버킷만 허용하도록 제한하는 것이 좋습니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 빅데이터 분석 플랫폼을 운영하는 회사를 생각해봅시다. 매일 수백 GB의 로그 파일을 S3에 저장하고, EMR 클러스터에서 분석합니다.
모든 컴퓨팅 리소스는 프라이빗 서브넷에 있습니다. S3 게이트웨이 엔드포인트를 사용하면 NAT 게이트웨이 없이도 S3에 접근할 수 있고, 한 달에 수천 달러의 비용을 절감할 수 있습니다.
넷플릭스, 에어비앤비 같은 데이터 집약적 서비스에서 필수로 사용하는 패턴입니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 퍼블릭 서브넷의 라우팅 테이블을 선택하는 것입니다. 퍼블릭 서브넷은 인터넷 게이트웨이를 통해 이미 S3에 접근할 수 있습니다.
게이트웨이 엔드포인트를 추가하면 라우팅 충돌이 발생할 수 있습니다. 따라서 프라이빗 서브넷의 라우팅 테이블만 선택해야 합니다.
또 하나 주의할 점은 엔드포인트 정책을 너무 개방적으로 설정하는 것입니다. 위 예제처럼 모든 버킷에 모든 작업을 허용하면 보안상 위험합니다.
실무에서는 특정 버킷만 허용하고, 필요한 작업만 허용해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨의 설명을 들은 김개발 씨는 프라이빗 서브넷의 라우팅 테이블을 선택하고 엔드포인트를 생성했습니다. 몇 초 후 상태가 Available로 바뀌었습니다.
"와, 정말 간단하네요!" 게이트웨이 엔드포인트를 제대로 이해하면 비용 효율적이고 안전한 AWS 아키텍처를 구성할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - 게이트웨이 엔드포인트는 S3와 DynamoDB만 지원하며 완전 무료입니다
- 프라이빗 서브넷의 라우팅 테이블만 선택하세요
- 엔드포인트 정책으로 특정 버킷만 접근하도록 제한할 수 있습니다
6. 인터페이스 엔드포인트
며칠 후 김개발 씨는 또 다른 과제를 받았습니다. "Lambda 함수를 VPC 내부에서 프라이빗하게 호출해야 한다는데, 어떻게 하죠?" S3는 게이트웨이 엔드포인트로 해결했지만, Lambda는 안 됩니다.
인터페이스 엔드포인트는 ENI를 생성하여 프라이빗 IP로 AWS 서비스에 접근합니다. 마치 VPC 안에 AWS 서비스의 출장소를 만드는 것과 같습니다.
대부분의 AWS 서비스를 지원하지만 시간당 요금이 발생합니다.
다음 코드를 살펴봅시다.
# Lambda 인터페이스 엔드포인트 생성
import boto3
ec2 = boto3.client('ec2')
# 인터페이스 엔드포인트 생성
response = ec2.create_vpc_endpoint(
VpcId='vpc-12345678',
VpcEndpointType='Interface',
ServiceName='com.amazonaws.ap-northeast-2.lambda',
SubnetIds=[
'subnet-private-1a',
'subnet-private-1c'
],
SecurityGroupIds=['sg-endpoint-12345'],
PrivateDnsEnabled=True
)
endpoint_id = response['VpcEndpoint']['VpcEndpointId']
print(f"인터페이스 엔드포인트 생성됨: {endpoint_id}")
# ENI의 프라이빗 IP 확인
print(f"DNS 이름: {response['VpcEndpoint']['DnsEntries']}")
김개발 씨는 Lambda 서비스를 찾아봤습니다. VPC 엔드포인트 목록에는 있지만, 타입이 "Interface"로 표시됩니다.
"게이트웨이가 아니라 인터페이스네요. 뭐가 다른 거지?" 이번에는 직접 문서를 읽어보기로 했습니다.
문서를 읽다 보니 ENI, 프라이빗 IP, DNS 같은 용어가 나옵니다. 점점 더 복잡해 보입니다.
결국 다시 박시니어 씨를 찾아갔습니다. "인터페이스 엔드포인트는 어떻게 작동하나요?" 그렇다면 인터페이스 엔드포인트는 어떻게 작동할까요?
쉽게 비유하자면, 인터페이스 엔드포인트는 마치 백화점에 브랜드 매장을 입점시키는 것과 같습니다. 백화점(VPC) 안에 나이키 매장(AWS 서비스)을 만들어서, 고객들이 밖으로 나가지 않고도 나이키 제품을 살 수 있게 합니다.
실제로는 본점이 따로 있지만, 백화점 안에서는 지점처럼 느껴집니다. 인터페이스 엔드포인트도 마찬가지입니다.
VPC 안에 ENI(네트워크 인터페이스)를 생성하고, 프라이빗 IP 주소를 할당받습니다. 그 IP로 AWS 서비스에 접근할 수 있습니다.
게이트웨이 엔드포인트와 무엇이 다를까요? 게이트웨이 엔드포인트는 라우팅 테이블에 경로만 추가합니다.
실제 네트워크 인터페이스를 만들지 않습니다. 반면 인터페이스 엔드포인트는 실제로 ENI를 생성합니다.
각 ENI는 서브넷에 배치되고 프라이빗 IP를 받습니다. 따라서 보안 그룹으로 트래픽을 제어할 수 있습니다.
더 큰 차이는 지원하는 서비스 범위입니다. 게이트웨이는 S3와 DynamoDB만 지원하지만, 인터페이스는 Lambda, SQS, SNS, EC2, CloudWatch 등 대부분의 AWS 서비스를 지원합니다.
바로 이런 유연성 때문에 인터페이스 엔드포인트를 사용합니다. 인터페이스 엔드포인트를 사용하면 거의 모든 AWS 서비스에 프라이빗하게 접근할 수 있습니다.
PrivateDnsEnabled 옵션을 켜면 기존 코드 수정 없이 사용 가능합니다. 또한 여러 서브넷에 ENI를 배치하여 고가용성을 확보할 수 있습니다.
무엇보다 보안 그룹으로 세밀하게 접근 제어를 할 수 있다는 큰 이점이 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 VpcEndpointType을 Interface로 지정합니다. ServiceName은 사용할 AWS 서비스를 지정합니다.
SubnetIds는 ENI를 생성할 서브넷 목록입니다. 고가용성을 위해 여러 가용 영역의 서브넷을 지정하는 것이 좋습니다.
SecurityGroupIds는 ENI에 적용할 보안 그룹입니다. PrivateDnsEnabled를 True로 설정하면 AWS 서비스의 기본 DNS 이름이 ENI의 프라이빗 IP로 자동 해석됩니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 서버리스 아키텍처를 사용하는 스타트업을 생각해봅시다.
Lambda 함수가 VPC의 RDS 데이터베이스에 접근하고, 동시에 다른 Lambda 함수를 호출해야 합니다. Lambda 인터페이스 엔드포인트를 만들면 VPC 내부에서 프라이빗하게 Lambda를 호출할 수 있습니다.
인터넷을 거치지 않으므로 보안성과 성능이 모두 향상됩니다. 많은 핀테크, 헬스케어 스타트업에서 이런 패턴을 사용합니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 보안 그룹 설정을 빠뜨리는 것입니다.
인터페이스 엔드포인트의 ENI도 보안 그룹이 필요합니다. 기본 보안 그룹은 모든 트래픽을 차단하므로, 필요한 포트를 열어줘야 합니다.
대부분의 AWS 서비스는 HTTPS(443 포트)를 사용하므로 443을 허용해야 합니다. 또 하나 주의할 점은 비용입니다.
인터페이스 엔드포인트는 시간당 약 0.01달러가 발생합니다. 하나면 별로 안 비싸 보이지만, 여러 서비스에 여러 가용 영역으로 만들면 한 달에 수백 달러가 나올 수 있습니다.
따라서 꼭 필요한 서비스에만 사용해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨의 도움으로 Lambda 인터페이스 엔드포인트를 만든 김개발 씨는 테스트를 해봤습니다. VPC 내부의 EC2에서 Lambda 함수를 호출하니 잘 작동합니다.
"오, 인터넷 없이도 Lambda를 쓸 수 있네요!" 인터페이스 엔드포인트를 제대로 이해하면 완전히 프라이빗한 AWS 환경을 구성할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - PrivateDnsEnabled를 활성화하면 기존 코드 수정 없이 사용 가능합니다
- 보안 그룹에서 443 포트를 허용해야 합니다
- 비용이 발생하므로 꼭 필요한 서비스에만 사용하세요
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
Helm 마이크로서비스 패키징 완벽 가이드
Kubernetes 환경에서 마이크로서비스를 효율적으로 패키징하고 배포하는 Helm의 핵심 기능을 실무 중심으로 학습합니다. Chart 생성부터 릴리스 관리까지 체계적으로 다룹니다.
보안 아키텍처 구성 완벽 가이드
프로젝트의 보안을 처음부터 설계하는 방법을 배웁니다. AWS 환경에서 VPC부터 WAF, 암호화, 접근 제어까지 실무에서 바로 적용할 수 있는 보안 아키텍처를 단계별로 구성해봅니다.
AWS Organizations 완벽 가이드
여러 AWS 계정을 체계적으로 관리하고 통합 결제와 보안 정책을 적용하는 방법을 실무 스토리로 쉽게 배워봅니다. 초보 개발자도 바로 이해할 수 있는 친절한 설명과 실전 예제를 제공합니다.
AWS KMS 암호화 완벽 가이드
AWS KMS(Key Management Service)를 활용한 클라우드 데이터 암호화 방법을 초급 개발자를 위해 쉽게 설명합니다. CMK 생성부터 S3, EBS 암호화, 봉투 암호화까지 실무에 필요한 모든 내용을 담았습니다.
AWS Secrets Manager 완벽 가이드
AWS에서 데이터베이스 비밀번호, API 키 등 민감한 정보를 안전하게 관리하는 Secrets Manager의 핵심 개념과 실무 활용법을 배워봅니다. 초급 개발자도 쉽게 따라할 수 있도록 실전 예제와 함께 설명합니다.