目的
CloudFrontでコンテンツを提供したいです。
ですが毎回コンソールで立ち上げるのはめんどうです。ある程度の雛形を作成しておいて、一部を書き換えることで簡単にデプロイするスクリプトを構築しました。
CloudFrontを構築したのちに、Route53にドメインを設定しています。
コード
CloudFront
まずベースとなるJSONを構築します。
以下のコマンドでゼロから雛形を生成できます。
aws cloudfront create-distribution-with-tags --generate-cli-skeleton
または既にあるCloudFrontから取得します。
aws cloudfront get-distribution --id xxxxxx
以下のようなJSONを用意します。
cloud_front_base.json
{
"Tags": {
"Items": [
{
"Key": "Name",
"Value": "test.example.com"
},
{
"Key": "Service",
"Value": "my_service"
}
]
},
"DistributionConfig": {
"CallerReference": "00000000-0000-0000-0000-000000000000",
"Aliases": {
"Quantity": 1,
"Items": [
"test.example.com"
]
},
"DefaultRootObject": "",
"Origins": {
"Quantity": 1,
"Items": [
{
"Id": "contents",
"DomainName": "my-bucket.s3.ap-northeast-1.amazonaws.com",
"OriginPath": "/contents",
"CustomHeaders": {
"Quantity": 0
},
"S3OriginConfig": {
"OriginAccessIdentity": "origin-access-identity/cloudfront/XXXXXXXXXX"
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
}
}
]
},
"OriginGroups": {
"Quantity": 0
},
"DefaultCacheBehavior": {
"TargetOriginId": "contents",
"TrustedSigners": {
"Enabled": false,
"Quantity": 0
},
"TrustedKeyGroups": {
"Enabled": false,
"Quantity": 0
},
"ViewerProtocolPolicy": "https-only",
"AllowedMethods": {
"Quantity": 3,
"Items": [
"HEAD",
"GET",
"OPTIONS"
],
"CachedMethods": {
"Quantity": 2,
"Items": [
"HEAD",
"GET"
]
}
},
"SmoothStreaming": false,
"Compress": true,
"LambdaFunctionAssociations": {
"Quantity": 0,
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "00000000-0000-0000-0000-000000000000"
},
"CustomErrorResponses": {
"Quantity": 0
},
"Comment": "",
"Logging": {
"Enabled": false,
"IncludeCookies": false,
"Bucket": "",
"Prefix": ""
},
"PriceClass": "PriceClass_200",
"Enabled": true,
"ViewerCertificate": {
"CloudFrontDefaultCertificate": false,
"ACMCertificateArn": "arn:aws:acm:us-east-1:9999999999:certificate/00000000-0000-0000-0000-000000000000",
"SSLSupportMethod": "sni-only",
"MinimumProtocolVersion": "TLSv1.2_2021",
"Certificate": "arn:aws:acm:us-east-1:9999999999:certificate/00000000-0000-0000-0000-000000000000",
"CertificateSource": "acm"
},
"Restrictions": {
"GeoRestriction": {
"RestrictionType": "none",
"Quantity": 0
}
},
"WebACLId": "",
"HttpVersion": "http2",
"IsIPV6Enabled": true
}
}
RubyプログラムでJSONで変更したいところを修正します。
cf.rb
require 'securerandom'
require 'json'
def read_json(path)
File.open(path) do |j|
hash = JSON.load(j)
end
end
base = read_json("#{__dir__}/cloud_front_base.json")
config = base['DistributionConfig']
fqdn = ARGV[0]
comment = ARGV[1]
s3_path = ARGV[2]
config['CallerReference'] = SecureRandom.uuid
config['Comment'] = comment
config['Aliases']['Items'][0] = fqdn
config['Origins']['Items'][0]['OriginPath'] = s3_path
base['Tags']['Items'][0]['Value'] = fqdn
puts JSON.pretty_generate(base)
Route53
雛形は以下の通りです。
route53_base.json
{
"Comment": "",
"Changes": [
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "cf.example.com",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "Z2FDTNDATAQYW2",
"DNSName": "example.com",
"EvaluateTargetHealth": false
}
}
}
]
}
こちらもRubyプログラムでJSONで変更したいところを修正します。
r53.rb
require 'securerandom'
require 'json'
def read_json(path)
File.open(path) do |j|
hash = JSON.load(j)
end
end
base = read_json("#{__dir__}/route53_base.json")
fqdn = ARGV[0]
dns_name = ARGV[1]
base['Comment'] = fqdn
rrs = base['Changes'][0]['ResourceRecordSet']
rrs['Name'] = fqdn
rrs['AliasTarget']['DNSName'] = dns_name
puts JSON.pretty_generate(base)
シェルスクリプト
awsコマンドとjqはインストールしておいてください。
make.sh
#!/bin/bash
AWS_ACCESS_KEY_ID=xxxxx
AWS_SECRET_ACCESS_KEY=xxxxx
HOST_ZONE_ID=Zxxxxxxxx
FQDN=$1
COMMENT=$2
S3_PATH=$3
# CloudFrontの構築
ruby cf.rb $FQDN $COMMENT $S3_PATH > temp_cf.json
AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \
AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \
aws cloudfront create-distribution-with-tags \
--distribution-config-with-tags file://temp_cf.json > result.json
CF_ID=$(cat result.json | jq -r '.Distribution.Id')
DNS_NAME=$(cat result.json | jq -r '.Distribution.DomainName')
echo $CF_ID > cf_id.txt
# Route53の登録
ruby r53.rb $FQDN $DNS_NAME > temp_r53.json
AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \
AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \
aws route53 change-resource-record-sets \
--hosted-zone-id $HOST_ZONE_ID \
--change-batch file://temp_r53.json > result2.json
# あとかたずけ
rm temp_cf.json
rm result.json
rm temp_r53.json
rm result2.json
echo $CF_ID
以下で実際に構築を行います。
./make.sh "www.example.com" "www.example.comのサイト" "/contents"