· 8 years ago · Dec 11, 2017, 01:34 PM
1#!/usr/bin/env python3
2"""Create fully-functional EC2 VPC."""
3import sys
4
5import boto3
6
7
8INGRESS_SSH = [
9 {
10 'IpProtocol': 'TCP',
11 'FromPort': 22,
12 'ToPort': 22,
13 'IpRanges': [{'CidrIp': '0.0.0.0/0'}],
14 'Ipv6Ranges': [{'CidrIpv6': '::/0'}]
15 }
16]
17
18IPV4_CIDR = '192.168.1.0/20'
19VPC_NAME = 'cloud-init-testing'
20RESOURCE = boto3.resource('ec2')
21
22
23def vpc_exist():
24 """Return if VPC exists with specific name."""
25 for vpc in list(RESOURCE.vpcs.all()):
26 if not vpc.tags:
27 continue
28
29 for tag in vpc.tags:
30 if tag['Value'] == VPC_NAME:
31 return True
32
33 return False
34
35
36def tag_resource(resource):
37 """Tag a resouce with specific name."""
38 resource.create_tags(Tags=[{'Key': 'Name', 'Value': VPC_NAME}])
39
40
41def create_internet_gateway(vpc):
42 """Create Internet Gateway and assign to VPC."""
43 print('creating internet gateway')
44 internet_gateway = RESOURCE.create_internet_gateway()
45 tag_resource(internet_gateway)
46 internet_gateway.attach_to_vpc(VpcId=vpc.vpc_id)
47 return internet_gateway
48
49
50def create_vpc():
51 """Create IPV4 and IPV6 enabled VPC."""
52 print('creating VPC')
53 vpc = RESOURCE.create_vpc(CidrBlock=IPV4_CIDR,
54 AmazonProvidedIpv6CidrBlock=True)
55 tag_resource(vpc)
56 vpc.wait_until_available()
57
58 return vpc
59
60
61def create_subnet(vpc, ipv6=False):
62 """Create subnet for VPC."""
63 print('creating subnet')
64 ipv6_block = vpc.ipv6_cidr_block_association_set[0]['Ipv6CidrBlock']
65 ipv6_cidr = ipv6_block[:-2] + '64'
66
67 subnet = vpc.create_subnet(CidrBlock=IPV4_CIDR, Ipv6CidrBlock=ipv6_cidr)
68 tag_resource(subnet)
69 modify_subnet = subnet.meta.client.modify_subnet_attribute
70 modify_subnet(SubnetId=subnet.id,
71 MapPublicIpOnLaunch={'Value': True})
72 if ipv6:
73 modify_subnet(SubnetId=subnet.id,
74 AssignIpv6AddressOnCreation={'Value': True})
75
76
77def update_routing_table(vpc, internet_gateway):
78 """Update default routing table with internet gateway."""
79 print('updating default gateway')
80 route_table = list(vpc.route_tables.all())[0]
81 tag_resource(route_table)
82 route_table.create_route(DestinationCidrBlock='0.0.0.0/0',
83 GatewayId=internet_gateway.internet_gateway_id)
84 route_table.create_route(DestinationIpv6CidrBlock='::/0',
85 GatewayId=internet_gateway.internet_gateway_id)
86
87
88def update_security_group(vpc):
89 """Update default security group that gets created when VPC is created."""
90 print('updating default security group')
91 security_group = list(vpc.security_groups.all())[0]
92 tag_resource(security_group)
93 security_group.revoke_ingress(IpPermissions=security_group.ip_permissions)
94 security_group.authorize_ingress(IpPermissions=INGRESS_SSH)
95
96
97def run():
98 """Create IPv4 and IPv6 enabled VPC.
99
100 This creates a VPC with all components tagged with the specified tag.
101
102 Modifies the default route table and security group to allow all traffic
103 outbound, but only SSH traffic inbound.
104 """
105 if vpc_exist():
106 print('VPC already exists!')
107 return
108
109 vpc = create_vpc()
110 internet_gateway = create_internet_gateway(vpc)
111 create_subnet(vpc)
112 update_routing_table(vpc, internet_gateway)
113 update_security_group(vpc)
114
115
116if __name__ == "__main__":
117 sys.exit(run())