Monday 20 May 2019

Create Basic Infrastructure CloudFormation template using troposphere

Here step by a step python code to create basic infra 
This is not production ready code. It is just as a sample.

________
Infra.py

from troposphere import GetAtt, Ref, Tags, Template, Join
from troposphere import GetAtt, Ref, Tags, Template, Join
from troposphere.ec2 import (Route, VPCGatewayAttachment, SubnetRouteTableAssociation, Subnet, RouteTable, VPC as Vpc,
                             InternetGateway, EIP, NatGateway, VPCEndpoint, VPNGateway, DHCPOptions,
                             VPCDHCPOptionsAssociation, VPNGatewayRoutePropagation, VPCPeeringConnection)

from libs.general import connect, validate_template, push_cloudformation


class ActiveVpcV3(object):
    def __init__(self):
        self.template = Template()
        self.template.add_description('Third instance of Active VPC')
        self.cost_allocation_tag = 'Base infrastructure'

    def resource_title(self, name):
        camel_case_name = name.title().replace("_", "").replace("-", "")
        return camel_case_name

    def create_vpc(self, ip_range):
        VPC = self.template.add_resource(
            Vpc(
                'VPC',
                CidrBlock=ip_range,
                EnableDnsHostnames=True,
                EnableDnsSupport=True,
                Tags=Tags(
                    cost_allocation=self.cost_allocation_tag,
                )
            ))
        return VPC

    def create_s3_endpoint(self, vpc, routes_tables_list):
        self.template.add_resource(VPCEndpoint(
            "S3VpcEndpoint",
            RouteTableIds=routes_tables_list,
            ServiceName=Join("", ["com.amazonaws.", Ref("AWS::Region"), ".s3"]),
            VpcId=vpc,
        ))

    def create_vpn_gateway(self, vpc, routes_tables_list):
        vpn_gateway = self.template.add_resource(VPNGateway(
            'VPNGateway',
            Type='ipsec.1',
            Tags=Tags(
                cost_allocation=self.cost_allocation_tag,
            )
        ))

        self.template.add_resource(VPCGatewayAttachment(
            'VPNGatewayAttachment',
            VpcId=vpc,
            VpnGatewayId=Ref(vpn_gateway),
        ))

        self.template.add_resource(VPNGatewayRoutePropagation(
            'VPNGatewayRoutePropagation',
            RouteTableIds=routes_tables_list,
            VpnGatewayId=Ref(vpn_gateway),
            DependsOn='VPNGatewayAttachment'
        ))

    def create_dhcp_options(self, vpc, domain, dns_server):
        dhcp_options = self.template.add_resource(DHCPOptions(
            'DHCPOptions',
            DomainName=domain,
            DomainNameServers=dns_server
        ))

        self.template.add_resource(VPCDHCPOptionsAssociation(
            'VPCDHCPOptionsAssociation',
            DhcpOptionsId=Ref(dhcp_options),
            VpcId=vpc
        ))

    def create_internet_gateway(self, vpc):
        internet_gateway = self.template.add_resource(
            InternetGateway(
                'InternetGateway',
                Tags=Tags(
                    cost_allocation=self.cost_allocation_tag)))

        self.template.add_resource(
            VPCGatewayAttachment(
                'InternetGatewayAttachment',
                VpcId=vpc,
                InternetGatewayId=Ref(internet_gateway)
            ))

        route_table = self.template.add_resource(RouteTable(
            'PublicRouteRouteTable',
            VpcId=vpc,
            Tags=Tags(
                cost_allocation=self.cost_allocation_tag)
        ))

        self.template.add_resource(Route(
            'PublicRoute',
            RouteTableId=Ref(route_table),
            DestinationCidrBlock='0.0.0.0/0',
            GatewayId=Ref(internet_gateway)
        ))

        return route_table

    def create_nat_gateway(self, name, subnet):
        elastic_ip = self.template.add_resource(EIP(
            "%sEIP" % (self.resource_title(name)),
            Domain="VPC",
        ))

        nat_gateway = self.template.add_resource(NatGateway(
            '%sNatGateway' % (self.resource_title(name)),
            AllocationId=GetAtt(elastic_ip, 'AllocationId'),
            SubnetId=subnet,
        ))
        return nat_gateway

    def create_public_subnet(self, name, vpc, region, ip_range, route_table):
        subnet = self.template.add_resource(
            Subnet(
                '%sSubnet' % self.resource_title(name),
                CidrBlock=ip_range,
                AvailabilityZone=region,
                VpcId=vpc,
                MapPublicIpOnLaunch=True,
                Tags=Tags(
                    cost_allocation=self.cost_allocation_tag,
                )
            ))

        self.template.add_resource(SubnetRouteTableAssociation(
            '%sRouteTableAssociation' % self.resource_title(name),
            SubnetId=Ref(subnet),
            RouteTableId=route_table,

        ))
        return subnet

    def create_private_subnet(self, name, vpc, ip_range, region, nat_gw):
        subnet = self.template.add_resource(
            Subnet(
                '%sSubnet' % self.resource_title(name),
                CidrBlock=ip_range,
                AvailabilityZone=region,
                VpcId=vpc,
                MapPublicIpOnLaunch=False,
                Tags=Tags(
                    cost_allocation=self.cost_allocation_tag,
                )
            ))

        route_table = self.template.add_resource(RouteTable(
            '%sRouteTable' % self.resource_title(name),
            VpcId=vpc,
            Tags=Tags(
                cost_allocation=self.cost_allocation_tag)
        ))

        self.template.add_resource(SubnetRouteTableAssociation(
            '%sRouteTableAssociation' % self.resource_title(name),
            SubnetId=Ref(subnet),
            RouteTableId=Ref(route_table),

        ))

        self.template.add_resource(Route(
            '%sNatRoute' % self.resource_title(name),
            RouteTableId=Ref(route_table),
            DestinationCidrBlock='0.0.0.0/0',
            NatGatewayId=nat_gw,
        ))

        return dict(subnet=subnet, route_table=route_table)

    def create_vpc_peering(self, name, local_vpc, remote_vpc):
        peering = self.template.add_resource(VPCPeeringConnection(
            '%sPeering' % self.resource_title(name),
            PeerVpcId=Ref(local_vpc),
            VpcId=remote_vpc,
        ))

        return peering

    def create_route_peering(self, name, destination_cidr, vpc_peering, route_table):
        self.template.add_resource(Route(
            '%sPeeringRoute' % self.resource_title(name),
            DestinationCidrBlock=destination_cidr,
            RouteTableId=route_table,
            VpcPeeringConnectionId=vpc_peering
        ))

v = ActiveVpcV3()
vpc = v.create_vpc('192.168.208.0/20')
v.create_dhcp_options(vpc=Ref(vpc),
                      domain='ec2.internal',
                      dns_server=['192.168.210.15', '192.168.215.225']
                      # DomainName='ec2.internal',
                      # DomainNameServers=['AmazonProvidedDNS']
                      )
default_igw_route = v.create_internet_gateway(vpc=Ref(vpc))

pub_subnet_a = v.create_public_subnet(name='general_public_a',
                                      ip_range='192.168.216.0/24',
                                      route_table=Ref(default_igw_route),
                                      region='us-east-1a',
                                      vpc=Ref(vpc))

pub_subnet_b = v.create_public_subnet(name='general_public_b',
                                      ip_range='192.168.217.0/24',
                                      route_table=Ref(default_igw_route),
                                      region='us-east-1b',
                                      vpc=Ref(vpc))

nat_gw_a = v.create_nat_gateway(name='nat_a', subnet=Ref(pub_subnet_a))
nat_gw_b = v.create_nat_gateway(name='nat_b', subnet=Ref(pub_subnet_b))

priv_subnet_a = v.create_private_subnet(name='general_private_1a',
                                        vpc=Ref(vpc),
                                        ip_range='192.168.208.0/22',
                                        region='us-east-1a',
                                        nat_gw=Ref(nat_gw_a))

priv_subnet_b = v.create_private_subnet(name='general_private_1b',
                                        vpc=Ref(vpc),
                                        ip_range='192.168.212.0/22',
                                        region='us-east-1b',
                                        nat_gw=Ref(nat_gw_b))

jenkins_dev_subnet = v.create_private_subnet(name='jenkins_dev_subnet1b',
                                             vpc=Ref(vpc),
                                             ip_range='192.168.218.0/26',
                                             region='us-east-1b',
                                             nat_gw=Ref(nat_gw_b))

jenkins_prod_subnet = v.create_private_subnet(name='jenkins_prod_subnet1b',
                                              vpc=Ref(vpc),
                                              ip_range='192.168.218.64/26',
                                              region='us-east-1b',
                                              nat_gw=Ref(nat_gw_b))

s3_proxy_subnet = v.create_private_subnet(name='s3_proxy_subnet',
                                          vpc=Ref(vpc),
                                          ip_range='192.168.223.224/27',
                                          region='us-east-1b',
                                          nat_gw=Ref(nat_gw_b))

v.create_vpn_gateway(vpc=Ref(vpc),
                     routes_tables_list=[Ref(priv_subnet_a['route_table']),
                                         Ref(priv_subnet_b['route_table']),
                                         Ref(jenkins_dev_subnet['route_table']),
                                         Ref(jenkins_prod_subnet['route_table']),
                                         Ref(s3_proxy_subnet['route_table'])]
                     )

v.create_s3_endpoint(vpc=Ref(vpc),
                     routes_tables_list=[Ref(default_igw_route),
                                         Ref(priv_subnet_a['route_table']),
                                         Ref(priv_subnet_b['route_table']),
                                         Ref(jenkins_dev_subnet['route_table']),
                                         Ref(jenkins_prod_subnet['route_table']),
                                         Ref(s3_proxy_subnet['route_table'])]
                     )

peer01 = v.create_vpc_peering(name='Active_v3_to_Active_v2', local_vpc=vpc, remote_vpc='vpc-833793e6')

v.create_route_peering(name='Active_v3_priv_subnet_a',
                       destination_cidr='192.168.0.0/22',
                       route_table=Ref(priv_subnet_a['route_table']),
                       vpc_peering=Ref(peer01))

v.create_route_peering(name='Active_v3_priv_subnet_b',
                       destination_cidr='192.168.0.0/22',
                       route_table=Ref(priv_subnet_b['route_table']),
                       vpc_peering=Ref(peer01))

v.create_route_peering(name='Active_v2_priv_subnet_a',
                       destination_cidr=GetAtt(vpc, 'CidrBlock'),
                       route_table='rtb-337cd956',
                       vpc_peering=Ref(peer01))


template = v.template.to_json(indent=None)
client = connect('us-east-1')
validate_template(client, template)

push_cloudformation(client, template, 'VPC-Activev3')


No comments:

Post a Comment