Ejemplo n.º 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')])))
Ejemplo n.º 2
0
    def add_origins(self, title, cf_origins_config):
        """
        Create Cloudfront Origin objects and append to list of origins
        :param title: Title of this Cloudfront Distribution
        :param cf_origins_config: List of CFOrigins
        """
        for number, origin in enumerate(cf_origins_config):

            created_origin = cloudfront.Origin('{0}Origin{1}'.format(
                title, number),
                                               DomainName=origin.domain_name,
                                               Id=origin.origin_id)

            if origin.origin_path:
                created_origin.OriginPath = origin.origin_path
            if origin.custom_headers:
                created_headers = []
                for k, v in origin.custom_headers.items():
                    if v is not None:
                        created_headers.append(
                            cloudfront.OriginCustomHeader(HeaderName=k,
                                                          HeaderValue=v))
                created_origin.OriginCustomHeaders = created_headers

            # Set S3 config
            if origin.origin_policy['is_s3']:
                # Create S3Origin
                s3_origin_config = cloudfront.S3Origin()

                # Ensure variables exist
                if origin.origin_access_identity:
                    s3_origin_config.OriginAccessIdentity = origin.origin_access_identity

                # Set S3Origin
                created_origin.S3OriginConfig = s3_origin_config
            # Set Custom config
            else:

                created_origin.DomainName = self.get_custom_reference(
                    origin.domain_name)

                # Create CustomOrigin
                custom_origin_config = cloudfront.CustomOrigin()

                # Ensure variables exist
                if origin.http_port:
                    custom_origin_config.HTTPPort = origin.http_port
                if origin.https_port:
                    custom_origin_config.HTTPSPort = origin.https_port
                if origin.origin_protocol_policy:
                    custom_origin_config.OriginProtocolPolicy = origin.origin_protocol_policy
                if origin.origin_ssl_protocols:
                    custom_origin_config.OriginSSLProtocols = origin.origin_ssl_protocols

                # Set CustomOrigin
                created_origin.CustomOriginConfig = custom_origin_config

            self.origins.append(created_origin)
Ejemplo n.º 3
0
 'visibilitycloudfront',
 DistributionConfig=cloudfront.DistributionConfig(
     WebACLId=Ref(waf),
     Origins=[
         cloudfront.Origin(
             Id='apiv1',
             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(
Ejemplo n.º 4
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(
            '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()))

        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,
                        ),
                        LambdaFunctionAssociations=If(
                            'DirectoryIndexSpecified',
                            [
                                cloudfront.LambdaFunctionAssociation(
                                    EventType='origin-request',
                                    LambdaFunctionARN=cfdirectoryindexrewritever
                                    .ref()  # noqa
                                )
                            ],
                            NoValue),
                        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')))
    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"],
            ))
Ejemplo n.º 6
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')))