def create_hosted_zone(self, domain, vpcs): """ Creates a route53 hosted zone object either public (vpcs=None) or private (vpcs=[vpc1,...]) AWS: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53-hostedzone.html Troposphere: https://github.com/cloudtools/troposphere/blob/master/troposphere/route53.py :param domain: The domain you would like for your hosted zone. MUST be 'something.something' (eg 'example.com') :param vpcs: A list of VPCs to associate this hosted zone with (if none, a public hosted zone is created) """ hz_type = 'private' if vpcs else 'public' hz_config = route53.HostedZoneConfiguration( Comment=Join('', [ hz_type, ' hosted zone created by Amazonia for stack: ', Ref('AWS::StackName') ])) hz = self.template.add_resource( route53.HostedZone(hz_type + 'HostedZone', HostedZoneConfig=hz_config, Name=domain)) if vpcs: hz.VPCs = [] for vpc in vpcs: hz.VPCs.append( HostedZoneVPCs(VPCId=vpc, VPCRegion=Ref('AWS::Region'))) return hz
def create_private_dns(template, hosted_zone_name, vpc_id, region): hosted_zone = template.add_resource(HostedZone( "HostedZone", Name=hosted_zone_name, VPCs=[HostedZoneVPCs(VPCId=vpc_id, VPCRegion=region)] )) template.add_output(Output( "HostedZone", Description="Hosted zone for internal access", Value=hosted_zone_name )) return hosted_zone
def create_internal_zone(self): t = self.template t.add_resource( HostedZone("InternalZone", Name=Ref("InternalDomain"), VPCs=[ HostedZoneVPCs(VPCId=VPC_ID, VPCRegion=Ref("AWS::Region")) ], Condition="HasInternalDomain")) t.add_output( Output("InternalZoneId", Value=Ref("InternalZone"), Condition="HasInternalDomain")) t.add_output( Output("InternalZoneName", Value=Ref("InternalDomain"), Condition="HasInternalDomain"))
def create_internal_zone(self): t = self.template variables = self.get_variables() if variables["InternalDomain"]: t.add_resource( HostedZone("InternalZone", Name=variables["InternalDomain"], VPCs=[ HostedZoneVPCs(VPCId=VPC_ID, VPCRegion=Ref("AWS::Region")) ])) t.add_output(Output( "InternalZoneId", Value=Ref("InternalZone"), )) t.add_output( Output( "InternalZoneName", Value=variables["InternalDomain"], ))
def create_hosted_zone(): hosted_zone_template = Template() hosted_zone_template.set_version("2010-09-09") hosted_zone_template.set_description( "Hosted zone stack created for testing existing DNS") hosted_zone_template.add_resource( HostedZone( "HostedZoneResource", Name=domain_name, VPCs=[ HostedZoneVPCs(VPCId=vpc_stack.cfn_outputs["VpcId"], VPCRegion=region) ], )) hosted_zone_stack = CfnStack( name=hosted_zone_stack_name, region=region, template=hosted_zone_template.to_json(), ) cfn_stacks_factory.create_stack(hosted_zone_stack) return hosted_zone_stack.cfn_resources[ "HostedZoneResource"], domain_name
from troposphere import Template from troposphere.route53 import HostedZone, HostedZoneVPCs domain = "weblox.io" region = "eu-west-1" template = Template(domain.replace(".", "") + "dns") public_dns = HostedZone(domain.replace(".", "") + "publicdns", Name="public." + region + "." + domain) private_dns = HostedZone(domain.replace(".", "") + "privatedns", Name="private." + region + "." + domain, VPCs=[ HostedZoneVPCs(VPCId="vpc-0e2786487ff4f2ef4", VPCRegion="eu-west-1") ]) template.add_resource(public_dns) template.add_resource(private_dns) print(template.to_yaml())
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 generate_vpc_template(layers, az_count, cidr_block): TPL = Template() TPL.set_description('VPC - Version 2019-06-05') TPL.set_metadata({'Author': 'https://github.com/johnpreston'}) VPC = VPCType('VPC', CidrBlock=cidr_block, EnableDnsHostnames=True, EnableDnsSupport=True, Tags=Tags(Name=Ref('AWS::StackName'), EnvironmentName=Ref('AWS::StackName'))) IGW = InternetGateway("InternetGateway") IGW_ATTACH = VPCGatewayAttachment("VPCGatewayAttachement", InternetGatewayId=Ref(IGW), VpcId=Ref(VPC)) DHCP_OPTIONS = DHCPOptions('VpcDhcpOptions', DomainName=Sub(f'${{AWS::StackName}}.local'), DomainNameServers=['AmazonProvidedDNS'], Tags=Tags(Name=Sub(f'DHCP-${{{VPC.title}}}'))) DHCP_ATTACH = VPCDHCPOptionsAssociation('VpcDhcpOptionsAssociate', DhcpOptionsId=Ref(DHCP_OPTIONS), VpcId=Ref(VPC)) DNS_HOSTED_ZONE = HostedZone( 'VpcHostedZone', VPCs=[HostedZoneVPCs(VPCId=Ref(VPC), VPCRegion=Ref('AWS::Region'))], Name=Sub(f'${{AWS::StackName}}.local'), HostedZoneTags=Tags(Name=Sub(f'ZoneFor-${{{VPC.title}}}'))) TPL.add_resource(VPC) TPL.add_resource(IGW) TPL.add_resource(IGW_ATTACH) TPL.add_resource(DHCP_OPTIONS) TPL.add_resource(DHCP_ATTACH) TPL.add_resource(DNS_HOSTED_ZONE) STORAGE_RTB = TPL.add_resource( RouteTable('StorageRtb', VpcId=Ref(VPC), Tags=Tags(Name='StorageRtb'))) STORAGE_SUBNETS = [] for count, subnet_cidr in zip(az_count, layers['stor']): subnet = Subnet( f'StorageSubnet{alpha[count].upper()}', CidrBlock=subnet_cidr, VpcId=Ref(VPC), AvailabilityZone=Sub(f'${{AWS::Region}}{alpha[count]}'), Tags=Tags(Name=Sub(f'${{AWS::StackName}}-Storage-{alpha[count]}'), Usage="Storage")) subnet_assoc = TPL.add_resource( SubnetRouteTableAssociation( f'StorageSubnetAssoc{alpha[count].upper()}', SubnetId=Ref(subnet), RouteTableId=Ref(STORAGE_RTB))) STORAGE_SUBNETS.append(subnet) TPL.add_resource(subnet) PUBLIC_RTB = TPL.add_resource( RouteTable('PublicRtb', VpcId=Ref(VPC), Tags=Tags(Name='PublicRtb'))) PUBLIC_ROUTE = TPL.add_resource( Route('PublicDefaultRoute', GatewayId=Ref(IGW), RouteTableId=Ref(PUBLIC_RTB), DestinationCidrBlock='0.0.0.0/0')) PUBLIC_SUBNETS = [] NAT_GATEWAYS = [] for count, subnet_cidr in zip(az_count, layers['pub']): subnet = Subnet( f'PublicSubnet{alpha[count].upper()}', CidrBlock=subnet_cidr, VpcId=Ref(VPC), AvailabilityZone=Sub(f'${{AWS::Region}}{alpha[count]}'), MapPublicIpOnLaunch=True, Tags=Tags(Name=Sub(f'${{AWS::StackName}}-Public-{alpha[count]}'))) eip = TPL.add_resource( EIP(f"NatGatewayEip{alpha[count].upper()}", Domain='vpc')) nat = NatGateway(f"NatGatewayAz{alpha[count].upper()}", AllocationId=GetAtt(eip, 'AllocationId'), SubnetId=Ref(subnet)) subnet_assoc = TPL.add_resource( SubnetRouteTableAssociation( f'PublicSubnetsRtbAssoc{alpha[count].upper()}', RouteTableId=Ref(PUBLIC_RTB), SubnetId=Ref(subnet))) NAT_GATEWAYS.append(nat) PUBLIC_SUBNETS.append(subnet) TPL.add_resource(nat) TPL.add_resource(subnet) APP_SUBNETS = [] APP_RTBS = [] for count, subnet_cidr, nat in zip(az_count, layers['app'], NAT_GATEWAYS): SUFFIX = alpha[count].upper() subnet = Subnet( f'AppSubnet{SUFFIX}', CidrBlock=subnet_cidr, VpcId=Ref(VPC), AvailabilityZone=Sub(f'${{AWS::Region}}{alpha[count]}'), Tags=Tags(Name=Sub(f'${{AWS::StackName}}-App-{alpha[count]}'))) APP_SUBNETS.append(subnet) rtb = RouteTable(f'AppRtb{alpha[count].upper()}', VpcId=Ref(VPC), Tags=Tags(Name=f'AppRtb{alpha[count].upper()}')) APP_RTBS.append(rtb) route = Route(f'AppRoute{alpha[count].upper()}', NatGatewayId=Ref(nat), RouteTableId=Ref(rtb), DestinationCidrBlock='0.0.0.0/0') subnet_assoc = SubnetRouteTableAssociation( f'SubnetRtbAssoc{alpha[count].upper()}', RouteTableId=Ref(rtb), SubnetId=Ref(subnet)) TPL.add_resource(subnet) TPL.add_resource(rtb) TPL.add_resource(route) TPL.add_resource(subnet_assoc) APP_S3_ENDPOINT = VPCEndpoint( 'AppS3Endpoint', VpcId=Ref(VPC), RouteTableIds=[Ref(rtb) for rtb in APP_RTBS], ServiceName=Sub('com.amazonaws.${AWS::Region}.s3'), VpcEndpointType='Gateway', ) PUBLIC_S3_ENDPOINT = VPCEndpoint( 'PublicS3Endpoint', VpcId=Ref(VPC), RouteTableIds=[Ref(PUBLIC_RTB)], ServiceName=Sub('com.amazonaws.${AWS::Region}.s3'), VpcEndpointType='Gateway', ) STORAGE_S3_ENDPOINT = VPCEndpoint( 'StorageS3Endpoint', VpcId=Ref(VPC), RouteTableIds=[Ref(STORAGE_RTB)], ServiceName=Sub('com.amazonaws.${AWS::Region}.s3'), VpcEndpointType='Gateway') RESOURCES = [] for count in az_count: resource = TPL.add_resource(EIP(f'Eip{count}', Domain='vpc')) RESOURCES.append(resource) TPL.add_resource(APP_S3_ENDPOINT) TPL.add_resource(PUBLIC_S3_ENDPOINT) TPL.add_resource(STORAGE_S3_ENDPOINT) SG_RULES = [] for subnet in layers['app']: RULE = SecurityGroupRule( IpProtocol="tcp", FromPort="443", ToPort="443", CidrIp=subnet, ) SG_RULES.append(RULE) ENDPOINT_SG = TPL.add_resource( SecurityGroup( 'VpcEndpointSecurityGroup', VpcId=Ref(VPC), GroupDescription='SG for all Interface VPC Endpoints', SecurityGroupIngress=SG_RULES, Tags=Tags(Name="sg-endpoints"), )) APP_SNS_ENDPOINT = VPCEndpoint( 'AppSNSEndpoint', VpcId=Ref(VPC), SubnetIds=[Ref(subnet) for subnet in APP_SUBNETS], SecurityGroupIds=[GetAtt(ENDPOINT_SG, 'GroupId')], ServiceName=Sub('com.amazonaws.${AWS::Region}.sns'), VpcEndpointType='Interface', PrivateDnsEnabled=True) TPL.add_resource(APP_SNS_ENDPOINT) APP_SQS_ENDPOINT = VPCEndpoint( 'AppSQSEndpoint', VpcId=Ref(VPC), SubnetIds=[Ref(subnet) for subnet in APP_SUBNETS], SecurityGroupIds=[GetAtt(ENDPOINT_SG, 'GroupId')], ServiceName=Sub('com.amazonaws.${AWS::Region}.sqs'), VpcEndpointType='Interface', PrivateDnsEnabled=True) TPL.add_resource(APP_SQS_ENDPOINT) APP_ECR_API_ENDPOINT = VPCEndpoint( 'AppECRAPIEndpoint', VpcId=Ref(VPC), SubnetIds=[Ref(subnet) for subnet in APP_SUBNETS], SecurityGroupIds=[GetAtt(ENDPOINT_SG, 'GroupId')], ServiceName=Sub('com.amazonaws.${AWS::Region}.ecr.api'), VpcEndpointType='Interface', PrivateDnsEnabled=True) TPL.add_resource(APP_ECR_API_ENDPOINT) APP_ECR_DKR_ENDPOINT = VPCEndpoint( 'AppECRDKREndpoint', VpcId=Ref(VPC), SubnetIds=[Ref(subnet) for subnet in APP_SUBNETS], SecurityGroupIds=[GetAtt(ENDPOINT_SG, 'GroupId')], ServiceName=Sub('com.amazonaws.${AWS::Region}.ecr.dkr'), VpcEndpointType='Interface', PrivateDnsEnabled=True) TPL.add_resource(APP_ECR_DKR_ENDPOINT) APP_SECRETS_MANAGER_ENDPOINT = VPCEndpoint( 'AppSecretsManagerEndpoint', VpcId=Ref(VPC), SubnetIds=[Ref(subnet) for subnet in APP_SUBNETS], SecurityGroupIds=[GetAtt(ENDPOINT_SG, 'GroupId')], ServiceName=Sub('com.amazonaws.${AWS::Region}.secretsmanager'), VpcEndpointType='Interface', PrivateDnsEnabled=True) TPL.add_resource(APP_SECRETS_MANAGER_ENDPOINT) APP_SSM_ENDPOINT = VPCEndpoint( 'AppSSMEndpoint', VpcId=Ref(VPC), SubnetIds=[Ref(subnet) for subnet in APP_SUBNETS], SecurityGroupIds=[GetAtt(ENDPOINT_SG, 'GroupId')], ServiceName=Sub('com.amazonaws.${AWS::Region}.ssm'), VpcEndpointType='Interface', PrivateDnsEnabled=True) TPL.add_resource(APP_SSM_ENDPOINT) APP_SSM_MESSAGES_ENDPOINT = VPCEndpoint( 'AppSSMMessagesEndpoint', VpcId=Ref(VPC), SubnetIds=[Ref(subnet) for subnet in APP_SUBNETS], SecurityGroupIds=[GetAtt(ENDPOINT_SG, 'GroupId')], ServiceName=Sub('com.amazonaws.${AWS::Region}.ssmmessages'), VpcEndpointType='Interface', PrivateDnsEnabled=True) TPL.add_resource(APP_SSM_MESSAGES_ENDPOINT) ################################################################################ # # OUTPUTS # TPL.add_output(object_outputs(VPC, name_is_id=True)) TPL.add_output(object_outputs(APP_SQS_ENDPOINT, name_is_id=True)) TPL.add_output(object_outputs(APP_SNS_ENDPOINT, name_is_id=True)) TPL.add_output( comments_outputs([{ 'EIP': Join(',', [GetAtt(resource, "AllocationId") for resource in RESOURCES]) }, { 'PublicSubnets': Join(',', [Ref(subnet) for subnet in PUBLIC_SUBNETS]) }, { 'StorageSubnets': Join(',', [Ref(subnet) for subnet in STORAGE_SUBNETS]) }, { 'ApplicationSubnets': Join(',', [Ref(subnet) for subnet in APP_SUBNETS]) }, { 'StackName': Ref('AWS::StackName') }, { 'VpcZoneId': Ref(DNS_HOSTED_ZONE) }])) return TPL
def hosted_zone_vpc(hz_vpc_title, vpcid, vpc_region): hostedzonevpc = HostedZoneVPCs(VPCId=vpcid, VPCRegion=vpc_region) return hostedzonevpc