You have a static website in an S3 bucket. You want to put CloudFront in front of that bucket site, for caching, SSL with a custom domain, etc. You want to use CloudFormation because Infrastructure as Code for the win, and artisanally hand-crafted systems for the lose.

In short, this is the magic you want in your CloudFormation template, with thanks to Eric Hammond and Ryan Brown:

SiteBucket : Type : " AWS::S3::Bucket" # Snip Mappings : RegionToS3DomainSuffix : " us-east-1" : suffix : " s3-website-us-east-1.amazonaws.com" " eu-central-1" : suffix : " s3-website.eu-central-1.amazonaws.com" # I've not investigated other regions... CF : Type : " AWS::CloudFront::Distribution" Properties : DistributionConfig : Origins : - DomainName : " Fn::Join" : - " ." - - !Ref SiteBucket - !FindInMap [ RegionToS3DomainSuffix , !Ref " AWS::Region" , suffix ]

Yes that’s an ugly hand-crafted Join . Yes that’s an ugly hand-crafted Mapping to account for different regions having different bucket website URL conventions. However, it works.

In an ideal world, AWS::S3::Bucket s would have a WebsiteDomain attribute so you could !GetAttr SiteBucket.WebsiteDomain . Alas at time of writing (October 2016) they don’t.

AWS::S3::Bucket.WebsiteURL exists but it returns a URL, with leading http:// and trailing / . Stripping these within a CloudFormation template is beyond me.

As far as I can tell, icky region-specific substitutions are where it’s at for now!