def __create_dmz_subnet(template: Template, vpc, public_subnet): dmz_subnet_cidr = template.add_parameter(parameter=Parameter( title='DmzSubnetCidr', Type='String', Default='192.168.3.0/24')) dmz_subnet = template.add_resource( resource=Subnet(title='SampleDmzSubnet', CidrBlock=Ref(dmz_subnet_cidr), VpcId=Ref(vpc))) dmz_route_table = template.add_resource( resource=RouteTable(title='SampleDmzRoteTable', VpcId=Ref(vpc))) template.add_resource(resource=SubnetRouteTableAssociation( title='SampleDmzRoteTableAssociation', RouteTableId=Ref(dmz_route_table), SubnetId=Ref(dmz_subnet))) eip = template.add_resource(resource=EIP(title='SampleEip', )) ngw = template.add_resource( resource=NatGateway(title='SampleNatGateway', AllocationId=GetAtt(eip, "AllocationId"), SubnetId=Ref(public_subnet))) template.add_resource(resource=Route(title='SampleDmzRoute', DestinationCidrBlock='0.0.0.0/0', NatGatewayId=Ref(ngw), RouteTableId=Ref(dmz_route_table)))
def create_private_resources(self): # If only a single NAT gateway name is defined, then this implies that the environment may have # multiple private subnets that will be attached with that single NAT gateway via a single private # route table. vpc_name = self.vpc_name t = self.template if "single_nat_gateway" in self.sceptre_user_data['resources']['vpc'][ 'private']: if self.sceptre_user_data['resources']['vpc']['private'][ 'single_nat_gateway'] is True: nat_gateway_name = "PrivateNATGateway" nat_gateway_subnet = self.public_subnets[0]["name"] nat_gateway_eip = nat_gateway_name + "EIP" nat_gateway_route_name = nat_gateway_name + "Route" private_route_table_name = "PrivateNetRouteTable" self.create_route_table(private_route_table_name, vpc_name) t.add_resource(EIP(nat_gateway_eip, Domain="vpc")) t.add_resource( NatGateway(nat_gateway_name, AllocationId=GetAtt(nat_gateway_eip, 'AllocationId'), SubnetId=Ref(nat_gateway_subnet))) route_dict = { "title": "PrivateRouteTable", "NatGatewayId": Ref(nat_gateway_name), "DestinationCidrBlock": "0.0.0.0/0", "RouteTableId": Ref(private_route_table_name), } self.create_route(route_dict)
def __add_nat_gateway(self): nat_ip = self.template.add_resource(EIP('NatEIP', Domain="vpc")) self.nat_gateway = self.template.add_resource( NatGateway('Nat', AllocationId=GetAtt(nat_ip, 'AllocationId'), SubnetId=Ref('PubSubnet0'))) self.nat_gateway.DependsOn = 'PubSubnet0'
def __build_nat_gateway(self, subnet_config: SubnetConfig, subnet_ref: Subnet): nat_eip = self.__template.add_resource(EIP("NatEIP" + subnet_config.name, Domain="vpc")) return self.__template.add_resource( NatGateway( "NatGateway" + subnet_config.name, AllocationId=GetAtt(nat_eip, "AllocationId"), SubnetId=Ref(subnet_ref), ) )
def add_eip(self): t = self.template self.vpnEip = t.add_resource(EIP("OpenVPNEIP", Domain="vpc")) self.eip = t.add_resource( EIPAssociation("ElasticIP", AllocationId=GetAtt(self.vpnEip, "AllocationId"), InstanceId=Ref(self.vpnInstance)))
def add_vpc_eip(self): ''' Add elastic ip to vpc ''' self.cfn_template.add_resource( EIP( title=constants.EIP, Domain='vpc', DependsOn=constants.ATTACH_GW, )) return self.cfn_template
def addNatGateway(template, subnet): ### Create EIP NATGatewayEIP = template.add_resource( EIP("NatEIP" + subnet.AvailabilityZone.replace("-", ""), Domain='vpc')) ### Create the NATGateway NATGateway = template.add_resource( NatGateway("NATGateway" + subnet.AvailabilityZone.replace("-", ""), AllocationId=GetAtt(NATGatewayEIP, 'AllocationId'), SubnetId=Ref(subnet))) return NATGateway
def add_nat_gateway(self, name, subnet): """ Add a NAT gateway :param name: Name to assign to the gateway :param subnet: Subnet in which to deploy it """ eip_name = "{}ElasticIP".format(name) self.template.add_resource(EIP(eip_name, Domain="vpc")) self.template.add_resource( NatGateway(name, AllocationId=GetAtt(eip_name, 'AllocationId'), SubnetId=subnet))
def set_eips(self, vpc_stack): """ :param ecs_composex.vpc.vpc_stack.VpcStack vpc_stack: :return: """ if self.is_nlb() and self.lb_is_public: if vpc_stack.vpc_resource.cfn_resource: for public_subnet in vpc_stack.vpc_resource.public_subnets[1]: self.lb_eips.append( EIP( f"{self.logical_name}Eip{public_subnet.title}", Domain="vpc", )) elif vpc_stack.vpc_resource.mappings: subnets = self.define_override_subnets(PUBLIC_SUBNETS.title, vpc_stack) for public_az in vpc_stack.vpc_resource.mappings[subnets][ "Azs"]: self.lb_eips.append( EIP( f"{self.logical_name}Eip{public_az.title().split('-')[-1]}", Domain="vpc", ))
def existing_eip(region, request, cfn_stacks_factory): template = Template() template.set_version("2010-09-09") template.set_description("EIP stack for testing existing EIP") template.add_resource(EIP("ElasticIP", Domain="vpc")) stack = CfnStack( name=generate_stack_name("integ-tests-eip", request.config.getoption("stackname_suffix")), region=region, template=template.to_json(), ) cfn_stacks_factory.create_stack(stack) yield stack.cfn_resources["ElasticIP"] if not request.config.getoption("no_delete"): cfn_stacks_factory.delete_stack(stack.name, region)
def add_public_ips(self, azs): """ Method to add EIPs for each AZ and adds these to the service template. :param azs: list of AZs to deploy the EIPs to :type azs: list :return: list of troposphere.ec2.EIP :rtype: list """ for az in azs: self.eips.append( EIP( f"EipPublicNlb{az.replace('-', '').strip()}{self.service_name}", template=self.template, Domain="vpc", ))
def build_hook(self): if len(self.subnet_cidrs) != len(self.azs): raise ValueError('VPNJumpbox: Wrong number of CIDRs, should be %s' % len(self.azs)) eip = self.add_resource(EIP( "%sEIP" % self.name, Domain="vpc", )) asg_name = '%sAutoscalingGroup' % self.name launch_config = self._get_launch_config(asg_name, eip) subnets = self._add_subnets() asg = self.add_resource(AutoScalingGroup( asg_name, AvailabilityZones=self.azs, LaunchConfigurationName=Ref(launch_config), MaxSize=1, MinSize=1, DesiredCapacity=1, VPCZoneIdentifier=subnets, CreationPolicy=CreationPolicy( ResourceSignal=ResourceSignal( Count=1, Timeout='PT10M' ) ), DependsOn=[])) asg.Tags = [ASGTag('Name', self.name, True)] self.add_output(Output( 'JumpboxEIP', Value=Ref(eip) ))
def __init__(self, title, template, *args, **kwargs): super().__init__(title, template, *args, **kwargs) EIP(title + 'eip', template, Domain='vpc', DependsOn='vpcgatewayattachment') NatGateway(title + 'natgateway', template, AllocationId=GetAtt(title + 'eip', 'AllocationId'), SubnetId=Ref(self), DependsOn=title + 'eip') RouteTable(title + 'routetable', template, VpcId=self.properties['VpcId'], Tags=kwargs['Tags']) Route(title + 'route', template, DestinationCidrBlock='0.0.0.0/0', GatewayId=Ref('internetgateway'), RouteTableId=Ref(title + 'routetable')) SubnetRouteTableAssociation(title + 'subnetroutetableassociation', template, RouteTableId=Ref(title + 'routetable'), SubnetId=Ref(self))
CidrBlock=FindInMap(Ref(environmentType_param), 'cidr', 'Private'), VpcId=Ref(VPC), Tags=Tags(Name=FindInMap(Ref(environmentType_param), 'tags', 'PrivateSubnet')))) InternetGateway = t.add_resource( InternetGateway( 'InternetGateway', Tags=Tags(Name=FindInMap(Ref(environmentType_param), 'tags', 'Igw')))) GatewayAttachment = t.add_resource( VPCGatewayAttachment('AttachGateway', VpcId=Ref(VPC), InternetGatewayId=Ref(InternetGateway))) NatEip = t.add_resource(EIP('NatEip', Domain="vpc")) NatGateway = t.add_resource( NatGateway( 'NatGateway', DependsOn='AttachGateway', AllocationId=GetAtt(NatEip, 'AllocationId'), SubnetId=Ref(PublicSubnet), Tags=Tags( Name=FindInMap(Ref(environmentType_param), 'tags', 'NatGateway')))) PublicRouteTable = t.add_resource( RouteTable('PublicRouteTable', VpcId=Ref(VPC), Tags=Tags(Name=FindInMap(Ref(environmentType_param), 'tags', 'PublicRouteTable'))))
def add_resource(self): self.PublicRouteTable = self.template.add_resource( RouteTable( "PublicRouteTable", VpcId=self.sceptre_user_data.get("VpcId"), Tags=Tags( Application=Ref("AWS::StackName"), Network="Public", Environment=self.sceptre_user_data.get("Environment"), Name=Join("-", ["RT-PU", self.sceptre_user_data.get("Project")]), ), )) self.PubSubnet = self.template.add_resource( Subnet( "PubSubnet", Tags=Tags( Application=Ref("AWS::StackName"), Environment=self.sceptre_user_data.get("Environment"), Network="Public", Name=Join("-", ["NT-PU", self.sceptre_user_data.get("Project")]), ), VpcId=self.sceptre_user_data.get("VpcId"), CidrBlock=Ref(self.PublicSubnet), AvailabilityZone=Ref(self.AvailabilityZone), MapPublicIpOnLaunch=True, )) self.PriSubnet = self.template.add_resource( Subnet( "PriSubnet", Tags=Tags( Application=Ref("AWS::StackName"), Environment=self.sceptre_user_data.get("Environment"), Network="Private", Name=Join("-", ["NT-PR", self.sceptre_user_data.get("Project")]), ), VpcId=self.sceptre_user_data.get("VpcId"), CidrBlock=Ref(self.PrivateSubnet), AvailabilityZone=Ref(self.AvailabilityZone), )) self.PublicRoute = self.template.add_resource( Route( "PublicRoute", GatewayId=self.igw_id, DestinationCidrBlock="0.0.0.0/0", RouteTableId=Ref(self.PublicRouteTable), )) self.PrivateRouteTable = self.template.add_resource( RouteTable( "PrivateRouteTable", VpcId=self.sceptre_user_data.get("VpcId"), Tags=Tags( Application=Ref("AWS::StackName"), Environment=self.sceptre_user_data.get("Environment"), Network="Private", Name=Join("-", ["RT-PR", self.sceptre_user_data.get("Project")]), ), )) self.PubSubnetRTAssoc = self.template.add_resource( SubnetRouteTableAssociation( "PubSubnetRTAssoc", SubnetId=Ref(self.PubSubnet), RouteTableId=Ref(self.PublicRouteTable), )) self.PriSubnetRTAssoc = self.template.add_resource( SubnetRouteTableAssociation( "PriSubnetRTAssoc", SubnetId=Ref(self.PriSubnet), RouteTableId=Ref(self.PrivateRouteTable), )) self.nat_eip = self.template.add_resource(EIP( 'NatEip', Domain="vpc", )) self.NatGateway = self.template.add_resource( NatGateway( "NatGateway", AllocationId=GetAtt(self.nat_eip, 'AllocationId'), SubnetId=Ref(self.PriSubnet), Tags=Tags( Application=Ref("AWS::StackName"), Environment=self.sceptre_user_data.get("Environment"), Name=Join( "-", ["NAT-PR", self.sceptre_user_data.get("Project")]), ), )) self.NatRoute = self.template.add_resource( Route( 'NatRoute', RouteTableId=Ref(self.PrivateRouteTable), DestinationCidrBlock='0.0.0.0/0', NatGatewayId=Ref(self.NatGateway), ))
CidrBlock=public_subnet_cidr, ) SubnetRouteTableAssociation( "PublicSubnetRouteTableAssociation", template=template, RouteTableId=Ref(public_route_table), SubnetId=Ref(public_subnet), ) # NAT nat_ip = EIP( "NatIp", template=template, Domain="vpc", ) nat_gateway = NatGateway( "NatGateway", template=template, AllocationId=GetAtt(nat_ip, "AllocationId"), SubnetId=Ref(public_subnet), ) # Holds load balancer loadbalancer_a_subnet_cidr = "10.0.2.0/24" loadbalancer_a_subnet = Subnet(
"CidrIp": "0.0.0.0/0" }, { "ToPort": "65535", "FromPort": "0", "IpProtocol": "udp", "CidrIp": "0.0.0.0/0" }, { "ToPort": "65535", "FromPort": "0", "IpProtocol": "tcp", "CidrIp": "0.0.0.0/0" }], )) EipNatAz3 = t.add_resource(EIP( "EipNatAz3", Domain="vpc", )) SubnetTestPrivateAz3 = t.add_resource( Subnet( "SubnetTestPrivateAz3", VpcId=Ref("VPC"), CidrBlock=FindInMap("SubnetMap", "TEST-PRIVATE-AZ3", "CIDR"), AvailabilityZone=Select("2", GetAZs("")), Tags=Tags( Name="SubnetTestPrivateAz3", project="ShelterMutual", ), )) SubnetTestPrivateAz2 = t.add_resource(
routetable = resources[ "PublicRouteTable" ] template.add_resource(SubnetRouteTableAssociation( "SubnetRouteTableAssociation" + subnet, DependsOn = [ resource for resource in [ routetable.name, subnet ] ], RouteTableId = Ref(routetable), SubnetId = Ref(resources[ subnet ]))) i = i+1 ### Elastic IP for NAT Gateway ### resources[ "ElasticIP" ] = template.add_resource(EIP( "ElasticIP", DependsOn = [ resource for resource in [ "VPCGatewayAttachmentIGW" ] ], Domain = "vpc" )) ### NAT Gateway ### resources[ "NatGateway" ] = template.add_resource(NatGateway( "NatGateway", DependsOn = [ resource for resource in [ "PUBA", "ElasticIP" ] ], AllocationId = GetAtt(resources[ "ElasticIP" ], "AllocationId" ), SubnetId = Ref(resources[ "PUBA" ]))) ### Routes ### template.add_resource(Route( "InternetGatewayRoute",
def create_template(num_masters, num_agents, num_publicAgents): #outfilename = "test.json" outfilename = "cf_" + str(num_masters) + "." + str(num_agents) + "." + str( num_publicAgents) + ".json" # Create the Template t = Template() t.add_version('2010-09-09') t.add_description('Creates a set of Servers for DC/OS using CentOS 7.3 AMI. Creates a boot server to host the DC/OS installer and a NAT Instance for outbound connections from private agents. Creates ' + str(num_masters) + ' Master(s), ' \ + str(num_agents) + ' Private Agent(s), and ' + str(num_publicAgents) + ' Public Agent(s). After creating the Stack; Log into the boot server and run the DCOS Bash Script installer for AWS') # Amazon Linux AMI 2016.09.1.20170119 x86_64 VPC NAT HVM EBS # amzn-ami-vpc-nat-hvm-2016.09.1.20170119-x86_64-ebs - # ami-dd3dd7cb us-east-1 (N. Virginia) # ami-564b6e33 us-east-2 (Ohio) # ami-7d54061d us-west-1 (N. Cal) # ami-3b6fd05b us-west-2 (Oregon) t.add_mapping( 'NATAmi', { 'us-east-1': { 'default': 'ami-dd3dd7cb' }, 'us-east-2': { 'default': 'ami-564b6e33' }, 'us-west-1': { 'default': 'ami-7d54061d' }, 'us-west-2': { 'default': 'ami-3b6fd05b' }, }) # The c73 AMI pre created and deployed on each region t.add_mapping( 'c73Ami', { 'us-east-1': { 'default': 'ami-46c1b650' }, 'us-east-2': { 'default': 'ami-18f8df7d' }, 'us-west-1': { 'default': 'ami-f5d7f195' }, 'us-west-2': { 'default': 'ami-f4533694' }, }) # CloudFormation Parameters # Sometimes when I deployed stack on us-east-1; it would fail on av zone us-east-1c with error messages instance type not support on this AZ. I added this parameter to fix all of the components in on AZ for now avzone_param = t.add_parameter( Parameter( "AVZoneName", ConstraintDescription='Must be the name of an an Availability Zone', Description='Name of an Availability Zone', Type='AWS::EC2::AvailabilityZone::Name', )) # Every agent will get a data drive of this size dataDriveSizeGB_param = t.add_parameter( Parameter( "dataDriveSizeGB", Default="100", MinValue=20, MaxValue=1000, Description= 'Size of data drive to add to private agents from 20 to 1000GB', Type='Number')) # The key will be added to the centos user so you can login to centos using the key keyname_param = t.add_parameter( Parameter( "KeyName", ConstraintDescription= 'Must be the name of an existing EC2 KeyPair.', Description= 'Name of an existing EC2 KeyPair to enable SSH access to the instance', Type='AWS::EC2::KeyPair::KeyName', )) # While you can allow everyone it's more secure to just allow a single machine or subnet of machines; web port will also be opened to this CIDR sshlocation_param = t.add_parameter( Parameter( "sshlocation", Type="String", Description= "Subnet allowed to ssh to these servers. 0.0.0.0/0 to allow all.")) # Instance type for Master instanceTypeMaster_param = t.add_parameter( Parameter( 'InstanceTypeMaster', Type='String', Description='EC2 instance type for ' + str(num_masters) + ' Masters(s)', Default='m4.xlarge', AllowedValues=[ 't2.xlarge', 't2.2xlarge', 'm4.xlarge', 'm4.2xlarge', 'm4.4xlarge', 'm4.10xlarge', 'c4.xlarge', 'c4.2xlarge', 'c4.4xlarge', 'c4.8xlarge', ], ConstraintDescription='Must be a valid EC2 instance type.', )) # Instance type for Agents instanceTypeAgent_param = t.add_parameter( Parameter( 'InstanceTypeAgent', Type='String', Description='EC2 instance type for ' + str(num_agents) + ' Private Agent(s)', Default='m4.2xlarge', AllowedValues=[ 't2.xlarge', 't2.2xlarge', 'm4.xlarge', 'm4.2xlarge', 'm4.4xlarge', 'm4.10xlarge', 'c4.xlarge', 'c4.2xlarge', 'c4.4xlarge', 'c4.8xlarge', ], ConstraintDescription='Must be a valid EC2 instance type.', )) # Instance type for Public Agents instanceTypePublicAgent_param = t.add_parameter( Parameter( 'InstanceTypePublicAgent', Type='String', Description='EC2 instance type for ' + str(num_publicAgents) + ' Public Agent(s)', Default='m4.xlarge', AllowedValues=[ 't2.xlarge', 't2.2xlarge', 'm4.xlarge', 'm4.2xlarge', 'm4.4xlarge', 'm4.10xlarge', 'c4.xlarge', 'c4.2xlarge', 'c4.4xlarge', 'c4.8xlarge', ], ConstraintDescription='Must be a valid EC2 instance type.', )) # Adding Resources ref_stack_id = Ref('AWS::StackId') ref_region = Ref('AWS::Region') ref_stack_name = Ref('AWS::StackName') # Create VPC nm = 'vpc' vpc = t.add_resource( VPC(nm, CidrBlock='10.10.0.0/16', EnableDnsSupport=True, EnableDnsHostnames=True, Tags=Tags(Application=ref_stack_id, Name=Join("", [Ref('AWS::StackName'), "-", nm])))) # Create Subnet for Masters nm = 'mastersSubnet' subnetMasters = t.add_resource( Subnet(nm, AvailabilityZone=Ref(avzone_param), CidrBlock='10.10.0.0/24', VpcId=Ref(vpc), Tags=Tags(Application=ref_stack_id, Name=Join("", [Ref('AWS::StackName'), "-", nm])))) # Create Subnet for Agents nm = 'agentsSubnet' subnetAgents = t.add_resource( Subnet(nm, AvailabilityZone=Ref(avzone_param), CidrBlock='10.10.16.0/24', VpcId=Ref(vpc), Tags=Tags(Application=ref_stack_id, Name=Join("", [Ref('AWS::StackName'), "-", nm])))) # Create Subnet for Public Agents nm = 'publicAgentsSubnet' subnetPublicAgents = t.add_resource( Subnet(nm, AvailabilityZone=Ref(avzone_param), CidrBlock='10.10.32.0/24', VpcId=Ref(vpc), Tags=Tags(Application=ref_stack_id, Name=Join("", [Ref('AWS::StackName'), "-", nm])))) # Create Gateway; route to the outside world (Internet) nm = 'ig' internetGateway = t.add_resource( InternetGateway(nm, Tags=Tags(Application=ref_stack_id, Name=Join( "", [Ref('AWS::StackName'), "-", nm])))) # Attach Gateway to VPC nm = 'gatewayAttachment' gatewayAttachment = t.add_resource( VPCGatewayAttachment(nm, VpcId=Ref(vpc), InternetGatewayId=Ref(internetGateway))) # Create Route Table nm = 'routeTable' routeTable = t.add_resource( RouteTable(nm, VpcId=Ref(vpc), Tags=Tags(Application=ref_stack_id, Name=Join("", [Ref('AWS::StackName'), "-", nm])))) # Add Routes # Allow all outbound traffic nm = 'route' route = t.add_resource( Route( nm, DependsOn=gatewayAttachment.title, GatewayId=Ref(internetGateway), DestinationCidrBlock='0.0.0.0/0', RouteTableId=Ref(routeTable), )) # Associate RouteTable to Master and Public Subnets nm = 'subnetRTAMasters' subnetRouteTableAssociation = t.add_resource( SubnetRouteTableAssociation( nm, SubnetId=Ref(subnetMasters), RouteTableId=Ref(routeTable), )) nm = 'subnetRTAPublicAgents' subnetRouteTableAssociation = t.add_resource( SubnetRouteTableAssociation( nm, SubnetId=Ref(subnetPublicAgents), RouteTableId=Ref(routeTable), )) # Create Security Group (General access to ssh and internal connectionsn between masters, agents, and public agents) nm = 'securityGroup' securityGroup = t.add_resource( SecurityGroup(nm, GroupDescription='Security Group', SecurityGroupIngress=[ SecurityGroupRule(IpProtocol='tcp', FromPort='22', ToPort='22', CidrIp=Ref(sshlocation_param)), SecurityGroupRule(IpProtocol='-1', CidrIp='10.10.0.0/16') ], VpcId=Ref(vpc), Tags=Tags(Application=ref_stack_id, Name=Join("", [Ref('AWS::StackName'), "-", nm])))) # Create Security Group Public Agents nm = 'securityGroupPublicAgents' publicAgentsSG = t.add_resource( SecurityGroup(nm, GroupDescription='Security Group Public Agents', SecurityGroupIngress=[ SecurityGroupRule(IpProtocol='tcp', FromPort='80', ToPort='80', CidrIp='0.0.0.0/0'), SecurityGroupRule(IpProtocol='tcp', FromPort='443', ToPort='443', CidrIp='0.0.0.0/0'), SecurityGroupRule(IpProtocol='tcp', FromPort='10000', ToPort='10010', CidrIp='0.0.0.0/0'), SecurityGroupRule(IpProtocol='tcp', FromPort='9090', ToPort='9090', CidrIp='0.0.0.0/0') ], VpcId=Ref(vpc), Tags=Tags(Application=ref_stack_id, Name=Join("", [Ref('AWS::StackName'), "-", nm])))) # Create Security Group Masters Allow Access from sshlocation param as test nm = 'securityGroupMasters' mastersSG = t.add_resource( SecurityGroup(nm, GroupDescription='Security Group Masters', SecurityGroupIngress=[ SecurityGroupRule(IpProtocol='tcp', FromPort='80', ToPort='80', CidrIp=Ref(sshlocation_param)), SecurityGroupRule(IpProtocol='tcp', FromPort='443', ToPort='443', CidrIp=Ref(sshlocation_param)) ], VpcId=Ref(vpc), Tags=Tags(Application=ref_stack_id, Name=Join("", [Ref('AWS::StackName'), "-", nm])))) if useNatInstance: # **** Also change in natRoute **** # Create NAT instance; This allows private agents to get out to the Internet nm = 'nat' nat = t.add_resource( Instance( nm, SourceDestCheck="false", ImageId=FindInMap("NATAmi", Ref("AWS::Region"), "default"), InstanceType="m4.large", AvailabilityZone=Ref(avzone_param), KeyName=Ref(keyname_param), DependsOn=internetGateway.title, NetworkInterfaces=[ NetworkInterfaceProperty(GroupSet=[Ref(securityGroup)], AssociatePublicIpAddress='true', DeviceIndex='0', DeleteOnTermination='true', SubnetId=Ref(subnetMasters), PrivateIpAddress='10.10.0.9') ], BlockDeviceMappings=[ BlockDeviceMapping(DeviceName="/dev/xvda", Ebs=EBSBlockDevice( DeleteOnTermination='true', )) ], Tags=Tags(Application=ref_stack_id, Name=Join("", [Ref('AWS::StackName'), "-", nm])))) else: # Create Elastic IP for NatGateay nm = 'natIP' nat_eip = t.add_resource(EIP( nm, Domain="vpc", )) # Create NAT Gateway nm = 'natGateway' nat = t.add_resource( NatGateway( nm, AllocationId=GetAtt(nat_eip, 'AllocationId'), SubnetId=Ref(subnetMasters), )) # Create Route Table for NAT nm = 'natRouteTable' routeTableNAT = t.add_resource( RouteTable(nm, VpcId=Ref(vpc), Tags=Tags(Application=ref_stack_id, Name=Join("", [Ref('AWS::StackName'), "-", nm])))) # Associate Agent Subnet to NAT nm = 'subnetRTAAgents' subnetRouteTableAssociation = t.add_resource( SubnetRouteTableAssociation( nm, SubnetId=Ref(subnetAgents), RouteTableId=Ref(routeTableNAT), )) # Add Routes (Agents can reach out anywhere) nm = 'natRoute' if useNatInstance: route = t.add_resource( Route( nm, RouteTableId=Ref(routeTableNAT), DestinationCidrBlock='0.0.0.0/0', InstanceId=Ref(nat), )) else: route = t.add_resource( Route( nm, RouteTableId=Ref(routeTableNAT), DestinationCidrBlock='0.0.0.0/0', NatGatewayId=Ref(nat), )) # **************************************** # NOTE: I am using static PrivateIPAddresses; this may not be a good choice; however, it simplified the install script. The range of IP's for the master and agents are limited to 24 subnet and I start at 11 # With this configuration the max number of agents is around 240. # **************************************** # Create boot instance # Installs on AWS so far have taken longer than on Azure. Takes about 10 minutes for the boot server to configure. # Tried several InstanceType from t2.micro to m4.large; all take about 10 minutes for boot to load. The docker start of mesosphere/dcos-genconf seems to be taking longer than it did on azure. nm = 'boot' boot = t.add_resource( Instance(nm, ImageId=FindInMap("c73Ami", Ref("AWS::Region"), "default"), InstanceType="m4.xlarge", AvailabilityZone=Ref(avzone_param), KeyName=Ref(keyname_param), NetworkInterfaces=[ NetworkInterfaceProperty(GroupSet=[Ref(securityGroup)], AssociatePublicIpAddress='true', DeviceIndex='0', DeleteOnTermination='true', SubnetId=Ref(subnetMasters), PrivateIpAddress='10.10.0.10') ], BlockDeviceMappings=[ BlockDeviceMapping(DeviceName="/dev/sda1", Ebs=EBSBlockDevice( VolumeSize="100", DeleteOnTermination='true', )) ], Tags=Tags(Application=ref_stack_id, Name=Join("", [Ref('AWS::StackName'), "-", nm])))) # Create master instance(s) masters = [] i = 1 while i <= num_masters: nm = 'm' + str(i) private_ip = "10.10.0." + str(i + 10) instance = t.add_resource( Instance(nm, ImageId=FindInMap("c73Ami", Ref("AWS::Region"), "default"), InstanceType=Ref(instanceTypeMaster_param), AvailabilityZone=Ref(avzone_param), KeyName=Ref(keyname_param), NetworkInterfaces=[ NetworkInterfaceProperty( GroupSet=[Ref(securityGroup), Ref(mastersSG)], AssociatePublicIpAddress='true', DeviceIndex='0', DeleteOnTermination='true', SubnetId=Ref(subnetMasters), PrivateIpAddress=private_ip) ], BlockDeviceMappings=[ BlockDeviceMapping(DeviceName="/dev/sda1", Ebs=EBSBlockDevice( VolumeSize="100", DeleteOnTermination='true', )) ], Tags=Tags(Application=ref_stack_id, Name=Join("", [Ref('AWS::StackName'), "-", nm])))) masters.append(instance) i += 1 # Create agent instance(s) i = 1 while i <= num_agents: nm = 'a' + str(i) private_ip = "10.10.16." + str(i + 10) instance = t.add_resource( Instance( nm, ImageId=FindInMap("c73Ami", Ref("AWS::Region"), "default"), InstanceType=Ref(instanceTypeAgent_param), AvailabilityZone=Ref(avzone_param), KeyName=Ref(keyname_param), NetworkInterfaces=[ NetworkInterfaceProperty(GroupSet=[Ref(securityGroup)], AssociatePublicIpAddress='false', DeviceIndex='0', DeleteOnTermination='true', SubnetId=Ref(subnetAgents), PrivateIpAddress=private_ip) ], BlockDeviceMappings=[ BlockDeviceMapping(DeviceName="/dev/sda1", Ebs=EBSBlockDevice( VolumeSize="100", DeleteOnTermination='true', )) ], Tags=Tags(Application=ref_stack_id, Name=Join("", [Ref('AWS::StackName'), "-", nm])))) volume = t.add_resource( Volume(nm + "data", AvailabilityZone=Ref(avzone_param), Size=Ref(dataDriveSizeGB_param), Tags=Tags( Application=ref_stack_id, Name=Join("", [Ref('AWS::StackName'), "-", nm + "data"])))) volattach = t.add_resource( VolumeAttachment(nm + "dataattach", InstanceId=Ref(instance), VolumeId=Ref(volume), Device="/dev/sdc")) i += 1 # Create public agent instance(s) publicAgents = [] i = 1 nm = "p1" while i <= num_publicAgents: nm = 'p' + str(i) private_ip = "10.10.32." + str(i + 10) instance = t.add_resource( Instance( nm, ImageId=FindInMap("c73Ami", Ref("AWS::Region"), "default"), InstanceType=Ref(instanceTypePublicAgent_param), AvailabilityZone=Ref(avzone_param), KeyName=Ref(keyname_param), NetworkInterfaces=[ NetworkInterfaceProperty( GroupSet=[Ref(securityGroup), Ref(publicAgentsSG)], AssociatePublicIpAddress='true', DeviceIndex='0', DeleteOnTermination='true', SubnetId=Ref(subnetPublicAgents), PrivateIpAddress=private_ip) ], BlockDeviceMappings=[ BlockDeviceMapping(DeviceName="/dev/sda1", Ebs=EBSBlockDevice( VolumeSize="100", DeleteOnTermination='true', )) ], Tags=Tags(Application=ref_stack_id, Name=Join("", [Ref('AWS::StackName'), "-", nm])))) publicAgents.append(instance) i += 1 # Load Balancer Masters nm = "masters" elasticLBMasters = t.add_resource( elb.LoadBalancer( nm, Instances=[Ref(r) for r in masters], Subnets=[Ref(subnetMasters)], SecurityGroups=[Ref(mastersSG)], CrossZone=False, Listeners=[ elb.Listener( LoadBalancerPort="80", InstancePort="80", Protocol="TCP", ), elb.Listener( LoadBalancerPort="443", InstancePort="443", Protocol="TCP", ), ], # Health Checking on port 80 which should be there after DCOS has been installed. HealthCheck=elb.HealthCheck( Target="TCP:80", HealthyThreshold="2", UnhealthyThreshold="2", Interval="30", Timeout="5", ), Tags=Tags(Application=ref_stack_id, Name=Join("", [Ref('AWS::StackName'), "-", nm])))) # Load Balancer Public Agents nm = "publicagents" elasticLBPublicAgents = t.add_resource( elb.LoadBalancer( nm, #AvailabilityZones=GetAZs(""), Instances=[Ref(r) for r in publicAgents], Subnets=[Ref(subnetPublicAgents)], SecurityGroups=[Ref(publicAgentsSG)], CrossZone=False, Listeners=[ elb.Listener( LoadBalancerPort="10000", InstancePort="10000", Protocol="TCP", ), elb.Listener( LoadBalancerPort="10001", InstancePort="10001", Protocol="TCP", ), elb.Listener( LoadBalancerPort="10002", InstancePort="10002", Protocol="TCP", ), elb.Listener( LoadBalancerPort="10003", InstancePort="10003", Protocol="TCP", ), elb.Listener( LoadBalancerPort="10004", InstancePort="10004", Protocol="TCP", ), elb.Listener( LoadBalancerPort="10005", InstancePort="10005", Protocol="TCP", ), elb.Listener( LoadBalancerPort="10006", InstancePort="10006", Protocol="TCP", ), elb.Listener( LoadBalancerPort="10007", InstancePort="10007", Protocol="TCP", ), elb.Listener( LoadBalancerPort="10008", InstancePort="10008", Protocol="TCP", ), elb.Listener( LoadBalancerPort="10009", InstancePort="10009", Protocol="TCP", ), elb.Listener( LoadBalancerPort="10010", InstancePort="10010", Protocol="TCP", ), elb.Listener( LoadBalancerPort="9090", InstancePort="9090", Protocol="TCP", ), elb.Listener( LoadBalancerPort="80", InstancePort="80", Protocol="TCP", ), elb.Listener( LoadBalancerPort="443", InstancePort="443", Protocol="TCP", ) ], # I've added health check for port 9090; becomes healthy after Marathon-LB is installed. HealthCheck=elb.HealthCheck( Target="TCP:9090", HealthyThreshold="2", UnhealthyThreshold="2", Interval="30", Timeout="5", ), Tags=Tags(Application=ref_stack_id, Name=Join("", [Ref('AWS::StackName'), "-", nm])))) # Outputs t.add_output( Output("BootServer", Description="Name/IP of Boot Server", Value=Join( "/", [GetAtt(boot, "PublicDnsName"), GetAtt(boot, "PublicIp")]))) t.add_output( Output("MastersURL", Description="URL of the Masters", Value=Join( "", ["http://", GetAtt(elasticLBMasters, "DNSName")]))) t.add_output( Output( "PublicAgentsURL", Description="URL of the Public Agents haproxy stats.", Value=Join("", [ "http://", GetAtt(elasticLBPublicAgents, "DNSName"), ":9090/haproxy?stats" ]))) # Write json to file jsonStr = t.to_json() fout = open(outfilename, "w") fout.write(jsonStr) fout.close() # Print the json to screen print(jsonStr)
instance = t.add_resource( Instance( config_file['ec2']['name'], ImageId=FindInMap( 'AWSRegionArch2AMI', config_file['vpc']['region'], FindInMap('AWSInstanceType2Arch', config_file['ec2']['type'], 'Arch')), InstanceType=config_file['ec2']['type'], KeyName=Ref(keyname_param), NetworkInterfaces=[ NetworkInterfaceProperty(GroupSet=[Ref(instanceSecurityGroup)], AssociatePublicIpAddress='true', DeviceIndex='0', DeleteOnTermination='true', SubnetId=Ref(subnet)) ], CreationPolicy=CreationPolicy(ResourceSignal=ResourceSignal( Timeout='PT15M')), Tags=Tags(Application=ref_stack_id), )) ipAddress = t.add_resource( EIP('IPAddress', DependsOn='AttachGateway', Domain='vpc', InstanceId=Ref(instance))) # WRITE TEMPLATE json = t.to_json() output_file.write(json)
NetworkAclId=Ref("{}NetworkAcl".format(a)), RuleNumber="100", Protocol="-1", Egress="true" if d == "Outbound" else "false", RuleAction="allow", CidrBlock="0.0.0.0/0", )) t.add_resource(Route( "RouteTablePublicInternetRoute", GatewayId=Ref("InternetGateway"), DestinationCidrBlock="0.0.0.0/0", RouteTableId=Ref("PublicRouteTable"), )) t.add_resource(EIP( "EIP", Domain="VPC" )) t.add_resource(NatGateway( "NatGateway", AllocationId=GetAtt("EIP", "AllocationId"), SubnetId=Ref("PublicSubnetA") )) t.add_resource(Route( "RouteNat", RouteTableId=Ref("PrivateRouteTable"), DestinationCidrBlock="0.0.0.0/0", NatGatewayId=Ref("NatGateway") )) t.add_output(Output( "VPCId", Description="VPCId of the newly created VPC",
VpcId=Ref(VPCId), CidrBlock=Ref(PrivateSubnet2CIDR), MapPublicIpOnLaunch=False, AvailabilityZone=Ref(AZ2))) PublicSubnet1RouteTableAssociation = t.add_resource( SubnetRouteTableAssociation( "PublicSubnet1RouteTableAssociation", SubnetId=Ref("PublicSubnet1"), RouteTableId=Ref("PublicRouteTable"), )) NatGateway1EIP = t.add_resource( EIP( "NatGateway1EIP", Domain="vpc", DependsOn="InternetGatewayAttachment", )) PrivateSubnet1RouteTableAssociation = t.add_resource( SubnetRouteTableAssociation( "PrivateSubnet1RouteTableAssociation", SubnetId=Ref(PrivateSubnet1), RouteTableId=Ref(PrivateRouteTable1), )) PublicRouteTable = t.add_resource( RouteTable( "PublicRouteTable", VpcId=Ref(VPCId), Tags=Tags(Name={"Fn::Sub": "${EnvironmentName} Public Routes"}, ),
"/opt/aws/bin/cfn-signal -e $? ", " --stack ", Ref("AWS::StackName"), " --resource WebServerInstance ", " --region ", Ref("AWS::Region"), "\n", ], ) ), CreationPolicy=CreationPolicy(ResourceSignal=ResourceSignal(Timeout="PT15M")), Tags=Tags(Application=ref_stack_id), ) ) ipAddress = t.add_resource( EIP("IPAddress", DependsOn="AttachGateway", Domain="vpc", InstanceId=Ref(instance)) ) t.add_output( [ Output( "URL", Description="Newly created application URL", Value=Join("", ["http://", GetAtt("WebServerInstance", "PublicIp")]), ) ] ) print(t.to_json())
def create_subnet(t, output): ref_region = Ref('AWS::Region') igw = t.add_resource( InternetGateway( "InternetGateway", Tags=Tags(Name=Join("", [output["service"], "-", output["env"]])))) GWattachment = t.add_resource( VPCGatewayAttachment( "AttachGateway", VpcId=output["vpc"], InternetGatewayId=Ref("InternetGateway"), )) # Pub Subnet Availability Zone A pubsubneta = t.add_resource( Subnet('PubSubnetA', CidrBlock=Join('', [output["vpcenvcidr"], '.', '0', '.0/24']), VpcId=output["vpc"], AvailabilityZone=Select("0", GetAZs(ref_region)), Tags=Tags(Name=Join( "", [output["service"], "-", output["env"], "-PubA"])))) # Pub Subnet Availability Zone B pubsubnetb = t.add_resource( Subnet('PubSubnetB', CidrBlock=Join('', [output["vpcenvcidr"], '.', '1', '.0/24']), VpcId=output["vpc"], AvailabilityZone=Select("1", GetAZs(ref_region)), Tags=Tags(Name=Join( "", [output["service"], "-", output["env"], "-PubB"])))) # Pub Subnet Availability Zone C pubsubnetc = t.add_resource( Subnet('PubSubnetC', CidrBlock=Join('', [output["vpcenvcidr"], '.', '2', '.0/24']), VpcId=output["vpc"], AvailabilityZone=Select("2", GetAZs(ref_region)), Tags=Tags(Name=Join( "", [output["service"], "-", output["env"], "-PubC"])))) # Private Subnet Availability Zone A privsubneta = t.add_resource( Subnet('PrivSubnetA', CidrBlock=Join('', [output["vpcenvcidr"], '.', '3', '.0/24']), VpcId=output["vpc"], AvailabilityZone=Select("0", GetAZs(ref_region)), Tags=Tags(Name=Join( "", [output["service"], "-", output["env"], "-PrivA"])))) # Private Subnet Availability Zone B privsubnetb = t.add_resource( Subnet('PrivSubnetB', CidrBlock=Join('', [output["vpcenvcidr"], '.', '4', '.0/24']), VpcId=output["vpc"], AvailabilityZone=Select("1", GetAZs(ref_region)), Tags=Tags(Name=Join( "", [output["service"], "-", output["env"], "-PrivB"])))) # Private Subnet Availability Zone C privsubnetc = t.add_resource( Subnet('PrivSubnetC', CidrBlock=Join('', [output["vpcenvcidr"], '.', '5', '.0/24']), VpcId=output["vpc"], AvailabilityZone=Select("2", GetAZs(ref_region)), Tags=Tags(Name=Join( "", [output["service"], "-", output["env"], "-PrivC"])))) output["SubnetIds"] = {} output["SubnetIds"]["pubsubneta"] = Ref(pubsubneta) output["SubnetIds"]["pubsubnetb"] = Ref(pubsubnetb) output["SubnetIds"]["pubsubnetc"] = Ref(pubsubnetc) # output["SubnetIds"]["privsubneta"] = Ref(privsubneta) # output["SubnetIds"]["privsubnetb"] = Ref(privsubnetb) # output["SubnetIds"]["privsubnetc"] = Ref(privsubnetc) # NAT Gateway # Availability Zone A nat_eip_a = t.add_resource(EIP('NATeipA', Domain="vpc")) nat_gw_a = t.add_resource( NatGateway( 'NatGwA', AllocationId=GetAtt(nat_eip_a, 'AllocationId'), SubnetId=Ref(pubsubneta), )) # Availability Zone B nat_eip_b = t.add_resource(EIP('NATeipB', Domain="vpc")) nat_gw_b = t.add_resource( NatGateway( 'NatGwB', AllocationId=GetAtt(nat_eip_b, 'AllocationId'), SubnetId=Ref(pubsubnetb), )) # Availability Zone C nat_eip_c = t.add_resource(EIP('NATeipC', Domain="vpc")) nat_gw_c = t.add_resource( NatGateway( 'NatGwC', AllocationId=GetAtt(nat_eip_c, 'AllocationId'), SubnetId=Ref(pubsubnetc), )) pubroutetable = t.add_resource( RouteTable( "PubRouteTable", VpcId=output["vpc"], Tags=Tags(Name=Join( "", [output["service"], "-", output["env"], "-", "PubRT"])))) pubroute = t.add_resource( Route("PubRoute", DependsOn="AttachGateway", RouteTableId=Ref(pubroutetable), DestinationCidrBlock="0.0.0.0/0", GatewayId=Ref(igw))) privroutetablea = t.add_resource( RouteTable( "PrivRouteTableA", VpcId=output["vpc"], Tags=Tags(Name=Join( "", [output["service"], "-", output["env"], "-", "PrivRT-A"])))) privroutea = t.add_resource( Route("PrivRouteA", RouteTableId=Ref(privroutetablea), DestinationCidrBlock="0.0.0.0/0", NatGatewayId=Ref(nat_gw_a))) privroutetableb = t.add_resource( RouteTable( "PrivRouteTableB", VpcId=output["vpc"], Tags=Tags(Name=Join( "", [output["service"], "-", output["env"], "-", "PrivRT-B"])))) privrouteb = t.add_resource( Route("PrivRouteB", RouteTableId=Ref(privroutetableb), DestinationCidrBlock="0.0.0.0/0", NatGatewayId=Ref(nat_gw_b))) privroutetablec = t.add_resource( RouteTable( "PrivRouteTableC", VpcId=output["vpc"], Tags=Tags(Name=Join( "", [output["service"], "-", output["env"], "-", "PrivRT-C"])))) privroutec = t.add_resource( Route("PrivRouteC", RouteTableId=Ref(privroutetablec), DestinationCidrBlock="0.0.0.0/0", NatGatewayId=Ref(nat_gw_c))) subnetroutetableassociationpuba = t.add_resource( SubnetRouteTableAssociation( 'SubnetRouteTableAssociationPubA', SubnetId=Ref(pubsubneta), RouteTableId=Ref(pubroutetable), )) subnetroutetableassociationpubb = t.add_resource( SubnetRouteTableAssociation( 'SubnetRouteTableAssociationPubB', SubnetId=Ref(pubsubnetb), RouteTableId=Ref(pubroutetable), )) subnetroutetableassociationpubc = t.add_resource( SubnetRouteTableAssociation( 'SubnetRouteTableAssociationPubC', SubnetId=Ref(pubsubnetc), RouteTableId=Ref(pubroutetable), )) subnetroutetableassociationpriva = t.add_resource( SubnetRouteTableAssociation( 'SubnetRouteTableAssociationPrivA', SubnetId=Ref(privsubneta), RouteTableId=Ref(privroutetablea), )) subnetroutetableassociationprivb = t.add_resource( SubnetRouteTableAssociation( 'SubnetRouteTableAssociationPrivB', SubnetId=Ref(privsubnetb), RouteTableId=Ref(privroutetableb), )) subnetroutetableassociationprivc = t.add_resource( SubnetRouteTableAssociation( 'SubnetRouteTableAssociationPrivC', SubnetId=Ref(privsubnetc), RouteTableId=Ref(privroutetablec), )) outputs = t.add_output([ Output("IGW", Value=Ref(igw), Export=Export(Sub("${AWS::StackName}-IGW")), Description="Internet Gateway"), Output("NatGWA", Value=Ref(nat_gw_a), Export=Export(Sub("${AWS::StackName}-NATGatewayA")), Description="NAT Gateway AZ A"), Output("NatGWB", Value=Ref(nat_gw_b), Export=Export(Sub("${AWS::StackName}-NATGatewayB")), Description="NAT Gateway AZ B"), Output("NatGWC", Value=Ref(nat_gw_c), Export=Export(Sub("${AWS::StackName}-NATGatewayC")), Description="NAT Gateway AZ C"), Output("VPCEnvCidr", Value=output["vpcenvcidr"], Export=Export(Sub("${AWS::StackName}-CIDR")), Description="First 2 CIDR Block of the VPC"), Output("ServiceID", Value=output["service_id"], Export=Export(Sub("${AWS::StackName}-ServiceID")), Description="3rd Oct of CIDR block"), Output("PUBSUBNETA", Value=Ref(pubsubneta), Export=Export(Sub("${AWS::StackName}-PubSubnetA")), Description="Public A Subnet"), Output("PUBSUBNETB", Value=Ref(pubsubnetb), Export=Export(Sub("${AWS::StackName}-PubSubnetB")), Description="Public B Subnet"), Output("PUBSUBNETC", Value=Ref(pubsubnetc), Export=Export(Sub("${AWS::StackName}-PubSubnetC")), Description="Public C Subnet"), Output("PRIVSUBNETA", Value=Ref(privsubneta), Export=Export(Sub("${AWS::StackName}-PrivSubnetA")), Description="Priv A Subnet"), Output("PRIVSUBNETB", Value=Ref(privsubnetb), Export=Export(Sub("${AWS::StackName}-PrivSubnetB")), Description="Priv B Subnet"), Output("PRIVSUBNETC", Value=Ref(privsubnetc), Export=Export(Sub("${AWS::StackName}-PrivSubnetC")), Description="Priv C Subnet"), ]) # t = create_sg(t, output) # output["SubnetIds"] = [Ref(pubsubneta), Ref(pubsubnetb), Ref(pubsubnetc)] # SubnetIds = [Ref(pubsubneta), Ref(pubsubnetb), Ref(pubsubnetc)] # security_group_id = [GetAtt(sgtrusted, "GroupId")] return t, output
def create_elastic_ip(stack, name): """Add VPC Elastic IP Resource.""" return stack.stack.add_resource(EIP('{0}eip'.format(name)))
def vpcTemplate(name, app, env, cidrBlock, publicSubnets, privateSubnets): template = Template() vpc = template.add_resource( VPC( "VPC" + name + app + env, CidrBlock=cidrBlock, EnableDnsSupport=True, EnableDnsHostnames=True, Tags=Tags( Env=env, Name=name + "-" + env, ), )) internetGateway = template.add_resource( InternetGateway( "InternetGateway" + name + app + env, Tags=Tags( Env=env, Name="igw-" + env, ), )) gatewayAttachment = template.add_resource( VPCGatewayAttachment("InternetGatewayAttachment" + name + app + env, InternetGatewayId=Ref(internetGateway), VpcId=Ref(vpc), DependsOn="VPC" + name + app + env)) publicRouteTable = template.add_resource( RouteTable( "PublicRouteTable", VpcId=Ref(vpc), Tags=Tags( Name="rt-public" + env, Env=env, ), )) internetGWRoute = template.add_resource( Route("RouteToIGW", RouteTableId=Ref(publicRouteTable), DestinationCidrBlock='0.0.0.0/0', GatewayId=Ref(internetGateway))) privateNetworkAcl = template.add_resource( NetworkAcl( "PrivateNetworkAcl", VpcId=Ref(vpc), Tags=Tags(Name="PrivateNetworkAcl" + env, ), )) zones = ["a", "b", "c"] for index, subnet in enumerate(privateSubnets): template.add_resource( Subnet("PrivateSubnet" + zones[index], CidrBlock=subnet, AvailabilityZone=Join("", [Ref("AWS::Region"), zones[index]]), MapPublicIpOnLaunch=False, Tags=Tags(Env=env, Name="Private-Subnet-" + zones[index]), VpcId=Ref(vpc), DependsOn="VPC" + name + app + env)) template.add_resource( RouteTable("PrivateRouteTable" + zones[index], VpcId=Ref(vpc), Tags=Tags( Name="rt-private" + env + "-" + zones[index], Env=env, ), DependsOn="VPC" + name + app + env)) template.add_resource(EIP("EIP" + zones[index], )) template.add_resource( NatGateway("NatGWZone" + zones[index], AllocationId=GetAtt("EIP" + zones[index], 'AllocationId'), SubnetId=Ref("PublicSubnet" + zones[index]), DependsOn="PublicSubnet" + zones[index])) template.add_resource( Route('NatRoute' + zones[index], RouteTableId=Ref("PrivateRouteTable" + zones[index]), DestinationCidrBlock='0.0.0.0/0', NatGatewayId=Ref("NatGWZone" + zones[index]), DependsOn="PrivateRouteTable" + zones[index])) template.add_resource( SubnetRouteTableAssociation( "PrivateSubnetRouteTable" + zones[index], RouteTableId=Ref("PrivateRouteTable" + zones[index]), SubnetId=Ref("PrivateSubnet" + zones[index]), DependsOn="PrivateRouteTable" + zones[index])) template.add_resource( SubnetNetworkAclAssociation("PrivateNetworkAclAss" + zones[index], SubnetId=Ref("PrivateSubnet" + zones[index]), NetworkAclId=Ref(privateNetworkAcl), DependsOn="PrivateNetworkAcl")) for index, subnet in enumerate(publicSubnets): template.add_resource( Subnet("PublicSubnet" + zones[index], CidrBlock=subnet, AvailabilityZone=Join("", [Ref("AWS::Region"), zones[index]]), MapPublicIpOnLaunch=True, Tags=Tags(Env=env, Name="Public-Subnet-" + zones[index]), VpcId=Ref(vpc), DependsOn="VPC" + name + app + env)) template.add_resource( SubnetRouteTableAssociation( "PublicSubnetRouteTable" + zones[index], RouteTableId=Ref(publicRouteTable), SubnetId=Ref("PublicSubnet" + zones[index]), DependsOn="VPC" + name + app + env)) template.add_resource( NetworkAclEntry("PrivateNetworkAclEntryIngress" + env, CidrBlock=cidrBlock, Egress=False, NetworkAclId=Ref(privateNetworkAcl), Protocol=-1, RuleAction="allow", RuleNumber=200, DependsOn="PrivateNetworkAcl")) template.add_resource( NetworkAclEntry("PrivateNetworkAclEntryEgress" + env, CidrBlock=cidrBlock, Egress=True, NetworkAclId=Ref(privateNetworkAcl), Protocol=-1, RuleAction="allow", RuleNumber=200, DependsOn="PrivateNetworkAcl")) for zone in zones: template.add_output( Output( "PublicSubnetOutput" + zone, Value=Ref("PublicSubnet" + zone), Export=Export("PublicSubnet" + env + zone), )) template.add_output( Output("PrivateSubnetOutput" + zone, Value=Ref("PrivateSubnet" + zone), Export=Export("PrivateSubnet" + env + zone))) template.add_output( Output("VPCOutput" + env, Value=Ref(vpc), Export=Export("VPC" + env))) return (template.to_json())
public_subnet = template.add_resource( Subnet( "PublicSubnet", VpcId=Ref(vpc), CidrBlock=public_subnet_cidr, )) template.add_resource( SubnetRouteTableAssociation( "PublicSubnetRouteTableAssociation", RouteTableId=Ref(public_route_table), SubnetId=Ref(public_subnet), )) nat_ip = template.add_resource(EIP( "NatIp", Domain="vpc", )) nat_gateway = template.add_resource( NatGateway( "NatGateway", AllocationId=GetAtt(nat_ip, "AllocationId"), SubnetId=Ref(public_subnet), )) loadbalancer_a_subnet = template.add_resource( Subnet( "LoadbalancerASubnet", VpcId=Ref(vpc), CidrBlock=loadbalancer_a_subnet_cidr, AvailabilityZone=Join("", [Ref(AWS_REGION), "a"]),
"NatHTTPIngress", ToPort="80", FromPort="80", IpProtocol="tcp", GroupId=Ref("NatSG"), CidrIp=Ref(privatesubnetcidr_param), )) PublicRouteTable = t.add_resource( RouteTable("PublicRouteTable", VpcId=Ref("VPC"), Tags=Tags(Name=Join("", [Ref("AWS::StackName"), "-public"]), ))) NatEIP = t.add_resource(EIP( "NatEIP", InstanceId=Ref("Nat"), Domain="vpc", )) NatSG = t.add_resource( SecurityGroup("NatSG", VpcId=Ref("VPC"), GroupDescription="Security group for NAT host.", Tags=Tags(Name=Join("", [Ref("AWS::StackName"), "-nat"]), ))) PublicAssociation = t.add_resource( SubnetRouteTableAssociation( "PublicAssociation", SubnetId=Ref("PublicSubnet"), RouteTableId=Ref(PublicRouteTable), ))
def __init__(self, parameters): super(Vpc, self).__init__() # Virtual Private Cloud self.vpc = VPC( "VPC", CidrBlock=Ref(parameters.VPCCIDR), EnableDnsHostnames=True, Tags=Tags( Name=Ref(AWS_STACK_NAME), ) ) # Public NACL self.GeneralPublicNACL = NetworkAcl( "GeneralPublicNACL", VpcId=Ref(self.vpc), Tags=Tags( Name=Join("-", [Ref(AWS_STACK_NAME), "public"]), ), ) # Private NACL self.GeneralPrivateNACL = NetworkAcl( "GeneralPrivateNACL", VpcId=Ref(self.vpc), Tags=Tags( Name=Join("-", [Ref(AWS_STACK_NAME), "private"]), ), ) # NACL Rules self.PublicNACLIngressRule100 = NetworkAclEntry( "PublicNACLIngressRule100", NetworkAclId=Ref(self.GeneralPublicNACL), RuleNumber="100", Protocol="-1", Egress=False, RuleAction="allow", CidrBlock="0.0.0.0/0", ) self.PublicNACLEgressRule100 = NetworkAclEntry( "PublicNACLEgressRule100", NetworkAclId=Ref(self.GeneralPublicNACL), RuleNumber="100", Protocol="-1", Egress=True, RuleAction="allow", CidrBlock="0.0.0.0/0", ) self.PrivateNACLEgressRule100 = NetworkAclEntry( "PrivateNACLEgressRule100", NetworkAclId=Ref(self.GeneralPrivateNACL), RuleNumber="100", Protocol="-1", Egress=True, RuleAction="allow", CidrBlock="0.0.0.0/0", ) self.PrivateNACLIngressRule100 = NetworkAclEntry( "PrivateNACLIngressRule100", NetworkAclId=Ref(self.GeneralPrivateNACL), RuleNumber="100", Protocol="-1", Egress=False, RuleAction="allow", CidrBlock=Ref(parameters.VPCCIDR), ) self.PrivateNACLIngressRule220 = NetworkAclEntry( "PrivateNACLIngressRule220", NetworkAclId=Ref(self.GeneralPrivateNACL), RuleNumber="220", Protocol="-1", Egress=False, RuleAction="allow", CidrBlock="0.0.0.0/0", ) self.PrivateNACLIngressRule400 = NetworkAclEntry( "PrivateNACLIngressRule400", NetworkAclId=Ref(self.GeneralPrivateNACL), RuleNumber="400", Protocol="6", PortRange=PortRange(To="65535", From="1024"), Egress=False, RuleAction="allow", CidrBlock="0.0.0.0/0", ) self.PrivateNACLIngressRule420 = NetworkAclEntry( "PrivateNACLIngressRule420", NetworkAclId=Ref(self.GeneralPrivateNACL), RuleNumber="420", Protocol="1", Egress=False, RuleAction="allow", Icmp=ICMP( Code="-1", Type="-1" ), CidrBlock="0.0.0.0/0", ) self.PrivateNACLIngressRule440 = NetworkAclEntry( "PrivateNACLIngressRule440", NetworkAclId=Ref(self.GeneralPrivateNACL), RuleNumber="440", Protocol="17", PortRange=PortRange(To="65535", From="1024"), Egress=False, RuleAction="allow", CidrBlock="0.0.0.0/0", ) # Shared services self.GeneralPrivateSubnetA = Subnet( "GeneralPrivateSubnetA", Tags=Tags( Name=Join("-", [Ref(AWS_STACK_NAME), "general-private-a"]), ), VpcId=Ref(self.vpc), MapPublicIpOnLaunch=False, CidrBlock=Ref(parameters.GeneralPrivateSubnetACIDR), AvailabilityZone=Ref(parameters.AvailabilityZoneA), ) self.GeneralPrivateSubnetB = Subnet( "GeneralPrivateSubnetB", Tags=Tags( Name=Join("-", [Ref(AWS_STACK_NAME), "general-private-b"]), ), VpcId=Ref(self.vpc), MapPublicIpOnLaunch=False, CidrBlock=Ref(parameters.GeneralPrivateSubnetBCIDR), AvailabilityZone=Ref(parameters.AvailabilityZoneB), ) self.SharedServicesPublicSubnetA = Subnet( "SharedServicesPublicSubnetA", VpcId=Ref(self.vpc), AvailabilityZone=Ref(parameters.AvailabilityZoneA), CidrBlock=Ref(parameters.SharedServicesPublicSubnetACIDR), MapPublicIpOnLaunch=False, Tags=Tags( Name=Join("-", [Ref(AWS_STACK_NAME), "shared-public-a"]), ) ) self.SharedServicesPublicSubnetB = Subnet( "SharedServicesPublicSubnetB", VpcId=Ref(self.vpc), AvailabilityZone=Ref(parameters.AvailabilityZoneB), CidrBlock=Ref(parameters.SharedServicesPublicSubnetBCIDR), MapPublicIpOnLaunch=False, Tags=Tags( Name=Join("-", [Ref(AWS_STACK_NAME), "shared-public-b"]), ) ) self.SharedServicesPrivateSubnetA = Subnet( "SharedServicesPrivateSubnetA", VpcId=Ref(self.vpc), AvailabilityZone=Ref(parameters.AvailabilityZoneA), CidrBlock=Ref(parameters.SharedServicesPrivateSubnetACIDR), MapPublicIpOnLaunch=False, Tags=Tags( Name=Join("-", [Ref(AWS_STACK_NAME), "shared-private-a"]), ) ) self.SharedServicesPrivateSubnetB = Subnet( "SharedServicesPrivateSubnetB", VpcId=Ref(self.vpc), AvailabilityZone=Ref(parameters.AvailabilityZoneB), CidrBlock=Ref(parameters.SharedServicesPrivateSubnetBCIDR), MapPublicIpOnLaunch=False, Tags=Tags( Name=Join("-", [Ref(AWS_STACK_NAME), "shared-private-b"]), ) ) self.SharedServicesPublicNACLSubnetAAssocation = SubnetNetworkAclAssociation( "SharedServicesPublicNACLSubnetAAssocation", SubnetId=Ref(self.SharedServicesPublicSubnetA), NetworkAclId=Ref(self.GeneralPublicNACL), ) self.SharedServicesPublicNACLSubnetBAssocation = SubnetNetworkAclAssociation( "SharedServicesPublicNACLSubnetBAssocation", SubnetId=Ref(self.SharedServicesPublicSubnetB), NetworkAclId=Ref(self.GeneralPublicNACL), ) self.SharedServicesPrivateNACLSubnetAAssocation = SubnetNetworkAclAssociation( "SharedServicesPrivateNACLSubnetAAssocation", SubnetId=Ref(self.SharedServicesPrivateSubnetA), NetworkAclId=Ref(self.GeneralPrivateNACL), ) self.SharedServicesPrivateNACLSubnetBAssocation = SubnetNetworkAclAssociation( "SharedServicesPrivateNACLSubnetBAssocation", SubnetId=Ref(self.SharedServicesPrivateSubnetB), NetworkAclId=Ref(self.GeneralPrivateNACL), ) self.GeneralPrivateNACLSubnetAAssocation = SubnetNetworkAclAssociation( "GeneralPrivateNACLSubnetAAssocation", SubnetId=Ref(self.GeneralPrivateSubnetA), NetworkAclId=Ref(self.GeneralPrivateNACL), ) self.GeneralPrivateNACLSubnetBAssocation = SubnetNetworkAclAssociation( "GeneralPrivateNACLSubnetBAssocation", SubnetId=Ref(self.GeneralPrivateSubnetB), NetworkAclId=Ref(self.GeneralPrivateNACL), ) # Route tables self.PublicRouteTable = RouteTable( "PublicRouteTable", VpcId=Ref(self.vpc), Tags=Tags( Name=Join("-", [Ref(AWS_STACK_NAME), "public"]), ), ) self.PrivateARouteTable = RouteTable( "PrivateARouteTable", VpcId=Ref(self.vpc), Tags=Tags( Name=Join("-", [Ref(AWS_STACK_NAME), "private-a"]), ), ) self.PrivateBRouteTable = RouteTable( "PrivateBRouteTable", VpcId=Ref(self.vpc), Tags=Tags( Name=Join("-", [Ref(AWS_STACK_NAME), "private-b"]), ), ) # Internet Gateway self.InternetGateway = InternetGateway( "InternetGateway", Tags=Tags( Name=Join("-", [Ref(AWS_STACK_NAME)]), ), ) self.VPNAttachment = VPCGatewayAttachment( "VPNAttachment", VpcId=Ref(self.vpc), InternetGatewayId=Ref(self.InternetGateway) ) # NAT Gateways self.NATGatewayAEIP = EIP( "NATGatewayAEIP", Domain=Ref(self.vpc), Condition="DeployNATGateways" ) self.NATGatewayBEIP = EIP( "NATGatewayBEIP", Domain=Ref(self.vpc), Condition="DeployNATGateways" ) self.NATGatewayA = NatGateway( "NATGatewayA", SubnetId=Ref(self.SharedServicesPublicSubnetA), AllocationId=GetAtt(self.NATGatewayAEIP, "AllocationId"), Condition="DeployNATGateways" ) self.NATGatewayB = NatGateway( "NATGatewayB", SubnetId=Ref(self.SharedServicesPublicSubnetB), AllocationId=GetAtt(self.NATGatewayBEIP, "AllocationId"), Condition="DeployNATGateways" ) # S3 VPC enpoint connection self.VPCS3Endpoint = VPCEndpoint( "VPCS3Endpoint", VpcId=Ref(self.vpc), ServiceName=Join("", ["com.amazonaws.", Ref(AWS_REGION), ".s3"]), RouteTableIds=[Ref(self.PublicRouteTable), Ref(self.PrivateARouteTable), Ref(self.PrivateBRouteTable)], ) # Security Groups self.ICMPSecurityGroup = SecurityGroup( "ICMPSecurityGroup", SecurityGroupIngress=[{ "ToPort": "-1", "IpProtocol": "icmp", "CidrIp": "0.0.0.0/0", "FromPort": "-1" }], VpcId=Ref(self.vpc), GroupDescription="Allows servers to be reached by ICMP", Tags=Tags( Name=Join("-", [Ref(AWS_STACK_NAME), "icmp"]), ), ) self.OpenPublicSSHSecurityGroup = SecurityGroup( "OpenPublicSSHSecurityGroup", SecurityGroupIngress=[{ "ToPort": "22", "IpProtocol": "tcp", "CidrIp": "0.0.0.0/0", "FromPort": "22" }], VpcId=Ref(self.vpc), GroupDescription="Allows instance to be publically managed over SSH from anywhere, probably a bad idea", Tags=Tags( Name=Join("-", [Ref(AWS_STACK_NAME), "open-public-ssh"]), ), ) # Route Tables self.GeneralPrivateSubnetARouteTable = SubnetRouteTableAssociation( "GeneralPrivateSubnetARouteTable", SubnetId=Ref(self.GeneralPrivateSubnetA), RouteTableId=Ref(self.PrivateARouteTable), ) self.GeneralPrivateSubnetBRouteTable = SubnetRouteTableAssociation( "GeneralPrivateSubnetBRouteTable", SubnetId=Ref(self.GeneralPrivateSubnetB), RouteTableId=Ref(self.PrivateBRouteTable), ) self.SharedServicesPublicSubnetARouteTable = SubnetRouteTableAssociation( "SharedServicesPublicSubnetARouteTable", SubnetId=Ref(self.SharedServicesPublicSubnetA), RouteTableId=Ref(self.PublicRouteTable), ) self.SharedServicesPublicSubnetBRouteTable = SubnetRouteTableAssociation( "SharedServicesPublicSubnetBRouteTable", SubnetId=Ref(self.SharedServicesPublicSubnetB), RouteTableId=Ref(self.PublicRouteTable), ) self.SharedServicesPrivateSubnetARouteTable = SubnetRouteTableAssociation( "SharedServicesPrivateSubnetARouteTable", SubnetId=Ref(self.SharedServicesPrivateSubnetA), RouteTableId=Ref(self.PrivateARouteTable), ) self.SharedServicesPrivateSubnetBRouteTable = SubnetRouteTableAssociation( "SharedServicesPrivateSubnetBRouteTable", SubnetId=Ref(self.SharedServicesPrivateSubnetB), RouteTableId=Ref(self.PrivateBRouteTable), ) # Routes self.PublicSharedRoute = Route( "PublicSharedRoute", DestinationCidrBlock="0.0.0.0/0", GatewayId=Ref(self.InternetGateway), RouteTableId=Ref(self.PublicRouteTable), ) self.PrivateANATRoute = Route( "PrivateANATRoute", DestinationCidrBlock="0.0.0.0/0", RouteTableId=Ref(self.PrivateARouteTable), NatGatewayId=Ref(self.NATGatewayB), #DependsOn=self.NATGatewayA, Condition="DeployNATGateways" ) self.PrivateBNATRoute = Route( "PrivateBNATRoute", DestinationCidrBlock="0.0.0.0/0", RouteTableId=Ref(self.PrivateBRouteTable), NatGatewayId=Ref(self.NATGatewayB), #DependsOn=self.NATGatewayB, Condition="DeployNATGateways" ) # Internal Zone standard self.InternalZone = HostedZone( "InternalZone", VPCs=[ HostedZoneVPCs( VPCId=Ref(self.vpc), VPCRegion=Ref("AWS::Region"), )], HostedZoneConfig=HostedZoneConfiguration( Comment="Internal (private) zone for name resolution" ), HostedZoneTags=Tags( Name=Join("-", [Ref(AWS_STACK_NAME), "internal"]), ), Name=Ref(parameters.DomainName), ) # Internal Zone production website self.InternalZoneProductionWebsite = HostedZone( "InternalZoneProductionWebsite", VPCs=[ HostedZoneVPCs( VPCId=Ref(self.vpc), VPCRegion=Ref("AWS::Region"), )], HostedZoneConfig=HostedZoneConfiguration( Comment="Internal (private) zone for name resolution for public website" ), HostedZoneTags=Tags( Name=Join("-", [Ref(AWS_STACK_NAME), "internal-public-site"]), ), Name="sharpe.capital", Condition="CreateProductionZone" ) # Custom Security Groups self.OpenPublicSSHSecurityGroup = SecurityGroup( "OpenPublicSSHSecurityGroup", GroupDescription="Allows server to be publically managed over SSH from anywhere", SecurityGroupIngress=[ SecurityGroupRule( IpProtocol="tcp", FromPort="22", ToPort="22", CidrIp="0.0.0.0/0" ), ], VpcId=Ref(self.vpc), Tags=Tags( Name=Join("-", [Ref(AWS_STACK_NAME), "open-public-ssh-access"]), ), ) # Public Load Balancer NACL self.PublicLBNACL = NetworkAcl( "PublicLBNACL", VpcId=Ref(self.vpc), Tags=Tags( Name=Ref(AWS_STACK_NAME), ), ) self.PublicLBRouteTable = RouteTable( "PublicLBRouteTable", VpcId=Ref(self.vpc), Tags=Tags( Name=Ref(AWS_STACK_NAME), ), ) self.LBPublicSubnetA = Subnet( "LBPublicSubnetA", VpcId=Ref(self.vpc), AvailabilityZone=Ref(parameters.AvailabilityZoneA), CidrBlock=Ref(parameters.LBSubnetACIDR), Tags=Tags( Name=Join("-", [Ref(AWS_STACK_NAME), "lb-public-a"]), ), ) self.LBPublicSubnetB = Subnet( "LBPublicSubnetB", VpcId=Ref(self.vpc), AvailabilityZone=Ref(parameters.AvailabilityZoneB), CidrBlock=Ref(parameters.LBSubnetBCIDR), Tags=Tags( Name=Join("-", [Ref(AWS_STACK_NAME), "lb-public-b"]), ), ) self.LBNACLIn100 = NetworkAclEntry( "LBNACLIn100", NetworkAclId=Ref(self.PublicLBNACL), RuleNumber=100, Protocol=6, PortRange=PortRange(To=443, From=443), Egress=False, RuleAction="allow", CidrBlock="0.0.0.0/0", ) self.LBNACLIn200 = NetworkAclEntry( "LBNACLIn200", NetworkAclId=Ref(self.PublicLBNACL), RuleNumber=200, Protocol=6, PortRange=PortRange(To=80, From=80), Egress=False, RuleAction="allow", CidrBlock="0.0.0.0/0", ) self.LBNACLIn300 = NetworkAclEntry( "LBNACLIn300", NetworkAclId=Ref(self.PublicLBNACL), RuleNumber=300, Protocol=6, PortRange=PortRange(To=65535, From=1024), Egress=False, RuleAction="allow", CidrBlock="0.0.0.0/0", ) self.LBNACLOut100 = NetworkAclEntry( "LBNACLOut100", NetworkAclId=Ref(self.PublicLBNACL), RuleNumber=100, Protocol=6, PortRange=PortRange(To=65535, From=1024), Egress=True, RuleAction="allow", CidrBlock="0.0.0.0/0", ) self.LBRouteTableAssociationA = SubnetRouteTableAssociation( "LBRouteTableAssociationA", SubnetId=Ref(self.LBPublicSubnetA), RouteTableId=Ref(self.PublicLBRouteTable), ) self.LBRouteTableAssociationB = SubnetRouteTableAssociation( "LBRouteTableAssociationB", SubnetId=Ref(self.LBPublicSubnetB), RouteTableId=Ref(self.PublicLBRouteTable), ) self.LBNACLAssociationB = SubnetNetworkAclAssociation( "LBNACLAssociationB", SubnetId=Ref(self.LBPublicSubnetB), NetworkAclId=Ref(self.PublicLBNACL), ) self.LBNACLAssociationA = SubnetNetworkAclAssociation( "LBNACLAssociationA", SubnetId=Ref(self.LBPublicSubnetA), NetworkAclId=Ref(self.PublicLBNACL), ) self.LBInternetGatewayRoute = Route( "LBInternetGatewayRoute", GatewayId=Ref(self.InternetGateway), DestinationCidrBlock="0.0.0.0/0", RouteTableId=Ref(self.PublicLBRouteTable), ) self.LBICMPSecurityGroup = SecurityGroup( "LBICMPSecurityGroup", SecurityGroupIngress=[{ "ToPort": "-1", "IpProtocol": "icmp", "CidrIp": "0.0.0.0/0", "FromPort": "-1" }], VpcId=Ref(self.vpc), GroupDescription="Allows servers to be reached by ICMP", Tags=Tags( Name=Join("-", [Ref(AWS_STACK_NAME), "icmp"]), ), ) self.LBSecurityGroup = SecurityGroup( "LBSecurityGroup", SecurityGroupIngress=[{ "ToPort": 80, "FromPort": 80, "IpProtocol": "tcp", "CidrIp": "0.0.0.0/0" }, { "ToPort": 443, "FromPort": 443, "IpProtocol": "tcp", "CidrIp": "0.0.0.0/0" }], VpcId=Ref(self.vpc), GroupDescription="Securty group for public facing web load balancers", Tags=Tags( Name=Ref(AWS_STACK_NAME), ), )
def __init__(self, keypair, availability_zones, vpc_cidr, home_cidrs, public_cidr, jump_image_id, jump_instance_type, nat_image_id, nat_instance_type, public_hosted_zone_name, private_hosted_zone_name, iam_instance_profile_arn, owner_emails, nat_highly_available, ec2_scheduled_shutdown): """ Create a vpc, nat, jumphost, internet gateway, public/private route tables, public/private subnets and collection of Amazonia units AWS CloudFormation - http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html Troposphere - https://github.com/cloudtools/troposphere/blob/master/troposphere/ec2.py :param keypair: ssh keypair to be used throughout stack :param availability_zones: availability zones to use :param vpc_cidr: cidr pattern for vpc :param home_cidrs: a list of tuple objects of 'title'(0) and 'ip'(1) to be used to create ingress rules for ssh to jumpboxes from home/office/company premises :param public_cidr: a cidr to be treated as a public location. (eg 0.0.0.0/0) :param jump_image_id: AMI for jumphost :param jump_instance_type: instance type for jumphost :param nat_image_id: AMI for nat :param nat_instance_type: instance type for nat :param public_hosted_zone_name: A string containing the name of the Route 53 hosted zone to create public record sets in. :param private_hosted_zone_name: name of private hosted zone to create :param iam_instance_profile_arn: the ARN for an IAM instance profile that enables cloudtrail access for logging :param owner_emails: a list of emails for owners of this stack. Used for alerting. :param nat_highly_available: True/False for whether or not to use a series of NAT gateways or a single NAT :param ec2_scheduled_shutdown: True/False for whether to schedule shutdown for EC2 instances outside work hours """ super(Network, self).__init__() # set parameters self.keypair = keypair self.availability_zones = availability_zones self.vpc_cidr = vpc_cidr self.home_cidrs = home_cidrs self.public_cidr = public_cidr self.public_hosted_zone_name = public_hosted_zone_name self.private_hosted_zone_name = private_hosted_zone_name self.jump_image_id = jump_image_id self.jump_instance_type = jump_instance_type self.nat_image_id = nat_image_id self.nat_instance_type = nat_instance_type self.owner_emails = owner_emails if owner_emails else [] self.nat_highly_available = nat_highly_available self.iam_instance_profile_arn = iam_instance_profile_arn self.ec2_scheduled_shutdown = ec2_scheduled_shutdown # initialize object references self.template = Template() self.private_subnets = [] self.public_subnets = [] self.public_subnet_mapping = {} self.vpc = None self.private_hosted_zone = None self.internet_gateway = None self.gateway_attachment = None self.public_route_table = None self.private_route_tables = {} self.nat = None self.nat_gateways = [] self.jump = None self.private_route = None self.public_route = None self.sns_topic = None # Add VPC and Internet Gateway with Attachment vpc_name = 'Vpc' self.vpc = Ref( self.template.add_resource( ec2.VPC(vpc_name, CidrBlock=self.vpc_cidr['cidr'], EnableDnsSupport='true', EnableDnsHostnames='true', Tags=Tags(Name=Join( '', [Ref('AWS::StackName'), '-', vpc_name]))))) self.private_hosted_zone = HostedZone(self.template, self.private_hosted_zone_name, vpcs=[self.vpc]) ig_name = 'Ig' self.internet_gateway = self.template.add_resource( ec2.InternetGateway( ig_name, Tags=Tags( Name=Join('', [Ref('AWS::StackName'), '-', ig_name])), DependsOn=vpc_name)) self.gateway_attachment = self.template.add_resource( ec2.VPCGatewayAttachment(self.internet_gateway.title + 'Atch', VpcId=self.vpc, InternetGatewayId=Ref( self.internet_gateway), DependsOn=self.internet_gateway.title)) # Add Public Route Table public_rt_name = 'PubRouteTable' self.public_route_table = self.template.add_resource( ec2.RouteTable( public_rt_name, VpcId=self.vpc, Tags=Tags(Name=Join( '', [Ref('AWS::StackName'), '-', public_rt_name])))) # Add Public and Private Subnets and Private Route Table for az in self.availability_zones: private_rt_name = get_cf_friendly_name(az) + 'PriRouteTable' private_route_table = self.template.add_resource( ec2.RouteTable( private_rt_name, VpcId=self.vpc, Tags=Tags(Name=Join( '', [Ref('AWS::StackName'), '-', private_rt_name])))) self.private_route_tables[az] = private_route_table self.private_subnets.append( Subnet(template=self.template, route_table=private_route_table, az=az, vpc=self.vpc, is_public=False, cidr=self.generate_subnet_cidr( is_public=False)).trop_subnet) public_subnet = Subnet( template=self.template, route_table=self.public_route_table, az=az, vpc=self.vpc, is_public=True, cidr=self.generate_subnet_cidr(is_public=True)).trop_subnet self.public_subnets.append(public_subnet) self.public_subnet_mapping[az] = Ref(public_subnet) self.sns_topic = SNS(self.template) for email in self.owner_emails: self.sns_topic.add_subscription(email, 'email') jump_config = SingleInstanceConfig( keypair=self.keypair, si_image_id=self.jump_image_id, si_instance_type=self.jump_instance_type, subnet=self.public_subnet_mapping[availability_zones[0]], vpc=self.vpc, public_hosted_zone_name=self.public_hosted_zone_name, instance_dependencies=self.gateway_attachment.title, iam_instance_profile_arn=self.iam_instance_profile_arn, is_nat=False, sns_topic=self.sns_topic, availability_zone=availability_zones[0], ec2_scheduled_shutdown=self.ec2_scheduled_shutdown) # Add Jumpbox and NAT and associated security group ingress and egress rules self.jump = SingleInstance(title='Jump', template=self.template, single_instance_config=jump_config) [ self.jump.add_ingress(sender=home_cidr, port='22') for home_cidr in self.home_cidrs ] self.jump.add_egress(receiver=self.public_cidr, port='-1') if self.nat_highly_available: for public_subnet in self.public_subnets: az = public_subnet.AvailabilityZone ip_address = self.template.add_resource( EIP(get_cf_friendly_name(az) + 'NatGwEip', DependsOn=self.gateway_attachment.title, Domain='vpc')) nat_gateway = self.template.add_resource( NatGateway(get_cf_friendly_name(az) + 'NatGw', AllocationId=GetAtt(ip_address, 'AllocationId'), SubnetId=Ref(public_subnet), DependsOn=self.gateway_attachment.title)) self.nat_gateways.append(nat_gateway) self.template.add_resource( ec2.Route(get_cf_friendly_name(az) + 'PriRoute', NatGatewayId=Ref(nat_gateway), RouteTableId=Ref(self.private_route_tables[az]), DestinationCidrBlock=self.public_cidr['cidr'], DependsOn=self.gateway_attachment.title)) else: nat_config = SingleInstanceConfig( keypair=self.keypair, si_image_id=self.nat_image_id, si_instance_type=self.nat_instance_type, subnet=self.public_subnet_mapping[availability_zones[0]], vpc=self.vpc, is_nat=True, instance_dependencies=self.gateway_attachment.title, iam_instance_profile_arn=self.iam_instance_profile_arn, public_hosted_zone_name=None, sns_topic=self.sns_topic, availability_zone=availability_zones[0], ec2_scheduled_shutdown=self.ec2_scheduled_shutdown) self.nat = SingleInstance(title='Nat', template=self.template, single_instance_config=nat_config) self.nat.add_egress(receiver=self.public_cidr, port='-1') self.nat.add_ingress(sender=self.vpc_cidr, port='-1') for az in self.availability_zones: self.template.add_resource( ec2.Route(get_cf_friendly_name(az) + 'PriRoute', InstanceId=Ref(self.nat.single), RouteTableId=Ref(self.private_route_tables[az]), DestinationCidrBlock=self.public_cidr['cidr'], DependsOn=self.gateway_attachment.title)) # Add Public Route self.public_route = self.template.add_resource( ec2.Route('PubRoute', GatewayId=Ref(self.internet_gateway), RouteTableId=Ref(self.public_route_table), DestinationCidrBlock=self.public_cidr['cidr'], DependsOn=self.gateway_attachment.title))