AWS 기본 VPC 쉽게 삭제하기 – CloudFormation, Lambda

AWS를 사용하는 개인이나 회사에서 규모가 어느 정도로 커지게 되면 가장 먼저 신경써야 할 부분이 바로 네트워크 입니다. 그리고 AWS에서 그런 네트워크의 가장 기본이 되는 자원이 바로 VPC (Virtual Private Cloud) 입니다. AWS에서 계정을 처음 생성하고 나면 기본적으로 설정되는 대다수의 리전에 기본 VPC가 생성되어 있습니다. 이러한 기본 VPC는 항상 같은 CIDR 영역인 172.31.0.0/16 대역을 가지고 있으며, 해당 리전의 가용 영역에 따라서 기본 서브넷들이 나뉘어 있습니다. 그리고 인터넷 통신이 가능하도록 기본 인터넷 게이트웨이와 이에 연관된 라우팅 테이블이 생성되어 있습니다.

이처럼 기본 VPC는 AWS 계정을 생성하자마자 곧바로 리소스 생성을 가능하게 해주는 좋은 설정이지만, 네트워크를 신경써서 구성해야 하는 개인이나 기업의 입장에서는 귀찮기만 한 설정이기도 합니다. 왜냐하면 다른 VPC와의 피어링등을 고려할 때에는 반드시 서로 다른 CIDR 대역을 사용해야 하는데 이러한 관점에서 기본 VPC는 항상 충돌이 발생하는 대역이므로 쓸모가 없기 때문입니다. 그래서 AWS에서도 대규모의 조직 관리가 필요한 고객을 위한 Landing Zone에서 AWS 계정 자판기 (Account Vending Machine)를 이용하여 신규 계정을 제공할 때에는 반드시 계정의 모든 기본 VPC를 삭제하고 제공하고 있습니다. 하지만 모두가 이런 계정 자판기를 이용할 수는 없으므로 사전 정의된 CloudFormation 템플릿을 이용하여 기본 VPC를 삭제해보도록 하겠습니다.

코드

기본 VPC를 삭제하기 위해서는 3단계의 과정이 필요합니다.

  • 인터넷 게이트웨이 Detach 후 삭제
  • 서브넷 삭제
  • VPC 삭제

개별 과정을 거치는 Python 기반의 Lambda 함수를 작성합니다.

import boto3
import os

def lambda_handler(event, context):

    ignore_regions = os.environ['IgnoreRegions'].replace(' ','').split(',')
    print('ignore_regions : ', ignore_regions)
    remove_regions = list(filter(lambda x: x not in ignore_regions, map(lambda x: x.get('RegionName'), boto3.resource('ec2').meta.client.describe_regions().get('Regions'))))
    print('remove_regions : ', remove_regions)

    for region in remove_regions:
        remove_vpc(region)
        
    return 200


def remove_vpc(region):

    ec2 = boto3.session.Session(region_name=region).resource('ec2')
    
    vpcs = ec2.vpcs.filter(Filters=[{'Name':'isDefault','Values':['true']}])
    
    for vpc in vpcs:
        
        igws = ec2.internet_gateways.filter(Filters=[{'Name':'attachment.vpc-id','Values':[vpc.id]}])
        
        for igw in igws:
            ec2.InternetGateway(igw.id).detach_from_vpc(VpcId=vpc.id)
            ec2.InternetGateway(igw.id).delete()
            
        subnets = ec2.subnets.filter(Filters=[{'Name':'vpc-id','Values':[vpc.id]}])
        
        for subnet in subnets:
            ec2.Subnet(subnet.id).delete()
            
        ec2.Vpc(vpc.id).delete()
        
        print(region.ljust(20), '|', vpc.id.ljust(24), '|', ' deleted')
Code language: Python (python)

그리고 해당 코드를 담아서 Lambda 함수를 생성하는 CloudFormation 템플릿을 작성합니다. 템플릿은 Lambda 함수를 실행하는데 필요한 최소한의 권한을 담고 있습니다. 이와는 별개로 템플릿을 CloudFormation으로 배포하는 것에도 별도의 권한이 필요하므로 참고하시기 바랍니다.

관련하여 자세한 내용은 아래 깃허브 리포지토리에서 확인하실 수 있습니다.

배포

리포지토리에서 다운로드 받은 template.yaml 파일을 CloudFormation으로 업로드합니다.

이름은 적당히 입력하면 됩니다. 해당 템플릿은 파라미터로 VPC를 삭제하지 않을 리전을 받고 있습니다. ,로 구분되는 리전 코드 (예: ap-northeast-2) 들을 제공하면 됩니다.

정상적으로 함수가 배포되었으면, Lambda의 함수 목록에서 lambda-aws-default-vpc-remover를 찾아볼 수 있습니다.

실행

실행 방법은 크게 두 가지 방법을 사용할 수 있습니다. 하나는 AWS CLI를 이용하는 것입니다. 이를 사용할 경우에 명령어는 다음과 같습니다.

aws lambda invoke --function-name lambda-aws-default-vpc-remover result.txt
Code language: JavaScript (javascript)

액세스 키를 발급받는 번거로운 과정을 생략하고 싶다면, Lambda 함수의 콘솔에서 테스트 이벤트를 작성하고 실행하면 됩니다.

테스트 이벤트의 Payload는 특별한 값을 제공할 필요가 없습니다. 적당히 생성된 테스트 이벤트를 실행하면 약 2분에 걸쳐서 기본 VPC들을 삭제하게 되고, 아래와 같이 결과가 나타나게 됩니다.

결과 값의 샘플은 다음과 같습니다.

START RequestId: fc722266-4dd9-4b98-8a8d-ba4388b79110 Version: $LATEST
ignore_regions :  ['None']
remove_regions :  ['eu-north-1', 'ap-south-1', 'eu-west-3', 'eu-west-2', 'eu-west-1', 'ap-northeast-3', 'ap-northeast-2', 'ap-northeast-1', 'sa-east-1', 'ca-central-1', 'ap-southeast-1', 'ap-southeast-2', 'eu-central-1', 'us-east-1', 'us-east-2', 'us-west-1', 'us-west-2']
eu-north-1           | vpc-01988a7c5a69841f8    |  deleted
ap-south-1           | vpc-05511c72e2ffcb87c    |  deleted
eu-west-3            | vpc-0e1f329abbe4fa223    |  deleted
eu-west-2            | vpc-006984b12904c3506    |  deleted
eu-west-1            | vpc-0b8a7c5b109d1ca4d    |  deleted
ap-northeast-3       | vpc-0ba819cb648b3c6ff    |  deleted
ap-northeast-2       | vpc-f2b35099             |  deleted
ap-northeast-1       | vpc-04d54b8b359099359    |  deleted
sa-east-1            | vpc-0c0c37bf6ab88b83d    |  deleted
ca-central-1         | vpc-0993d43d02d9d3a7f    |  deleted
ap-southeast-1       | vpc-069bc492bfc17c8d8    |  deleted
ap-southeast-2       | vpc-0787fb9fdec3b8bd3    |  deleted
eu-central-1         | vpc-0d6969012d833113b    |  deleted
us-east-1            | vpc-052cb5d2bfc5e5598    |  deleted
us-east-2            | vpc-300b0858             |  deleted
us-west-1            | vpc-0075c027846049805    |  deleted
us-west-2            | vpc-0b929a73             |  deleted
END RequestId: fc722266-4dd9-4b98-8a8d-ba4388b79110
REPORT RequestId: fc722266-4dd9-4b98-8a8d-ba4388b79110	Duration: 104447.43 ms	Billed Duration: 104448 ms
Code language: PHP (php)

모든 작업이 완료되었으면, CloudFormation으로 가서 스택을 삭제함으로써 aws-default-vpc-remover를 완전히 삭제할 수 있습니다.

맺음말

기존에 작성한 글이 있었는데, 이번 글을 통해서는 좀 더 간편하게 CloudFormation을 사용하여 빠른 작업을 할 수 있도록 하였습니다.

AWS의 조직 계정을 이용하면서 새로운 연결 계정을 생성할 때마다 VPC를 삭제하는게 여간 고역이 아니었습니다. 이제는 간단한 템플릿으로 제공되는 aws-default-vpc-remover를 사용하여 모든 혹은 예외 처리된 리전의 기본 VPC를 손쉽게 삭제할 수 있게 되었습니다. 다른 분들도 이러한 혜택을 함께 누렸으면 하는 마음으로 글을 공유합니다.

Leave a Reply

Your email address will not be published. Required fields are marked *