def create_dhcp_options(self): t = self.template variables = self.get_variables() domain_name = Join( " ", [variables["InternalDomain"], variables["BaseDomain"]]) if self.has_hosted_zones(): dhcp_options = t.add_resource( ec2.DHCPOptions( 'DHCPOptions', DomainName=domain_name, DomainNameServers=[ 'AmazonProvidedDNS', ], )) t.add_resource( ec2.VPCDHCPOptionsAssociation( 'DHCPAssociation', VpcId=VPC_ID, DhcpOptionsId=Ref(dhcp_options), )) else: dhcp_options = t.add_resource( ec2.DHCPOptions( 'DHCPOptions', DomainNameServers=[ 'AmazonProvidedDNS', ], )) t.add_resource( ec2.VPCDHCPOptionsAssociation( 'DHCPAssociation', VpcId=VPC_ID, DhcpOptionsId=Ref(dhcp_options), ))
def create_dhcp_options(self): t = self.template search_path = NoValue if self.zone: search_path = self.zone.Name self.dhcp_options = t.add_resource( ec2.DHCPOptions( "DHCPOptions", DomainName=search_path, DomainNameServers=[ "AmazonProvidedDNS", ], )) t.add_output(Output( "DHCPOptionsId", Value=self.dhcp_options.Ref(), )) self.dhcp_association = t.add_resource( ec2.VPCDHCPOptionsAssociation( "VPCDHCPOptionsAssociation", VpcId=self.vpc.Ref(), DhcpOptionsId=self.dhcp_options.Ref(), )) t.add_output( Output( "VPCDHCPOptionsAssociation", Value=self.dhcp_association.Ref(), ))
def _dhcp_options_no_hosted_zones(self): t = self.template dhcp_options = t.add_resource(ec2.DHCPOptions( 'DHCPOptionsNoDNS', DomainNameServers=['AmazonProvidedDNS', ], Condition="NoHostedZones")) t.add_resource(ec2.VPCDHCPOptionsAssociation( 'DHCPAssociationNoDNS', VpcId=VPC_ID, DhcpOptionsId=Ref(dhcp_options), Condition="NoHostedZones"))
def _dhcp_options_hosted_zones(self): t = self.template domain_name = Join(" ", [Ref("BaseDomain"), Ref("InternalDomain")]) dhcp_options = t.add_resource(ec2.DHCPOptions( 'DHCPOptionsWithDNS', DomainName=domain_name, DomainNameServers=['AmazonProvidedDNS', ], Condition="HasHostedZones")) t.add_resource(ec2.VPCDHCPOptionsAssociation( 'DHCPAssociationWithDNS', VpcId=VPC_ID, DhcpOptionsId=Ref(dhcp_options), Condition="HasHostedZones"))
"BastionSG", GroupDescription=BastionSGProperties.get("GroupDescription"), Tags=BastionSGProperties.get("Tags"), VpcId=BastionSGProperties.get("VpcId")) template.add_resource(BastionSG) # Add CloudWatch Alarm Topic from SNS CloudWatchAlarmTopic = sns.Topic("CloudWatchAlarmTopic", TopicName="ApiDev-Dev-CloudWatchAlarms") template.add_resource(CloudWatchAlarmTopic) # Add DHCP Options resource_tags.update({"Name": "ApiDev-Dev-DhcpOptions"}) DhcpOptions = ec2.DHCPOptions( "DhcpOptions", DomainName=Join("", (Ref("AWS::Region"), ".compute.internal")), DomainNameServers=["AmazonProvidedDNS"], Tags=Tags(resource_tags)) template.add_resource(DhcpOptions) # Add Internet Gateway resource_tags.update({"Name": "ApiDev-Dev-InternetGateway"}) InternetGateway = ec2.InternetGateway("InternetGateway", Tags=Tags(resource_tags)) template.add_resource(InternetGateway) # Add NAT Emergency SNS Topic NatEmergencyTopic = sns.Topic("NatEmergencyTopic", TopicName="ApiDev-Dev-NatEmergencyTopic") template.add_resource(NatEmergencyTopic)
def configure(self): self.vpc_metadata = constants.ENVIRONMENTS[self.env]['vpc'] self.set_description('VPC, Routes, Base Security Groups, and NATs') common_vpc_tags = [ec2.Tag('Name', self.env) ] + self.get_tags(service_override='VPC') _vpc = self.add_resource( ec2.VPC('VPC', CidrBlock=self.vpc_metadata['cidrblock'], EnableDnsSupport=True, EnableDnsHostnames=True, Tags=common_vpc_tags)) _dhcp_options = self.add_resource( ec2.DHCPOptions('DHCPOptions', DomainName="node.{}.{}".format( self.env, constants.TAG), DomainNameServers=['AmazonProvidedDNS'], Tags=common_vpc_tags)) self.add_resource( ec2.VPCDHCPOptionsAssociation('VPCDHCPOptionsAssociation', DhcpOptionsId=Ref(_dhcp_options), VpcId=Ref(_vpc))) _internet_gateway = self.add_resource( ec2.InternetGateway('InternetGateway', Tags=self.get_tags( service_override='InternetGateway', role_override='InternetGateway'))) self.add_resource( ec2.VPCGatewayAttachment('AttachInternetGateway', VpcId=Ref(_vpc), InternetGatewayId=Ref(_internet_gateway))) # route_tables stores all ec2.RouteTables generated and adds them to # a private vpc s3 endpoint route_tables = [] _public_route_table = self.add_resource( ec2.RouteTable('PublicRouteTable', VpcId=Ref(_vpc), Tags=self.get_tags( service_override='PublicRouteTable', role_override='PublicRouteTable'))) route_tables.append(_public_route_table) # Public Subnet Routes and ACLs self.add_resource( ec2.Route('PublicRoute', RouteTableId=Ref(_public_route_table), DestinationCidrBlock='0.0.0.0/0', GatewayId=Ref(_internet_gateway))) _public_network_acl = self.add_resource( ec2.NetworkAcl('PublicNetworkAcl', VpcId=Ref(_vpc), Tags=self.get_tags( service_override='PublicNetworkAcl', role_override='PublicNetworkAcl'))) self.add_resource( ec2.NetworkAclEntry('IngressPublicNetworkAclEntry', NetworkAclId=Ref(_public_network_acl), RuleNumber=100, Protocol='-1', RuleAction='allow', Egress=False, CidrBlock='0.0.0.0/0', PortRange=ec2.PortRange(From=1, To=65535))) self.add_resource( ec2.NetworkAclEntry('EgressPublicNetworkAclEntry', NetworkAclId=Ref(_public_network_acl), RuleNumber=101, Protocol='-1', RuleAction='allow', Egress=True, CidrBlock='0.0.0.0/0', PortRange=ec2.PortRange(From=1, To=65535))) # Private Network ACLs _private_network_acl = self.add_resource( ec2.NetworkAcl('PrivateNetworkAcl', VpcId=Ref(_vpc), Tags=self.get_tags( service_override='PrivateNetworkAcl', role_override='PrivateNetworkAcl'))) self.add_resource( ec2.NetworkAclEntry('IngressPrivateNetworkAclEntry', NetworkAclId=Ref(_private_network_acl), RuleNumber=100, Protocol='-1', RuleAction='allow', Egress=False, CidrBlock='0.0.0.0/0', PortRange=ec2.PortRange(From=1, To=65535))) self.add_resource( ec2.NetworkAclEntry('EgressPrivateNetworkAclEntry', NetworkAclId=Ref(_private_network_acl), RuleNumber=101, Protocol='-1', RuleAction='allow', Egress=True, CidrBlock='0.0.0.0/0', PortRange=ec2.PortRange(From=1, To=65535))) # Default security groups - referenced by name by constants/default-security-groups # _nat_security_group = self.add_resource( # ec2.SecurityGroup( # 'NATSecurityGroup', # VpcId=Ref(_vpc), # GroupDescription='Security Group for NAT Instances', # SecurityGroupIngress=[ # {'IpProtocol': '-1', 'FromPort': 1, 'ToPort': 65535, 'CidrIp': self.vpc_metadata['cidrblock']}, # {'IpProtocol': '-1', 'FromPort': 1, 'ToPort': 65535, 'CidrIp': '10.0.0.0/8'} # ], # Tags=self.get_tags(service_override='NAT', role_override='NAT-SecurityGroup') # ) # ) # _consul_security_group = self.add_resource( # ec2.SecurityGroup( # 'ConsulSecurityGroup', # VpcId=Ref(_vpc), # GroupDescription='Security Group for Consul access', # SecurityGroupIngress=[ # {'IpProtocol': 'tcp', 'FromPort': 8300, 'ToPort': 8302, 'CidrIp': '10.0.0.0/8'}, # consul server rpc/serf # {'IpProtocol': 'udp', 'FromPort': 8300, 'ToPort': 8302, 'CidrIp': '10.0.0.0/8'}, # consul server rpc/serf # {'IpProtocol': 'tcp', 'FromPort': 8400, 'ToPort': 8400, 'CidrIp': '10.0.0.0/8'}, # consul client rpc # {'IpProtocol': 'tcp', 'FromPort': 8500, 'ToPort': 8500, 'CidrIp': '10.0.0.0/8'}, # consul http # {'IpProtocol': 'tcp', 'FromPort': 8600, 'ToPort': 8600, 'CidrIp': '10.0.0.0/8'}, # consul dns # {'IpProtocol': 'udp', 'FromPort': 8600, 'ToPort': 8600, 'CidrIp': '10.0.0.0/8'} # consul dns # ], # Tags=[ # ec2.Tag('ivy:team', self.TEAM['email']), # ec2.Tag('ivy:environment', self.env), # ec2.Tag('ivy:service', 'Consul'), # ec2.Tag('ivy:role', 'Consul-SecurityGroup') # ] # ) # ) # _ssh_security_group = self.add_resource( # ec2.SecurityGroup( # 'InternalSecurityGroup', # VpcId=Ref(_vpc), # GroupDescription='Internal Rules', # SecurityGroupIngress=[ # {'IpProtocol': 'icmp', 'FromPort': -1, 'ToPort': -1, 'CidrIp': '10.0.0.0/8'}, # {'IpProtocol': 'tcp', 'FromPort': 22, 'ToPort': 22, 'CidrIp': '10.0.0.0/8'} # ], # SecurityGroupEgress=[ # {'IpProtocol': '-1', 'FromPort': 0, 'ToPort': 65535, 'CidrIp': '0.0.0.0/0'} # ], # Tags=[ # ec2.Tag('ivy:team', self.TEAM['email']), # ec2.Tag('ivy:environment', self.env), # ec2.Tag('ivy:service', 'infrastructure'), # ec2.Tag('ivy:role', 'internal') # ] # ) # ) # # self.add_security_group(Ref(_nat_security_group), Ref(_consul_security_group), Ref(_ssh_security_group)) ## This sets up all private and public AZs for index, zone in enumerate(self.vpc_metadata['zones'], 1): _public_subnet = self.add_resource( ec2.Subnet( 'PublicSubnet{}'.format(index), VpcId=Ref(_vpc), CidrBlock=zone['public-cidrblock'], AvailabilityZone=zone['availability-zone'], MapPublicIpOnLaunch=True, Tags=self.get_tags( service_override='PublicSubnet', role_override='PublicSubnet{}'.format(index)) + [ ec2.Tag('Name', '{}-PublicSubnet{}'.format( self.env, index)) ])) self.add_resource( ec2.SubnetRouteTableAssociation( 'PublicSubnetRouteTableAssociation{}'.format(index), SubnetId=Ref(_public_subnet), RouteTableId=Ref(_public_route_table))) self.add_resource( ec2.SubnetNetworkAclAssociation( 'PublicSubnetNetworkAclAssociation{}'.format(index), SubnetId=Ref(_public_subnet), NetworkAclId=Ref(_public_network_acl))) # Allow VPCs with no private subnets (save money on NAT instances for VPCs with only public instances) if zone.get('private-cidrblock'): _private_subnet = self.add_resource( ec2.Subnet( 'PrivateSubnet{}'.format(index), VpcId=Ref(_vpc), CidrBlock=zone['private-cidrblock'], AvailabilityZone=zone['availability-zone'], Tags=self.get_tags( service_override='PrivateSubnet', role_override='PrivateSubnet{}'.format(index)) + [ ec2.Tag( 'Name', '{}-PrivateSubnet{}'.format( self.env, index)) ])) # Private subnets get their own route table for AZ-specific NATs _private_route_table = self.add_resource( ec2.RouteTable( 'PrivateRouteTable{}'.format(index), VpcId=Ref(_vpc), Tags=self.get_tags( service_override='PrivateRouteTable', role_override='PrivateRouteTable{}'.format( index)))) route_tables.append(_private_route_table) # Create an EIP to be used with the NAT instance or gateway _nat_eip = self.add_resource( ec2.EIP('NATInstanceEIP{}'.format(index), Domain='vpc')) # Use VPC NAT Gateway _nat_gw = self.add_resource( ec2.NatGateway('NATGateway{}'.format(index), AllocationId=GetAtt(_nat_eip, "AllocationId"), SubnetId=Ref(_public_subnet))) # Create a route via the NAT GW for the private route table self.add_resource( ec2.Route('PrivateRoute{}'.format(index), RouteTableId=Ref(_private_route_table), DestinationCidrBlock='0.0.0.0/0', NatGatewayId=Ref(_nat_gw))) self.add_resource( ec2.SubnetRouteTableAssociation( 'PrivateSubnetRouteTableAssociation{}'.format(index), SubnetId=Ref(_private_subnet), RouteTableId=Ref(_private_route_table))) self.add_resource( ec2.SubnetNetworkAclAssociation( 'PrivateSubnetNetworkAclAssociation{}'.format(index), SubnetId=Ref(_private_subnet), NetworkAclId=Ref(_private_network_acl))) # use route_table to create a VPC S3 endpoint self.add_resource( ec2.VPCEndpoint('S3VPCEndpoint', RouteTableIds=[Ref(rt) for rt in route_tables], ServiceName='com.amazonaws.{}.s3'.format( self.region), VpcId=Ref(_vpc)))
def __setup_template(self): """ Produces a valid template instance which can then be print as json or yaml """ template = Template() template.add_description("Service VPC - used for services") template.add_metadata({ "Build": "development", "DependsOn": [], "Environment": "ApiDev", "Revision": "develop", "StackName": "ApiDev-Dev-VPC", "StackType": "InfrastructureResource", "TemplateBucket": "cfn-apidev", "TemplateName": "VPC", "TemplatePath": "ApiDev/Dev/VPC" }) vpc = template.add_resource( ec2.VPC( "VPC", CidrBlock="10.0.0.0/16", EnableDnsHostnames="true", EnableDnsSupport="true", InstanceTenancy="default", Tags=self.__get_tags("ServiceVPC"), ) ) instance_sg = template.add_resource( ec2.SecurityGroup( "BastionSG", GroupDescription="Used for source/dest rules", Tags=self.__get_tags("VPC-Bastion-SG"), VpcId=Ref( vpc ) ), ) cw_alarm_topic = template.add_resource( Topic( "CloudWatchAlarmTopic", TopicName="ApiDev-Dev-CloudWatchAlarms", ) ) dhcp_options = template.add_resource( ec2.DHCPOptions( "DhcpOptions", DomainName=Join( "", [ Ref("AWS::Region"), ".compute.internal" ] ), DomainNameServers=["AmazonProvidedDNS"], Tags=self.__get_tags("DhcpOptions"), ) ) gateway = template.add_resource( ec2.InternetGateway( "InternetGateway", Tags=self.__get_tags("InternetGateway") ) ) nat_emergency_topic = template.add_resource( Topic( "NatEmergencyTopic", TopicName="ApiDev-Dev-NatEmergencyTopic", ) ) vpc_dhcp_options_assoc = template.add_resource( ec2.VPCDHCPOptionsAssociation( "VpcDhcpOptionsAssociation", DhcpOptionsId=Ref( dhcp_options ), VpcId=Ref( vpc ) ) ) vpc_gw_attachment = template.add_resource( ec2.VPCGatewayAttachment( "VpcGatewayAttachment", InternetGatewayId=Ref( gateway ), VpcId=Ref( vpc ) ) ) vpc_network_acl = template.add_resource( ec2.NetworkAcl( "VpcNetworkAcl", Tags=self.__get_tags("NetworkAcl"), VpcId=Ref( vpc ) ) ) vpc_network_acl_rules = template.add_resource([ ec2.NetworkAclEntry( "VpcNetworkAclInboundRulePublic443", CidrBlock="0.0.0.0/0", Egress="false", NetworkAclId=Ref( vpc_network_acl ), PortRange=ec2.PortRange( From="443", To="443", ), Protocol="6", RuleAction="allow", RuleNumber=20001 ), ec2.NetworkAclEntry( "VpcNetworkAclInboundRulePublic80", CidrBlock="0.0.0.0/0", Egress="false", NetworkAclId=Ref( vpc_network_acl ), PortRange=ec2.PortRange( From="80", To="80", ), Protocol="6", RuleAction="allow", RuleNumber=20000 ), ec2.NetworkAclEntry( "VpcNetworkAclOutboundRule", CidrBlock="0.0.0.0/0", Egress="true", NetworkAclId=Ref( vpc_network_acl ), Protocol="-1", RuleAction="allow", RuleNumber=30000 ), ec2.NetworkAclEntry( "VpcNetworkAclSsh", CidrBlock="127.0.0.1/32", Egress="false", NetworkAclId=Ref( vpc_network_acl ), PortRange=ec2.PortRange( From="22", To="22", ), Protocol="6", RuleAction="allow", RuleNumber=10000 ) ]) template.add_output([ Output( "BastionSG", Value=Ref(instance_sg) ), Output( "CloudWatchAlarmTopic", Value=Ref(cw_alarm_topic) ), Output( "InternetGateway", Value=Ref(gateway) ), Output( "NatEmergencyTopicARN", Value=Ref(nat_emergency_topic) ), Output( "VPCID", Value=Ref(vpc) ), Output( "VPCName", Value=Ref("AWS::StackName") ), Output( "VpcNetworkAcl", Value=Ref(vpc_network_acl) ) ]) return template
# # Conditions # t.add_condition('4AZCondition', Equals(Ref(param_number_of_azs), '4')) t.add_condition( '3AZCondition', Or(Equals(Ref(param_number_of_azs), '3'), Condition('4AZCondition'))) # # Resources # dhcp_options = t.add_resource( ec2.DHCPOptions('DHCPOptions', DomainNameServers=['AmazonProvidedDNS'])) vpc = t.add_resource( ec2.VPC('VPC', CidrBlock=Ref(param_vpc_cidr), EnableDnsSupport='true', EnableDnsHostnames='true', Tags=Tags(Name=Ref(AWS_STACK_NAME)))) dhcp_association = t.add_resource( ec2.VPCDHCPOptionsAssociation( 'VPCDHCPOptionsAssociation', VpcId=Ref(vpc), DhcpOptionsId=Ref(dhcp_options), ))