Route53・S3・Cloudfrontを連携させる設定はAWS初見の人では難しく感じると思います。私がそうでした。
今はSeverless Frameworkを使い、一発でデプロイするファイルを作成して運用しているので、公開します。
Githubはこちら、デモページはこちらです。
テンプレは以下の環境で動作・デプロイされます。適宜読み替えてください。
-
umihi.co
というドメインをroute53で管理している。 -
us-east-1
のACMにてumihi.co
と*.umihi.co
を1つとして証明書を発行している。 - サブドメイン
sls-static-website.umihi.co
として静的サイトをデプロイする
以下のファイルを作成し、AcmCertificateArn
と、ドメイン各所の書き換えを行いsls deploy
でデプロイします。分かりやすさ重視でなるべくハードコーディングしています。
serverless.yaml
service: sls-static-website
provider:
name: aws
runtime: provided
stage: dev
region: ap-northeast-1
resources:
Resources:
WebsiteBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: sls-static-website.umihi.co
WebsiteConfiguration:
IndexDocument: index.html
ErrorDocument: 404.html
DeletionPolicy: Retain
WebsiteCloudfront:
Type: AWS::CloudFront::Distribution
DependsOn:
- WebsiteBucket
Properties:
DistributionConfig:
Origins:
- DomainName: sls-static-website.umihi.co.s3-website-ap-northeast-1.amazonaws.com
Id: S3Origin
CustomOriginConfig:
HTTPPort: '80'
HTTPSPort: '443'
OriginProtocolPolicy: http-only
Enabled: true
HttpVersion: 'http2'
DefaultRootObject: index.html
Aliases:
- sls-static-website.umihi.co
DefaultCacheBehavior:
AllowedMethods:
- GET
- HEAD
Compress: true
TargetOriginId: S3Origin
ForwardedValues:
QueryString: true
Cookies:
Forward: none
ViewerProtocolPolicy: redirect-to-https
PriceClass: PriceClass_All
ViewerCertificate:
AcmCertificateArn: arn:aws:acm:us-east-1:123456789:certificate/xxxxxxxx-yyyy-zzzz-aaaa-123456789 # must be in us-east-1
SslSupportMethod: sni-only
WebsiteDNSName:
Type: AWS::Route53::RecordSetGroup
Properties:
HostedZoneName: umihi.co. # you need (.)period at the end
RecordSets:
- Name: sls-static-website.umihi.co. # you need (.)period at the end
Type: A
AliasTarget:
HostedZoneId: Z2FDTNDATAQYW2 # This is always the hosted zone ID when you create an alias record that routes traffic to a CloudFront distribution.
# DNSName: ddddxxxxyyyyzzzzz.cloudfront.net # you can also hard-code like this
DNSName:
Fn::GetAtt: [ WebsiteCloudfront, DomainName ]
作成時にハマったのは
- route53の
HostedZoneName
やRecordSets.Name
の値には末尾にピリオドが必要がある。 - S3にアップロード・更新しても、Cloudfrontがキャッシュを持つと反映されないので都度Invalidationする必要がある
- CloudfrontのOrigin設定の
DomainName
で補完で候補に表示されるsls-static-website.umihi.co.s3.amazonaws.com
ではなく、
Static Website Hostingのエンドポイントのsls-static-website.umihi.co.s3-website-ap-northeast-1.amazonaws.com
を使わないと、この構成だとリダイレクトのループになった。
リダイレクト問題自体は解決せず分からなかったのですが仮に解決したら、どちらのエンドポイントを使うべきかはこちらが参考になりました。
バケットにファイルを手動でアップロードすると、公開する作業が必要になります。serverless-s3-syncを使い設定すればデプロイ時にローカルファイルを常に同期することが可能になり、公開作業も不要になります。Githubレポジトリのserverless.yml
にはその設定も含まれているので、参考にしてください。
参考
- https://github.com/sjevs/cloudformation-s3-static-website-with-cloudfront-and-route-53/blob/master/s3-static-website-with-cloudfront-and-route-53.yaml
- https://gist.github.com/matalo33/fc2a9d8698c069e134b4b0b6640f0c84
- https://github.com/awslabs/aws-cloudformation-templates/blob/master/aws/services/S3/S3_Website_With_CloudFront_Distribution.yaml
- https://masaru-tech.hateblo.jp/entry/2018/03/27/111327
- https://qiita.com/NaokiIshimura/items/46994e67b712831c3016
- https://forum.serverless.com/t/unclear-how-to-reference-lambda-role-arn-in-serverless-yml/1147/5
- https://simonecarletti.com/blog/2016/08/redirect-domain-https-amazon-cloudfront/
- https://stackoverflow.com/questions/43835731/301-redirect-for-specific-page-with-cloudfront