LoginSignup
6
0

More than 1 year has passed since last update.

AWSのCloudFrontを構築するスクリプトをRubyで作った

Posted at

目的

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"
6
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
0