AWS
S3
CloudFormation
CloudFront

CloudFormationを使ってS3とCloudFrontの構成で静的Webサイトを構築する(Origin Access Identityは使わない)


はじめに

本記事では、AWS CloudFormation管理コンソールを使って、S3とCloudFrontで、静的Webサイトの環境を構築する手順を説明しています。(初心者向け)

また、CloudFrontのOriginの設定においては、OAI(Origin Access Identity)を使わず、S3の静的Webサイトには、直接アクセスできる 構成としています。

直接アクセスできない構成にしたい場合は、下記の記事を参考にしてください。

CloudFormationを使ってS3とCloudFrontの構成で静的Webサイトを構築する(Origin Access Identityは使う)

本記事で掲載しているテンプレートの最新版は、下記に置いてます。

https://github.com/okubo-t/aws-cloudformation


構成図


前提条件

CloudFrontに設定するSSLサーバ証明書を、リージョンがバージニア北部のAWS Certificate Manager(ACM)にインポートしていること。

ACM管理コンソールで、CloudFrontに設定する証明書の識別子をメモしておく。

インデックスドキュメントは、index.html とする。


構築手順

1 AWS CloudFormation管理コンソールから、スタックの作成をクリックします。

2 後述のテンプレートを選択します。

3 各パラメータを入力します。

パラメータ名
用途
備考

スタックの名前
テンプレートから作成するリソース一式の名前
例 s3-cf-web-20190226

WebsiteDomainName
静的Webサイトのドメイン名
必須 S3のバケット名となります

CFSSLCertificateId
前提条件でメモした証明書の識別子
必須

4 後続は、デフォルトのまま次へ次へで、作成します。

5 状況が CREATE COMPLETEになれば、S3とCloudFrontの構築が完了です。

6 管理コンソールの下部の出力から、構築した静的WebサイトのエンドポイントとCloudFrontの情報を確認できます。

ここで、キーが、DomainNameとWebsiteURLの値をメモしておきます。

7 確認のために、S3の管理コンソールから、バケット(バケット名はWebsiteDomainNameに設定した値)に、index.htmlファイルをアップロードします。

8 ブラウザから、先ほどメモしたDomainNameの値にWebアクセス(CloudFrontにWebアクセス)して、index.htmlの内容が表示されれば、OKです。

また、WebsiteURLの値にWebアクセス(S3にWebアクセス)して、index.htmlの内容が表示されれば、OKです。

9 最後に、適宜、WebsiteDomainNameのCNAMEレコード(Route53の場合は、ALIASレコード)として、CloudFrontのドメイン名をDNSサーバ(Route53)に登録してください。


テンプレート


s3-cloudfront-web-hosting-01.yml

AWSTemplateFormatVersion: "2010-09-09"

Description:
S3 and CloudFront for Static website hosting (OAI Not available)

Metadata:
"AWS::CloudFormation::Interface":
ParameterGroups:
- Label:
default: "S3 and CloudFront Configuration"
Parameters:
- WebsiteDomainName
- CFSSLCertificateId

ParameterLabels:
WebsiteDomainName:
default: "WebsiteDomainName"
CFSSLCertificateId:
default: "CFSSLCertificateId"

# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------#
Parameters:
WebsiteDomainName:
Type: String

CFSSLCertificateId:
Type: String

Resources:
# ------------------------------------------------------------#
# S3 Bucket
# ------------------------------------------------------------#
# Bucket
Bucket:
Type: "AWS::S3::Bucket"
Properties:
BucketName: !Ref WebsiteDomainName
AccessControl: PublicRead
WebsiteConfiguration:
IndexDocument: index.html

BucketPolicy:
Type: "AWS::S3::BucketPolicy"
Properties:
Bucket: !Ref Bucket
PolicyDocument:
Statement:
- Action: "s3:GetObject"
Effect: Allow
Resource: !Sub "arn:aws:s3:::${Bucket}/*"
Principal: '*'

# ------------------------------------------------------------#
# CloudFront
# ------------------------------------------------------------#
CloudFrontDistribution:
Type: "AWS::CloudFront::Distribution"
Properties:
DistributionConfig:
PriceClass: PriceClass_All
Aliases:
- !Ref WebsiteDomainName
Origins:
- CustomOriginConfig:
OriginProtocolPolicy: http-only
DomainName: !Sub "${WebsiteDomainName}.s3-website-${AWS::Region}.amazonaws.com"
Id: !Sub "S3-Website-${WebsiteDomainName}.s3-website-ap-northeast-1.amazonaws.com"
DefaultCacheBehavior:
TargetOriginId: !Sub "S3-Website-${WebsiteDomainName}.s3-website-ap-northeast-1.amazonaws.com"
ViewerProtocolPolicy: redirect-to-https
AllowedMethods:
- GET
- HEAD
CachedMethods:
- GET
- HEAD
DefaultTTL: 3600
MaxTTL: 86400
MinTTL: 60
Compress: true
ForwardedValues:
Cookies:
Forward: none
QueryString: false
ViewerCertificate:
SslSupportMethod: sni-only
MinimumProtocolVersion: TLSv1.1_2016
AcmCertificateArn: !Sub "arn:aws:acm:us-east-1:${AWS::AccountId}:certificate/${CFSSLCertificateId}"
HttpVersion: http2
Enabled: true

# ------------------------------------------------------------#
# Output Parameters
# ------------------------------------------------------------#
Outputs:
#WebsiteURL:
WebsiteURL:
Value: !GetAtt Bucket.WebsiteURL

#DistributionID
DistributionID:
Value: !Ref CloudFrontDistribution

#DmainName
DomainName:
Value: !GetAtt CloudFrontDistribution.DomainName