料金

料金体系はわかりにくいが、最低利用料はなく利用した分だけ。

データ転送アウト (インターネット/オリジン)
HTTP/HTTPS リクエスト
無効リクエスト
フィールドレベル暗号化リクエスト
CLOUDFRONT ディストリビューションに関連する、専用 IP カスタム SSL 証明書

12カ月利用枠として以下が利用できる。

50 GB のデータ送信
12 か月間無料
200 万件の HTTP および HTTPS リクエスト
毎月 1 年間

S3バケットをオリジンにしてキャッシュ配信する

cloudfront_s3.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
AWSTemplateFormatVersion: "2010-09-09"
Description: Cloudfront + S3

Metadata:
# ------------------------------------------------------------ #
# Input Parameters
# ------------------------------------------------------------ #
"AWS::CloudFormation::Interface":
ParameterGroups:
- Label:
default: "S3 and CloudFront Configuration"
Parameters:
- DomainName
- S3BucketName
- MyHostedZoneId
- CFSSLCertificateId

ParameterLabels:
DomainName:
default: "example.com"
MyHostedZoneId:
default: "ZNXXXXXXXXX"
S3BucketName:
default: "myBucketName"
CFSSLCertificateId:
default: "CFSSLCertificateId"

Parameters:
DomainName:
Type: String
S3BucketName:
Type: String
MyHostedZoneId:
Type: String
CFSSLCertificateId:
Type: String

Resources:
# ------------------------------------------------------------ #
# S3 - Contents
# ------------------------------------------------------------ #
StaticContentsBcuket:
Type: "AWS::S3::Bucket"
Properties:
BucketName: !Ref S3BucketName

CloudFrontOriginAccessIdentity:
Type: "AWS::CloudFront::CloudFrontOriginAccessIdentity"
Properties:
CloudFrontOriginAccessIdentityConfig:
Comment: !Sub "access-identity-${StaticContentsBcuket}"

StaticContentsBcuketPolicy:
Type: "AWS::S3::BucketPolicy"
Properties:
Bucket: !Ref StaticContentsBcuket
PolicyDocument:
Statement:
- Action: "s3:GetObject"
Effect: Allow
Resource: !Sub "arn:aws:s3:::${StaticContentsBcuket}/*"
Principal:
CanonicalUser: !GetAtt CloudFrontOriginAccessIdentity.S3CanonicalUserId

CloudFrontLog:
Type: "AWS::S3::Bucket"
Properties:
BucketName: !Sub "log.${S3BucketName}"
AccessControl: LogDeliveryWrite
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
LifecycleConfiguration:
Rules:
- Id: !Sub "${S3BucketName}-log-LifeCycle"
Status: Enabled
Prefix: log/
ExpirationInDays: 365
Transitions:
- StorageClass: GLACIER
TransitionInDays: 180

# ------------------------------------------------------------ #
# CloudFront
# ------------------------------------------------------------ #
# CloudFrontは利用可能になるまで時間がかかる
CloudFrontDistribution:
Type: "AWS::CloudFront::Distribution"
Properties:
DistributionConfig:
# PriceClass
# https://aws.amazon.com/jp/cloudfront/pricing/
# PriceClass_200は日本を含むが南米やオーストラリアは含まない
PriceClass: PriceClass_200

# Aliases
Aliases:
- !Ref DomainName

# Logging
Logging:
IncludeCookies: false
Bucket: !GetAtt CloudFrontLog.DomainName
Prefix: cloudfront-logs

# DefaultRootObject
DefaultRootObject: index.html

# CustomErrorResponses
CustomErrorResponses:
- ErrorCode: 403
ErrorCachingMinTTL: 30
ResponseCode: 403
ResponsePagePath: /error.html
- ErrorCode: 404
ErrorCachingMinTTL: 30
ResponseCode: 404
ResponsePagePath: /error.html

# CacheBehavior … キャッシュルール
#
# CacheBehaviors:
# CacheBehaviorがない場合はDefaultCacheBehaviorを使用する
DefaultCacheBehavior:
AllowedMethods:
- GET
- HEAD
CachedMethods:
- GET
- HEAD
Compress: true
# オリジンサーバがキャッシュ制御(Cache-Controlなど)を行わない場合のTTL
DefaultTTL: 3600
# FieldLevelEncryptionId: String
# クエリ文字列やCookieの処理方法
ForwardedValues:
Cookies:
Forward: none
QueryString: false
# LambdaFunctionAssociations:
# オリジンサーバがキャッシュ制御(Cache-Controlなど)を行った場合の最大TTL
MaxTTL: 86400
# オブジェクト更新チェックのTTL
MinTTL: 60
# PathPattern: String
# SmoothStreaming: Boolean
# リクエストをルーティングするオリジンID
TargetOriginId: !Sub "S3origin-${S3BucketName}"
# TrustedSigners:
ViewerProtocolPolicy: redirect-to-https

# HttpVersion … 使用するHTTPバージョン
# http2ならhttp2以下を使用する
HttpVersion: http2

# Enabled … 選択したディストリビューションの有効/無効
Enabled: true

# Origin … コンテンツ配信元
#
# S3をオリジンサーバにする場合、静的webホスティングを利用する必要はなく、S3バケットでいい。
# CloudFrontとS3の通信はHTTPSになる, 静的Webホスティング機能を利用した場合はHTTPになる。
# S3バケットの場合はIndex DocumentはROOTオブジェクトに対してのみ有効になる。
Origins:
- DomainName: !GetAtt StaticContentsBcuket.DomainName
Id: !Sub "S3origin-${S3BucketName}"
S3OriginConfig:
OriginAccessIdentity: !Sub "origin-access-identity/cloudfront/${CloudFrontOriginAccessIdentity}"

# ViewerCertificate
ViewerCertificate:
AcmCertificateArn: !Ref CFSSLCertificateId
# CloudFrontDefaultCertificate: Boolean
# IamCertificateId: String
MinimumProtocolVersion: TLSv1.1_2016
SslSupportMethod: sni-only

# ------------------------------------------------------------ #
# Route 53
# ------------------------------------------------------------ #
Route53RecordSetGroup:
Type: AWS::Route53::RecordSetGroup
Properties:
HostedZoneId: !Ref MyHostedZoneId
RecordSets:
- Name: !Sub "${DomainName}."
Type: A
AliasTarget:
HostedZoneId: Z2FDTNDATAQYW2
DNSName: !GetAtt CloudFrontDistribution.DomainName
EvaluateTargetHealth: false
- Name: !Sub 'www.${DomainName}'
Type: A
AliasTarget:
HostedZoneId: Z2FDTNDATAQYW2
DNSName: !GetAtt CloudFrontDistribution.DomainName
EvaluateTargetHealth: false

# ------------------------------------------------------------ #
# Output Parameters
# ------------------------------------------------------------ #
Outputs:
#BucketName
BucketName:
Value: !Ref StaticContentsBcuket

#DistributionID
DistributionID:
Value: !Ref CloudFrontDistribution

#DmainName
DomainName:
Value: !GetAtt CloudFrontDistribution.DomainName

parameters.json

オリジンサーバーとして使用するS3バケットと公開するドメイン名、DNSレコードを登録するRoute53のHostedZoneIdと別途発行した証明書のCertificateIdを指定する。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[
{
"ParameterKey": "S3BucketName",
"ParameterValue": "<domainname>.web"
},
{
"ParameterKey": "DomainName",
"ParameterValue": "<domainname>"
},
{
"ParameterKey": "MyHostedZoneId",
"ParameterValue": "<domainname>のHostedZoneId"
},
{
"ParameterKey": "CFSSLCertificateId",
"ParameterValue": "arn:aws:acm:us-east-1:XXXXXXXXXXXXXX:certificate/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
]

オリジンサーバー(S3バケット)の設定

S3バケットのアクセス制御でAWS::CloudFront::CloudFrontOriginAccessIdentityによりCloudFrontからのアクセスを許可する。

キャッシュ(CroudFront)の設定

CroudFrontの設定の中心はCacheBehaviorでキャッシュルールを定義できるが、ここではDefaultの設定のみしかしていない。
サーバ証明書は別途CertificateManagerで発行したものを適用している。

DNSによる公開

ハードコーディングしているZ2FDTNDATAQYW2はCroudFrontの固定値で、AWS::Route53::RecordSetGroup AliasTargetに記述がある。

CloudFront distribution
Specify Z2FDTNDATAQYW2. This is always the hosted zone ID when you create an alias record that routes traffic to a CloudFront distribution.
Alias records for CloudFront can’t be created in a private zone.

キャッシュ配信を構築する

コンテンツを配置するバケットとキャッシュを作成し、コンテンツを置く。

1
2
3
4
5
6
7
8
$ aws cloudformation create-stack --stack-name tutorial-cloudfront-s3 --template-body "file://./cloudfront_s3.yml" --parameters "file://./parameters.json"
{
"StackId": "arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXXX:stack/tutorial-cloudfront-s3/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
$ aws s3 cp contents/index.html s3://<domainname>.web/
upload: contents/index.html to s3://<domainname>.web/index.html
$ aws s3 cp contents/error.html s3://<domainname>.web/
upload: contents/error.html to s3://<domainname>.web/error.html

Route53ホストゾーン width=640

CroudFront width=640

すぐに配信できるわけではない

CloudFormationのスタックがコンプリートになっても、キャッシュ配信はまだ使えない。作成直後にアクセスするとエラーになる。

キャッシュが有効になるまで width=640

一時間程度時間待ってアクセスすると、配置したコンテンツにアクセスできる。

キャッシュが有効になるまで width=640

キャッシュが有効になるまで width=640