Canvas 1 Layer 1

AWS CLI로 기본 VPC 관련 리소스들 탐색하기
VPC, 서브넷, 시큐리티 그룹

들어가며

아마존 웹서비스Amazon Web Service에서는 네트워크 자원을 직접 설계하고 관리할 수 있도록 아마존 버추얼 프라이빗 클라우드Amazon Virtual Private Cloud, VPC를 제공하고 있습니다. 2013년 12월 이후에 생성된 계정에서는 기존의 VPC 없이 AWS의 리소스를 사용할 수 있었던 EC2-클래식EC2-Classic 플랫폼을 사용할 수 없게 되었습니다. 그 대신 계정을 생성할 때 기본 VPCDefault VPC가 자동으로 생성되고, VPC를 의식하거나 직접 설계하지 않아도 기존의 EC2-클래식 플랫폼처럼 EC2 인스턴스나 RDS 인스턴스를 곧바로 실행할 수 있습니다. 하지만 AWS를 제대로 사용하려면 VPC나 이 기본 VPC에 대해서 어느정도 이해를 할 필요가 있습니다. 이 글에서는 AWS 계정 생성 시에 자동으로 생성되는 기본 VPC와 이에 속한 서브넷과 시큐리티 그룹에 대해서 간략히 설명합니다.

AWS 계정과 함께 생성되는 기본 VPC와 네트워크 리소스들

클라우드에서 가장 기본이 되는 서비스는 EC2와 같은 가상화된 컴퓨팅 리소스를 제공하는 서비스입니다. EC2를 실행하려면 EC2가 실행되는 VPC와 서브넷을 지정할 필요가 있습니다. AWS에서는 사용자가 직접 VPC나 서브넷을 생성한 적이 없더라도 EC2를 생성하는 것이 가능합니다. 이는 계정 생성 시에 기본 VPC와 서브넷이 함께 생성되기 때문입니다. 예를 들어 아래 이미지는 서울 리전에서 VPC 대시보드에 접속한 화면입니다. AWS 계정이 있다면 자신의 계정에서 직접 접속해보시기 바랍니다.

VPC에 속한 모든 네트워크 리소스 목록
VPC에 속한 모든 네트워크 리소스 목록

이 화면의 각 항목들은 VPC와 연관된 리소스 타입들입니다. 각 항목 별로 오른쪽의 숫자는 리소스의 개수입니다. 각 리소스에 대해서는 정확하게 이해하지 않더라도 괜찮습니다. 현재 생성된 리소스들을 한 번 세어보겠습니다. 서울 리전에는 현재 VPC 1개, 서브넷 2개, 라우트 테이블 1개, 네트워크 ACL 1개, 인터넷 게이트웨이 1개, 시큐리티 그룹 4개, DHCP 옵션 셋 1개 총 11개의 리소스가 생성되어있습니다. 시큐리티 그룹은 현재 4개가 있지만 실제로 계정 생성시에 만들어진 것은 1개입니다. 따라서 총 8개의 리소스가 있는 것을 알 수 있습니다. 이 리소스들은 계정 생성 시에 기본 VPC를 생성하면서 자동으로 만들어집니다. 그리고 이 리소스들은 리전 별로 생성이 됩니다. 따라서 리전을 15개 정도로 계산해보면 대략 100개 이상의 네트워크 관련 리소스들이 계정 생성 시에 함께 생성된다는 것을 알 수 있습니다.

VPC와 서브넷의 관계
VPC와 서브넷의 관계

먼저 이 중에 가장 중요한 개념이 VPC입니다. VPC는 IP 대역의 일부를 할당해서 만드는 가상 네트워크입니다. 그리고 서브넷은 이 VPC 내부를 다시 잘게 나눈 네트워크 대역들입니다. 서브넷은 서비스가 실제로 실행되는 네트워크 대역으로 VPC보다 범위가 좁습니다. 하나의 AWS 리전에는 다수의 가용 영역이 존재합니다. 가용 영역은 서버가 존재하는 물리적인 공간을 의미하며, 사용가능한 가용전은 계정에 따라서 다릅니다. 서브넷은 각각 해당 리전의 1개의 가용존에 직접 연결되어 있어야합니다. 예를 들어 ap-northeast-2a 가용 영역에 연결된 서브넷에서 EC2 인스턴스를 실행하는 경우 이 인스턴스는 ap-northeast-2a에서 실행됩니다.

서브넷은 하나의 가용존과 연결되어있으며, 서브넷에 속한 모든 리소스는 이 가용존에 속한다
서브넷은 하나의 가용존과 연결되어있으며, 서브넷에 속한 모든 리소스는 이 가용존에 속한다

기본 VPC의 서브넷은 해당 계정에서 사용가능한 n개의 가용 영역에 대해서 1:1 관계로 n개가 만들어집니다. 예를 들어 어떤 계정이 서울 리전의 가용존 ap-northeast-2a, ap-northeast-2b를 사용할 수 있다면 각 서브넷에 연결된 2개의 서브넷이 만들어집니다. 얼핏 생각해보면 가용 영역을 나누면 아키텍처는 복잡해지고 레이턴시도 늘어납니다. 네트워크 아키텍처에 대한 이해가 없다면 이러한 구성은 생소하게 느껴질 수도 있습니다. 둘 이상의 가용 영역으로 분산해서 서비스를 운용하면 하나의 가용 영역에 장애가 나더라도 문제없이 서비스를 운영할 수 있다는 장점이 있습니다. 따라서 클라우드에서 서비스를 구성할 때는 인스턴스도 최소한 2개 이상, 가용 영역도 최소한 2개 이상으로 분산해서 구성하는 것이 일반적입니다.

가용 영역은 리전과 계정에 따라서 사용할 수 있는 개수가 다릅니다. 이에 따라 자동적으로 생성되는 개수도 다릅니다. 예를 들어 같은 계정에서 버지니아 리전에 접속해보면 서브넷에 6개가 만들어져있습니다. 이는 이 계정에서 버지니아 리전에 대해 사용가능한 가용 영역이 6개이기 때문입니다.

버지니아 리전에는 기본적으로 6개의 서브넷이 만들어져 있습니다
버지니아 리전에는 기본적으로 6개의 서브넷이 만들어져 있습니다

AWS CLI로 기본 VPC 관련 리소스 탐색

여기서부터는 AWS 커맨드라인 인터페이스를 사용해 기본 VPC와 관련된 리소스들을 조회해보는 방법을 알아보겠습니다. 앞서 살펴보았듯이 기본 VPC는 VPC, 서브넷, 라우트 테이블, 네트워크 ACL, 인터넷 게이트웨이, 시큐리티 그룹, DHCP 옵션 셋 등 다양한 리소스들로 구성됩니다. 여기서는 VPC, 서브넷, 시큐리티 그룹을 중심으로 살펴보겠습니다. AWSCLI의 기본적인 사용법은 AWS 커맨드라인 인터페이스 기초, jq의 사용법은 커맨드라인 JSON 프로세서 jq: 기초 문법과 작동 원리를 참고해주세요. 여기에서는 서울 리전(ap-northeast-2)를 사용합니다.*

* AWS 리전은 AWS_DEFAULT_REGION 환경 변수로 설정할 수 있습니다.

기본 VPC(default VPC)

VPC에 대한 정보는 aws ec2 describe-vpcs로 조회할 수 있습니다. 필터를 사용해 기본 VPC만 조회해봅니다.

$ aws ec2 describe-vpcs --filter 'Name=isDefault,Values=true'

실행 결과는 다음과 같습니다.

CidrBlock이 이 VPC에 할당된 범위를 의미합니다. 간단히 설명하면 172.31.0.0부터 65,536개의 IP가 할당되어있습니다. IsDefault 속성으로 이 VPC가 기본 VPC 임을 확인할 수 있습니다.

jq를 사용해 VPC ID를 조회합니다. 이 VPC ID를 알아야 이 VPC에 속해있는 서브넷을 조회할 수 있습니다.

$ aws ec2 describe-vpcs --filter 'Name=isDefault,Values=true' \
  | jq '.Vpcs[0].VpcId'
"vpc-12345678"
노트
기본 VPC를 삭제해버렸다면?

AWS 네트워크 환경에 익숙하지 않은 사용자가 의도치 않게 기본 VPC를 삭제해버리는 경우가 종종 있습니다. 이런 경우 사용자가 직접 원래의 기본 VPC를 재생성하는 방법은 없습니다. 이 문제를 해결하기 위한 몇 가지 방법이 있습니다.

첫 번째 방법은 VPC 메뉴에서 VPC Wizard를 사용해 새로운 VPC를 구성하는 방법입니다. 하지만 마법사를 사용하기 위해서 기본적인 AWS 네트워크에 대한 이해가 필요하며, 자동적으로 생성되는 기본 VPC와 완전히 같다고 보장하기는 어렵습니다.

두 번째 방법은 아마존 지원 센터Support Center 메뉴에서 케이스를 열어 기본 VPC를 재생성해달라고 요청하는 방법입니다.

세 번째 방법은 기본 VPC를 삭제하지 않은 다른 리전을 이용하는 방법입니다. 이 튜토리얼은 서울 리전을 가정하고 있지만, AMI만 바꾸면 다른 리전에서도 그대로 따라할 수 있습니다.

기본 VPC에 속해있는 서브넷

서브넷은 ec2 describe-subnets 명령어로 조회할 수 있습니다. VPC ID로 필터링을 해서 기본 VPC에 연결된 서브넷을 조회합니다.

$ aws ec2 describe-subnets --filter 'Name=vpc-id,Values=vpc-12345678'

실행 결과는 다음과 같습니다.

앞서 살펴보았듯이 기본 VPC에는 2개의 서브넷이 생성되어있는 걸을 알 수 있습니다. 첫 번째 서브넷은 가용 영역 ap-northeast-2a, 두 번째 서브넷은 ap-northeast-2c에 연결 되어있습니다. 첫 번째 서브넷의 범위는 172.31.0.0/20입니다. 이는 172.31.0.0부터 4,096개의 범위를 의미합니다. AvailabeIpAddressCount 속성으로 현재 사용 가능한 IP 개수를 확인할 수 있습니다. 4,096보다 5가 적은 4,091개입니다. 이는 5개를 어떤 리소스에서 사용하고 있는 의미입니다.

AWS의 각 서비스에서 리소스를 생성할 때는 일반적으로 서브넷을 지정합니다. 따라서 필요한 경우 서브넷의 ID를 조회해서 지정해주면 됩니다. 어떤 가용 영역에 연결된 서브넷을 사용하더라도 무관합니다만, 엘라스틱 로드 밸런서ELB, Elastic Load Balancer와 같은 서비스에서는 필수적으로 2개 이상의 서브넷을 지정하도록 강제되어있습니다.

jq를 사용해 서브넷들의 아이디를 가져오는 명령어는 다읍과 같습니다.

$ aws ec2 describe-subnets --filter 'Name=vpc-id,Values=vpc-12345678' \
  | jq '.Subnets[].SubnetId'
"subnet-12345678"
"subnet-12345679"

기본 VPC에 속해있는 시큐리티 그룹

마지막으로 살펴볼 리소스는 시큐리티 그룹입니다. 시큐리티 그룹은 EC2를 사용해봤다면 비교적 익숙할 것입니다. 재미있는 점은 시큐리티 그룹이 EC2 대시보드VPC 대시보드에 모두 존재한다는 점입니다. 사실 이 둘은 같습니다. 중요한 점은 시큐리티 그룹이 VPC에 속해있는 네트워크 리소스라는 점입니다. 따라서 다수의 VPC가 정의되어있는 경우 완전히 같은 보안 규칙을 가지고 있더라도 VPC 별로 시큐리티 그룹을 만들어야만합니다. 앞서 조회한 VPC ID로 기본 VPC의 기본 시큐리티 그룹을 조회해보겠습니다. 시큐리티 그룹은 ec2 describe-security-groups 명령어로 조회할 수 있습니다.

$ aws ec2 describe-security-groups \
  --filter 'Name=vpc-id,Values=vpc-12345678' \
  --filter 'Name=group-name,Values=default'

실행 결과는 다음과 같습니다.

GroupNameDescription을 통해서 이 시큐리티 그룹이 기본 시큐리티 그룹인 것을 확인할 수 있습니다. 이 시큐리티 그룹에는 2개의 규칙이 있습니다.

먼저 IpPermissionsEgress는 아웃바운드 규칙 목록입니다. 여기에 정의된 규칙은 인스턴스에서 외부로 나가는 트래픽을 모든 포트("IpProtocol": "-1")와 모든 IP에 대해서("CidrIp": "0.0.0.0/0") 허용한다는 의미입니다.

IpPermissions는 인바운드 규칙 목록입니다. 이는 외부에서 이 시큐리티 그룹을 가진 리소스에 접근할 때 사용하는 규칙입니다. 이 규칙은 조금 독특합니다. UserIdGroupPairs의 내용을 해석해보면 모든 포트("IpProtocol": "-1")에 대해서 sg-12345678 시큐리티 그룹을 가진 리소스의 트래픽만을 허용한다는 의미입니다. sg-12345678 이 시큐리티 그룹의 아이디입니다.

예를 들어서 설명해보겠습니다. 어떤 인스턴스 A가 기본 시큐리티 그룹(sg-12345678)을 가지고 있습니다. 그리고 인스턴스 B도 기본 시큐리티 그룹(sg-12345678)을 가지고 있습니다. 이 경우 A와 B는 서로에 대해서 요청을 할 수 있습니다. 반면에 인스턴스 C는 이 기본 시큐리티 그룹을 사용하지 않는다고 가정해보겠습니다. 이 경우 C는 A나 B에 대한 요청에 대한 응답을 받을 수 없습니다.*

* A나 B에서 C에 대한 요청이 가능한지는 전적으로 C의 시큐리티 그룹 설정에 따라 다를 것입니다. 따라서 알 수 없습니다.

기본 VPC에서 생성하는 리소스들에는 일반적으로 이 시큐리티 그룹도 함께 할당해줍니다. 이를 통해서 VPC 내부의 자원 간에 이루어지는 통신이 복잡한 설정 없이도 쉽게 이루어질 수 있습니다.

jq로 시큐리티 그룹의 ID를 가져오는 방법은 다음과 같습니다.

$ aws ec2 describe-security-groups \
  --filter 'Name=vpc-id,Values=vpc-12345678' \
  --filter 'Name=group-name,Values=default' \
  | jq '.SecurityGroups[].GroupId '

마치며

AWS를 처음 사용할 때는 VPC를 이해하지 못 하더라도 크게 문제가 되지 않습니다. 하지만 기본 VPC를 전제로 서비스가 구성된다는 것을 이해하고 있다면 VPC나 서브넷이 여기저기서 언급되더라도 충분히 대응할 수 있을 것입니다. 또한 프로덕션 환경에서는 이러한 VPC에 대한 이해가 필수적이기 때문에 함께 공부해두면 도움이 될 것입니다.

더 읽을 거리