Ejemplo n.º 1
0
def create_dnsrecords():
    return route53.RecordSetGroup(
        'dns',
        HostedZoneName=Sub('${domain}.'),
        RecordSets=[
            route53.RecordSet(
                'dnsInstance',
                Name=_subdomain_for_instance(),
                ResourceRecords=[GetAtt('devserver', 'PublicIp')],
                Type='A',
                TTL=300,
            ),
            route53.RecordSet(
                'dnsTlsApplication',
                Name=_subdomain_for_application(),
                Type='A',
                AliasTarget=route53.AliasTarget(
                    DNSName=GetAtt('tlsFrontend', 'DNSName'),
                    HostedZoneId=GetAtt('tlsFrontend',
                                        'CanonicalHostedZoneID'),
                ),
            ),
            route53.RecordSet(
                'dnsTlsJenkins',
                Name=_subdomain_for_jenkins(),
                Type='A',
                AliasTarget=route53.AliasTarget(
                    DNSName=GetAtt('tlsFrontend', 'DNSName'),
                    HostedZoneId=GetAtt('tlsFrontend',
                                        'CanonicalHostedZoneID'),
                ),
            ),
        ],
    )
Ejemplo n.º 2
0
 def create_dns_records(self, rds_database, elasticache_group):
     self.add_resource(
         r53.RecordSetGroup(
             'dnsPrivateRecords',
             HostedZoneId=Ref(self.private_hosted_zone_id),
             RecordSets=[
                 r53.RecordSet('dnsDatabaseServer',
                               Name=Join('', [
                                   'database.service.',
                                   Ref(self.private_hosted_zone_name), '.'
                               ]),
                               Type='CNAME',
                               TTL='10',
                               ResourceRecords=[
                                   GetAtt(rds_database, 'Endpoint.Address')
                               ]),
                 r53.RecordSet('dnsCacheServer',
                               Name=Join('', [
                                   'cache.service.',
                                   Ref(self.private_hosted_zone_name), '.'
                               ]),
                               Type='CNAME',
                               TTL='10',
                               ResourceRecords=[
                                   GetAtt(elasticache_group,
                                          'PrimaryEndPoint.Address')
                               ])
             ]))
Ejemplo n.º 3
0
    def create_dns_records(self, bastion_host, rds_database,
                           elasticache_group):
        self.add_resource(
            r53.RecordSetGroup(
                'dnsPublicRecords',
                HostedZoneName=Join('',
                                    [Ref(self.public_hosted_zone_name), '.']),
                RecordSets=[
                    r53.RecordSet(
                        'dnsMonitoringServer',
                        Name=Join('', [
                            'monitoring.',
                            Ref(self.public_hosted_zone_name), '.'
                        ]),
                        Type='A',
                        TTL='300',
                        ResourceRecords=[GetAtt(bastion_host, 'PublicIp')])
                ]))

        self.add_resource(
            r53.RecordSetGroup(
                'dnsPrivateRecords',
                HostedZoneId=Ref(self.private_hosted_zone_id),
                RecordSets=[
                    r53.RecordSet(
                        'dnsBastionHost',
                        Name=Join('', [
                            'monitoring.service.',
                            Ref(self.private_hosted_zone_name), '.'
                        ]),
                        Type='A',
                        TTL='10',
                        ResourceRecords=[GetAtt(bastion_host, 'PrivateIp')]),
                    r53.RecordSet('dnsDatabaseServer',
                                  Name=Join('', [
                                      'database.service.',
                                      Ref(self.private_hosted_zone_name), '.'
                                  ]),
                                  Type='CNAME',
                                  TTL='10',
                                  ResourceRecords=[
                                      GetAtt(rds_database, 'Endpoint.Address')
                                  ]),
                    r53.RecordSet('dnsCacheServer',
                                  Name=Join('', [
                                      'cache.service.',
                                      Ref(self.private_hosted_zone_name), '.'
                                  ]),
                                  Type='CNAME',
                                  TTL='10',
                                  ResourceRecords=[
                                      GetAtt(elasticache_group,
                                             'PrimaryEndPoint.Address')
                                  ])
                ]))
Ejemplo n.º 4
0
    def handle(self, chain_context):
        template = chain_context.template

        template.add_resource(route53.RecordSetGroup(
            "Route53Records",
            RecordSets=[
                route53.RecordSet(
                    DNS_NAME % self.name,
                    Weight=1,
                    SetIdentifier="original",
                    AliasTarget=route53.AliasTarget(
                        HostedZoneId=self.hosted_zone_id,
                        DNSName=self.target,
                        EvaluateTargetHealth=False,
                    ),
                    Name=Join("", [
                        self.dns_name,
                        ".",
                        self.base_domain,
                        "."
                    ]),
                    Type="A",
                )
            ],
            HostedZoneName=Join("", [self.base_domain, "."])
        ))
Ejemplo n.º 5
0
    def create_r53_record(self, hosted_zone_name):
        """
        Function to create r53 recourdset to associate with ELB
        :param hosted_zone_name: R53 hosted zone to create record in
        """
        if self.elb_config.public_unit:
            name = Join('', [Ref('AWS::StackName'),
                             '-',
                             self.title,
                             '.',
                             hosted_zone_name])
        else:
            name = Join('', [self.title,
                             '.',
                             hosted_zone_name])
        self.elb_r53 = self.template.add_resource(route53.RecordSetGroup(
            self.title + 'R53',
            RecordSets=[route53.RecordSet(
                Name=name,
                AliasTarget=route53.AliasTarget(dnsname=GetAtt(self.trop_elb, 'DNSName'),
                                                hostedzoneid=GetAtt(self.trop_elb, 'CanonicalHostedZoneNameID')),
                Type='A')]))

        if not self.elb_config.public_unit:
            self.elb_r53.HostedZoneId = self.network_config.private_hosted_zone_id
        else:
            self.elb_r53.HostedZoneName = hosted_zone_name

        self.template.add_output(Output(
            self.trop_elb.title,
            Description='URL of the {0} ELB'.format(self.title),
            Value=Join('', ['http://', self.elb_r53.RecordSets[0].Name])
        ))
Ejemplo n.º 6
0
    def create_r53_record(self):
        """
        Function to create r53 recourdset to associate with the RDS
        """
        self.rds_r53 = self.template.add_resource(
            route53.RecordSetGroup(
                self.title + 'R53',
                HostedZoneId=self.network_config.private_hosted_zone_id,
                RecordSets=[
                    route53.RecordSet(Name=Join('', [
                        self.title, '.',
                        self.network_config.private_hosted_zone_domain
                    ]),
                                      ResourceRecords=[
                                          GetAtt(self.trop_db,
                                                 'Endpoint.Address')
                                      ],
                                      TTL=300,
                                      Type='CNAME')
                ]))

        self.template.add_output(
            Output(self.trop_db.title + 'Endpoint',
                   Description='Address of the {0} RDS'.format(self.title),
                   Value=Join('', [
                       self.rds_r53.RecordSets[0].Name, ':',
                       GetAtt(self.trop_db, 'Endpoint.Port')
                   ])))
    def route53_record_set(self):
        t = self.template
        LocalDNS = t.add_resource(
            route53.RecordSetGroup(
                "LocalDNS",
                HostedZoneName=self.vars["HostedZoneDomainName"] + ".",
                RecordSets=[
                    route53.RecordSet(
                        Name=self.vars["FQDNInternal"] + ".",
                        Type="A",
                        AliasTarget=route53.AliasTarget(
                            HostedZoneId=CLOUDFRONT_HOSTEDZONEID,
                            DNSName=GetAtt(self.SiteCFDistribution,
                                           "DomainName"),
                        ),
                    )
                ],
            ))

        LocalDNS = t.add_output(
            Output(
                "LocalDNS",
                Description="Internal DNS domainname set in route53",
                Value=self.vars["FQDNInternal"],
            ))
Ejemplo n.º 8
0
    def handle(self, chain_context):
        template = chain_context.template

        name = 'AlbAlias%s' % chain_context.instance_name

        template.add_resource(
            route53.RecordSetGroup(
                "Route53Records",
                RecordSets=[
                    route53.RecordSet(
                        name,
                        Weight=1,
                        SetIdentifier="original",
                        AliasTarget=route53.AliasTarget(
                            HostedZoneId=self.hosted_zone_id,
                            DNSName=self.dns_name,
                            EvaluateTargetHealth=False,
                        ),
                        Name=Join("", [
                            Ref("namespace"), "-",
                            Ref("env"), ".", self.base_domain, "."
                        ]),
                        Type="A",
                    )
                ],
                HostedZoneName=Join("", [self.base_domain, "."])))
Ejemplo n.º 9
0
    def create_dns_records(self, bastion_host):
        private_hosted_zone = self.add_resource(
            r53.HostedZone('dnsPrivateHostedZone',
                           Name=Join(
                               '', [Ref(self.private_hosted_zone_name), '.']),
                           VPCs=[
                               r53.HostedZoneVPCs(VPCId=Ref(self.vpc),
                                                  VPCRegion=self.region)
                           ]))

        self.add_resource(
            r53.RecordSetGroup(
                'dnsPublicRecords',
                HostedZoneName=Join('',
                                    [Ref(self.public_hosted_zone_name), '.']),
                RecordSets=[
                    r53.RecordSet(
                        'dnsMonitoringServer',
                        Name=Join('', [
                            'monitoring.',
                            Ref(self.public_hosted_zone_name), '.'
                        ]),
                        Type='A',
                        TTL='300',
                        ResourceRecords=[GetAtt(bastion_host, 'PublicIp')])
                ]))

        self.add_resource(
            r53.RecordSetGroup(
                'dnsPrivateRecords',
                HostedZoneId=Ref(private_hosted_zone),
                RecordSets=[
                    r53.RecordSet(
                        'dnsBastionHost',
                        Name=Join('', [
                            'monitoring.service.',
                            Ref(self.private_hosted_zone_name), '.'
                        ]),
                        Type='A',
                        TTL='10',
                        ResourceRecords=[GetAtt(bastion_host, 'PrivateIp')])
                ]))

        return private_hosted_zone
Ejemplo n.º 10
0
    def create_dns_records(self, tile_server_lb):
        self.add_condition('BlueCondition', Equals('Blue', Ref(self.color)))
        self.add_condition('GreenCondition', Equals('Green', Ref(self.color)))

        self.add_resource(r53.RecordSetGroup(
            'dnsPublicRecordsBlue',
            Condition='BlueCondition',
            HostedZoneName=Join('', [Ref(self.public_hosted_zone_name), '.']),
            RecordSets=[
                r53.RecordSet(
                    'dnsTileServersBlue',
                    AliasTarget=r53.AliasTarget(
                        GetAtt(tile_server_lb, 'CanonicalHostedZoneNameID'),
                        GetAtt(tile_server_lb, 'DNSName'),
                        True
                    ),
                    Name=Join('', ['blue-tiles.',
                                   Ref(self.public_hosted_zone_name), '.']),
                    Type='A'
                )
            ]
        ))

        self.add_resource(r53.RecordSetGroup(
            'dnsPublicRecordsGreen',
            Condition='GreenCondition',
            HostedZoneName=Join('', [Ref(self.public_hosted_zone_name), '.']),
            RecordSets=[
                r53.RecordSet(
                    'dnsTileServersGreen',
                    AliasTarget=r53.AliasTarget(
                        GetAtt(tile_server_lb, 'CanonicalHostedZoneNameID'),
                        GetAtt(tile_server_lb, 'DNSName'),
                        True
                    ),
                    Name=Join('', ['green-tiles.',
                                   Ref(self.public_hosted_zone_name), '.']),
                    Type='A'
                )
            ]
        ))
Ejemplo n.º 11
0
    def add_to_template(self, t):

        dns_param = ensure_param(t, self.value.output_dns(), 'String')
        zone_id = "Z2FDTNDATAQYW2"
        r = route53.RecordSet(
            '{}CFRecord'.format(self._safe_dns_name(self.name)),
            Name="{}{}.".format(self.name, self.stack.domain_name),
            Type="A",
            AliasTarget=route53.AliasTarget(HostedZoneId=zone_id,
                                            DNSName=Ref(dns_param)))

        return r
Ejemplo n.º 12
0
    def add_to_template(self, t):

        dns_param = ensure_param(t, self.value.output_endpoint(), 'String')
        r = route53.RecordSet('{}RDSRecord'.format(
            self._safe_dns_name(self.name)),
                              Name="{}{}.".format(self.name,
                                                  self.stack.domain_name),
                              Type="CNAME",
                              TTL=self.ttl,
                              ResourceRecords=[Ref(dns_param)])

        return r
    def create_s3_resources(self):
        s3_bucket = self.add_resource(
            s3.Bucket('s3TileCacheBucket',
                      BucketName=Join(
                          '.',
                          ['tile-cache',
                           Ref(self.public_hosted_zone_name)]),
                      AccessControl=s3.PublicRead,
                      CorsConfiguration=s3.CorsConfiguration(CorsRules=[
                          s3.CorsRules(
                              AllowedOrigins=['*'],
                              AllowedMethods=['GET'],
                              MaxAge=3000,
                              AllowedHeaders=['*'],
                          )
                      ])))

        self.add_resource(
            s3.BucketPolicy(
                's3TileCacheBucketPolicy',
                Bucket=Ref(s3_bucket),
                PolicyDocument={
                    'Statement': [{
                        'Action': ['s3:GetObject'],
                        'Effect': 'Allow',
                        'Resource': {
                            'Fn::Join':
                            ['', ['arn:aws:s3:::',
                                  Ref(s3_bucket), '/*']]
                        },
                        'Principal': '*'
                    }]
                }))

        self.add_resource(
            r53.RecordSetGroup(
                'dnsPublicRecordsCache',
                HostedZoneName=Join('',
                                    [Ref(self.public_hosted_zone_name), '.']),
                RecordSets=[
                    r53.RecordSet('dnsTileServersCache',
                                  AliasTarget=r53.AliasTarget(
                                      AMAZON_S3_HOSTED_ZONE_ID,
                                      AMAZON_S3_WEBSITE_DOMAIN,
                                      True,
                                  ),
                                  Name=Join('', [
                                      'tile-cache.',
                                      Ref(self.public_hosted_zone_name), '.'
                                  ]),
                                  Type='A')
                ]))
Ejemplo n.º 14
0
    def add_to_template(self, t):
        """
        """
        zone_param = ensure_param(t, self.value.output_hosted_zone(), 'String')
        dns_param = ensure_param(t, self.value.output_dns_name(), 'String')
        r = route53.RecordSet(
            '{}ELBRecord'.format(self._safe_dns_name(self.name)),
            Name="{}{}.".format(self.name, self.stack.domain_name),
            Type="A",
            AliasTarget=route53.AliasTarget(HostedZoneId=Ref(zone_param),
                                            DNSName=Ref(dns_param)))

        return r
Ejemplo n.º 15
0
    def add_to_template(self, template):

        param = Ref(ensure_param(template, self.value.output_eip()))

        record = route53.RecordSet('{}EipARecord'.format(
            self._safe_dns_name(self.name)),
                                   Name="{}{}.".format(self.name,
                                                       self.stack.domain_name),
                                   Type=self.type,
                                   TTL=self.ttl,
                                   ResourceRecords=[param])

        return record
Ejemplo n.º 16
0
    def add_api(self):
        api = self.add_resource(
            apigatewayv2.Api(
                'HttpApi',
                Name=StackName,
                Description=Join(' ',
                                 [Ref(self.domain), 'Terraform Registry']),
                ProtocolType='HTTP',
                Target=Ref(self._lambda_function),
            ))

        self.add_resource(
            awslambda.Permission(
                f'ApigatewayPermission',
                Principal='apigateway.amazonaws.com',
                Action='lambda:InvokeFunction',
                FunctionName=Ref(self._lambda_function),
                SourceArn=Join('', [
                    'arn:aws:execute-api:', Region, ':', AccountId, ':',
                    Ref(api), '/*'
                ])))

        domain = self.add_resource(
            apigatewayv2.DomainName('HttpApiDomain',
                                    DomainName=Ref(self.domain),
                                    DomainNameConfigurations=[
                                        apigatewayv2.DomainNameConfiguration(
                                            CertificateArn=Ref(
                                                self.certificate), )
                                    ]))

        mapping = self.add_resource(
            apigatewayv2.ApiMapping('Mapping',
                                    DomainName=Ref(domain),
                                    ApiId=Ref(api),
                                    Stage='$default'))

        dns_record = self.add_resource(
            route53.RecordSetGroup(
                'ApiDnsRecord',
                HostedZoneId=Ref(self.hosted_zone),
                RecordSets=[
                    route53.RecordSet(
                        Name=Ref(self.domain),
                        AliasTarget=route53.AliasTarget(
                            DNSName=GetAtt(domain, 'RegionalDomainName'),
                            HostedZoneId=GetAtt(domain,
                                                'RegionalHostedZoneId')),
                        Type='A')
                ]))
Ejemplo n.º 17
0
    def add_to_template(self, template):

        res = self.value

        if not isinstance(res, list):
            res = [res]

        record = route53.RecordSet('{}ARecord'.format(
            self._safe_dns_name(self.name)),
                                   Name="{}{}.".format(self.name,
                                                       self.stack.domain_name),
                                   Type=self.type,
                                   TTL=self.ttl,
                                   ResourceRecords=res)

        return record
Ejemplo n.º 18
0
    def add_elasticache_dns_alias(self, cluster, name, engine, zone_name):
        if engine == 'redis':
            address = "RedisEndpoint.Address"
        if engine == 'memcached':
            address = "ConfigurationEndpoint.Address"

        return self.add_resource(
            route53.RecordSetGroup(
                name + engine + "ElastiCacheRecordSetGroup",
                HostedZoneName=zone_name,
                RecordSets=[
                    route53.RecordSet(
                        Name=name + engine + '.' + zone_name,
                        Type='CNAME',
                        TTL='60',
                        ResourceRecords=[GetAtt(cluster, address)])
                ]))
Ejemplo n.º 19
0
 def add_dns_alias(self, name, dns_name, zone_id, zone_name):
     """
     Helper to attach an alias dns entry to an elb
     @param dns_name [string] name of the domain
     @param zone_id [string] hostzone id for the target
     @param zone_name [string] hostzone name
     """
     return self.add_resource(
         route53.RecordSetGroup(
             name.replace(".", "") + "AliasRecordSetGroup" +
             zone_name.replace('.', ''),
             HostedZoneName=zone_name,
             RecordSets=[
                 route53.RecordSet(Name=name,
                                   Type='A',
                                   AliasTarget=route53.AliasTarget(
                                       zone_id, dns_name))
             ]))
Ejemplo n.º 20
0
 def route53_record_set(self):
     t = self.template
     t.add_resource(
         route53.RecordSetGroup(
             "RecordSetGroup",
             HostedZoneName=self.vars["HostedZone"] + ".",
             RecordSets=[
                 route53.RecordSet(
                     Name=self.vars['ServiceFqdn'] + ".",
                     Type="A",
                     AliasTarget=route53.AliasTarget(
                         HostedZoneId=get_elb_hosted_zone_id(
                             self.vars['LoadBalancerArn']),
                         DNSName=self.vars['LoadBalancerUrl'],
                     ),
                 )
             ],
         ))
     return
Ejemplo n.º 21
0
 def add_instance_dns_a_record(self,
                               instance,
                               name,
                               zone_name,
                               att='PrivateIp'):
     """
     Helper to attach an alias dns entry to an elb
     @param instance [Instance] target instance
     @param name [string] name of the domain
     @param zone_name [string] hostzone name
     @param att [string] the attribute to use for binding the record
     """
     return self.add_resource(
         route53.RecordSetGroup(
             name.replace(".", "") + "InstanceRecordSetGroup",
             HostedZoneName=zone_name,
             RecordSets=[
                 route53.RecordSet(Name=name + '.' + zone_name,
                                   Type='A',
                                   TTL='60',
                                   ResourceRecords=[GetAtt(instance, att)])
             ]))
Ejemplo n.º 22
0
 def add_elb_dns_alias(self, elb, name, zone_name):
     """
     Helper to attach an alias dns entry to an elb
     @param elb [ELB] target elb
     @param name [string] name of the domain
     @param zone_name [string] hostzone name
     """
     if name:
         name = name.lower() + '.' + zone_name
     else:
         name = zone_name.lower()
     return self.add_resource(
         route53.RecordSetGroup(
             name.replace('.', '') + "ELBRecordSetGroup" +
             zone_name.replace('.', ''),
             HostedZoneName=zone_name.lower(),
             RecordSets=[
                 route53.RecordSet(Name=name,
                                   Type='A',
                                   AliasTarget=route53.AliasTarget(
                                       GetAtt(elb, "CanonicalHostedZoneID"),
                                       GetAtt(elb, "DNSName")))
             ]))
Ejemplo n.º 23
0
    def add_rds_dns_alias(self, rds, name, zone_name):
        """
        Helper to attach an alias dns entry to an elb
        @param instance [Instance] target instance
        @param name [string] name of the domain
        @param zone_name [string] hostzone name
        @param att [string] the attribute to use for binding the record
        """
        if 'admin' in zone_name:
            record_name = 'rds' + name + '.' + zone_name
        else:
            record_name = name + '.rds.' + zone_name

        return self.add_resource(
            route53.RecordSetGroup(
                name.replace(".", "") + "RDSRecordSetGroup",
                HostedZoneName=zone_name,
                RecordSets=[
                    route53.RecordSet(
                        Name=record_name,
                        Type='CNAME',
                        TTL='60',
                        ResourceRecords=[GetAtt(rds, "Endpoint.Address")])
                ]))
Ejemplo n.º 24
0
    def add_api(self):
        rest_api = self.add_resource(
            apigateway.RestApi(
                'Api',
                Description=Join(' ',
                                 [Ref(self.domain), 'Terraform Registry']),
                Name=StackName))

        methods = self.add_registry_api(rest_api)
        methods += [self.add_service_discovery_api(rest_api)]

        self.add_resource(
            awslambda.Permission(
                f'ApigatewayPermission',
                Principal='apigateway.amazonaws.com',
                Action='lambda:InvokeFunction',
                FunctionName=Ref(self._lambda_function),
                SourceArn=Join('', [
                    'arn:aws:execute-api:', Region, ':', AccountId, ':',
                    Ref(rest_api), '/*'
                ])))

        deployment_id = 'ApiDeployment' + ''.join(
            random.choice(string.ascii_letters) for _ in range(5))

        deployment = self.add_resource(
            apigateway.Deployment(deployment_id,
                                  Description=self._build_version,
                                  RestApiId=Ref(rest_api),
                                  DependsOn=methods,
                                  DeletionPolicy=Retain))

        stage = self.add_resource(
            apigateway.Stage('ApiStage',
                             MethodSettings=[
                                 apigateway.MethodSetting(
                                     HttpMethod='*',
                                     LoggingLevel='INFO',
                                     MetricsEnabled=True,
                                     ResourcePath='/*',
                                     DataTraceEnabled=True,
                                 )
                             ],
                             TracingEnabled=True,
                             StageName='prd',
                             RestApiId=Ref(rest_api),
                             DeploymentId=Ref(deployment),
                             DependsOn=[deployment]))

        domain = self.add_resource(
            apigateway.DomainName(
                'ApiDomain',
                DomainName=Ref(self.domain),
                CertificateArn=Ref(self.certificate),
                EndpointConfiguration=apigateway.EndpointConfiguration(
                    Types=['EDGE'])))

        mapping = self.add_resource(
            apigateway.BasePathMapping('Mapping',
                                       DomainName=Ref(domain),
                                       RestApiId=Ref(rest_api),
                                       Stage='prd',
                                       DependsOn=['ApiStage']))

        dns_record = self.add_resource(
            route53.RecordSetGroup('ApiDnsRecord',
                                   HostedZoneId=Ref(self.hosted_zone),
                                   RecordSets=[
                                       route53.RecordSet(
                                           Name=Ref(self.domain),
                                           AliasTarget=route53.AliasTarget(
                                               DNSName=GetAtt(
                                                   domain,
                                                   'DistributionDomainName'),
                                               HostedZoneId='Z2FDTNDATAQYW2'),
                                           Type='A')
                                   ]))
Ejemplo n.º 25
0
    def configure(self):
        """
        Returns a Pritunl template
        """
        self.defaults = {'instance_type': 't3.large'}

        self.service = 'pritunl'
        self.set_description('Sets up Pritunl servers')
        self.get_default_security_groups()
        self.get_standard_parameters()
        self.get_standard_policies()

        _vpn_config = constants.ENVIRONMENTS[self.env]['pritunl']
        _global_config = constants.ENVIRONMENTS[self.env]
        _bootstrap_mode = _vpn_config.get('bootstrap_mode', False)

        _bootstrap_ami = get_latest_ami_id(
            self.region, 'amzn2-ami-hvm-2.0.????????-x86_64-gp2', 'amazon')
        _ivy_ami = get_latest_ami_id(self.region, 'ivy-base',
                                     _global_config.get('ami_owner', 'self'))

        self.ami = self.add_parameter(
            Parameter('AMI',
                      Type='String',
                      Description='AMI ID for instances',
                      Default=_bootstrap_ami if _bootstrap_mode else _ivy_ami))

        _public_dns = _vpn_config['public_dns']

        _vpn_name = '{}Pritunl'.format(self.env)

        # We want the preferred subnet only.
        _vpn_subnet = self.get_subnets('public', _preferred_only=True)[0]

        # Add our security group
        _vpn_security_group = self.add_resource(
            ec2.SecurityGroup(
                '{}SecurityGroup'.format(_vpn_name),
                VpcId=self.vpc_id,
                GroupDescription='Security Group for Pritunl {}'.format(
                    _vpn_name),
                SecurityGroupIngress=[
                    {
                        "IpProtocol": "icmp",
                        "FromPort": "-1",
                        "ToPort": "-1",
                        "CidrIp": "0.0.0.0/0"
                    },  # Ping
                    {
                        "IpProtocol": "tcp",
                        "FromPort": "80",
                        "ToPort": "80",
                        "CidrIp": "0.0.0.0/0"
                    },  # HTTP
                    {
                        "IpProtocol": "tcp",
                        "FromPort": "443",
                        "ToPort": "443",
                        "CidrIp": "0.0.0.0/0"
                    },  # HTTPS
                    {
                        "IpProtocol": "tcp",
                        "FromPort": "22",
                        "ToPort": "22",
                        "CidrIp": "0.0.0.0/0"
                    },  # SSH
                    {
                        "IpProtocol": "udp",
                        "FromPort": "10000",
                        "ToPort": "20000",
                        "CidrIp": "0.0.0.0/0"
                    },  # HTTPS/OVPN
                    {
                        "IpProtocol": "tcp",
                        "FromPort": "27017",
                        "ToPort": "27017",
                        "CidrIp": constants.SUPERNET
                    },  # mongodb master
                    {
                        "IpProtocol": "-1",
                        "FromPort": "-1",
                        "ToPort": "-1",
                        "CidrIp": constants.SUPERNET
                    }  # Replies from local VPC
                ],
                SecurityGroupEgress=[{
                    "IpProtocol": "-1",
                    "FromPort": "-1",
                    "ToPort": "-1",
                    "CidrIp": "0.0.0.0/0"
                }]))

        # Add EBS volume if local mongo used
        _data_volume = None
        if _vpn_config.get('local_mongo', False):
            self.add_iam_policy(
                iam.Policy(
                    PolicyName='AttachVolume',
                    PolicyDocument={
                        'Statement': [{
                            'Effect':
                            'Allow',
                            'Resource':
                            '*',
                            'Action': [
                                'ec2:AttachVolume', 'ec2:DeleteSnapshot',
                                'ec2:DescribeTags',
                                'ec2:DescribeVolumeAttribute',
                                'ec2:DescribeVolumeStatus',
                                'ec2:DescribeVolumes', 'ec2:DetachVolume'
                            ]
                        }]
                    }))
            _data_volume = ec2.Volume(
                '{}DataVolume'.format(_vpn_name),
                Size=_vpn_config.get('data_volume_size', 20),
                VolumeType='gp2',
                AvailabilityZone=_vpn_subnet['AvailabilityZone'],
                DeletionPolicy='Retain',
                Tags=self.get_tags(service_override=self.service,
                                   role_override=_vpn_name) +
                [ec2.Tag('Name', _vpn_name + "-datavol")])
            self.add_resource(_data_volume)

        # Add the elastic IP and the ENI for it, then attach it.
        _vpn_eip = self.add_resource(
            ec2.EIP('{}InstanceEIP'.format(_vpn_name), Domain='vpc'))
        _vpn_eni = self.add_resource(
            ec2.NetworkInterface(
                '{}InstanceENI'.format(_vpn_name),
                SubnetId=_vpn_subnet['SubnetId'],
                Description='ENI for {}'.format(_vpn_name),
                GroupSet=[Ref(_vpn_security_group)] + self.security_groups,
                SourceDestCheck=False,
                Tags=self.get_tags(service_override=self.service,
                                   role_override=_vpn_name)))
        self.get_eni_policies()

        self.add_resource(
            ec2.EIPAssociation('{}AssociateVPNInstanceENI'.format(_vpn_name),
                               AllocationId=GetAtt(_vpn_eip, "AllocationId"),
                               NetworkInterfaceId=Ref(_vpn_eni)))

        # Add a route53 DNS name
        if self.get_partition() != 'aws-us-gov':
            self.add_resource(
                route53.RecordSetGroup('{}Route53'.format(_vpn_name),
                                       HostedZoneName=constants.ENVIRONMENTS[
                                           self.env]['route53_zone'],
                                       RecordSets=[
                                           route53.RecordSet(
                                               Name=_public_dns,
                                               ResourceRecords=[Ref(_vpn_eip)],
                                               Type='A',
                                               TTL=600)
                                       ]))

        # Get all route tables in the VPC
        _vpc_route_tables = self.ec2_conn.describe_route_tables(
            Filters=[{
                'Name': 'vpc-id',
                'Values': [self.vpc_id]
            }])['RouteTables']

        # Set up the routing table for the VPC
        # Allow for changing client subnets in constants.py
        for client_subnet in _vpn_config['client_subnets']:
            for route_table in _vpc_route_tables:
                self.add_resource(
                    ec2.Route('{}Route{}{}'.format(
                        _vpn_name,
                        client_subnet.translate({
                            ord("."): "",
                            ord("/"): ""
                        }), route_table['RouteTableId'].replace('-', '')),
                              RouteTableId=route_table['RouteTableId'],
                              DestinationCidrBlock=client_subnet,
                              NetworkInterfaceId=Ref(_vpn_eni)))

        _mongodb = _vpn_config.get('mongodb')
        _server_id = _vpn_config['server_id']

        _userdata_template = self.get_cloudinit_template(
            _tpl_name="pritunl_bootstrap" if _bootstrap_mode else None,
            replacements=(('__PROMPT_COLOR__', self.prompt_color()),
                          ('__SERVER_ID__', _server_id), ('__SERVICE__',
                                                          self.service),
                          ('__MONGODB__', _mongodb if _mongodb else '')))

        _userdata = Sub(
            _userdata_template.replace(
                '${', '${!')  # Replace bash brackets with CFN escaped style
            .replace(
                '{#', '${'
            ),  # Replace rain-style CFN escapes with proper CFN brackets
            {
                'CFN_ENI_ID': Ref(_vpn_eni),
                'CFN_EBS_ID': Ref(_data_volume) if _data_volume else ''
            })

        _vpn_launch_configuration = self.add_resource(
            autoscaling.LaunchConfiguration(
                '{}LaunchConfiguration'.format(_vpn_name),
                AssociatePublicIpAddress=True,
                KeyName=Ref(self.keypair_name),
                ImageId=Ref(self.ami),
                InstanceType=Ref(self.instance_type),
                InstanceMonitoring=False,
                IamInstanceProfile=Ref(self.instance_profile),
                UserData=Base64(_userdata)))
        self.add_resource(
            autoscaling.AutoScalingGroup(
                '{}ASGroup'.format(_vpn_name),
                AvailabilityZones=[_vpn_subnet['AvailabilityZone']],
                HealthCheckType='EC2',
                LaunchConfigurationName=Ref(_vpn_launch_configuration),
                MinSize=0,
                MaxSize=1,
                VPCZoneIdentifier=[_vpn_subnet['SubnetId']],
                Tags=self.get_autoscaling_tags(service_override=self.service,
                                               role_override=_vpn_name) +
                [autoscaling.Tag('Name', _vpn_name, True)]))
Ejemplo n.º 26
0
        DistributionConfig=cloudfront.DistributionConfig(
            Aliases=[Ref(domain)],
            Origins=[
                cloudfront.Origin(Id=Ref(root_bucket),
                                  DomainName=GetAtt(root_bucket, 'DomainName'),
                                  S3OriginConfig=cloudfront.S3Origin())
            ],
            DefaultCacheBehavior=cloudfront.DefaultCacheBehavior(
                Compress=True,
                ForwardedValues=cloudfront.ForwardedValues(QueryString=False),
                TargetOriginId=Ref(root_bucket),
                ViewerProtocolPolicy='redirect-to-https'),
            DefaultRootObject=Ref(index_page),
            Enabled=True)))

hosted_zone = Join('', [Ref(zone), '.'])
template.add_resource(
    route53.RecordSetGroup('WebsiteDNSRecord',
                           HostedZoneName=hosted_zone,
                           Comment='Records for the root of the hosted zone',
                           RecordSets=[
                               route53.RecordSet(
                                   Name=Ref(domain),
                                   Type='A',
                                   AliasTarget=route53.AliasTarget(
                                       CLOUDFRONT_HOSTED_ZONE_ID,
                                       GetAtt(cdn, 'DomainName')))
                           ]))

print(template.to_json())
Ejemplo n.º 27
0
    def configure(self):
        """
        Returns a Nexus template
        """
        self.defaults = {'instance_type': 't3.xlarge'}

        self.service = 'nexus'
        self.set_description('Sets up Nexus repository manager servers')
        self.get_default_security_groups()
        self.get_standard_parameters()
        self.get_standard_policies()
        self.ami = self.add_parameter(
            Parameter('AMI',
                      Type='String',
                      Description='AMI ID for instances',
                      Default=get_latest_ami_id(
                          self.region, 'amzn2-ami-hvm-2.0.????????-x86_64-gp2',
                          'amazon')))

        config = constants.ENVIRONMENTS[self.env][self.service]

        # We want the preferred subnet only.
        subnet = self.get_subnets('private', _preferred_only=True)[0]

        # Add our security group
        security_group = self.add_resource(
            ec2.SecurityGroup(
                '{}SecurityGroup'.format(self.name),
                VpcId=self.vpc_id,
                GroupDescription='Security Group for {}'.format(self.name),
                SecurityGroupIngress=[
                    {
                        "IpProtocol": "tcp",
                        "FromPort": "80",
                        "ToPort": "80",
                        "CidrIp": constants.SUPERNET
                    },  # HTTP
                    {
                        "IpProtocol": "tcp",
                        "FromPort": "443",
                        "ToPort": "443",
                        "CidrIp": constants.SUPERNET
                    },  # HTTPS
                    # {"IpProtocol": "tcp", "FromPort": "8081", "ToPort": "8081", "CidrIp": constants.SUPERNET},  # NexusRM Direct (disabled!)
                ],
                SecurityGroupEgress=[{
                    "IpProtocol": "-1",
                    "FromPort": "-1",
                    "ToPort": "-1",
                    "CidrIp": "0.0.0.0/0"
                }]))

        # Add our EBS data volume
        data_volume = ec2.Volume(
            '{}DataVolume'.format(self.name),
            Size=config.get('data_volume_size', 20),
            VolumeType='gp2',
            AvailabilityZone=subnet['AvailabilityZone'],
            DeletionPolicy='Retain',
            Tags=self.get_tags(service_override=self.service,
                               role_override=self.name) +
            [ec2.Tag('Name', self.name + "-datavol")])
        self.add_resource(data_volume)
        self.add_iam_policy(
            iam.Policy(PolicyName='AttachVolume',
                       PolicyDocument={
                           'Statement': [{
                               'Effect':
                               'Allow',
                               'Resource':
                               '*',
                               'Action': [
                                   'ec2:AttachVolume', 'ec2:DeleteSnapshot',
                                   'ec2:DescribeTags',
                                   'ec2:DescribeVolumeAttribute',
                                   'ec2:DescribeVolumeStatus',
                                   'ec2:DescribeVolumes', 'ec2:DetachVolume'
                               ]
                           }]
                       }))

        # Add a ENI for static IP address
        eni = self.add_resource(
            ec2.NetworkInterface(
                '{}InstanceENI'.format(self.name),
                SubnetId=subnet['SubnetId'],
                Description='ENI for {}'.format(self.name),
                GroupSet=[Ref(security_group)] + self.security_groups,
                SourceDestCheck=True,
                Tags=self.get_tags(service_override=self.service,
                                   role_override=self.name)))
        self.get_eni_policies()

        # Add a route53 A record for the main Nexus host
        route53_zone = constants.ENVIRONMENTS[self.env]['route53_zone']
        private_dns = config.get('private_dns',
                                 'nexus.{}'.format(route53_zone))
        self.add_resource(
            route53.RecordSetGroup(
                '{}Route53'.format(self.name),
                HostedZoneName=route53_zone,
                RecordSets=[
                    route53.RecordSet(Name=private_dns,
                                      ResourceRecords=[
                                          GetAtt(eni,
                                                 'PrimaryPrivateIpAddress')
                                      ],
                                      Type='A',
                                      TTL=600)
                ]))
        # Add CNAME records for each repository, pointing to the main
        for repository in config['repositories']:
            self.add_resource(
                route53.RecordSetGroup(
                    '{}{}Route53'.format(self.name, self.cfn_name(repository)),
                    HostedZoneName=route53_zone,
                    RecordSets=[
                        route53.RecordSet(Name='{}.{}'.format(
                            repository, route53_zone),
                                          ResourceRecords=[private_dns],
                                          Type='CNAME',
                                          TTL=600)
                    ]))

        # Add S3 IAM role for nexus blobstore access
        self.add_iam_policy(
            iam.Policy(
                PolicyName='S3Access',
                PolicyDocument={
                    'Statement': [{
                        "Effect":
                        "Allow",
                        "Action": [
                            "s3:ListBucket", "s3:GetBucketLocation",
                            "s3:ListBucketMultipartUploads",
                            "s3:ListBucketVersions", "s3:GetBucketAcl",
                            "s3:GetLifecycleConfiguration",
                            "s3:PutLifecycleConfiguration"
                        ],
                        "Resource": [
                            'arn:{}:s3:::{}'.format(self.get_partition(),
                                                    config['s3_bucket'])
                        ]
                    }, {
                        "Effect":
                        "Allow",
                        "Action": [
                            "s3:GetObject", "s3:PutObject", "s3:DeleteObject",
                            "s3:AbortMultipartUpload",
                            "s3:ListMultipartUploadParts",
                            "s3:GetObjectTagging", "s3:PutObjectTagging",
                            "s3:GetObjectTagging", "s3:DeleteObjectTagging"
                        ],
                        "Resource": [
                            'arn:{}:s3:::{}/*'.format(self.get_partition(),
                                                      config['s3_bucket'])
                        ]
                    }]
                }))

        # Substitute the userdata template and feed it to CFN
        userdata_template = self.get_cloudinit_template(replacements=(
            ('__PROMPT_COLOR__', self.prompt_color()),
            ('__SERVICE__', self.service),
            ('__DEFAULT_DOMAIN__',
             route53_zone[:-1]),  # route53_zone has a trailing '.', strip it
            ('__TOP_DOMAIN__', constants.ROOT_ROUTE53_ZONE),
            # ('__REPOSITORIES__', " ".join(['"{}"'.format(x) for x in config['repositories']]))  # '"abc" "def" "ghi"'
        ))
        userdata = Sub(
            userdata_template.replace(
                '${', '${!')  # Replace bash brackets with CFN escaped style
            .replace(
                '{#', '${'
            ),  # Replace rain-style CFN escapes with proper CFN brackets
            {
                'CFN_ENI_ID': Ref(eni),
                'CFN_EBS_ID': Ref(data_volume)
            })

        launch_configuration = self.add_resource(
            autoscaling.LaunchConfiguration(
                '{}LaunchConfiguration'.format(self.name),
                AssociatePublicIpAddress=False,
                KeyName=Ref(self.keypair_name),
                ImageId=Ref(self.ami),
                InstanceType=Ref(self.instance_type),
                InstanceMonitoring=False,
                IamInstanceProfile=Ref(self.instance_profile),
                UserData=Base64(userdata)))
        self.add_resource(
            autoscaling.AutoScalingGroup(
                '{}ASGroup'.format(self.name),
                AvailabilityZones=[subnet['AvailabilityZone']],
                HealthCheckType='EC2',
                LaunchConfigurationName=Ref(launch_configuration),
                MinSize=0,
                MaxSize=1,
                DesiredCapacity=0,
                VPCZoneIdentifier=[subnet['SubnetId']],
                Tags=self.get_autoscaling_tags(service_override=self.service,
                                               role_override=self.name) +
                [autoscaling.Tag('Name', self.name, True)]))
Ejemplo n.º 28
0
    def configure(self):
        config = constants.ENVIRONMENTS[self.env]['mesos']['agent']
        self.defaults = {
            'instance_type': config.get('instance_type', 'r5.xlarge')
        }

        self.add_description('Sets up Mesos Agents in all Zones')
        self.get_standard_parameters()
        self.get_standard_policies()
        self.get_default_security_groups()

        _global_config = constants.ENVIRONMENTS[self.env]

        self.ami = self.add_parameter(
            Parameter(
                'AMI',
                Type='String',
                Description='AMI ID for instances',
                Default=get_latest_ami_id(self.region, 'ivy-mesos', _global_config.get('ami_owner', 'self'))
            )
        )

        # Mesos Agent Security Group
        self.mesos_agent_security_group = self.add_resource(
            ec2.SecurityGroup(
                'MesosAgentSecurityGroup',
                VpcId=self.vpc_id,
                GroupDescription='Security Group for MesosAgent Instances',
                SecurityGroupIngress=[
                    # public http via ELB
                    {'IpProtocol': 'tcp', 'FromPort': 80, 'ToPort': 80, 'CidrIp': self.vpc_cidr},
                    # internal service SSL direct
                    {'IpProtocol': 'tcp', 'FromPort': 443, 'ToPort': 443, 'CidrIp': self.vpc_cidr},
                    # host-network services (tcp)
                    {'IpProtocol': 'tcp', 'FromPort': 5000, 'ToPort': 5049, 'CidrIp': self.vpc_cidr},
                    # host-network services (udp)
                    {'IpProtocol': 'udp', 'FromPort': 5000, 'ToPort': 5049, 'CidrIp': self.vpc_cidr},
                    # mesos agent api
                    {'IpProtocol': 'tcp', 'FromPort': 5050, 'ToPort': 5051, 'CidrIp': self.vpc_cidr},
                    # internal http-alt direct
                    {'IpProtocol': 'tcp', 'FromPort': 8000, 'ToPort': 8000, 'CidrIp': self.vpc_cidr},
                    # internal http via ELB
                    {'IpProtocol': 'tcp', 'FromPort': 8080, 'ToPort': 8080, 'CidrIp': self.vpc_cidr},
                    # internal http-alt direct
                    {'IpProtocol': 'tcp', 'FromPort': 9090, 'ToPort': 9090, 'CidrIp': self.vpc_cidr},
                    # mesos tasks (udp)
                    {'IpProtocol': 'udp', 'FromPort': 31000, 'ToPort': 32000, 'CidrIp': self.vpc_cidr},
                    # mesos tasks (tcp)
                    {'IpProtocol': 'tcp', 'FromPort': 31000, 'ToPort': 32000, 'CidrIp': self.vpc_cidr}
                ]
            )
        )
        self.add_resource(
            ec2.SecurityGroupIngress(
                'MesosAgentIngressSecurityGroup',
                GroupId=Ref(self.mesos_agent_security_group),
                IpProtocol='-1',
                FromPort=-1,
                ToPort=-1,
                SourceSecurityGroupId=Ref(self.mesos_agent_security_group)
                # All Mesos agents can access all ports on each other
            )
        )
        self.add_security_group(Ref(self.mesos_agent_security_group))

        # Security group for the internet-facing (external) ELBs - not added to the mesos agents themselves
        self.elb_external_security_group = self.add_resource(
            ec2.SecurityGroup(
                'MesosAgentELBExternalSecurityGroup',
                VpcId=self.vpc_id,
                GroupDescription='External Security Group for MesosAgent ELB Instances',
                SecurityGroupIngress=[
                    {'IpProtocol': 'tcp', 'FromPort': 80, 'ToPort': 80, 'CidrIp': '0.0.0.0/0'},  # http
                    {'IpProtocol': 'tcp', 'FromPort': 443, 'ToPort': 443, 'CidrIp': '0.0.0.0/0'},  # https
                    {'IpProtocol': 'tcp', 'FromPort': 8443, 'ToPort': 8443, 'CidrIp': '0.0.0.0/0'},  # https-alt
                    {'IpProtocol': 'icmp', 'FromPort': -1, 'ToPort': -1, 'CidrIp': '0.0.0.0/0'}  # ping (health checks)
                ]
            )
        )

        #
        # Docker roles
        #

        # Allow assume /docker roles by ec2metaproxy
        self.add_iam_policy(
            iam.Policy(
                PolicyName='AssumeDockerRoles',
                PolicyDocument={
                    'Statement': [
                        {
                            'Effect': 'Allow',
                            'Action': ["sts:AssumeRole"],
                            "Resource": {
                                "Fn::Join": [
                                    "",
                                    ["arn:{}:iam::".format(self.get_partition()), {"Ref": "AWS::AccountId"}, ":role/docker/*"]
                                ]
                            },
                        }
                    ]
                }
            )
        )
        # Add docker roles to assumable roles list
        for r in self.generate_docker_roles():
            self.add_resource(r)

        #
        # Load Balancers
        #

        lb_type = config.get('lb_type', 'classic')
        elb_log_bucket = config.get('log_bucket', '{}-{}-logs'.format(constants.TAG, self.env))

        if lb_type == 'classic':
            internal_elb = self.add_resource(
                self.generate_load_balancer(
                    "{}MesosAgentInternalELB".format(self.env),
                    "internal",
                    8080,
                    constants.SSL_CERTIFICATES[config['private_elb_cert']]['Arn'],
                    elb_log_bucket
                )
            )

            external_elb = self.add_resource(
                self.generate_load_balancer(
                    "{}MesosAgentExternalELB".format(self.env),
                    "internet-facing",
                    80,
                    constants.SSL_CERTIFICATES[config['public_elb_cert']]['Arn'],
                    elb_log_bucket
                )
            )
        elif lb_type == 'application':
            internal_elb, internal_target_group = self.generate_app_load_balancer(
                "{}MesosAgentInternalALB".format(self.env),
                "internal",
                8080,
                constants.SSL_CERTIFICATES[config['private_elb_cert']]['Arn'],
                elb_log_bucket
            )
            self.add_resource(internal_elb)
            self.add_resource(internal_target_group)

            external_elb, external_target_group = self.generate_app_load_balancer(
                "{}MesosAgentExternalALB".format(self.env),
                "internet-facing",
                80,
                constants.SSL_CERTIFICATES[config['public_elb_cert']]['Arn'],
                elb_log_bucket
            )
            self.add_resource(external_elb)
            self.add_resource(external_target_group)

        # extra public load balancers (for SSL termination, ELB doesn't do SNI)
        extra_public_load_balancers = []
        for lb_config in config.get('extra_public_load_balancers', []):
            if lb_type == 'classic':
                extra_public_load_balancers.append(Ref(self.add_resource(
                    self.generate_load_balancer(
                        "{}{}MesosAgentExternalELB".format(self.env, lb_config['name']),
                        "internet-facing",
                        80,
                        constants.SSL_CERTIFICATES[lb_config['cert']]['Arn'],
                        elb_log_bucket
                    )
                )))
            elif lb_type == 'application':
                _extra_public_lb, _extra_external_tg = self.generate_app_load_balancer(
                    "{}{}MesosAgentExternalALB".format(self.env, lb_config['name']),
                    "internet-facing",
                    80,
                    constants.SSL_CERTIFICATES[lb_config['cert']]['Arn'],
                    elb_log_bucket
                )
                self.add_resource(_extra_public_lb)
                extra_public_load_balancers.append(Ref(self.add_resource(_extra_external_tg)))

        #
        # Instances
        #

        # Add docker volume
        block_device_mapping = get_block_device_mapping(self.parameters['InstanceType'].resource['Default'])
        block_device_mapping.extend([
            ec2.BlockDeviceMapping(
                DeviceName="/dev/xvda",  # rootfs
                Ebs=ec2.EBSBlockDevice(
                    DeleteOnTermination=True,
                    VolumeSize=config.get('rootfs_size', 50),
                    VolumeType="gp2"
                )
            ),
            ec2.BlockDeviceMapping(
                DeviceName="/dev/xvdb",
                Ebs=ec2.EBSBlockDevice(
                    DeleteOnTermination=True,
                    VolumeSize=config.get('dockervol_size', 100),
                    VolumeType=config.get('dockervol_type', 'gp2')
                )
            )
        ])

        # Launch configurations
        preferred_only = config.get('preferred_placement', False)

        if lb_type == 'classic':
            # Private ASG
            self.generate_asg("private",
                              count=config['count'].get('private', 2),
                              block_mapping=block_device_mapping,
                              load_balancers=[Ref(internal_elb), Ref(external_elb)] + extra_public_load_balancers,
                              preferred_subnets_only=preferred_only
                              )

            # Public ASG
            self.generate_asg("public",
                              count=config['count'].get('public', 0),
                              block_mapping=block_device_mapping,
                              load_balancers=[Ref(internal_elb), Ref(external_elb)] + extra_public_load_balancers,
                              preferred_subnets_only=preferred_only
                              )
        elif lb_type == 'application':
            # Private ASG
            self.generate_asg("private",
                              count=config['count'].get('private', 2),
                              block_mapping=block_device_mapping,
                              target_group_arns=[Ref(internal_target_group), Ref(external_target_group)] + extra_public_load_balancers,
                              preferred_subnets_only=preferred_only
                              )

            # Public ASG
            self.generate_asg("public",
                              count=config['count'].get('public', 0),
                              block_mapping=block_device_mapping,
                              target_group_arns=[Ref(internal_target_group), Ref(external_target_group)] + extra_public_load_balancers,
                              preferred_subnets_only=preferred_only
                              )

        #
        # DNS Records
        #

        if self.get_partition() != 'aws-us-gov':
            zone = constants.ENVIRONMENTS[self.env]['route53_zone']
            self.add_resource(
                route53.RecordSetGroup(
                    'ELBRoute53',
                    HostedZoneName=zone,
                    RecordSets=[
                        route53.RecordSet(
                            Name='internal.{}'.format(zone)[:-1],
                            ResourceRecords=[GetAtt(internal_elb, 'DNSName')],
                            Type='CNAME',
                            TTL=300
                        ),
                        route53.RecordSet(
                            Name='external.{}'.format(zone)[:-1],
                            ResourceRecords=[GetAtt(external_elb, 'DNSName')],
                            Type='CNAME',
                            TTL=300
                        )
                    ]
                )
            )
Ejemplo n.º 29
0
    def configure(self):
        rds_metadata = constants.ENVIRONMENTS[self.env]['rds']
        self.name = 'rds'
        self.add_description('Sets up an RDS Instance in a VPC')
        self.get_standard_parameters()
        self.get_default_security_groups()

        for db in rds_metadata:
            name = self.env + db['name']

            # get secrets
            env_name = "DB_{}_".format(db['name'])
            db_user = db.get('admin_user',
                             os.environ.get(env_name + "USER", None))
            db_pass = db.get('admin_pass',
                             os.environ.get(env_name + "PASS", None))

            if (db_user or db_pass) is None:
                raise KeyError(
                    "Database user or password not set. Please set {0}USER or {0}PASS environment variables"
                    .format(env_name))

            if db_user in ("rdsadmin", "admin"):
                raise ValueError(
                    "Database admin '{}' cannot be used as it is a reserved word used by the engine"
                    .format(db_user))

            tags = self.get_tags(service_override=self.name,
                                 role_override=db['name'])
            security_group = self.add_resource(
                ec2.SecurityGroup(
                    '{}RDSSecurityGroup'.format(name),
                    VpcId=self.vpc_id,
                    GroupDescription='Security Group for {} Access'.format(
                        self.name),
                    SecurityGroupIngress=[{
                        'IpProtocol': 'tcp',
                        'FromPort': 5432,
                        'ToPort': 5432,
                        'CidrIp': self.vpc_cidr
                    }  # Allow DB access
                                          ],
                    Tags=tags))
            self.add_security_group(Ref(security_group))

            # Default to true for preferred subnet unless using multi_az
            preferred_only = False if db.get('multi_az') is True else db.get(
                'preferred_only', True)

            rds_subnet_group = self.add_resource(
                rds.DBSubnetGroup(
                    '{}RDSSubnetGroup'.format(name),
                    DBSubnetGroupDescription='Subnet group for {} RDS'.format(
                        name),
                    SubnetIds=list(
                        map(
                            lambda x: x['SubnetId'],
                            self.get_subnets(
                                'private', _preferred_only=preferred_only)))))
            rds_parameter_group = self.add_resource(
                rds.DBParameterGroup(
                    '{}DBParameterGroup'.format(name),
                    Description='RDS ParameterGroup for {}'.format(name),
                    Family=db.get('engine_family', 'postgres11'),
                    Parameters={
                        'log_min_duration_statement':
                        250,
                        'max_connections':
                        '{DBInstanceClassMemory/10485760}',
                        'pg_stat_statements.track':
                        'all',
                        'pg_stat_statements.max':
                        db.get('max_logged_statements', '1000')
                    },
                    Tags=tags))
            rds_instance = self.add_resource(
                rds.DBInstance(
                    '{}RDSInstance'.format(name),
                    AllocatedStorage=db['allocated_storage'],
                    AutoMinorVersionUpgrade=True,
                    BackupRetentionPeriod=7,
                    DBInstanceClass=db['instance_type'],
                    DBInstanceIdentifier=name,
                    DBParameterGroupName=Ref(rds_parameter_group),
                    #DBSnapshotIdentifier=db['snapshot_id'],
                    DBSubnetGroupName=Ref(rds_subnet_group),
                    Engine='postgres',
                    EngineVersion=db.get('engine_version', '11.5'),
                    LicenseModel='postgresql-license',
                    MultiAZ=db.get('multi_az', False),
                    PreferredBackupWindow='06:00-07:00',
                    PreferredMaintenanceWindow='sat:07:00-sat:08:00',
                    PubliclyAccessible=False,
                    StorageEncrypted=True,
                    StorageType='gp2',
                    Tags=tags,
                    VPCSecurityGroups=self.security_groups,
                    MasterUsername=db_user,
                    MasterUserPassword=db_pass,
                ))

            if self.get_partition(
            ) == 'aws':  # aws-us-gov and aws-cn may not have route53 public zones
                hosted_zone = constants.ENVIRONMENTS[self.env]['route53_zone']
                self.add_resource(
                    route53.RecordSetGroup(
                        '{}Route53'.format(name),
                        HostedZoneName=hosted_zone,
                        RecordSets=[
                            route53.RecordSet(Name='{}.rds.{}'.format(
                                db['name'], hosted_zone),
                                              ResourceRecords=[
                                                  GetAtt(
                                                      rds_instance,
                                                      'Endpoint.Address')
                                              ],
                                              Type='CNAME',
                                              TTL=600)
                        ]))
Ejemplo n.º 30
0
                ),
            ],
            PriceClass='PriceClass_100',
            ViewerCertificate=cloudfront.ViewerCertificate(
                AcmCertificateArn=Ref(certificate),
                SslSupportMethod='sni-only',
            ))))

record_set_group = template.add_resource(
    route53.RecordSetGroup(
        'RecordSetGroup',
        HostedZoneId=Ref(hosted_zone_id),
        RecordSets=[
            route53.RecordSet(Name=Ref(domain),
                              Type='A',
                              AliasTarget=route53.AliasTarget(
                                  HostedZoneId=CLOUDFRONT_HOSTED_ZONE_ID,
                                  DNSName=GetAtt(distribution, 'DomainName'),
                              )),
        ]))
# endregion

# region Outputs
template.add_output(Output('Distribution', Value=Ref(distribution)))
# endregion

# region Metadata
template.add_metadata({
    'AWS::CloudFormation::Interface': {
        'ParameterLabels': {
            # Project
            email.title: {