예제 #1
0
 def create_distribution(self):
     t = self.template
     t.add_resource(
         cf.Distribution(
             DISTRIBUTION,
             DistributionConfig=cf.DistributionConfig(
                 Origins=[
                     cf.Origin(
                         Id='1',
                         DomainName=GetAtt(BUCKET, 'DomainName'),
                         S3OriginConfig=cf.S3Origin(),
                     )
                 ],
                 Enabled=Ref('Enabled'),
                 DefaultCacheBehavior=cf.DefaultCacheBehavior(
                     TargetOriginId='1',
                     ForwardedValues=cf.ForwardedValues(
                         QueryString=False, ),
                     ViewerProtocolPolicy='allow-all',
                 ),
             ),
         ))
     t.add_output(
         Output('DomainName',
                Value=Join('',
                           ['https://',
                            GetAtt(DISTRIBUTION, 'DomainName')])))
예제 #2
0
    def create_distribution(self):
        t = self.template

        s3_origin = cloudfront.Origin(
            DomainName=self.origin_bucket_url,
            Id="s3",
            CustomOriginConfig=cloudfront.CustomOrigin(
                HTTPPort=80,
                HTTPSPort=443,
                OriginProtocolPolicy="http-only"
            ),
        )

        default_behavior = cloudfront.DefaultCacheBehavior(
            AllowedMethods=["GET", "HEAD"],
            CachedMethods=["GET", "HEAD"],
            ViewerProtocolPolicy="redirect-to-https",
            ForwardedValues=cloudfront.ForwardedValues(
                QueryString=True,
                Cookies=cloudfront.Cookies(
                    Forward="none"
                )
            ),
            MinTTL=0,
            MaxTTL=31536000,
            DefaultTTL=86400,
            SmoothStreaming=False,
            TargetOriginId="s3",
        )

        viewer_certificate = NoValue
        if self.certificate_arn:
            viewer_certificate = cloudfront.ViewerCertificate(
                AcmCertificateArn=self.certificate_arn,
                SslSupportMethod="sni-only",
            )

        config = cloudfront.DistributionConfig(
            Aliases=self.aliases,
            DefaultCacheBehavior=default_behavior,
            Comment="%s" % self.origin_bucket_url,
            Enabled=True,
            PriceClass="PriceClass_All",
            ViewerCertificate=viewer_certificate,
            Origins=[s3_origin],
        )

        self.distribution = t.add_resource(
            cloudfront.Distribution(
                "Distribution",
                DistributionConfig=config,
            )
        )

        self.add_output("DistributionId", self.distribution.Ref())
        self.add_output(
            "DomainName",
            self.distribution.GetAtt("DomainName")
        )
예제 #3
0
 def _cache_behavior(origin_id, pattern):
     return cloudfront.CacheBehavior(
         TargetOriginId=origin_id,
         DefaultTTL=context['cloudfront']['default-ttl'],
         ForwardedValues=cloudfront.ForwardedValues(QueryString=False),
         PathPattern=pattern,
         ViewerProtocolPolicy='allow-all',
     )
예제 #4
0
    def add_cache_behaviors(self, title, cf_cache_behavior_config):
        """
        Create Cloudfront CacheBehavior objects and append to list of cache_behaviors
        :param title: Title of this Cloudfront Distribution
        :param cf_cache_behavior_config: list of CFCacheBehavior
        """

        default_cache_behavior_count = 0
        cache_behavior_count = 0

        for number, cache_behavior in enumerate(cf_cache_behavior_config):

            forwarded_values = cloudfront.ForwardedValues(
                Cookies=cloudfront.Cookies(
                    Forward=cache_behavior.forward_cookies),
                QueryString=cache_behavior.query_string)
            if cache_behavior.forwarded_headers is not None:
                forwarded_values.Headers = cache_behavior.forwarded_headers

            cf_cache_behavior_params = {
                'AllowedMethods': cache_behavior.allowed_methods,
                'CachedMethods': cache_behavior.cached_methods,
                'Compress': False,
                'TargetOriginId': cache_behavior.target_origin_id,
                'ForwardedValues': forwarded_values,
                'TrustedSigners': cache_behavior.trusted_signers,
                'ViewerProtocolPolicy': cache_behavior.viewer_protocol_policy,
                'MinTTL': cache_behavior.min_ttl,
                'DefaultTTL': cache_behavior.default_ttl,
                'MaxTTL': cache_behavior.max_ttl,
                'SmoothStreaming': False
            }

            if cache_behavior.is_default:
                # Add default cache behavior
                self.default_cache_behavior = cloudfront.DefaultCacheBehavior(
                    '{0}DefaultCacheBehavior'.format(title),
                    **cf_cache_behavior_params)

                default_cache_behavior_count += 1
            else:
                # Append additional cache behaviors to list
                cf_cache_behavior_params[
                    'PathPattern'] = cache_behavior.path_pattern

                created_cache_behavior = cloudfront.CacheBehavior(
                    '{0}CacheBehavior{1}'.format(title, number),
                    **cf_cache_behavior_params)

                self.cache_behaviors.append(created_cache_behavior)
                cache_behavior_count += 1

            # if there is at least one cache behavior, there must be exactly one default cache behavior
            if cache_behavior_count > 0 and default_cache_behavior_count != 1:
                raise CloudfrontConfigError(
                    'Error: cf_distribution_unit {0} must have exactly one default cache behavior.'
                    .format(title))
예제 #5
0
파일: trop.py 프로젝트: swipswaps/builder
 def _cache_behavior(origin_id, pattern, headers=None, cookies=None):
     return cloudfront.CacheBehavior(
         TargetOriginId=origin_id,
         DefaultTTL=context['cloudfront']['default-ttl'],
         ForwardedValues=cloudfront.ForwardedValues(
             Cookies=_cookies(cookies),
             QueryString=False,
             Headers=headers if headers else []),
         PathPattern=pattern,
         ViewerProtocolPolicy='allow-all',
     )
    def create_cloudfront_distributions(self):
        blue_tile_distribution = self.add_resource(
            cf.Distribution(
                'tileDistributionBlue',
                DistributionConfig=cf.DistributionConfig(
                    Origins=[
                        cf.Origin(Id='tileOriginId',
                                  DomainName=Join('.', [
                                      'tile-cache',
                                      Ref(self.public_hosted_zone_name)
                                  ]),
                                  CustomOriginConfig=cf.CustomOrigin(
                                      OriginProtocolPolicy='http-only'))
                    ],
                    DefaultCacheBehavior=cf.DefaultCacheBehavior(
                        ForwardedValues=cf.ForwardedValues(QueryString=True),
                        TargetOriginId='tileOriginId',
                        ViewerProtocolPolicy='allow-all'),
                    Enabled=True)))

        green_tile_distribution = self.add_resource(
            cf.Distribution(
                'tileDistributionGreen',
                DistributionConfig=cf.DistributionConfig(
                    Origins=[
                        cf.Origin(Id='tileOriginId',
                                  DomainName=Join('.', [
                                      'tile-cache',
                                      Ref(self.public_hosted_zone_name)
                                  ]),
                                  CustomOriginConfig=cf.CustomOrigin(
                                      OriginProtocolPolicy='http-only'))
                    ],
                    DefaultCacheBehavior=cf.DefaultCacheBehavior(
                        ForwardedValues=cf.ForwardedValues(QueryString=True),
                        TargetOriginId='tileOriginId',
                        ViewerProtocolPolicy='allow-all'),
                    Enabled=True)))

        return blue_tile_distribution, green_tile_distribution
예제 #7
0
    def get_cloudfront_distribution_options(
        self,
        bucket: s3.Bucket,
        oai: cloudfront.CloudFrontOriginAccessIdentity,
        lambda_function_associations: List[
            cloudfront.LambdaFunctionAssociation],
    ) -> Dict[str, Any]:
        """Retrieve the options for our CloudFront distribution.

        Args:
            bucket: The bucket resource
            oai: The origin access identity resource.
            lambda_function_associations: List of Lambda Function associations.

        Return:
            The CloudFront Distribution Options.

        """
        if os.getenv("AWS_REGION") == "us-east-1":
            # use global endpoint for us-east-1
            origin = Join(".", [bucket.ref(), "s3.amazonaws.com"])
        else:
            # use reginal endpoint to avoid "temporary" redirect that can last over an hour
            # https://forums.aws.amazon.com/message.jspa?messageID=677452
            origin = Join(".", [bucket.ref(), "s3", Region, "amazonaws.com"])

        return {
            "Aliases":
            self.add_aliases(),
            "Origins": [
                cloudfront.Origin(
                    DomainName=origin,
                    S3OriginConfig=cloudfront.
                    S3OriginConfig(OriginAccessIdentity=Join(
                        "", ["origin-access-identity/cloudfront/",
                             oai.ref()])),
                    Id="S3Origin",
                )
            ],
            "DefaultCacheBehavior":
            cloudfront.DefaultCacheBehavior(
                AllowedMethods=["GET", "HEAD"],
                Compress=False,
                DefaultTTL="86400",
                ForwardedValues=cloudfront.ForwardedValues(
                    Cookies=cloudfront.Cookies(Forward="none"),
                    QueryString=False),
                LambdaFunctionAssociations=lambda_function_associations,
                TargetOriginId="S3Origin",
                ViewerProtocolPolicy="redirect-to-https",
            ),
            "DefaultRootObject":
            "index.html",
            "Logging":
            self.add_logging_bucket(),
            "PriceClass":
            self.variables["PriceClass"],
            "CustomErrorResponses": [
                cloudfront.CustomErrorResponse(
                    ErrorCode=response["ErrorCode"],
                    ResponseCode=response["ResponseCode"],
                    ResponsePagePath=response["ResponsePagePath"],
                ) for response in self.variables["custom_error_responses"]
            ],
            "Enabled":
            True,
            "WebACLId":
            self.add_web_acl(),
            "ViewerCertificate":
            self.add_acm_cert(),
        }
예제 #8
0
         DomainName='applicationelasticlb-208988572.us-east-1.elb.amazonaws.com',
         CustomOriginConfig=cloudfront.CustomOrigin(
             HTTPPort="80",
             OriginProtocolPolicy="http-only",
         ),
     ),
     cloudfront.Origin(
         Id='staticv1',
         DomainName='cihackathon.s3.amazonaws.com',
         S3OriginConfig=cloudfront.S3Origin(),
     ),
 ],
 DefaultCacheBehavior=cloudfront.DefaultCacheBehavior(
     TargetOriginId="staticv1",
     ForwardedValues=cloudfront.ForwardedValues(
         QueryString=False,
     ),
     ViewerProtocolPolicy="allow-all",
     MinTTL=1,
     MaxTTL=60,
 ),
 CacheBehaviors=[
     cloudfront.CacheBehavior(
         TargetOriginId='apiv1',
         ForwardedValues=cloudfront.ForwardedValues(
             QueryString=True,
         ),
         ViewerProtocolPolicy="allow-all",
         MinTTL=1,
         MaxTTL=60,
         PathPattern='/api/v1/*',
예제 #9
0
    def get_distribution_options(self,
                                 bucket,  # type: s3.Bucket
                                 oai,  # type: cloudfront.CloudFrontOriginAccessIdentity
                                 lambda_funcs,  # type: List[cloudfront.LambdaFunctionAssociation]
                                 check_auth_lambda_version,  # type: awslambda.Version
                                 http_headers_lambda_version,  # type: awslambda.Version
                                 parse_auth_lambda_version,  # type: awslambda.Version
                                 refresh_auth_lambda_version,  # type: awslambda.Version
                                 sign_out_lambda_version  # type: awslambda.Version
                                ):  # noqa: E124
        # type: (...) -> Dict[str, Any]
        """Retrieve the options for our CloudFront distribution.

        Keyword Args:
            bucket (dict): The bucket resource
            oai (dict): The origin access identity resource

        Return:
            dict: The CloudFront Distribution Options

        """
        variables = self.get_variables()

        default_cache_behavior_lambdas = lambda_funcs
        default_cache_behavior_lambdas.append(
            cloudfront.LambdaFunctionAssociation(
                EventType='viewer-request',
                LambdaFunctionARN=check_auth_lambda_version.ref()
            )
        )
        default_cache_behavior_lambdas.append(
            cloudfront.LambdaFunctionAssociation(
                EventType='origin-response',
                LambdaFunctionARN=http_headers_lambda_version.ref()
            )
        )

        return {
            'Aliases': self.add_aliases(),
            'Origins': [
                cloudfront.Origin(
                    DomainName=Join(
                        '.',
                        [bucket.ref(),
                         's3.amazonaws.com']),
                    S3OriginConfig=cloudfront.S3OriginConfig(
                        OriginAccessIdentity=Join(
                            '',
                            ['origin-access-identity/cloudfront/',
                             oai.ref()])
                    ),
                    Id='protected-bucket'
                )
            ],
            'CacheBehaviors': [
                cloudfront.CacheBehavior(
                    PathPattern=variables['RedirectPathSignIn'],
                    Compress=True,
                    ForwardedValues=cloudfront.ForwardedValues(
                        QueryString=True
                    ),
                    LambdaFunctionAssociations=[
                        cloudfront.LambdaFunctionAssociation(
                            EventType='viewer-request',
                            LambdaFunctionARN=parse_auth_lambda_version.ref()
                        )
                    ],
                    TargetOriginId='protected-bucket',
                    ViewerProtocolPolicy="redirect-to-https"
                ),
                cloudfront.CacheBehavior(
                    PathPattern=variables['RedirectPathAuthRefresh'],
                    Compress=True,
                    ForwardedValues=cloudfront.ForwardedValues(
                        QueryString=True
                    ),
                    LambdaFunctionAssociations=[
                        cloudfront.LambdaFunctionAssociation(
                            EventType='viewer-request',
                            LambdaFunctionARN=refresh_auth_lambda_version.ref()
                        )
                    ],
                    TargetOriginId='protected-bucket',
                    ViewerProtocolPolicy="redirect-to-https"
                ),
                cloudfront.CacheBehavior(
                    PathPattern=variables['SignOutUrl'],
                    Compress=True,
                    ForwardedValues=cloudfront.ForwardedValues(
                        QueryString=True
                    ),
                    LambdaFunctionAssociations=[
                        cloudfront.LambdaFunctionAssociation(
                            EventType='viewer-request',
                            LambdaFunctionARN=sign_out_lambda_version.ref()
                        )
                    ],
                    TargetOriginId='protected-bucket',
                    ViewerProtocolPolicy="redirect-to-https"
                ),
            ],
            'DefaultCacheBehavior': cloudfront.DefaultCacheBehavior(
                AllowedMethods=['GET', 'HEAD'],
                Compress=True,
                DefaultTTL='86400',
                ForwardedValues=cloudfront.ForwardedValues(
                    QueryString=True,
                ),
                LambdaFunctionAssociations=default_cache_behavior_lambdas,
                TargetOriginId='protected-bucket',
                ViewerProtocolPolicy='redirect-to-https'
            ),
            'DefaultRootObject': 'index.html',
            'Logging': self.add_logging_bucket(),
            'PriceClass': variables['PriceClass'],
            'Enabled': True,
            'WebACLId': self.add_web_acl(),
            'CustomErrorResponses': self._get_error_responses(),
            'ViewerCertificate': self.add_acm_cert()
        }
예제 #10
0
    def create_template(self):
        """Create template (main function called by Stacker)."""
        template = self.template
        variables = self.get_variables()
        template.set_version('2010-09-09')
        template.set_description('Static Website - Bucket and Distribution')

        # Conditions
        template.add_condition(
            'AcmCertSpecified',
            And(Not(Equals(variables['AcmCertificateArn'].ref, '')),
                Not(Equals(variables['AcmCertificateArn'].ref, 'undefined')))
        )
        template.add_condition(
            'AliasesSpecified',
            And(Not(Equals(Select(0, variables['Aliases'].ref), '')),
                Not(Equals(Select(0, variables['Aliases'].ref), 'undefined')))
        )
        template.add_condition(
            'CFLoggingEnabled',
            And(Not(Equals(variables['LogBucketName'].ref, '')),
                Not(Equals(variables['LogBucketName'].ref, 'undefined')))
        )
        template.add_condition(
            'DirectoryIndexSpecified',
            And(Not(Equals(variables['RewriteDirectoryIndex'].ref, '')),
                Not(Equals(variables['RewriteDirectoryIndex'].ref, 'undefined')))  # noqa
        )
        template.add_condition(
            'WAFNameSpecified',
            And(Not(Equals(variables['WAFWebACL'].ref, '')),
                Not(Equals(variables['WAFWebACL'].ref, 'undefined')))
        )

        # Resources
        oai = template.add_resource(
            cloudfront.CloudFrontOriginAccessIdentity(
                'OAI',
                CloudFrontOriginAccessIdentityConfig=cloudfront.CloudFrontOriginAccessIdentityConfig(  # noqa pylint: disable=line-too-long
                    Comment='CF access to website'
                )
            )
        )

        bucket = template.add_resource(
            s3.Bucket(
                'Bucket',
                AccessControl=s3.Private,
                LifecycleConfiguration=s3.LifecycleConfiguration(
                    Rules=[
                        s3.LifecycleRule(
                            NoncurrentVersionExpirationInDays=90,
                            Status='Enabled'
                        )
                    ]
                ),
                VersioningConfiguration=s3.VersioningConfiguration(
                    Status='Enabled'
                ),
                WebsiteConfiguration=s3.WebsiteConfiguration(
                    IndexDocument='index.html',
                    ErrorDocument='error.html'
                )
            )
        )
        template.add_output(Output(
            'BucketName',
            Description='Name of website bucket',
            Value=bucket.ref()
        ))

        allowcfaccess = template.add_resource(
            s3.BucketPolicy(
                'AllowCFAccess',
                Bucket=bucket.ref(),
                PolicyDocument=PolicyDocument(
                    Version='2012-10-17',
                    Statement=[
                        Statement(
                            Action=[awacs.s3.GetObject],
                            Effect=Allow,
                            Principal=Principal(
                                'CanonicalUser',
                                oai.get_att('S3CanonicalUserId')
                            ),
                            Resource=[
                                Join('', [bucket.get_att('Arn'),
                                          '/*'])
                            ]
                        )
                    ]
                )
            )
        )

        cfdirectoryindexrewriterole = template.add_resource(
            iam.Role(
                'CFDirectoryIndexRewriteRole',
                Condition='DirectoryIndexSpecified',
                AssumeRolePolicyDocument=PolicyDocument(
                    Version='2012-10-17',
                    Statement=[
                        Statement(
                            Effect=Allow,
                            Action=[awacs.sts.AssumeRole],
                            Principal=Principal('Service',
                                                ['lambda.amazonaws.com',
                                                 'edgelambda.amazonaws.com'])
                        )
                    ]
                ),
                ManagedPolicyArns=[
                    IAM_ARN_PREFIX + 'AWSLambdaBasicExecutionRole'
                ]
            )
        )

        cfdirectoryindexrewrite = template.add_resource(
            awslambda.Function(
                'CFDirectoryIndexRewrite',
                Condition='DirectoryIndexSpecified',
                Code=awslambda.Code(
                    ZipFile=Join(
                        '',
                        ["'use strict';\n",
                         "exports.handler = (event, context, callback) => {\n",
                         "\n",
                         "    // Extract the request from the CloudFront event that is sent to Lambda@Edge\n",  # noqa pylint: disable=line-too-long
                         "    var request = event.Records[0].cf.request;\n",
                         "    // Extract the URI from the request\n",
                         "    var olduri = request.uri;\n",
                         "    // Match any '/' that occurs at the end of a URI. Replace it with a default index\n",  # noqa pylint: disable=line-too-long
                         "    var newuri = olduri.replace(/\\/$/, '\\/",
                         variables['RewriteDirectoryIndex'].ref,
                         "');\n",  # noqa
                         "    // Log the URI as received by CloudFront and the new URI to be used to fetch from origin\n",  # noqa pylint: disable=line-too-long
                         "    console.log(\"Old URI: \" + olduri);\n",
                         "    console.log(\"New URI: \" + newuri);\n",
                         "    // Replace the received URI with the URI that includes the index page\n",  # noqa pylint: disable=line-too-long
                         "    request.uri = newuri;\n",
                         "    // Return to CloudFront\n",
                         "    return callback(null, request);\n",
                         "\n",
                         "};\n"]
                    )
                ),
                Description='Rewrites CF directory HTTP requests to default page',  # noqa
                Handler='index.handler',
                Role=cfdirectoryindexrewriterole.get_att('Arn'),
                Runtime='nodejs8.10'
            )
        )

        # Generating a unique resource name here for the Lambda version, so it
        # updates automatically if the lambda code changes
        code_hash = hashlib.md5(
            str(cfdirectoryindexrewrite.properties['Code'].properties['ZipFile'].to_dict()).encode()  # noqa pylint: disable=line-too-long
        ).hexdigest()

        cfdirectoryindexrewritever = template.add_resource(
            awslambda.Version(
                'CFDirectoryIndexRewriteVer' + code_hash,
                Condition='DirectoryIndexSpecified',
                FunctionName=cfdirectoryindexrewrite.ref()
            )
        )

        # If custom associations defined, use them
        if variables['lambda_function_associations']:
            lambda_function_associations = [
                cloudfront.LambdaFunctionAssociation(
                    EventType=x['type'],
                    LambdaFunctionARN=x['arn']
                ) for x in variables['lambda_function_associations']
            ]
        else:  # otherwise fallback to pure CFN condition
            lambda_function_associations = If(
                'DirectoryIndexSpecified',
                [cloudfront.LambdaFunctionAssociation(
                    EventType='origin-request',
                    LambdaFunctionARN=cfdirectoryindexrewritever.ref()
                )],
                NoValue
            )

        cfdistribution = template.add_resource(
            get_cf_distribution_class()(
                'CFDistribution',
                DependsOn=allowcfaccess.title,
                DistributionConfig=get_cf_distro_conf_class()(
                    Aliases=If(
                        'AliasesSpecified',
                        variables['Aliases'].ref,
                        NoValue
                    ),
                    Origins=[
                        get_cf_origin_class()(
                            DomainName=Join(
                                '.',
                                [bucket.ref(),
                                 's3.amazonaws.com']),
                            S3OriginConfig=get_s3_origin_conf_class()(
                                OriginAccessIdentity=Join(
                                    '',
                                    ['origin-access-identity/cloudfront/',
                                     oai.ref()])
                            ),
                            Id='S3Origin'
                        )
                    ],
                    DefaultCacheBehavior=cloudfront.DefaultCacheBehavior(
                        AllowedMethods=['GET', 'HEAD'],
                        Compress=False,
                        DefaultTTL='86400',
                        ForwardedValues=cloudfront.ForwardedValues(
                            Cookies=cloudfront.Cookies(Forward='none'),
                            QueryString=False,
                        ),
                        LambdaFunctionAssociations=lambda_function_associations,  # noqa
                        TargetOriginId='S3Origin',
                        ViewerProtocolPolicy='redirect-to-https'
                    ),
                    DefaultRootObject='index.html',
                    Logging=If(
                        'CFLoggingEnabled',
                        cloudfront.Logging(
                            Bucket=Join('.',
                                        [variables['LogBucketName'].ref,
                                         's3.amazonaws.com'])
                        ),
                        NoValue
                    ),
                    PriceClass=variables['PriceClass'].ref,
                    Enabled=True,
                    WebACLId=If(
                        'WAFNameSpecified',
                        variables['WAFWebACL'].ref,
                        NoValue
                    ),
                    ViewerCertificate=If(
                        'AcmCertSpecified',
                        cloudfront.ViewerCertificate(
                            AcmCertificateArn=variables['AcmCertificateArn'].ref,  # noqa
                            SslSupportMethod='sni-only'
                        ),
                        NoValue
                    )
                )
            )
        )
        template.add_output(Output(
            'CFDistributionId',
            Description='CloudFront distribution ID',
            Value=cfdistribution.ref()
        ))
        template.add_output(
            Output(
                'CFDistributionDomainName',
                Description='CloudFront distribution domain name',
                Value=cfdistribution.get_att('DomainName')
            )
        )
예제 #11
0
                # has the Lambda-function associated.
            ],
            DefaultCacheBehavior=cloudfront.DefaultCacheBehavior(
                ViewerProtocolPolicy=
                'redirect-to-https',  # HTTPS required. Cookies need to be sent securely
                LambdaFunctionAssociations=[
                    cloudfront.LambdaFunctionAssociation(
                        EventType='viewer-request',
                        LambdaFunctionARN=Ref(param_authorizer_lae_arn)),
                ],
                # Rest of config as per your needs
                TargetOriginId='ExampleS3',
                ForwardedValues=cloudfront.ForwardedValues(
                    QueryString=True,
                    Cookies=cloudfront.Cookies(
                        Forward=
                        'all',  # Don't do this. Done here to validate cookie-removal logic
                    ),
                ),
            ),
            ViewerCertificate=cloudfront.ViewerCertificate(
                AcmCertificateArn=Ref(acm_cert),
                SslSupportMethod='sni-only',
            ),
        ),
        Tags=GetAtt(cloudformation_tags, 'TagList'),
    ))

hosted_zone_map = "HostedZoneMap"
template.add_mapping(hosted_zone_map, cfnutils.mappings.r53_hosted_zone_id())
예제 #12
0
    def create_template(self):
        """Create template (main function called by Stacker)."""
        template = self.template
        variables = self.get_variables()
        template.add_version('2010-09-09')
        template.add_description('Static Website - Bucket and Distribution')

        # Conditions
        template.add_condition(
            'AcmCertSpecified',
            And(Not(Equals(variables['AcmCertificateArn'].ref, '')),
                Not(Equals(variables['AcmCertificateArn'].ref, 'undefined'))))
        template.add_condition(
            'AliasesSpecified',
            And(Not(Equals(Select(0, variables['Aliases'].ref), '')),
                Not(Equals(Select(0, variables['Aliases'].ref), 'undefined'))))
        template.add_condition(
            'CFLoggingEnabled',
            And(Not(Equals(variables['LogBucketName'].ref, '')),
                Not(Equals(variables['LogBucketName'].ref, 'undefined'))))
        template.add_condition(
            'WAFNameSpecified',
            And(Not(Equals(variables['WAFWebACL'].ref, '')),
                Not(Equals(variables['WAFWebACL'].ref, 'undefined'))))

        # Resources
        oai = template.add_resource(
            cloudfront.CloudFrontOriginAccessIdentity(
                'OAI',
                CloudFrontOriginAccessIdentityConfig=cloudfront.
                CloudFrontOriginAccessIdentityConfig(  # noqa pylint: disable=line-too-long
                    Comment='CF access to website')))

        bucket = template.add_resource(
            s3.Bucket(
                'Bucket',
                AccessControl=s3.Private,
                LifecycleConfiguration=s3.LifecycleConfiguration(Rules=[
                    s3.LifecycleRule(NoncurrentVersionExpirationInDays=90,
                                     Status='Enabled')
                ]),
                VersioningConfiguration=s3.VersioningConfiguration(
                    Status='Enabled'),
                WebsiteConfiguration=s3.WebsiteConfiguration(
                    IndexDocument='index.html', ErrorDocument='error.html')))
        template.add_output(
            Output('BucketName',
                   Description='Name of website bucket',
                   Value=bucket.ref()))

        allowcfaccess = template.add_resource(
            s3.BucketPolicy(
                'AllowCFAccess',
                Bucket=bucket.ref(),
                PolicyDocument=Policy(
                    Version='2012-10-17',
                    Statement=[
                        Statement(
                            Action=[awacs.s3.GetObject],
                            Effect=Allow,
                            Principal=Principal(
                                'CanonicalUser',
                                oai.get_att('S3CanonicalUserId')),
                            Resource=[Join('', [bucket.get_att('Arn'), '/*'])])
                    ])))

        cfdistribution = template.add_resource(
            cloudfront.Distribution(
                'CFDistribution',
                DependsOn=allowcfaccess.title,
                DistributionConfig=cloudfront.DistributionConfig(
                    Aliases=If('AliasesSpecified', variables['Aliases'].ref,
                               NoValue),
                    Origins=[
                        cloudfront.Origin(
                            DomainName=Join(
                                '.', [bucket.ref(), 's3.amazonaws.com']),
                            S3OriginConfig=cloudfront.S3Origin(
                                OriginAccessIdentity=Join(
                                    '', [
                                        'origin-access-identity/cloudfront/',
                                        oai.ref()
                                    ])),
                            Id='S3Origin')
                    ],
                    DefaultCacheBehavior=cloudfront.DefaultCacheBehavior(
                        AllowedMethods=['GET', 'HEAD'],
                        Compress=False,
                        DefaultTTL='86400',
                        ForwardedValues=cloudfront.ForwardedValues(
                            Cookies=cloudfront.Cookies(Forward='none'),
                            QueryString=False,
                        ),
                        TargetOriginId='S3Origin',
                        ViewerProtocolPolicy='redirect-to-https'),
                    DefaultRootObject='index.html',
                    Logging=If(
                        'CFLoggingEnabled',
                        cloudfront.Logging(Bucket=Join('.', [
                            variables['LogBucketName'].ref, 's3.amazonaws.com'
                        ])), NoValue),
                    PriceClass=variables['PriceClass'].ref,
                    Enabled=True,
                    WebACLId=If('WAFNameSpecified', variables['WAFWebACL'].ref,
                                NoValue),
                    ViewerCertificate=If(
                        'AcmCertSpecified',
                        cloudfront.ViewerCertificate(
                            AcmCertificateArn=variables['AcmCertificateArn'].
                            ref,  # noqa
                            SslSupportMethod='sni-only'),
                        NoValue))))
        template.add_output(
            Output('CFDistributionId',
                   Description='CloudFront distribution ID',
                   Value=cfdistribution.ref()))
        template.add_output(
            Output('CFDistributionDomainName',
                   Description='CloudFront distribution domain name',
                   Value=cfdistribution.get_att('DomainName')))
예제 #13
0
    def __init__(self, title, key, **kwargs):
        super().__init__(title, **kwargs)

        name = self.title
        if 'AllowedMethods' in key:
            self.AllowedMethods = get_endvalue(f'{name}AllowedMethods')

        if 'CachedMethods' in key:
            self.CachedMethods = get_endvalue(f'{name}CachedMethods')

        # If not defined default to True
        if 'Compress' in key:
            self.Compress = get_endvalue(f'{name}Compress')
        else:
            self.Compress = True

        if 'DefaultTTL' in key:
            self.DefaultTTL = get_endvalue(f'{name}DefaultTTL')

        self.ForwardedValues = clf.ForwardedValues()
        # If not defined default to True
        if 'QueryString' in key:
            self.ForwardedValues.QueryString = get_endvalue(
                f'{name}QueryString')
        else:
            self.ForwardedValues.QueryString = True

        if 'CookiesForward' in key:
            self.ForwardedValues.Cookies = clf.Cookies(
                Forward=get_endvalue(f'{name}CookiesForward'))
            if 'CookiesWhitelistedNames' in key:
                self.ForwardedValues.Cookies.WhitelistedNames = (get_endvalue(
                    f'{name}CookiesWhitelistedNames', condition=True))
                # conditions
                c_CookiesForward = get_condition(
                    f'{name}CookiesWhitelistedNames', 'equals', 'whitelist',
                    f'{name}CookiesForward')

                add_obj(c_CookiesForward)

        # If not defined default to 'Host'
        if 'Headers' in key:
            self.ForwardedValues.Headers = get_endvalue(f'{name}Headers')
        else:
            self.ForwardedValues.Headers = ['Host']

        if 'QueryStringCacheKeys' in key:
            self.ForwardedValues.QueryStringCacheKeys = get_endvalue(
                f'{name}QueryStringCacheKeys', condition=True)
            # conditions
            c_QueryString = get_condition(f'{name}QueryStringCacheKeys',
                                          'equals', True, f'{name}QueryString')

            add_obj(c_QueryString)

        if 'TargetOriginId' in key:
            self.TargetOriginId = get_endvalue(f'{name}TargetOriginId')
        else:
            self.TargetOriginId = If(
                'CloudFrontOriginAdHoc', Ref('RecordSetExternal'),
                Sub('${EnvRole}${RecordSetCloudFrontSuffix}.origin.%s' %
                    cfg.HostedZoneNameEnv))

        if 'MaxTTL' in key:
            self.MaxTTL = get_endvalue(f'{name}MaxTTL')

        if 'MinTTL' in key:
            self.MinTTL = get_endvalue(f'{name}MinTTL')

        if 'LambdaFunctionARN' in key:
            condname = f'{name}LambdaFunctionARN'
            eventType = 'origin-request'
            if 'LambdaEventType' in key:
                eventType = key['LambdaEventType']
            # conditions
            add_obj(get_condition(condname, 'not_equals', 'None'))

            self.LambdaFunctionAssociations = [
                If(
                    condname,
                    clf.LambdaFunctionAssociation(
                        EventType=eventType,
                        LambdaFunctionARN=get_endvalue(condname)),
                    Ref('AWS::NoValue'))
            ]

        if 'ViewerProtocolPolicy' in key:
            self.ViewerProtocolPolicy = get_endvalue(
                f'{name}ViewerProtocolPolicy')
        else:
            self.ViewerProtocolPolicy = 'redirect-to-https'
예제 #14
0
    def get_cloudfront_distribution_options(
        self,  # type: StaticSite
        bucket,  # type: s3.Bucket
        oai,  # type: cloudfront.CloudFrontOriginAccessIdentity # noqa pylint: disable=line-too-long
        lambda_function_associations  # type: List[cloudfront.LambdaFunctionAssociation] # noqa pylint: disable=line-too-long
        # TODO remove after dropping python 2
    ):  # pylint: disable=bad-continuation
        # type: (...) -> Dict[str, Any]
        """Retrieve the options for our CloudFront distribution.

        Keyword Args:
            bucket (dict): The bucket resource
            oai (dict): The origin access identity resource
            lambda_function_associations (array): The lambda function association array

        Return:
            dict: The CloudFront Distribution Options

        """
        variables = self.get_variables()
        return {
            'Aliases':
            self.add_aliases(),
            'Origins': [
                cloudfront.Origin(
                    DomainName=Join('.', [bucket.ref(), 's3.amazonaws.com']),
                    S3OriginConfig=cloudfront.
                    S3OriginConfig(OriginAccessIdentity=Join(
                        '', ['origin-access-identity/cloudfront/',
                             oai.ref()])),
                    Id='S3Origin')
            ],
            'DefaultCacheBehavior':
            cloudfront.DefaultCacheBehavior(
                AllowedMethods=['GET', 'HEAD'],
                Compress=False,
                DefaultTTL='86400',
                ForwardedValues=cloudfront.ForwardedValues(
                    Cookies=cloudfront.Cookies(Forward='none'),
                    QueryString=False,
                ),
                LambdaFunctionAssociations=lambda_function_associations,
                TargetOriginId='S3Origin',
                ViewerProtocolPolicy='redirect-to-https'),
            'DefaultRootObject':
            'index.html',
            'Logging':
            self.add_logging_bucket(),
            'PriceClass':
            variables['PriceClass'],
            'CustomErrorResponses': [
                cloudfront.CustomErrorResponse(
                    ErrorCode=response['ErrorCode'],
                    ResponseCode=response['ResponseCode'],
                    ResponsePagePath=response['ResponsePagePath'])
                for response in variables['custom_error_responses']
            ],
            'Enabled':
            True,
            'WebACLId':
            self.add_web_acl(),
            'ViewerCertificate':
            self.add_acm_cert()
        }
예제 #15
0
                        }]
                    }))

cdn = template.add_resource(
    cloudfront.Distribution(
        'WebsiteDistribution',
        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(
예제 #16
0
    def get_cloudfront_distribution_options(
            self,
            bucket,  # type: s3.Bucket
            oai,  # type: cloudfront.CloudFrontOriginAccessIdentity
            lambda_function_associations,  # type: List[cloudfront.LambdaFunctionAssociation]
    ):
        # type: (...) -> Dict[str, Any]
        """Retrieve the options for our CloudFront distribution.

        Args:
            bucket: The bucket resource
            oai: The origin access identity resource.
            lambda_function_associations: List of Lambda Function associations.

        Return:
            The CloudFront Distribution Options.

        """
        variables = self.get_variables()
        return {
            "Aliases":
            self.add_aliases(),
            "Origins": [
                cloudfront.Origin(
                    DomainName=Join(".", [bucket.ref(), "s3.amazonaws.com"]),
                    S3OriginConfig=cloudfront.
                    S3OriginConfig(OriginAccessIdentity=Join(
                        "", ["origin-access-identity/cloudfront/",
                             oai.ref()])),
                    Id="S3Origin",
                )
            ],
            "DefaultCacheBehavior":
            cloudfront.DefaultCacheBehavior(
                AllowedMethods=["GET", "HEAD"],
                Compress=False,
                DefaultTTL="86400",
                ForwardedValues=cloudfront.ForwardedValues(
                    Cookies=cloudfront.Cookies(Forward="none"),
                    QueryString=False,
                ),
                LambdaFunctionAssociations=lambda_function_associations,
                TargetOriginId="S3Origin",
                ViewerProtocolPolicy="redirect-to-https",
            ),
            "DefaultRootObject":
            "index.html",
            "Logging":
            self.add_logging_bucket(),
            "PriceClass":
            variables["PriceClass"],
            "CustomErrorResponses": [
                cloudfront.CustomErrorResponse(
                    ErrorCode=response["ErrorCode"],
                    ResponseCode=response["ResponseCode"],
                    ResponsePagePath=response["ResponsePagePath"],
                ) for response in variables["custom_error_responses"]
            ],
            "Enabled":
            True,
            "WebACLId":
            self.add_web_acl(),
            "ViewerCertificate":
            self.add_acm_cert(),
        }
예제 #17
0
        Default='/media/*',
        Description='Specify which requests you want to route to the origin.',
        Type='String'))
# endregion

# region Resources
distribution = template.add_resource(
    cloudfront.Distribution(
        'Distribution',
        DistributionConfig=cloudfront.DistributionConfig(
            Aliases=[Ref(domain)],
            CacheBehaviors=[
                cloudfront.CacheBehavior(
                    Compress=True,
                    ForwardedValues=cloudfront.ForwardedValues(
                        Cookies=cloudfront.Cookies(Forward='none'),
                        QueryString=False,
                    ),
                    PathPattern=Ref(media_pattern),
                    TargetOriginId=Sub(
                        '${domain}${path}', **{
                            'domain': Ref(media_domain),
                            'path': Ref(media_path)
                        }),
                    ViewerProtocolPolicy='redirect-to-https',
                )
            ],
            Comment=Sub('${AWS::StackName}'),
            DefaultCacheBehavior=cloudfront.DefaultCacheBehavior(
                Compress=True,
                ForwardedValues=cloudfront.ForwardedValues(
                    Cookies=cloudfront.Cookies(Forward='none'),
예제 #18
0
    def get_distribution_options(
        self,
        bucket: s3.Bucket,
        oai: cloudfront.CloudFrontOriginAccessIdentity,
        lambda_funcs: List[cloudfront.LambdaFunctionAssociation],
        check_auth_lambda_version: awslambda.Version,
        http_headers_lambda_version: awslambda.Version,
        parse_auth_lambda_version: awslambda.Version,
        refresh_auth_lambda_version: awslambda.Version,
        sign_out_lambda_version: awslambda.Version,
    ) -> Dict[str, Any]:
        """Retrieve the options for our CloudFront distribution.

        Keyword Args:
            bucket: The bucket resource.
            oai: The origin access identity resource.
            lambda_funcs: List of Lambda Function associations.
            check_auth_lambda_version: Lambda Function Version to use.
            http_headers_lambda_version: Lambda Function Version to use.
            parse_auth_lambda_version: Lambda Function Version to use.
            refresh_auth_lambda_version: Lambda Function Version to use.
            sign_out_lambda_version: Lambda Function Version to use.

        Return:
            The CloudFront Distribution Options.

        """
        default_cache_behavior_lambdas = lambda_funcs
        default_cache_behavior_lambdas.append(
            cloudfront.LambdaFunctionAssociation(
                EventType="viewer-request",
                LambdaFunctionARN=check_auth_lambda_version.ref(),
            ))
        default_cache_behavior_lambdas.append(
            cloudfront.LambdaFunctionAssociation(
                EventType="origin-response",
                LambdaFunctionARN=http_headers_lambda_version.ref(),
            ))

        return {
            "Aliases":
            self.add_aliases(),
            "Origins": [
                cloudfront.Origin(
                    DomainName=Join(".", [bucket.ref(), "s3.amazonaws.com"]),
                    S3OriginConfig=cloudfront.
                    S3OriginConfig(OriginAccessIdentity=Join(
                        "", ["origin-access-identity/cloudfront/",
                             oai.ref()])),
                    Id="protected-bucket",
                )
            ],
            "CacheBehaviors": [
                cloudfront.CacheBehavior(
                    PathPattern=self.variables["RedirectPathSignIn"],
                    Compress=True,
                    ForwardedValues=cloudfront.ForwardedValues(
                        QueryString=True),
                    LambdaFunctionAssociations=[
                        cloudfront.LambdaFunctionAssociation(
                            EventType="viewer-request",
                            LambdaFunctionARN=parse_auth_lambda_version.ref(),
                        )
                    ],
                    TargetOriginId="protected-bucket",
                    ViewerProtocolPolicy="redirect-to-https",
                ),
                cloudfront.CacheBehavior(
                    PathPattern=self.variables["RedirectPathAuthRefresh"],
                    Compress=True,
                    ForwardedValues=cloudfront.ForwardedValues(
                        QueryString=True),
                    LambdaFunctionAssociations=[
                        cloudfront.LambdaFunctionAssociation(
                            EventType="viewer-request",
                            LambdaFunctionARN=refresh_auth_lambda_version.ref(
                            ),
                        )
                    ],
                    TargetOriginId="protected-bucket",
                    ViewerProtocolPolicy="redirect-to-https",
                ),
                cloudfront.CacheBehavior(
                    PathPattern=self.variables["SignOutUrl"],
                    Compress=True,
                    ForwardedValues=cloudfront.ForwardedValues(
                        QueryString=True),
                    LambdaFunctionAssociations=[
                        cloudfront.LambdaFunctionAssociation(
                            EventType="viewer-request",
                            LambdaFunctionARN=sign_out_lambda_version.ref(),
                        )
                    ],
                    TargetOriginId="protected-bucket",
                    ViewerProtocolPolicy="redirect-to-https",
                ),
            ],
            "DefaultCacheBehavior":
            cloudfront.DefaultCacheBehavior(
                AllowedMethods=["GET", "HEAD"],
                Compress=True,
                DefaultTTL="86400",
                ForwardedValues=cloudfront.ForwardedValues(QueryString=True),
                LambdaFunctionAssociations=default_cache_behavior_lambdas,
                TargetOriginId="protected-bucket",
                ViewerProtocolPolicy="redirect-to-https",
            ),
            "DefaultRootObject":
            "index.html",
            "Logging":
            self.add_logging_bucket(),
            "PriceClass":
            self.variables["PriceClass"],
            "Enabled":
            True,
            "WebACLId":
            self.add_web_acl(),
            "CustomErrorResponses":
            self._get_error_responses(),
            "ViewerCertificate":
            self.add_acm_cert(),
        }
예제 #19
0
    def create_cloudfront_distributions(self):
        blue_tile_distribution = self.add_resource(
            cf.Distribution(
                'tileDistributionBlue',
                DistributionConfig=cf.DistributionConfig(
                    Origins=[
                        cf.Origin(Id='tileOriginId',
                                  DomainName=Join('.', [
                                      'blue-tiles',
                                      Ref(self.public_hosted_zone_name)
                                  ]),
                                  CustomOriginConfig=cf.CustomOrigin(
                                      OriginProtocolPolicy='http-only'))
                    ],
                    DefaultCacheBehavior=cf.DefaultCacheBehavior(
                        ForwardedValues=cf.ForwardedValues(QueryString=True),
                        TargetOriginId='tileOriginId',
                        ViewerProtocolPolicy='allow-all'),
                    Enabled=True)))

        self.add_resource(
            cw.Alarm('alarmTileDistributionBlueOrigin4XX',
                     AlarmDescription='Tile distribution origin 4XXs',
                     AlarmActions=[Ref(self.notification_topic_arn)],
                     Statistic='Average',
                     Period=300,
                     Threshold='20',
                     EvaluationPeriods=1,
                     ComparisonOperator='GreaterThanThreshold',
                     MetricName='4xxErrorRate',
                     Namespace='AWS/CloudFront',
                     Dimensions=[
                         cw.MetricDimension('metricDistributionId',
                                            Name='DistributionId',
                                            Value=Ref(blue_tile_distribution)),
                         cw.MetricDimension('metricRegion',
                                            Name='Region',
                                            Value='Global')
                     ]))

        self.add_resource(
            cw.Alarm('alarmTileDistributionBlueOrigin5XX',
                     AlarmDescription='Tile distribution origin 5XXs',
                     AlarmActions=[Ref(self.notification_topic_arn)],
                     Statistic='Average',
                     Period=60,
                     Threshold='0',
                     EvaluationPeriods=1,
                     ComparisonOperator='GreaterThanThreshold',
                     MetricName='5xxErrorRate',
                     Namespace='AWS/CloudFront',
                     Dimensions=[
                         cw.MetricDimension('metricDistributionId',
                                            Name='DistributionId',
                                            Value=Ref(blue_tile_distribution)),
                         cw.MetricDimension('metricRegion',
                                            Name='Region',
                                            Value='Global')
                     ]))

        green_tile_distribution = self.add_resource(
            cf.Distribution(
                'tileDistributionGreen',
                DistributionConfig=cf.DistributionConfig(
                    Origins=[
                        cf.Origin(Id='tileOriginId',
                                  DomainName=Join('.', [
                                      'green-tiles',
                                      Ref(self.public_hosted_zone_name)
                                  ]),
                                  CustomOriginConfig=cf.CustomOrigin(
                                      OriginProtocolPolicy='http-only'))
                    ],
                    DefaultCacheBehavior=cf.DefaultCacheBehavior(
                        ForwardedValues=cf.ForwardedValues(QueryString=True),
                        TargetOriginId='tileOriginId',
                        ViewerProtocolPolicy='allow-all'),
                    Enabled=True)))

        self.add_resource(
            cw.Alarm('alarmTileDistributionGreenOrigin4XX',
                     AlarmDescription='Tile distribution origin 4XXs',
                     AlarmActions=[Ref(self.notification_topic_arn)],
                     Statistic='Average',
                     Period=300,
                     Threshold='20',
                     EvaluationPeriods=1,
                     ComparisonOperator='GreaterThanThreshold',
                     MetricName='4xxErrorRate',
                     Namespace='AWS/CloudFront',
                     Dimensions=[
                         cw.MetricDimension(
                             'metricDistributionId',
                             Name='DistributionId',
                             Value=Ref(green_tile_distribution)),
                         cw.MetricDimension('metricRegion',
                                            Name='Region',
                                            Value='Global')
                     ]))

        self.add_resource(
            cw.Alarm('alarmTileDistributionGreenOrigin5XX',
                     AlarmDescription='Tile distribution origin 5XXs',
                     AlarmActions=[Ref(self.notification_topic_arn)],
                     Statistic='Average',
                     Period=60,
                     Threshold='0',
                     EvaluationPeriods=1,
                     ComparisonOperator='GreaterThanThreshold',
                     MetricName='5xxErrorRate',
                     Namespace='AWS/CloudFront',
                     Dimensions=[
                         cw.MetricDimension(
                             'metricDistributionId',
                             Name='DistributionId',
                             Value=Ref(green_tile_distribution)),
                         cw.MetricDimension('metricRegion',
                                            Name='Region',
                                            Value='Global')
                     ]))

        return blue_tile_distribution, green_tile_distribution
    def cloudfront_distribution(self):
        if self.vars["AcmCertificateARN"]:
            viewer_certificate = cf.ViewerCertificate(
                SslSupportMethod="sni-only",
                MinimumProtocolVersion="TLSv1",
                AcmCertificateArn=self.vars["AcmCertificateARN"],
            )
            url_prefix = 'https://'
        else:
            viewer_certificate = NoValue
            url_prefix = 'http://'

        t = self.template
        self.SiteCFDistribution = t.add_resource(
            cf.Distribution(
                "SiteCFDistribution",
                DistributionConfig=cf.DistributionConfig(
                    Comment="S3 Distribution",
                    Logging=cf.Logging(
                        Prefix=self.vars["FQDNPublic"] + "/cloudfront_logs/",
                        Bucket=self.vars["LogBucket"] + ".s3.amazonaws.com",
                        IncludeCookies="false"),
                    WebACLId=self.vars["WebACLId"],
                    Origins=[
                        cf.Origin(
                            S3OriginConfig=cf.S3Origin(OriginAccessIdentity=(
                                "origin-access-identity/cloudfront/" +
                                self.vars["OriginAccessIdentity"]), ),
                            Id="myS3Origin",
                            DomainName=GetAtt(self.SiteBucket, "DomainName"),
                            OriginPath=self.vars["OriginPath"],
                        )
                    ],
                    DefaultRootObject=self.vars["DefaultRootObject"],
                    PriceClass="PriceClass_100",
                    Enabled="true",
                    DefaultCacheBehavior=cf.DefaultCacheBehavior(
                        ViewerProtocolPolicy="redirect-to-https",
                        ForwardedValues=cf.ForwardedValues(
                            Cookies=cf.Cookies(Forward="none"),
                            QueryString="true"),
                        TargetOriginId="myS3Origin",
                        DefaultTTL=self.vars["DefaultTTL"],
                    ),
                    Aliases=[self.vars["FQDNPublic"]],
                    ViewerCertificate=viewer_certificate,
                ),
            ))

        CloudFrontDistribution = t.add_output(
            Output(
                "CloudFrontDistribution",
                Description="Cloudfront distribution domainname in AWS",
                Value=GetAtt(self.SiteCFDistribution, "DomainName"),
            ))
        WebsiteURL = t.add_output(
            Output(
                "WebsiteURL",
                Description="Public URL of cloudfront hosted website",
                Value=url_prefix + self.vars["FQDNPublic"],
            ))
예제 #21
0
파일: trop.py 프로젝트: swipswaps/builder
def render_cloudfront(context, template, origin_hostname):
    if not context['cloudfront']['origins']:
        ensure(
            context['full_hostname'],
            "A public hostname is required to be pointed at by the Cloudfront CDN"
        )

    allowed_cnames = context['cloudfront']['subdomains'] + context[
        'cloudfront']['subdomains-without-dns']

    def _cookies(cookies):
        if cookies:
            return cloudfront.Cookies(Forward='whitelist',
                                      WhitelistedNames=cookies)
        return cloudfront.Cookies(Forward='none')

    if context['cloudfront']['origins']:
        origins = [
            cloudfront.Origin(DomainName=o['hostname'],
                              Id=o_id,
                              CustomOriginConfig=cloudfront.CustomOrigin(
                                  HTTPSPort=443,
                                  OriginProtocolPolicy='https-only'))
            for o_id, o in context['cloudfront']['origins'].items()
        ]
        origin = origins[0].Id
    else:
        origin = CLOUDFRONT_TITLE + 'Origin'
        origins = [
            cloudfront.Origin(DomainName=origin_hostname,
                              Id=origin,
                              CustomOriginConfig=cloudfront.CustomOrigin(
                                  HTTPSPort=443,
                                  OriginProtocolPolicy='https-only'))
        ]
    props = {
        'Aliases':
        allowed_cnames,
        'CacheBehaviors': [],
        'DefaultCacheBehavior':
        cloudfront.DefaultCacheBehavior(
            AllowedMethods=[
                'DELETE', 'GET', 'HEAD', 'OPTIONS', 'PATCH', 'POST', 'PUT'
            ],
            CachedMethods=['GET', 'HEAD'],
            Compress=context['cloudfront']['compress'],
            DefaultTTL=context['cloudfront']['default-ttl'],
            TargetOriginId=origin,
            ForwardedValues=cloudfront.ForwardedValues(
                Cookies=_cookies(context['cloudfront']['cookies']),
                Headers=context['cloudfront']
                ['headers'],  # 'whitelisted' headers
                QueryString=True),
            ViewerProtocolPolicy='redirect-to-https',
        ),
        'Enabled':
        True,
        'HttpVersion':
        'http2',
        'Origins':
        origins,
        'ViewerCertificate':
        cloudfront.ViewerCertificate(
            IamCertificateId=context['cloudfront']['certificate_id'],
            SslSupportMethod='sni-only')
    }

    def _cache_behavior(origin_id, pattern, headers=None, cookies=None):
        return cloudfront.CacheBehavior(
            TargetOriginId=origin_id,
            DefaultTTL=context['cloudfront']['default-ttl'],
            ForwardedValues=cloudfront.ForwardedValues(
                Cookies=_cookies(cookies),
                QueryString=False,
                Headers=headers if headers else []),
            PathPattern=pattern,
            ViewerProtocolPolicy='allow-all',
        )

    if context['cloudfront']['errors']:
        props['Origins'].append(
            cloudfront.Origin(
                DomainName=context['cloudfront']['errors']['domain'],
                # TODO: constant
                Id=CLOUDFRONT_ERROR_ORIGIN_ID,
                # no advantage in using cloudfront.S3Origin for public buckets
                CustomOriginConfig=cloudfront.CustomOrigin(
                    HTTPSPort=443,
                    OriginProtocolPolicy='https-only'
                    if context['cloudfront']['errors']['protocol'] == 'https'
                    else 'http-only')))
        props['CacheBehaviors'].append(
            _cache_behavior(
                CLOUDFRONT_ERROR_ORIGIN_ID,
                context['cloudfront']['errors']['pattern'],
            ))
        props['CustomErrorResponses'] = [
            cloudfront.CustomErrorResponse(ErrorCode=code,
                                           ResponseCode=code,
                                           ResponsePagePath=page)
            for code, page in context['cloudfront']['errors']['codes'].items()
        ]

    if context['cloudfront']['logging']:
        props['Logging'] = cloudfront.Logging(
            Bucket="%s.s3.amazonaws.com" %
            context['cloudfront']['logging']['bucket'],
            Prefix="%s/" % context['stackname'])

    if context['cloudfront']['origins']:
        props['CacheBehaviors'].extend([
            _cache_behavior(o_id,
                            o['pattern'],
                            headers=o['headers'],
                            cookies=o['cookies'])
            for o_id, o in context['cloudfront']['origins'].items()
            if o['pattern']
        ])

    template.add_resource(
        cloudfront.Distribution(
            CLOUDFRONT_TITLE,
            DistributionConfig=cloudfront.DistributionConfig(**props)))

    for dns in external_dns_cloudfront(context):
        template.add_resource(dns)
예제 #22
0
 CacheBehaviors=[
     cloudfront.CacheBehavior(
         # The authorizer hijacks a set of URL-paths from your website. All paths are prefixed
         # with `/auth-<UUID>/`, so they are very unlikely to collide with your content.
         # Insert this as the first Behaviour.
         PathPattern=Join('', [
             ImportValue(
                 Sub('${' + authorizer_stack.title +
                     '}-magic-path')),
             '/*',
         ]),
         ViewerProtocolPolicy='https-only',
         TargetOriginId='Authorizer',
         ForwardedValues=cloudfront.ForwardedValues(
             QueryString=True,
             Cookies=cloudfront.Cookies(
                 Forward='all',  # Needed to allow Set-Cookie:-headers
             ),
         ),
         MinTTL=0,
         DefaultTTL=0,
         MaxTTL=0,
     )
 ],
 DefaultCacheBehavior=cloudfront.DefaultCacheBehavior(
     ViewerProtocolPolicy=
     'redirect-to-https',  # HTTPS required. Cookies need to be sent securely
     LambdaFunctionAssociations=[
         cloudfront.LambdaFunctionAssociation(
             EventType='viewer-request',
             LambdaFunctionARN=Ref(param_authorizer_lae_arn)),
     ],
예제 #23
0
     cdnOrigin,
 ],
 Aliases=[cdn_domain, alternate_name],
 ViewerCertificate=cf.ViewerCertificate(
     AcmCertificateArn=Ref(cdnCertificate),
     SslSupportMethod='sni-only',
     MinimumProtocolVersion='TLSv1.2_2018',
 ),
 DefaultCacheBehavior=cf.DefaultCacheBehavior(
     AllowedMethods=['GET', 'HEAD', 'OPTIONS'],
     CachedMethods=['GET', 'HEAD'],
     ViewerProtocolPolicy='redirect-to-https',
     TargetOriginId='{}-{}-{}'.format(env_l, app_group_l,
                                      src_domain),
     ForwardedValues=cf.ForwardedValues(
         Headers=["Accept-Encoding"],
         QueryString=True,
     ),
     MinTTL=0,
     MaxTTL=int(max_ttl[0]),
     DefaultTTL=int(default_ttl[0]),
     SmoothStreaming=False,
     Compress=True),
 CustomErrorResponses=[
     cf.CustomErrorResponse(
         ErrorCachingMinTTL='0',
         ErrorCode='403',
     ),
     cf.CustomErrorResponse(
         ErrorCachingMinTTL='0',
         ErrorCode='404',
     ),