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')])))
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)
'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(
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"], ))
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')))