Esempio n. 1
0
 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),
             ))
Esempio n. 2
0
    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(),
            ))
Esempio n. 3
0
 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"))
Esempio n. 4
0
 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"))
Esempio n. 5
0
    "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)
Esempio n. 6
0
    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)))
Esempio n. 7
0
    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),
    ))