この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、おんづか(@onzuka_muscle)です!
こちらのブログを参考にアカウントが特定OUに所属したタイミングでLambdaを実行し、デフォルトVPCを削除してみました。
注意点
- 作成したばかりのAWSアカウントを想定しています
- そのためデフォルトVPCに紐づいたリソースをユーザーが作成していると本Lambdaは失敗します
- Lambdaが実行された後もLambda , IAMロール , CloudWatch Logsといったリソースは残ります
- 必要に応じて削除してください
- あくまでサンプルコードです
- エラーハンドリング・ロギングについてはそこそこなので必要に応じてカスタマイズください
テンプレート
AWSTemplateFormatVersion: "2010-09-09"
# ------------------------------------------------------------#
# デフォルト VPC を削除する Lambda-backed custom resources
# ------------------------------------------------------------#
Parameters:
RoleName:
Type: String
FunctionName:
Type: String
Resources:
# ------------------------------------------------------------#
# Lambda-backed custom resources
# ------------------------------------------------------------#
DeleteDefaultVPC:
Type: Custom::DeleteDefaultVPC
Properties:
ServiceToken: !GetAtt "LambdaFunction.Arn"
# ------------------------------------------------------------#
# Lambda 関数
# ------------------------------------------------------------#
LambdaFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: !Ref FunctionName
Description: Lambda for delete default VPC
Role: !GetAtt "LambdaExecutionRole.Arn"
Runtime: "python3.8"
Handler: index.lambda_handler
Timeout: 120
Code:
ZipFile: |
import boto3
import json
import cfnresponse
from logging import getLogger, INFO
logger = getLogger()
logger.setLevel(INFO)
def delete_default_vpc(event, context):
region_list = []
ec2_client = boto3.client('ec2')
regions = ec2_client.describe_regions()
for r in range(0, len(regions['Regions'])):
region_name = regions['Regions'][r]['RegionName']
region_list.append(region_name)
for region in region_list:
try:
client = boto3.client('ec2', region_name=region)
ec2 = boto3.resource('ec2', region_name=region)
vpcs = get_default_vpcs(client)
except boto3.exceptions.Boto3Error as e:
logger.info(e)
exit(1)
else:
for vpc in vpcs:
logger.info("\n" + "\n" + "REGION:" +
region + "\n" + "VPC Id:" + vpc)
del_igw(ec2, vpc)
del_sub(ec2, vpc)
del_vpc(ec2, vpc)
def lambda_handler(event, context):
if event['RequestType'] == 'Create':
# Create時に実行したい処理 --> デフォルト VPC を削除する
delete_default_vpc(event, context)
cfnresponse.send(event, context, cfnresponse.SUCCESS,
{'Response': 'Success'})
if event['RequestType'] == 'Delete':
# Delete時に実行したい処理 --> 無し
cfnresponse.send(event, context, cfnresponse.SUCCESS,
{'Response': 'Success'})
if event['RequestType'] == 'Update':
# Update時に実行したい処理 --> 無し
cfnresponse.send(event, context, cfnresponse.SUCCESS,
{'Response': 'Success'})
def get_default_vpcs(client):
vpc_list = []
vpcs = client.describe_vpcs(
Filters=[
{
'Name': 'isDefault',
'Values': [
'true',
],
},
]
)
vpcs_str = json.dumps(vpcs)
resp = json.loads(vpcs_str)
data = json.dumps(resp['Vpcs'])
vpcs = json.loads(data)
for vpc in vpcs:
vpc_list.append(vpc['VpcId'])
return vpc_list
def del_igw(ec2, vpcid):
vpc_resource = ec2.Vpc(vpcid)
igws = vpc_resource.internet_gateways.all()
if igws:
for igw in igws:
try:
igw.detach_from_vpc(
VpcId=vpcid
)
igw.delete()
except boto3.exceptions.Boto3Error as e:
logger.info(e)
def del_sub(ec2, vpcid):
vpc_resource = ec2.Vpc(vpcid)
subnets = vpc_resource.subnets.all()
default_subnets = [ec2.Subnet(subnet.id)
for subnet in subnets if subnet.default_for_az]
if default_subnets:
try:
for sub in default_subnets:
sub.delete()
except boto3.exceptions.Boto3Error as e:
logger.info(e)
def del_vpc(ec2, vpcid):
vpc_resource = ec2.Vpc(vpcid)
try:
vpc_resource.delete()
except boto3.exceptions.Boto3Error as e:
logger.info(e)
logger.info("Please remove dependencies and delete VPC manually.")
# ------------------------------------------------------------#
# Lambda 関数用の IAM ロール
# ------------------------------------------------------------#
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Ref RoleName
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: "lambda.amazonaws.com"
Action: "sts:AssumeRole"
ManagedPolicyArns:
- "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
Policies:
- PolicyName: DeleteDefaultVPCPolicy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- "ec2:DescribeRegions"
- "ec2:DescribeInternetGateways"
- "ec2:DetachInternetGateway"
- "ec2:DeleteInternetGateway"
- "ec2:DescribeSubnets"
- "ec2:DeleteSubnet"
- "ec2:DescribeVpcs"
- "ec2:DeleteVpc"
Resource: "*"
動作確認
EC2 Global View
より確認しました。
Before
After
綺麗さっぱりになりました!
おわり
サンプルコードになりますが需要あるかなと思いブログにしました。
こちらのブログのようにCloudFormation StackSetsと組み合わせることで新しく作成したアカウントのデフォルトVPC削除を効率化できます。
誰かのお役に立てば嬉しいです。