Aws-cdk: CloudFrontWebDistribution S3 website bucket

Created on 7 Jan 2020  路  13Comments  路  Source: aws/aws-cdk

I'm trying to setup a simple webpage with static html.
I want to have redirect from domainname to www.domainname and it should support SSL.
What I have setup is :

  1. Route53 (domainname) -> Cloudfront (with certificate) -> S3 bucket (set to redirect to www.domainname)
  2. Route53 (www.domainname) -> Cloudfront (with certificate) -> S3 bucket (serves files)

The thing is that the origin path in Cloudfront for the redirect is using the URL directly to the S3 bucket and not the website version which is needed for redirect to work properly.

    // ---- Buckets ----
    const websiteBucket = new s3.Bucket(this, 'WebsiteBucket', {
      bucketName: `www.${domainName}`,
      websiteErrorDocument: 'index.html',
      websiteIndexDocument: 'index.html',
      publicReadAccess: true
    });

    const redirectBucket = new s3.Bucket(this, 'WebsiteRedirectBucket', {
      bucketName: domainName,
      websiteRedirect: {
        hostName: `www.${domainName}`
      },
      publicReadAccess: true
    });

    // ---- Cloudfront ----
    const websiteCloudfront = new cloudfront.CloudFrontWebDistribution(this, 'WebsiteCloudfront', {
      originConfigs: [{
        s3OriginSource: { s3BucketSource: websiteBucket },
        behaviors: [{ 
          compress: true,
          isDefaultBehavior: true,
        }],
      }],
      viewerCertificate: cloudfront.ViewerCertificate.fromAcmCertificate(
        certificate,
        { aliases: [`www.${domainName}`] }
      ),
    });

    const websiteRedirectCloudfront = new cloudfront.CloudFrontWebDistribution(this, 'WebsiteRedirectCloudfront', {
      originConfigs: [{
        s3OriginSource: { s3BucketSource: redirectBucket },
        behaviors: [{ 
          isDefaultBehavior: true,
        }],
      }],
      viewerCertificate: cloudfront.ViewerCertificate.fromAcmCertificate(
        certificate,
        { aliases: [domainName] }
      ),
    });

    // ---- DNS Records ----
    new route53.ARecord(this, 'WebsiteAlias', {
      recordName: 'www',
      target: route53.RecordTarget.fromAlias(new route53targets.CloudFrontTarget(websiteCloudfront)),
      zone,
    });

    new route53.ARecord(this, 'WebsiteRedirectAlias', {
      target: route53.RecordTarget.fromAlias(new route53targets.CloudFrontTarget(websiteRedirectCloudfront)),
      zone
    });

Is there a workaround I can use?

This is :bug: Bug Report

@aws-cdaws-cloudfront bug p1

Most helpful comment

All 13 comments

The HttpsRedirect construct from @aws-cdk/aws-route53-patterns does exactly that. Does it match your use case?

@jogold I ended up using customOriginSource. Thanks
But it would be great if you could just send in a S3 bucket with redirect properties and it would be automatic for you :)

Hi @johankvint, I'm glad @jogold's tips helped! 馃憤 Please open a new feature request for the implementation you would like and make sure to reference this issue. Thanks!

I have a related issue. If it's the same, I'll be happy to open a ticket. I'm currently trying to use HttpsRedirect to send www.api.com traffic to an api gateway at api.com. The trouble is that the root path gets redirected to index.html, rather than /. I'm guessing this is an artifact of using s3 to handle the redirect. Is this a separate bug?

I have a related issue. If it's the same, I'll be happy to open a ticket. I'm currently trying to use HttpsRedirect to send www.api.com traffic to an api gateway at api.com. The trouble is that the root path gets redirected to index.html, rather than /. I'm guessing this is an artifact of using s3 to handle the redirect. Is this a separate bug?

It should not be the case, care to share the code/resulting template/screenshot of general tab of the distribution in the console?

Sure! Thanks!

You can see the bug in action by comparing:

I expect the former to lead to the latter.

new HttpsRedirect(stack, 'WwwRedirect', {
  targetDomain: 'api.dev.sitearcade.com',
  recordNames: ['www.api.dev.sitearcade.com'],
  zone: stack.publicZone,
  certificate: stack.publicCert,
});


Here's the output...

{
  "Resources": {
    "DevPublicCertCertificateRequestorFunctionServiceRoleDAB239A8": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                "Service": "lambda.amazonaws.com"
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "ManagedPolicyArns": [
          {
            "Fn::Join": [
              "",
              [
                "arn:",
                {
                  "Ref": "AWS::Partition"
                },
                ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
              ]
            ]
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "DevStack/DevPublicCert/CertificateRequestorFunction/ServiceRole/Resource"
      }
    },
    "DevPublicCertCertificateRequestorFunctionServiceRoleDefaultPolicyDDB2AD8E": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyDocument": {
          "Statement": [
            {
              "Action": [
                "acm:RequestCertificate",
                "acm:DescribeCertificate",
                "acm:DeleteCertificate"
              ],
              "Effect": "Allow",
              "Resource": "*"
            },
            {
              "Action": "route53:GetChange",
              "Effect": "Allow",
              "Resource": "*"
            },
            {
              "Action": "route53:changeResourceRecordSets",
              "Effect": "Allow",
              "Resource": {
                "Fn::Join": [
                  "",
                  [
                    "arn:",
                    {
                      "Ref": "AWS::Partition"
                    },
                    ":route53:::hostedzone/Z09945891J6MDLQLBTQI9"
                  ]
                ]
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "PolicyName": "DevPublicCertCertificateRequestorFunctionServiceRoleDefaultPolicyDDB2AD8E",
        "Roles": [
          {
            "Ref": "DevPublicCertCertificateRequestorFunctionServiceRoleDAB239A8"
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "DevStack/DevPublicCert/CertificateRequestorFunction/ServiceRole/DefaultPolicy/Resource"
      }
    },
    "DevPublicCertCertificateRequestorFunction6D060721": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Code": {
          "S3Bucket": {
            "Ref": "AssetParameters19e461d2ff1a5b90438fed6ceee4c197d7efee8712a6f76d85b501ab20bfb1a2S3BucketFCCD3A76"
          },
          "S3Key": {
            "Fn::Join": [
              "",
              [
                {
                  "Fn::Select": [
                    0,
                    {
                      "Fn::Split": [
                        "||",
                        {
                          "Ref": "AssetParameters19e461d2ff1a5b90438fed6ceee4c197d7efee8712a6f76d85b501ab20bfb1a2S3VersionKey07AF06B6"
                        }
                      ]
                    }
                  ]
                },
                {
                  "Fn::Select": [
                    1,
                    {
                      "Fn::Split": [
                        "||",
                        {
                          "Ref": "AssetParameters19e461d2ff1a5b90438fed6ceee4c197d7efee8712a6f76d85b501ab20bfb1a2S3VersionKey07AF06B6"
                        }
                      ]
                    }
                  ]
                }
              ]
            ]
          }
        },
        "Handler": "index.certificateRequestHandler",
        "Role": {
          "Fn::GetAtt": [
            "DevPublicCertCertificateRequestorFunctionServiceRoleDAB239A8",
            "Arn"
          ]
        },
        "Runtime": "nodejs10.x",
        "Timeout": 900
      },
      "DependsOn": [
        "DevPublicCertCertificateRequestorFunctionServiceRoleDefaultPolicyDDB2AD8E",
        "DevPublicCertCertificateRequestorFunctionServiceRoleDAB239A8"
      ],
      "Metadata": {
        "aws:cdk:path": "DevStack/DevPublicCert/CertificateRequestorFunction/Resource",
        "aws:asset:path": "asset.19e461d2ff1a5b90438fed6ceee4c197d7efee8712a6f76d85b501ab20bfb1a2",
        "aws:asset:property": "Code"
      }
    },
    "DevPublicCertCertificateRequestorResource06671558": {
      "Type": "AWS::CloudFormation::CustomResource",
      "Properties": {
        "ServiceToken": {
          "Fn::GetAtt": [
            "DevPublicCertCertificateRequestorFunction6D060721",
            "Arn"
          ]
        },
        "DomainName": "dev.sitearcade.com",
        "SubjectAlternativeNames": [
          "api.dev.sitearcade.com",
          "admin.dev.sitearcade.com",
          "cdn.dev.sitearcade.com",
          "*.dev.sitearcade.com",
          "*.api.dev.sitearcade.com",
          "*.admin.dev.sitearcade.com",
          "*.cdn.dev.sitearcade.com"
        ],
        "HostedZoneId": "Z09945891J6MDLQLBTQI9"
      },
      "UpdateReplacePolicy": "Delete",
      "DeletionPolicy": "Delete",
      "Metadata": {
        "aws:cdk:path": "DevStack/DevPublicCert/CertificateRequestorResource/Default"
      }
    },
    "DevDevWwwRedirectRedirectBucketED0E435A": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "WebsiteConfiguration": {
          "RedirectAllRequestsTo": {
            "HostName": "dev.sitearcade.com",
            "Protocol": "https"
          }
        }
      },
      "UpdateReplacePolicy": "Delete",
      "DeletionPolicy": "Delete",
      "Metadata": {
        "aws:cdk:path": "DevStack/DevDevWwwRedirect/RedirectBucket/Resource"
      }
    },
    "DevDevWwwRedirectRedirectDistributionCFDistribution703B6DE6": {
      "Type": "AWS::CloudFront::Distribution",
      "Properties": {
        "DistributionConfig": {
          "Aliases": [
            "www.dev.sitearcade.com"
          ],
          "Comment": "Redirect to dev.sitearcade.com from www.dev.sitearcade.com",
          "DefaultCacheBehavior": {
            "AllowedMethods": [
              "GET",
              "HEAD"
            ],
            "CachedMethods": [
              "GET",
              "HEAD"
            ],
            "Compress": true,
            "ForwardedValues": {
              "Cookies": {
                "Forward": "none"
              },
              "QueryString": false
            },
            "TargetOriginId": "origin1",
            "ViewerProtocolPolicy": "redirect-to-https"
          },
          "DefaultRootObject": "index.html",
          "Enabled": true,
          "HttpVersion": "http2",
          "IPV6Enabled": true,
          "Origins": [
            {
              "CustomOriginConfig": {
                "HTTPPort": 80,
                "HTTPSPort": 443,
                "OriginKeepaliveTimeout": 5,
                "OriginProtocolPolicy": "http-only",
                "OriginReadTimeout": 30,
                "OriginSSLProtocols": [
                  "TLSv1.2"
                ]
              },
              "DomainName": {
                "Fn::Select": [
                  2,
                  {
                    "Fn::Split": [
                      "/",
                      {
                        "Fn::GetAtt": [
                          "DevDevWwwRedirectRedirectBucketED0E435A",
                          "WebsiteURL"
                        ]
                      }
                    ]
                  }
                ]
              },
              "Id": "origin1"
            }
          ],
          "PriceClass": "PriceClass_All",
          "ViewerCertificate": {
            "AcmCertificateArn": {
              "Fn::GetAtt": [
                "DevPublicCertCertificateRequestorResource06671558",
                "Arn"
              ]
            },
            "SslSupportMethod": "sni-only"
          }
        }
      },
      "Metadata": {
        "aws:cdk:path": "DevStack/DevDevWwwRedirect/RedirectDistribution/CFDistribution"
      }
    },
    "DevDevWwwRedirectRedirectAliasRecord42e8f4282711D7": {
      "Type": "AWS::Route53::RecordSet",
      "Properties": {
        "Name": "www.dev.sitearcade.com.",
        "Type": "A",
        "AliasTarget": {
          "DNSName": {
            "Fn::GetAtt": [
              "DevDevWwwRedirectRedirectDistributionCFDistribution703B6DE6",
              "DomainName"
            ]
          },
          "HostedZoneId": "Z2FDTNDATAQYW2"
        },
        "HostedZoneId": "Z09945891J6MDLQLBTQI9"
      },
      "Metadata": {
        "aws:cdk:path": "DevStack/DevDevWwwRedirect/RedirectAliasRecord42e8f4/Resource"
      }
    },
    "DevApiDevWwwRedirectRedirectBucket7C29EBAD": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "WebsiteConfiguration": {
          "RedirectAllRequestsTo": {
            "HostName": "api.dev.sitearcade.com",
            "Protocol": "https"
          }
        }
      },
      "UpdateReplacePolicy": "Delete",
      "DeletionPolicy": "Delete",
      "Metadata": {
        "aws:cdk:path": "DevStack/DevApiDevWwwRedirect/RedirectBucket/Resource"
      }
    },
    "DevApiDevWwwRedirectRedirectDistributionCFDistribution4F30C5E3": {
      "Type": "AWS::CloudFront::Distribution",
      "Properties": {
        "DistributionConfig": {
          "Aliases": [
            "www.api.dev.sitearcade.com"
          ],
          "Comment": "Redirect to api.dev.sitearcade.com from www.api.dev.sitearcade.com",
          "DefaultCacheBehavior": {
            "AllowedMethods": [
              "GET",
              "HEAD"
            ],
            "CachedMethods": [
              "GET",
              "HEAD"
            ],
            "Compress": true,
            "ForwardedValues": {
              "Cookies": {
                "Forward": "none"
              },
              "QueryString": false
            },
            "TargetOriginId": "origin1",
            "ViewerProtocolPolicy": "redirect-to-https"
          },
          "DefaultRootObject": "index.html",
          "Enabled": true,
          "HttpVersion": "http2",
          "IPV6Enabled": true,
          "Origins": [
            {
              "CustomOriginConfig": {
                "HTTPPort": 80,
                "HTTPSPort": 443,
                "OriginKeepaliveTimeout": 5,
                "OriginProtocolPolicy": "http-only",
                "OriginReadTimeout": 30,
                "OriginSSLProtocols": [
                  "TLSv1.2"
                ]
              },
              "DomainName": {
                "Fn::Select": [
                  2,
                  {
                    "Fn::Split": [
                      "/",
                      {
                        "Fn::GetAtt": [
                          "DevApiDevWwwRedirectRedirectBucket7C29EBAD",
                          "WebsiteURL"
                        ]
                      }
                    ]
                  }
                ]
              },
              "Id": "origin1"
            }
          ],
          "PriceClass": "PriceClass_All",
          "ViewerCertificate": {
            "AcmCertificateArn": {
              "Fn::GetAtt": [
                "DevPublicCertCertificateRequestorResource06671558",
                "Arn"
              ]
            },
            "SslSupportMethod": "sni-only"
          }
        }
      },
      "Metadata": {
        "aws:cdk:path": "DevStack/DevApiDevWwwRedirect/RedirectDistribution/CFDistribution"
      }
    },
    "DevApiDevWwwRedirectRedirectAliasRecord9d898eB64A33D2": {
      "Type": "AWS::Route53::RecordSet",
      "Properties": {
        "Name": "www.api.dev.sitearcade.com.",
        "Type": "A",
        "AliasTarget": {
          "DNSName": {
            "Fn::GetAtt": [
              "DevApiDevWwwRedirectRedirectDistributionCFDistribution4F30C5E3",
              "DomainName"
            ]
          },
          "HostedZoneId": "Z2FDTNDATAQYW2"
        },
        "HostedZoneId": "Z09945891J6MDLQLBTQI9"
      },
      "Metadata": {
        "aws:cdk:path": "DevStack/DevApiDevWwwRedirect/RedirectAliasRecord9d898e/Resource"
      }
    },
    "DevAdminDevWwwRedirectRedirectBucket754D70A2": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "WebsiteConfiguration": {
          "RedirectAllRequestsTo": {
            "HostName": "admin.dev.sitearcade.com",
            "Protocol": "https"
          }
        }
      },
      "UpdateReplacePolicy": "Delete",
      "DeletionPolicy": "Delete",
      "Metadata": {
        "aws:cdk:path": "DevStack/DevAdminDevWwwRedirect/RedirectBucket/Resource"
      }
    },
    "DevAdminDevWwwRedirectRedirectDistributionCFDistribution3F51C742": {
      "Type": "AWS::CloudFront::Distribution",
      "Properties": {
        "DistributionConfig": {
          "Aliases": [
            "www.admin.dev.sitearcade.com"
          ],
          "Comment": "Redirect to admin.dev.sitearcade.com from www.admin.dev.sitearcade.com",
          "DefaultCacheBehavior": {
            "AllowedMethods": [
              "GET",
              "HEAD"
            ],
            "CachedMethods": [
              "GET",
              "HEAD"
            ],
            "Compress": true,
            "ForwardedValues": {
              "Cookies": {
                "Forward": "none"
              },
              "QueryString": false
            },
            "TargetOriginId": "origin1",
            "ViewerProtocolPolicy": "redirect-to-https"
          },
          "DefaultRootObject": "index.html",
          "Enabled": true,
          "HttpVersion": "http2",
          "IPV6Enabled": true,
          "Origins": [
            {
              "CustomOriginConfig": {
                "HTTPPort": 80,
                "HTTPSPort": 443,
                "OriginKeepaliveTimeout": 5,
                "OriginProtocolPolicy": "http-only",
                "OriginReadTimeout": 30,
                "OriginSSLProtocols": [
                  "TLSv1.2"
                ]
              },
              "DomainName": {
                "Fn::Select": [
                  2,
                  {
                    "Fn::Split": [
                      "/",
                      {
                        "Fn::GetAtt": [
                          "DevAdminDevWwwRedirectRedirectBucket754D70A2",
                          "WebsiteURL"
                        ]
                      }
                    ]
                  }
                ]
              },
              "Id": "origin1"
            }
          ],
          "PriceClass": "PriceClass_All",
          "ViewerCertificate": {
            "AcmCertificateArn": {
              "Fn::GetAtt": [
                "DevPublicCertCertificateRequestorResource06671558",
                "Arn"
              ]
            },
            "SslSupportMethod": "sni-only"
          }
        }
      },
      "Metadata": {
        "aws:cdk:path": "DevStack/DevAdminDevWwwRedirect/RedirectDistribution/CFDistribution"
      }
    },
    "DevAdminDevWwwRedirectRedirectAliasRecordec00f5AD5FC7BA": {
      "Type": "AWS::Route53::RecordSet",
      "Properties": {
        "Name": "www.admin.dev.sitearcade.com.",
        "Type": "A",
        "AliasTarget": {
          "DNSName": {
            "Fn::GetAtt": [
              "DevAdminDevWwwRedirectRedirectDistributionCFDistribution3F51C742",
              "DomainName"
            ]
          },
          "HostedZoneId": "Z2FDTNDATAQYW2"
        },
        "HostedZoneId": "Z09945891J6MDLQLBTQI9"
      },
      "Metadata": {
        "aws:cdk:path": "DevStack/DevAdminDevWwwRedirect/RedirectAliasRecordec00f5/Resource"
      }
    },
    "DevCdnDevWwwRedirectRedirectBucket733500AC": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "WebsiteConfiguration": {
          "RedirectAllRequestsTo": {
            "HostName": "cdn.dev.sitearcade.com",
            "Protocol": "https"
          }
        }
      },
      "UpdateReplacePolicy": "Delete",
      "DeletionPolicy": "Delete",
      "Metadata": {
        "aws:cdk:path": "DevStack/DevCdnDevWwwRedirect/RedirectBucket/Resource"
      }
    },
    "DevCdnDevWwwRedirectRedirectDistributionCFDistribution04E6968A": {
      "Type": "AWS::CloudFront::Distribution",
      "Properties": {
        "DistributionConfig": {
          "Aliases": [
            "www.cdn.dev.sitearcade.com"
          ],
          "Comment": "Redirect to cdn.dev.sitearcade.com from www.cdn.dev.sitearcade.com",
          "DefaultCacheBehavior": {
            "AllowedMethods": [
              "GET",
              "HEAD"
            ],
            "CachedMethods": [
              "GET",
              "HEAD"
            ],
            "Compress": true,
            "ForwardedValues": {
              "Cookies": {
                "Forward": "none"
              },
              "QueryString": false
            },
            "TargetOriginId": "origin1",
            "ViewerProtocolPolicy": "redirect-to-https"
          },
          "DefaultRootObject": "index.html",
          "Enabled": true,
          "HttpVersion": "http2",
          "IPV6Enabled": true,
          "Origins": [
            {
              "CustomOriginConfig": {
                "HTTPPort": 80,
                "HTTPSPort": 443,
                "OriginKeepaliveTimeout": 5,
                "OriginProtocolPolicy": "http-only",
                "OriginReadTimeout": 30,
                "OriginSSLProtocols": [
                  "TLSv1.2"
                ]
              },
              "DomainName": {
                "Fn::Select": [
                  2,
                  {
                    "Fn::Split": [
                      "/",
                      {
                        "Fn::GetAtt": [
                          "DevCdnDevWwwRedirectRedirectBucket733500AC",
                          "WebsiteURL"
                        ]
                      }
                    ]
                  }
                ]
              },
              "Id": "origin1"
            }
          ],
          "PriceClass": "PriceClass_All",
          "ViewerCertificate": {
            "AcmCertificateArn": {
              "Fn::GetAtt": [
                "DevPublicCertCertificateRequestorResource06671558",
                "Arn"
              ]
            },
            "SslSupportMethod": "sni-only"
          }
        }
      },
      "Metadata": {
        "aws:cdk:path": "DevStack/DevCdnDevWwwRedirect/RedirectDistribution/CFDistribution"
      }
    },
    "DevCdnDevWwwRedirectRedirectAliasRecordcef449DCC08011": {
      "Type": "AWS::Route53::RecordSet",
      "Properties": {
        "Name": "www.cdn.dev.sitearcade.com.",
        "Type": "A",
        "AliasTarget": {
          "DNSName": {
            "Fn::GetAtt": [
              "DevCdnDevWwwRedirectRedirectDistributionCFDistribution04E6968A",
              "DomainName"
            ]
          },
          "HostedZoneId": "Z2FDTNDATAQYW2"
        },
        "HostedZoneId": "Z09945891J6MDLQLBTQI9"
      },
      "Metadata": {
        "aws:cdk:path": "DevStack/DevCdnDevWwwRedirect/RedirectAliasRecordcef449/Resource"
      }
    },
    "DevBucketStackNestedStackDevBucketStackNestedStackResourceF417631B": {
      "Type": "AWS::CloudFormation::Stack",
      "Properties": {
        "TemplateURL": {
          "Fn::Join": [
            "",
            [
              "https://s3.us-east-1.",
              {
                "Ref": "AWS::URLSuffix"
              },
              "/",
              {
                "Ref": "AssetParameters0d4b6585f29f7edb8edbec0a08b8e88c147d713d2afa4163213bdf7567151e23S3Bucket3BC300AE"
              },
              "/",
              {
                "Fn::Select": [
                  0,
                  {
                    "Fn::Split": [
                      "||",
                      {
                        "Ref": "AssetParameters0d4b6585f29f7edb8edbec0a08b8e88c147d713d2afa4163213bdf7567151e23S3VersionKey099DC754"
                      }
                    ]
                  }
                ]
              },
              {
                "Fn::Select": [
                  1,
                  {
                    "Fn::Split": [
                      "||",
                      {
                        "Ref": "AssetParameters0d4b6585f29f7edb8edbec0a08b8e88c147d713d2afa4163213bdf7567151e23S3VersionKey099DC754"
                      }
                    ]
                  }
                ]
              }
            ]
          ]
        }
      },
      "Metadata": {
        "aws:cdk:path": "DevStack/DevBucketStack.NestedStack/DevBucketStack.NestedStackResource"
      }
    },
    "DevTableStackNestedStackDevTableStackNestedStackResourceEF601B5A": {
      "Type": "AWS::CloudFormation::Stack",
      "Properties": {
        "TemplateURL": {
          "Fn::Join": [
            "",
            [
              "https://s3.us-east-1.",
              {
                "Ref": "AWS::URLSuffix"
              },
              "/",
              {
                "Ref": "AssetParameters23fa1f525023fdb46c023aef831464304bf2073a8b297838529204f8dabe2fa3S3Bucket75F10B51"
              },
              "/",
              {
                "Fn::Select": [
                  0,
                  {
                    "Fn::Split": [
                      "||",
                      {
                        "Ref": "AssetParameters23fa1f525023fdb46c023aef831464304bf2073a8b297838529204f8dabe2fa3S3VersionKey9DDC5400"
                      }
                    ]
                  }
                ]
              },
              {
                "Fn::Select": [
                  1,
                  {
                    "Fn::Split": [
                      "||",
                      {
                        "Ref": "AssetParameters23fa1f525023fdb46c023aef831464304bf2073a8b297838529204f8dabe2fa3S3VersionKey9DDC5400"
                      }
                    ]
                  }
                ]
              }
            ]
          ]
        }
      },
      "Metadata": {
        "aws:cdk:path": "DevStack/DevTableStack.NestedStack/DevTableStack.NestedStackResource"
      }
    },
    "DevFuncStackNestedStackDevFuncStackNestedStackResourceFFECED99": {
      "Type": "AWS::CloudFormation::Stack",
      "Properties": {
        "TemplateURL": {
          "Fn::Join": [
            "",
            [
              "https://s3.us-east-1.",
              {
                "Ref": "AWS::URLSuffix"
              },
              "/",
              {
                "Ref": "AssetParametersa0a58494f8a44077a14f4eeda2e98a6b27e61e5ff83a4ee8a89212e208f43e02S3Bucket3B1344D5"
              },
              "/",
              {
                "Fn::Select": [
                  0,
                  {
                    "Fn::Split": [
                      "||",
                      {
                        "Ref": "AssetParametersa0a58494f8a44077a14f4eeda2e98a6b27e61e5ff83a4ee8a89212e208f43e02S3VersionKey76F9C632"
                      }
                    ]
                  }
                ]
              },
              {
                "Fn::Select": [
                  1,
                  {
                    "Fn::Split": [
                      "||",
                      {
                        "Ref": "AssetParametersa0a58494f8a44077a14f4eeda2e98a6b27e61e5ff83a4ee8a89212e208f43e02S3VersionKey76F9C632"
                      }
                    ]
                  }
                ]
              }
            ]
          ]
        },
        "Parameters": {
          "referencetoDevStackDevTableStackNestedStackDevTableStackNestedStackResource6C3151EDOutputsDevStackDevTableStackDevAuthorDataTableB5007CA3Arn": {
            "Fn::GetAtt": [
              "DevTableStackNestedStackDevTableStackNestedStackResourceEF601B5A",
              "Outputs.DevStackDevTableStackDevAuthorDataTableB5007CA3Arn"
            ]
          },
          "referencetoDevStackAssetParametersee0ee29c442ca1b5d6a41d43d3edf06b821e1ee595cd506a7ef0b72d61844fd0S3Bucket7E2F0F23Ref": {
            "Ref": "AssetParametersee0ee29c442ca1b5d6a41d43d3edf06b821e1ee595cd506a7ef0b72d61844fd0S3BucketBB9CF0F9"
          },
          "referencetoDevStackAssetParametersee0ee29c442ca1b5d6a41d43d3edf06b821e1ee595cd506a7ef0b72d61844fd0S3VersionKeyC361135ERef": {
            "Ref": "AssetParametersee0ee29c442ca1b5d6a41d43d3edf06b821e1ee595cd506a7ef0b72d61844fd0S3VersionKey9EE98BC9"
          },
          "referencetoDevStackDevTableStackNestedStackDevTableStackNestedStackResource6C3151EDOutputsDevStackDevTableStackDevAuthorDataTableB5007CA3Ref": {
            "Fn::GetAtt": [
              "DevTableStackNestedStackDevTableStackNestedStackResourceEF601B5A",
              "Outputs.DevStackDevTableStackDevAuthorDataTableB5007CA3Ref"
            ]
          },
          "referencetoDevStackDevBucketStackNestedStackDevBucketStackNestedStackResource00BF8FB4OutputsDevStackDevBucketStackDevAuthorFileBucket8FD40670Ref": {
            "Fn::GetAtt": [
              "DevBucketStackNestedStackDevBucketStackNestedStackResourceF417631B",
              "Outputs.DevStackDevBucketStackDevAuthorFileBucket8FD40670Ref"
            ]
          },
          "referencetoDevStackAssetParametersa4d3c3628a20d1a2eda92c0c3e916bffdb1127fabaa37cc47899b516e31de2b6S3BucketC2B718DFRef": {
            "Ref": "AssetParametersa4d3c3628a20d1a2eda92c0c3e916bffdb1127fabaa37cc47899b516e31de2b6S3Bucket9B001351"
          },
          "referencetoDevStackAssetParametersa4d3c3628a20d1a2eda92c0c3e916bffdb1127fabaa37cc47899b516e31de2b6S3VersionKeyAF1867E2Ref": {
            "Ref": "AssetParametersa4d3c3628a20d1a2eda92c0c3e916bffdb1127fabaa37cc47899b516e31de2b6S3VersionKeyB471B797"
          },
          "referencetoDevStackAssetParameters5465f59a4de80a9712dcb91d89e9dbae77a04ec36f8a9449a1e61e68e93d2ca2S3BucketEA0BF937Ref": {
            "Ref": "AssetParameters5465f59a4de80a9712dcb91d89e9dbae77a04ec36f8a9449a1e61e68e93d2ca2S3Bucket83374E87"
          },
          "referencetoDevStackAssetParameters5465f59a4de80a9712dcb91d89e9dbae77a04ec36f8a9449a1e61e68e93d2ca2S3VersionKey23CAA14FRef": {
            "Ref": "AssetParameters5465f59a4de80a9712dcb91d89e9dbae77a04ec36f8a9449a1e61e68e93d2ca2S3VersionKeyB379DDC0"
          },
          "referencetoDevStackAssetParametersce3d0eb2e7a864c1777f739b1831eb47fc5cd7304a6e0857e65a874a0589428bS3BucketF8A4E116Ref": {
            "Ref": "AssetParametersce3d0eb2e7a864c1777f739b1831eb47fc5cd7304a6e0857e65a874a0589428bS3Bucket79F74184"
          },
          "referencetoDevStackAssetParametersce3d0eb2e7a864c1777f739b1831eb47fc5cd7304a6e0857e65a874a0589428bS3VersionKeyA8689EDCRef": {
            "Ref": "AssetParametersce3d0eb2e7a864c1777f739b1831eb47fc5cd7304a6e0857e65a874a0589428bS3VersionKeyCEB79340"
          },
          "referencetoDevStackAssetParametersd5bd51f1d9922ea7943985e4d34779895cc7e81fdb9b2d4c1619a5ec4e4337c2S3BucketAFFA34A0Ref": {
            "Ref": "AssetParametersd5bd51f1d9922ea7943985e4d34779895cc7e81fdb9b2d4c1619a5ec4e4337c2S3Bucket0D77CFE0"
          },
          "referencetoDevStackAssetParametersd5bd51f1d9922ea7943985e4d34779895cc7e81fdb9b2d4c1619a5ec4e4337c2S3VersionKey36450652Ref": {
            "Ref": "AssetParametersd5bd51f1d9922ea7943985e4d34779895cc7e81fdb9b2d4c1619a5ec4e4337c2S3VersionKeyC101E2EC"
          }
        }
      },
      "Metadata": {
        "aws:cdk:path": "DevStack/DevFuncStack.NestedStack/DevFuncStack.NestedStackResource"
      }
    },
    "DevApiStackNestedStackDevApiStackNestedStackResource1DDF5163": {
      "Type": "AWS::CloudFormation::Stack",
      "Properties": {
        "TemplateURL": {
          "Fn::Join": [
            "",
            [
              "https://s3.us-east-1.",
              {
                "Ref": "AWS::URLSuffix"
              },
              "/",
              {
                "Ref": "AssetParameters32dda4abd3f04d1cd486b2d06a639a7b667a4f49114ea4c152d485af5a04d951S3BucketEC84AE8D"
              },
              "/",
              {
                "Fn::Select": [
                  0,
                  {
                    "Fn::Split": [
                      "||",
                      {
                        "Ref": "AssetParameters32dda4abd3f04d1cd486b2d06a639a7b667a4f49114ea4c152d485af5a04d951S3VersionKeyC122875F"
                      }
                    ]
                  }
                ]
              },
              {
                "Fn::Select": [
                  1,
                  {
                    "Fn::Split": [
                      "||",
                      {
                        "Ref": "AssetParameters32dda4abd3f04d1cd486b2d06a639a7b667a4f49114ea4c152d485af5a04d951S3VersionKeyC122875F"
                      }
                    ]
                  }
                ]
              }
            ]
          ]
        },
        "Parameters": {
          "referencetoDevStackDevFuncStackNestedStackDevFuncStackNestedStackResource73B6CECCOutputsDevStackDevFuncStackDevStatusFuncF99F599FArn": {
            "Fn::GetAtt": [
              "DevFuncStackNestedStackDevFuncStackNestedStackResourceFFECED99",
              "Outputs.DevStackDevFuncStackDevStatusFuncF99F599FArn"
            ]
          },
          "referencetoDevStackDevFuncStackNestedStackDevFuncStackNestedStackResource73B6CECCOutputsDevStackDevFuncStackDevGraphqlFunc61E506E0Arn": {
            "Fn::GetAtt": [
              "DevFuncStackNestedStackDevFuncStackNestedStackResourceFFECED99",
              "Outputs.DevStackDevFuncStackDevGraphqlFunc61E506E0Arn"
            ]
          },
          "referencetoDevStackDevFuncStackNestedStackDevFuncStackNestedStackResource73B6CECCOutputsDevStackDevFuncStackDevAuthorDataFunc5E1BD623Arn": {
            "Fn::GetAtt": [
              "DevFuncStackNestedStackDevFuncStackNestedStackResourceFFECED99",
              "Outputs.DevStackDevFuncStackDevAuthorDataFunc5E1BD623Arn"
            ]
          },
          "referencetoDevStackDevFuncStackNestedStackDevFuncStackNestedStackResource73B6CECCOutputsDevStackDevFuncStackDevAuthorScrapeFunc263D4430Arn": {
            "Fn::GetAtt": [
              "DevFuncStackNestedStackDevFuncStackNestedStackResourceFFECED99",
              "Outputs.DevStackDevFuncStackDevAuthorScrapeFunc263D4430Arn"
            ]
          },
          "referencetoDevStackDevFuncStackNestedStackDevFuncStackNestedStackResource73B6CECCOutputsDevStackDevFuncStackDevAuthorFileFunc62FC074CArn": {
            "Fn::GetAtt": [
              "DevFuncStackNestedStackDevFuncStackNestedStackResourceFFECED99",
              "Outputs.DevStackDevFuncStackDevAuthorFileFunc62FC074CArn"
            ]
          },
          "referencetoDevStackDevPublicCertCertificateRequestorResource37EA3ED1Arn": {
            "Fn::GetAtt": [
              "DevPublicCertCertificateRequestorResource06671558",
              "Arn"
            ]
          }
        }
      },
      "Metadata": {
        "aws:cdk:path": "DevStack/DevApiStack.NestedStack/DevApiStack.NestedStackResource"
      }
    }
  },
  "Parameters": {
    "AssetParameters19e461d2ff1a5b90438fed6ceee4c197d7efee8712a6f76d85b501ab20bfb1a2S3BucketFCCD3A76": {
      "Type": "String",
      "Description": "S3 bucket for asset \"19e461d2ff1a5b90438fed6ceee4c197d7efee8712a6f76d85b501ab20bfb1a2\""
    },
    "AssetParameters19e461d2ff1a5b90438fed6ceee4c197d7efee8712a6f76d85b501ab20bfb1a2S3VersionKey07AF06B6": {
      "Type": "String",
      "Description": "S3 key for asset version \"19e461d2ff1a5b90438fed6ceee4c197d7efee8712a6f76d85b501ab20bfb1a2\""
    },
    "AssetParameters19e461d2ff1a5b90438fed6ceee4c197d7efee8712a6f76d85b501ab20bfb1a2ArtifactHash652C125C": {
      "Type": "String",
      "Description": "Artifact hash for asset \"19e461d2ff1a5b90438fed6ceee4c197d7efee8712a6f76d85b501ab20bfb1a2\""
    },
    "AssetParametersee0ee29c442ca1b5d6a41d43d3edf06b821e1ee595cd506a7ef0b72d61844fd0S3BucketBB9CF0F9": {
      "Type": "String",
      "Description": "S3 bucket for asset \"ee0ee29c442ca1b5d6a41d43d3edf06b821e1ee595cd506a7ef0b72d61844fd0\""
    },
    "AssetParametersee0ee29c442ca1b5d6a41d43d3edf06b821e1ee595cd506a7ef0b72d61844fd0S3VersionKey9EE98BC9": {
      "Type": "String",
      "Description": "S3 key for asset version \"ee0ee29c442ca1b5d6a41d43d3edf06b821e1ee595cd506a7ef0b72d61844fd0\""
    },
    "AssetParametersee0ee29c442ca1b5d6a41d43d3edf06b821e1ee595cd506a7ef0b72d61844fd0ArtifactHash8B5CD32B": {
      "Type": "String",
      "Description": "Artifact hash for asset \"ee0ee29c442ca1b5d6a41d43d3edf06b821e1ee595cd506a7ef0b72d61844fd0\""
    },
    "AssetParametersa4d3c3628a20d1a2eda92c0c3e916bffdb1127fabaa37cc47899b516e31de2b6S3Bucket9B001351": {
      "Type": "String",
      "Description": "S3 bucket for asset \"a4d3c3628a20d1a2eda92c0c3e916bffdb1127fabaa37cc47899b516e31de2b6\""
    },
    "AssetParametersa4d3c3628a20d1a2eda92c0c3e916bffdb1127fabaa37cc47899b516e31de2b6S3VersionKeyB471B797": {
      "Type": "String",
      "Description": "S3 key for asset version \"a4d3c3628a20d1a2eda92c0c3e916bffdb1127fabaa37cc47899b516e31de2b6\""
    },
    "AssetParametersa4d3c3628a20d1a2eda92c0c3e916bffdb1127fabaa37cc47899b516e31de2b6ArtifactHashD3A89D8D": {
      "Type": "String",
      "Description": "Artifact hash for asset \"a4d3c3628a20d1a2eda92c0c3e916bffdb1127fabaa37cc47899b516e31de2b6\""
    },
    "AssetParameters5465f59a4de80a9712dcb91d89e9dbae77a04ec36f8a9449a1e61e68e93d2ca2S3Bucket83374E87": {
      "Type": "String",
      "Description": "S3 bucket for asset \"5465f59a4de80a9712dcb91d89e9dbae77a04ec36f8a9449a1e61e68e93d2ca2\""
    },
    "AssetParameters5465f59a4de80a9712dcb91d89e9dbae77a04ec36f8a9449a1e61e68e93d2ca2S3VersionKeyB379DDC0": {
      "Type": "String",
      "Description": "S3 key for asset version \"5465f59a4de80a9712dcb91d89e9dbae77a04ec36f8a9449a1e61e68e93d2ca2\""
    },
    "AssetParameters5465f59a4de80a9712dcb91d89e9dbae77a04ec36f8a9449a1e61e68e93d2ca2ArtifactHashC68F5E7E": {
      "Type": "String",
      "Description": "Artifact hash for asset \"5465f59a4de80a9712dcb91d89e9dbae77a04ec36f8a9449a1e61e68e93d2ca2\""
    },
    "AssetParametersce3d0eb2e7a864c1777f739b1831eb47fc5cd7304a6e0857e65a874a0589428bS3Bucket79F74184": {
      "Type": "String",
      "Description": "S3 bucket for asset \"ce3d0eb2e7a864c1777f739b1831eb47fc5cd7304a6e0857e65a874a0589428b\""
    },
    "AssetParametersce3d0eb2e7a864c1777f739b1831eb47fc5cd7304a6e0857e65a874a0589428bS3VersionKeyCEB79340": {
      "Type": "String",
      "Description": "S3 key for asset version \"ce3d0eb2e7a864c1777f739b1831eb47fc5cd7304a6e0857e65a874a0589428b\""
    },
    "AssetParametersce3d0eb2e7a864c1777f739b1831eb47fc5cd7304a6e0857e65a874a0589428bArtifactHashC7CAE808": {
      "Type": "String",
      "Description": "Artifact hash for asset \"ce3d0eb2e7a864c1777f739b1831eb47fc5cd7304a6e0857e65a874a0589428b\""
    },
    "AssetParametersd5bd51f1d9922ea7943985e4d34779895cc7e81fdb9b2d4c1619a5ec4e4337c2S3Bucket0D77CFE0": {
      "Type": "String",
      "Description": "S3 bucket for asset \"d5bd51f1d9922ea7943985e4d34779895cc7e81fdb9b2d4c1619a5ec4e4337c2\""
    },
    "AssetParametersd5bd51f1d9922ea7943985e4d34779895cc7e81fdb9b2d4c1619a5ec4e4337c2S3VersionKeyC101E2EC": {
      "Type": "String",
      "Description": "S3 key for asset version \"d5bd51f1d9922ea7943985e4d34779895cc7e81fdb9b2d4c1619a5ec4e4337c2\""
    },
    "AssetParametersd5bd51f1d9922ea7943985e4d34779895cc7e81fdb9b2d4c1619a5ec4e4337c2ArtifactHashACBDB04E": {
      "Type": "String",
      "Description": "Artifact hash for asset \"d5bd51f1d9922ea7943985e4d34779895cc7e81fdb9b2d4c1619a5ec4e4337c2\""
    },
    "AssetParameters32dda4abd3f04d1cd486b2d06a639a7b667a4f49114ea4c152d485af5a04d951S3BucketEC84AE8D": {
      "Type": "String",
      "Description": "S3 bucket for asset \"32dda4abd3f04d1cd486b2d06a639a7b667a4f49114ea4c152d485af5a04d951\""
    },
    "AssetParameters32dda4abd3f04d1cd486b2d06a639a7b667a4f49114ea4c152d485af5a04d951S3VersionKeyC122875F": {
      "Type": "String",
      "Description": "S3 key for asset version \"32dda4abd3f04d1cd486b2d06a639a7b667a4f49114ea4c152d485af5a04d951\""
    },
    "AssetParameters32dda4abd3f04d1cd486b2d06a639a7b667a4f49114ea4c152d485af5a04d951ArtifactHash5DBA1A60": {
      "Type": "String",
      "Description": "Artifact hash for asset \"32dda4abd3f04d1cd486b2d06a639a7b667a4f49114ea4c152d485af5a04d951\""
    },
    "AssetParametersa0a58494f8a44077a14f4eeda2e98a6b27e61e5ff83a4ee8a89212e208f43e02S3Bucket3B1344D5": {
      "Type": "String",
      "Description": "S3 bucket for asset \"a0a58494f8a44077a14f4eeda2e98a6b27e61e5ff83a4ee8a89212e208f43e02\""
    },
    "AssetParametersa0a58494f8a44077a14f4eeda2e98a6b27e61e5ff83a4ee8a89212e208f43e02S3VersionKey76F9C632": {
      "Type": "String",
      "Description": "S3 key for asset version \"a0a58494f8a44077a14f4eeda2e98a6b27e61e5ff83a4ee8a89212e208f43e02\""
    },
    "AssetParametersa0a58494f8a44077a14f4eeda2e98a6b27e61e5ff83a4ee8a89212e208f43e02ArtifactHashC216333C": {
      "Type": "String",
      "Description": "Artifact hash for asset \"a0a58494f8a44077a14f4eeda2e98a6b27e61e5ff83a4ee8a89212e208f43e02\""
    },
    "AssetParameters23fa1f525023fdb46c023aef831464304bf2073a8b297838529204f8dabe2fa3S3Bucket75F10B51": {
      "Type": "String",
      "Description": "S3 bucket for asset \"23fa1f525023fdb46c023aef831464304bf2073a8b297838529204f8dabe2fa3\""
    },
    "AssetParameters23fa1f525023fdb46c023aef831464304bf2073a8b297838529204f8dabe2fa3S3VersionKey9DDC5400": {
      "Type": "String",
      "Description": "S3 key for asset version \"23fa1f525023fdb46c023aef831464304bf2073a8b297838529204f8dabe2fa3\""
    },
    "AssetParameters23fa1f525023fdb46c023aef831464304bf2073a8b297838529204f8dabe2fa3ArtifactHash78AE178F": {
      "Type": "String",
      "Description": "Artifact hash for asset \"23fa1f525023fdb46c023aef831464304bf2073a8b297838529204f8dabe2fa3\""
    },
    "AssetParameters0d4b6585f29f7edb8edbec0a08b8e88c147d713d2afa4163213bdf7567151e23S3Bucket3BC300AE": {
      "Type": "String",
      "Description": "S3 bucket for asset \"0d4b6585f29f7edb8edbec0a08b8e88c147d713d2afa4163213bdf7567151e23\""
    },
    "AssetParameters0d4b6585f29f7edb8edbec0a08b8e88c147d713d2afa4163213bdf7567151e23S3VersionKey099DC754": {
      "Type": "String",
      "Description": "S3 key for asset version \"0d4b6585f29f7edb8edbec0a08b8e88c147d713d2afa4163213bdf7567151e23\""
    },
    "AssetParameters0d4b6585f29f7edb8edbec0a08b8e88c147d713d2afa4163213bdf7567151e23ArtifactHashA0341E8B": {
      "Type": "String",
      "Description": "Artifact hash for asset \"0d4b6585f29f7edb8edbec0a08b8e88c147d713d2afa4163213bdf7567151e23\""
    }
  }
}

Screen Shot 2020-04-15 at 3 16 30 PM

@mikestopcontinues I see where the problem comes from: it's the default root object that is set to index.html in the distribution. This is the default in the CDK for a distribution and the HttpsRedirect uses the default instead of setting it to '' (empty value).

As a temporary workaround you should be able to do this:

const redirect = new HttpsRedirect(stack, 'WwwRedirect', {
  targetDomain: 'api.dev.sitearcade.com',
  recordNames: ['www.api.dev.sitearcade.com'],
  zone: stack.publicZone,
  certificate: stack.publicCert,
});
const distribution = redirect.node.tryFindChild('RedirectDistribution') as CfnDistribution;
distribution.addPropertyOverride('DefaultRootObject', '');

Can you confirm that this works once deployed? I will then submit a PR to fix this.

Hey @jogold , thanks! Unfortunately, that syntax doesn't work for me. I couldn't find a good way to replicate this way of casting in vanilla JS, so I set up typescript (been meaning to anyway)... But it doesn't seem to work in TS either. distribution doesn't have addPropertyOverride. My TS config could be off, but I can't see any way as would compile if it was. I also did some digging down node tree, but I couldn't find a way to surface the CfnDistribution that's a _defaultNode of RedirectDistribution.

Sorry my mistake it's nested, and in JS just drop the as:

const redirect = new HttpsRedirect(stack, 'WwwRedirect', {
  targetDomain: 'api.dev.sitearcade.com',
  recordNames: ['www.api.dev.sitearcade.com'],
  zone: stack.publicZone,
  certificate: stack.publicCert,
});
const distribution = redirect.node.tryFindChild('RedirectDistribution');
const cfnDistribution = distribution.node.defaultChild;
cfnDistribution.addPropertyOverride('DistributionConfig.DefaultRootObject', '');

Thanks, @jogold ! That works perfectly. Test at http://www.api.dev.sitearcade.com

I think this issue might be closable. @jogold can you confirm?

The original bug filed -- wrong behavior when using a "website" bucket as an s3OriginSource seems to be resolved as receiving the right guidance. For what it's worth, the new Distribution construct and S3Origin origin does do as requested; automatically determines if an origin should be treated as a website or not.

Regarding the default root object, this is now able to be specified without resorting to escape hatches.

Closing as I believe both of the issues here have been resolved.

Was this page helpful?
0 / 5 - 0 ratings