Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save it-am/3185d3f0c6e8afcd3664f9b195e7c70a to your computer and use it in GitHub Desktop.
Save it-am/3185d3f0c6e8afcd3664f9b195e7c70a to your computer and use it in GitHub Desktop.
Python script with troposphere library which creates CloudFormation template for you (VPC, Subnets, IGW, NAT etc.)
import troposphere.ec2 as ec2
from troposphere import Ref, Template, Tags, GetAtt
from troposphere.ec2 import Route, VPCGatewayAttachment, SubnetRouteTableAssociation, \
Subnet, RouteTable, VPC, SubnetNetworkAclAssociation, EIP, InternetGateway
#user input requests
input_tag = input('Tag (name tag of each aws resource will include it)(ex.: projectx): ').lower()
input_aws_region = input('AWS region (ex.: us-east-1): ')
input_vpc_cidr = input('VPC CIDR (ex.: 10.0.0.0/16): ')
input_pub_az_amount = int(input('In how many different AZs you want to create PUBLIC subnets? (max. 3): '))
input_pri_az_amount = int(input('In how many different AZs you want to create PRIVATE subnets? (max. 3): '))
t = Template()
t.set_version('2010-09-09')
t.set_description('AWS CloudFormation VPC Custom Template')
ref_stack_id = Ref('AWS::StackId')
ref_region = Ref('AWS::Region')
ref_stack_name = Ref('AWS::StackName')
#Create VPC
VPC = t.add_resource(
VPC(
'VPC',
CidrBlock=input_vpc_cidr,
Tags=Tags(
Application=ref_stack_id,
Name=input_tag+'-vpc'
)))
#Create Internet Gateway
internetGateway = t.add_resource(
InternetGateway(
'InternetGateway',
Tags=Tags(
Application=ref_stack_id,
Name=input_tag+'-ig'
)))
#Attach Internet Gateway to the VPC
gatewayAttachment = t.add_resource(
VPCGatewayAttachment(
'AttachGateway',
VpcId=Ref(VPC),
InternetGatewayId=Ref(internetGateway)))
#Create default Main Public RouteTable
mainRouteTable = t.add_resource(
RouteTable(
'MainRouteTable',
VpcId=Ref(VPC),
Tags=Tags(
Application=ref_stack_id,
Name=input_tag+'-PublicRouteTable-Main'
)))
#Create default route 0.0.0.0/0 in the Public RouteTable
route = t.add_resource(
Route(
'Route',
DependsOn='AttachGateway',
GatewayId=Ref('InternetGateway'),
DestinationCidrBlock='0.0.0.0/0',
RouteTableId=Ref(mainRouteTable),
))
#Create Public Subnets and associate them with MainRouteTable
for i in range(input_pub_az_amount):
if i == 0: AZ = input_aws_region+'a'
elif i == 1: AZ = input_aws_region+'b'
elif i == 2: AZ = input_aws_region+'c'
input_number_of_public_subnets = int(input('How many PUBLIC subnets in ' + AZ + ' AZ you need?: ')) #user input request
while input_number_of_public_subnets > 0:
subnet_logical_id = 'PubSubnet' + str(input_number_of_public_subnets) + AZ.replace("-", "")
input_number_of_public_subnets -= 1
input_pub_subnet_cidr = input('Public Subnet ' + subnet_logical_id + ' desired CIDR (ex. 10.0.1.0/24): ') #user input request
#Create Public Subnet
subnet = t.add_resource(
Subnet(
subnet_logical_id,
CidrBlock=input_pub_subnet_cidr,
VpcId=Ref(VPC),
AvailabilityZone=AZ,
Tags=Tags(
Application=ref_stack_id,
Name=input_tag + '-' + subnet_logical_id
)))
#Create RouteTable Association (MAIN)
UniqueSubnetRouteTableAssociation = 'SubnetRouteTableAssociation' + subnet_logical_id
subnetRouteTableAssociation = t.add_resource(
SubnetRouteTableAssociation(
UniqueSubnetRouteTableAssociation,
SubnetId=Ref(subnet),
RouteTableId=Ref(mainRouteTable),
))
#user input request
input_nat_gateway_option = int(input('''Please choose option "1" or "2".
- Option#1: create only one NAT Gateway per each AZ
- Option#2: create a separate NAT Gateway for each private subnet: '''))
#Create Private Subnets
for i in range(input_pri_az_amount):
if i == 0: AZ = input_aws_region+'a'
elif i == 1: AZ = input_aws_region+'b'
elif i == 2: AZ = input_aws_region+'c'
#Create Public Subnet for NATGateway
subnet_logical_id = 'PubSubnetNAT' + AZ.replace("-", "")
input_pub_subnet_cidr = input('Public Subnet ' + subnet_logical_id + ' desired CIDR (ex. 10.0.100.0/28): ') #user input request
public_nat_net = t.add_resource(
Subnet(
subnet_logical_id,
CidrBlock=input_pub_subnet_cidr,
VpcId=Ref(VPC),
AvailabilityZone=AZ,
Tags=Tags(
Application=ref_stack_id,
Name=input_tag + '-' + subnet_logical_id
)))
#Create RouteTable Association (MAIN)
UniqueSubnetRouteTableAssociation = 'SubnetRouteTableAssociation' + subnet_logical_id
subnetRouteTableAssociation = t.add_resource(
SubnetRouteTableAssociation(
UniqueSubnetRouteTableAssociation,
SubnetId=Ref(public_nat_net),
RouteTableId=Ref(mainRouteTable),
))
#Create NAT Gateway - one per each AZ
if input_nat_gateway_option == 1:
#Allocate EIP
UniqueNatEipName = 'NatEip' + AZ.replace("-", "")
nat_eip = t.add_resource(ec2.EIP(
UniqueNatEipName,
Domain="vpc",
))
#Create NAT Gateway
UniqueNatGatewayName = 'NAT' + AZ.replace("-", "")
nat = t.add_resource(ec2.NatGateway(
UniqueNatGatewayName,
AllocationId=GetAtt(nat_eip, 'AllocationId'),
SubnetId=Ref(public_nat_net),
Tags=Tags(
Application=ref_stack_id,
Name=input_tag + '-' + UniqueNatGatewayName
)))
input_number_of_private_subnets = int(input('How many PRIVATE subnets in ' + AZ + ' AZ you need?: ')) #user input request
while input_number_of_private_subnets > 0:
subnet_logical_id = 'PriSubnet' + str(input_number_of_private_subnets) + AZ.replace("-", "")
input_number_of_private_subnets -= 1
input_pri_subnet_cidr = input('Private Subnet ' + subnet_logical_id + ' desired CIDR (ex. 10.0.10.0/24): ')
#Create Private Subnet
subnet = t.add_resource(
Subnet(
subnet_logical_id,
CidrBlock=input_pri_subnet_cidr,
VpcId=Ref(VPC),
AvailabilityZone=AZ,
Tags=Tags(
Application=ref_stack_id,
Name=input_tag + '-' + subnet_logical_id
)))
#Create RouteTable for each private subnet
UniqueRouteTableName = 'PrivateRouteTable' + subnet_logical_id
privateRouteTable = t.add_resource(
RouteTable(
UniqueRouteTableName,
VpcId=Ref(VPC),
Tags=Tags(
Application=ref_stack_id,
Name=input_tag + '-' + UniqueRouteTableName
)))
#Create RouteTable Association for each private subnet
UniqueSubnetRouteTableAssociation = 'SubnetRouteTableAssociation' + subnet_logical_id
subnetRouteTableAssociation = t.add_resource(
SubnetRouteTableAssociation(
UniqueSubnetRouteTableAssociation,
SubnetId=Ref(subnet),
RouteTableId=Ref(privateRouteTable),
))
if input_nat_gateway_option == 1:
#Add default route NAT
UniqueNatRouteName = 'NATRoute' + subnet_logical_id
route = t.add_resource(
Route(
UniqueNatRouteName,
DependsOn=UniqueNatGatewayName,
NatGatewayId=Ref(UniqueNatGatewayName),
DestinationCidrBlock='0.0.0.0/0',
RouteTableId=Ref(UniqueRouteTableName),
))
elif input_nat_gateway_option == 2:
#Allocate EIP for new NAT Gateway
UniqueNatEipName = 'NatEip' + subnet_logical_id
nat_eip = t.add_resource(ec2.EIP(
UniqueNatEipName,
Domain="vpc",
))
#Create NAT Gateway for each private subnet
UniqueNatGatewayName = 'NATGateway' + subnet_logical_id
nat = t.add_resource(ec2.NatGateway(
UniqueNatGatewayName,
AllocationId=GetAtt(nat_eip, 'AllocationId'),
SubnetId=Ref(public_nat_net),
Tags=Tags(
Application=ref_stack_id,
Name=input_tag + '-' + UniqueNatGatewayName
)))
#Add default route NAT
UniqueNatRouteName = 'NATRoute' + subnet_logical_id
route = t.add_resource(
Route(
UniqueNatRouteName,
DependsOn=UniqueNatGatewayName,
NatGatewayId=Ref(UniqueNatGatewayName),
DestinationCidrBlock='0.0.0.0/0',
RouteTableId=Ref(UniqueRouteTableName),
))
input_json_or_yaml = input('Get CF template in JSON or YAML format? (ex.: yaml, json, both): ')
if input_json_or_yaml.lower() == 'yaml':
print('---YAML-CF-TEMPLATE-START----\n')
print(t.to_yaml())
print('---YAML-CF-TEMPLATE-END----')
elif input_json_or_yaml.lower() == 'json':
print('---JSON-CF-TEMPLATE-START----\n')
print(t.to_json())
print('---JSON-CF-TEMPLATE-START----')
elif input_json_or_yaml.lower() == 'both':
print('---YAML-CF-TEMPLATE-START----\n')
print(t.to_yaml())
print('---YAML-CF-TEMPLATE-END----\n')
print('---JSON-CF-TEMPLATE-START----\n')
print(t.to_json())
print('---JSON-CF-TEMPLATE-START----')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment