Skip to content

Instantly share code, notes, and snippets.

@akira345
Created February 7, 2016 07:01
Show Gist options
  • Save akira345/5c5cd77044788c995cba to your computer and use it in GitHub Desktop.
Save akira345/5c5cd77044788c995cba to your computer and use it in GitHub Desktop.
S3+CloudFrontでCache Distributionパターンを構築するスクリプト。S3バケットの作成からアクセスポリシーの設定、CloudFrontの設定まで一通りやります。
# -*- coding: utf-8 -*-
#
# S3+CloudFrontでCache Distributionパターンを構築するスクリプトです。
# 要 AWS SDK for Ruby V2
require 'aws-sdk-core'
require 'yaml'
require 'pp'
config = YAML.load(File.read("config.yml"))
Aws.config[:credentials] = Aws::Credentials.new(config['access_key_id'],config['secret_access_key'])
s3 = Aws::S3::Client.new(region:config['region'])
cf = Aws::CloudFront::Client.new(region:config['region'])
###### 設定 ###########################################
# バケット名
bucket_name = "hogehogehugahuga"
# CloudFrontで設定するアクセス識別子のコメント
cloudfront_origin_access_identity_comment = "hogehogehugahuga_access_identity"
# CloudFrontのコメント
cloudfront_comment = "test cloudfront"
#######################################################
reference = bucket_name + "_identity"
# CloudFrontからS3へ接続するための識別子を作成
ret = cf.create_cloud_front_origin_access_identity({
cloud_front_origin_access_identity_config: {
caller_reference: reference,
comment:cloudfront_origin_access_identity_comment,
}
})
cf_identity_id = ret.cloud_front_origin_access_identity.id
# S3へ設定するアクセスポリシーJSON
cf_policy = <<"EOL"
{
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity #{cf_identity_id}"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::#{bucket_name}/*"
}
]
}
EOL
# S3バケット作成
exist_flg = false
s3.list_buckets.buckets.each do |b|
if b.name == bucket_name
exist_flg = true
exit
end
end
if !exist_flg
s3.create_bucket({
acl: "private", # CloudFrontからアクセスするので外部公開設定にしない。
bucket: bucket_name,
create_bucket_configuration: {
location_constraint: config['region'],
},
})
# S3のバージョニングは設定しない
s3.put_bucket_versioning({
bucket: bucket_name,
versioning_configuration: {
status: "Suspended"
}
})
pp "Create S3 Bucket #{bucket_name}"
end
# S3バケットへアクセスポリシー適用
s3.put_bucket_policy({
bucket: bucket_name,
policy: cf_policy,
})
# CloudFront作成
pp "Creating CroudFront..."
begin
resp = cf.create_distribution({
distribution_config: {
caller_reference: reference, # CloudFrontからS3へ接続するための識別子を参照するユニークな文字列(…っと思う。リファレンス見ても良く分からない)
aliases: { # CNAMEの設定
quantity: 0, # item数。指定しない場合はゼロ
},
default_root_object: "index.html", # デフォルトRootオブジェクト
#オリジン設定
origins: {
quantity: 1, # 設定するアイテムの数
items: [
{
id: "S3-#{bucket_name}",
domain_name: "#{bucket_name}.s3.amazonaws.com",
s3_origin_config: {
origin_access_identity: "origin-access-identity/cloudfront/#{cf_identity_id}",
},
},
],
},
#デフォルトのキャッシュ動作設定
default_cache_behavior: {
target_origin_id: "S3-#{bucket_name}",
forwarded_values: {
query_string: false, #クエリ文字列を転送するか?
cookies: {
forward: "none", #クッキーを転送するか?
},
},
trusted_signers: { # 署名つきURLを使用するか?
enabled: false,
quantity: 0,
},
viewer_protocol_policy: "allow-all", #受け付けるリクエスト。allow-allだとHTTPとHTTPSを受け付ける。
min_ttl: 0,
allowed_methods: { # アクセスを許可するメソッド
quantity: 2, # itemの数
items: ["GET","HEAD"],
cached_methods: {
quantity: 2, # itemの数
items: ["GET","HEAD"],
},
},
},
comment: cloudfront_comment, #コメント
price_class: "PriceClass_200", # CloudFrontを配置する場所。PriceClass_100, PriceClass_200, PriceClass_Allから選択。PriceClass_200は米国とアジア
enabled: true, # CloudFrontを有効化するか?
viewer_certificate: { # SSL周り。CloudFrontのデフォルト証明書を使用する。
minimum_protocol_version: "SSLv3",
cloud_front_default_certificate: true,
},
restrictions: {
geo_restriction: { #アクセスを制限したい地域の設定。ブラックリストやホワイトリストを設定できる
restriction_type: "none",
quantity: 0,
},
},
},
})
pp "Please Wait a few minutes..."
cf.wait_until(:distribution_deployed,id:resp.distribution.id)
pp "CloudFront Deploy Succcess!!"
pp "Endpoint:#{resp.distribution.domain_name}"
rescue Aws::Waiters::Errors::WaiterFailed => e
pp "Failed waiting for CloudFront Deploy: #{e.message}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment