{CloudFront}CloudFront オリジンフェイルオーバーによる高可用性の最適化

https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/high_availability_origin_failover.html

https://dev.classmethod.jp/articles/cloudfront-origin-failover/


プライマリオリジン: ALB
セカンダリオリジン: S3


-- 1. コマンド等のインストール

-- 1.1 aws cli version 2 インストール

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
aws --version

 

-- 1.2 jqインストール
sudo yum -y install jq


-- 2. EC2インスタンス作成


-- ap-northeast-1a


vim a.sh

#!/bin/bash
yum -y update
yum -y install httpd
systemctl start httpd
systemctl enable httpd
echo $(hostname) > /var/www/html/index.html

 

aws ec2 run-instances \
--image-id ami-0404778e217f54308 \
--instance-type t3.nano \
--key-name key1 \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=instance01}]' \
--subnet-id subnet-11111111111111111 \
--user-data file://a.sh

 

aws ec2 describe-instances

 


-- 3. ロードバランサーの作成


aws elbv2 create-load-balancer \
--name alb01  \
--subnets subnet-11111111111111111 subnet-22222222222222222 \
--security-groups sg-33333333333333333


aws elbv2 describe-load-balancers
aws elbv2 describe-load-balancers| jq -r .LoadBalancers.LoadBalancerArn

 


aws elbv2 create-target-group \
--name target01 \
--protocol HTTP \
--port 80 \
--vpc-id vpc-44444444444444444 \
--ip-address-type ipv4 \
--target-type instance

aws elbv2 describe-target-groups
aws elbv2 describe-target-groups| jq -r .TargetGroups.TargetGroupArn

aws elbv2 describe-target-group-attributes \
--target-group-arn arn:aws:elasticloadbalancing:ap-northeast-1:999999999999:targetgroup/target01/5555555555555555

 

aws elbv2 register-targets \
--target-group-arn arn:aws:elasticloadbalancing:ap-northeast-1:999999999999:targetgroup/target01/5555555555555555  \
--targets Id=i-88888888888888888


aws elbv2 describe-target-health \
--target-group-arn arn:aws:elasticloadbalancing:ap-northeast-1:999999999999:targetgroup/target01/5555555555555555

 


-- 4. リスナーの作成

aws elbv2 create-listener \
--load-balancer-arn arn:aws:elasticloadbalancing:ap-northeast-1:999999999999:loadbalancer/app/alb01/6666666666666666 \
--protocol HTTP \
--port 80  \
--default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:ap-northeast-1:999999999999:targetgroup/target01/5555555555555555


aws elbv2 describe-listeners \
--load-balancer-arn arn:aws:elasticloadbalancing:ap-northeast-1:999999999999:loadbalancer/app/alb01/6666666666666666

aws elbv2 describe-listeners \
--load-balancer-arn arn:aws:elasticloadbalancing:ap-northeast-1:999999999999:loadbalancer/app/alb01/6666666666666666 | jq -r .Listeners[].ListenerArn

 


-- 5. ディストリビューションの作成


aws cloudfront create-distribution \
--origin-domain-name alb01-0000000000.ap-northeast-1.elb.amazonaws.com

 


aws cloudfront list-distributions

aws cloudfront get-distribution \
--id AAAAAAAAAAAAAA

aws cloudfront get-distribution-config \
--id AAAAAAAAAAAAAA

 

 

-- 6. S3 バケットを作成する

aws s3 ls

aws s3 mb s3://bucket123

 

 

-- 7. パブリックアクセスブロック設定の編集

-- 7.1 アカウントレベル
aws s3control put-public-access-block \
--account-id 999999999999 \
--public-access-block-configuration "BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false"

aws s3control get-public-access-block \
--account-id 999999999999

-- 7.2 バケットレベル
aws s3api put-public-access-block \
--bucket bucket123 \
--public-access-block-configuration "BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false"

aws s3api get-public-access-block \
--bucket bucket123


-- 8. バケットポリシーの設定

vim b.json

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::bucket123/*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": "0.0.0.0/0"
                }
            }
        }
    ]
}

 

aws s3api put-bucket-policy \
--bucket bucket123 \
--policy file://b.json


aws s3api get-bucket-policy \
--bucket bucket123


-- 9. インデックスドキュメントの設定

vim index.html

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>My Website Home Page</title>
</head>
<body>
  <h1>Welcome to my website</h1>
  <p>Now hosted on Amazon S3!</p>
</body>
</html>

aws s3api put-object --bucket bucket123 --key index.html --body index.html --content-type text/html

 


-- 10. セカンドオリジンの追加


aws cloudfront get-distribution \
--id AAAAAAAAAAAAAA

aws cloudfront get-distribution-config \
--id AAAAAAAAAAAAAA


aws cloudfront get-distribution-config \
--id AAAAAAAAAAAAAA | jq -r .DistributionConfig > distribution.json

vim distribution.json


Origins -> Items に下記を追加し、Quantityを1 → 2に修正

      {
        "Id": "bucket123.s3.ap-northeast-1.amazonaws.com",
        "DomainName": "bucket123.s3.ap-northeast-1.amazonaws.com",
        "OriginPath": "",
        "CustomHeaders": {
          "Quantity": 0
        },
        "S3OriginConfig": {
          "OriginAccessIdentity": ""
        },
        "ConnectionAttempts": 3,
        "ConnectionTimeout": 10,
        "OriginShield": {
          "Enabled": false
        }
      },


aws cloudfront get-distribution-config \
--id AAAAAAAAAAAAAA | jq -r .ETag

aws cloudfront update-distribution \
--id AAAAAAAAAAAAAA \
--if-match BBBBBBBBBBBBBB \
--distribution-config file://distribution.json


-- 11. オリジングループの作成


aws cloudfront get-distribution \
--id AAAAAAAAAAAAAA

aws cloudfront get-distribution-config \
--id AAAAAAAAAAAAAA


aws cloudfront get-distribution-config \
--id AAAAAAAAAAAAAA | jq -r .DistributionConfig > distribution.json

vim distribution.json


OriginGroups を下記のように修正

  "OriginGroups": {
    "Quantity": 1,
    "Items": [
      {
        "Id": "og01",
        "FailoverCriteria": {
          "StatusCodes": {
            "Quantity": 8,
            "Items": [
              400,
              403,
              404,
              416,
              500,
              502,
              503,
              504
            ]
          }
        },
        "Members": {
          "Quantity": 2,
          "Items": [
            {
              "OriginId": "alb01-0000000000.ap-northeast-1.elb.amazonaws.com-0000000000-000000"
            },
            {
              "OriginId": "bucket123.s3.ap-northeast-1.amazonaws.com"
            }
          ]
        }
      }
    ]
  },


aws cloudfront get-distribution-config \
--id AAAAAAAAAAAAAA | jq -r .ETag

aws cloudfront update-distribution \
--id AAAAAAAAAAAAAA \
--if-match CCCCCCCCCCCCCC \
--distribution-config file://distribution.json


-- 12. デフォルトビヘイビアの修正


aws cloudfront get-distribution \
--id AAAAAAAAAAAAAA

aws cloudfront get-distribution-config \
--id AAAAAAAAAAAAAA


aws cloudfront get-distribution-config \
--id AAAAAAAAAAAAAA | jq -r .DistributionConfig > distribution.json

vim distribution.json


DefaultCacheBehavior を下記のように修正
※オブジェクトキャッシュの最大TTLと デフォルトTTLを10秒に設定

  "DefaultCacheBehavior": {
    "TargetOriginId": "og01",
    "TrustedSigners": {
      "Enabled": false,
      "Quantity": 0
    },
    "TrustedKeyGroups": {
      "Enabled": false,
      "Quantity": 0
    },
    "ViewerProtocolPolicy": "allow-all",
    "AllowedMethods": {
      "Quantity": 2,
      "Items": [
        "HEAD",
        "GET"
      ],
      "CachedMethods": {
        "Quantity": 2,
        "Items": [
          "HEAD",
          "GET"
        ]
      }
    },
    "SmoothStreaming": false,
    "Compress": false,
    "LambdaFunctionAssociations": {
      "Quantity": 0
    },
    "FunctionAssociations": {
      "Quantity": 0
    },
    "FieldLevelEncryptionId": "",
    "ForwardedValues": {
      "QueryString": false,
      "Cookies": {
        "Forward": "none"
      },
      "Headers": {
        "Quantity": 0
      },
      "QueryStringCacheKeys": {
        "Quantity": 0
      }
    },
    "MinTTL": 0,
    "DefaultTTL": 10,
    "MaxTTL": 10
  },
  

 


aws cloudfront get-distribution-config \
--id AAAAAAAAAAAAAA | jq -r .ETag

aws cloudfront update-distribution \
--id AAAAAAAAAAAAAA \
--if-match DDDDDDDDDDDDDD \
--distribution-config file://distribution.json

 


-- 13. 動作確認


curl -v -X GET https://xxxxxxxxxxxxx.cloudfront.net/index.html


curl -v -X GET http://alb01-0000000000.ap-northeast-1.elb.amazonaws.com/index.html


curl -v -X GET https://bucket123.s3.ap-northeast-1.amazonaws.com/index.html


ALBのEC2を停止してS3にフェイルオーバーを確認

ALBのステータスコードは503 Service Temporarily Unavailable

 


-- 14. クリーンアップ

 


-- ディストリビューションの無効化

aws cloudfront get-distribution \
--id AAAAAAAAAAAAAA

aws cloudfront get-distribution-config \
--id AAAAAAAAAAAAAA


※ distribution.jsonはget-distribution-configコマンドのDistributionConfigから取得し、Enabledをfalseに変更する

aws cloudfront get-distribution-config \
--id AAAAAAAAAAAAAA | jq -r .DistributionConfig > distribution.json

sed -i 's/"Enabled": true/"Enabled": false/' distribution.json

 

aws cloudfront get-distribution-config \
--id AAAAAAAAAAAAAA | jq -r .ETag

aws cloudfront update-distribution \
--id AAAAAAAAAAAAAA \
--if-match EEEEEEEEEEEEEE \
--distribution-config file://distribution.json


※ if-matchにはETagの値をセット

無効化されるまで待つ


-- ディストリビューションの削除

aws cloudfront get-distribution \
--id AAAAAAAAAAAAAA

aws cloudfront get-distribution-config \
--id AAAAAAAAAAAAAA

aws cloudfront get-distribution-config \
--id AAAAAAAAAAAAAA | jq -r .ETag

aws cloudfront delete-distribution \
--id AAAAAAAAAAAAAA \
--if-match FFFFFFFFFFFFF

aws cloudfront list-distributions

 

-- リスナーの削除

aws elbv2 describe-listeners \
--load-balancer-arn arn:aws:elasticloadbalancing:ap-northeast-1:999999999999:loadbalancer/app/alb01/6666666666666666


aws elbv2 delete-listener \
--listener-arn arn:aws:elasticloadbalancing:ap-northeast-1:999999999999:listener/app/alb01/6666666666666666/7777777777777777


-- ターゲットグループの削除

aws elbv2 describe-target-groups

aws elbv2 deregister-targets \
--target-group-arn arn:aws:elasticloadbalancing:ap-northeast-1:999999999999:targetgroup/target01/5555555555555555 \
--targets Id=i-88888888888888888

aws elbv2 delete-target-group \
--target-group-arn arn:aws:elasticloadbalancing:ap-northeast-1:999999999999:targetgroup/target01/5555555555555555

 


-- ロードバランサーの削除

aws elbv2 describe-load-balancers

aws elbv2 delete-load-balancer \
--load-balancer-arn arn:aws:elasticloadbalancing:ap-northeast-1:999999999999:loadbalancer/app/alb01/6666666666666666

 

-- EC2インスタンスの削除

aws ec2 describe-instances

aws ec2 terminate-instances --instance-ids i-88888888888888888

 

 

-- バケットの削除
aws s3 ls

aws s3 rb s3://bucket123 --force

-- アカウントレベルのパブリックアクセスブロックの有効化

aws s3control put-public-access-block \
--account-id 999999999999 \
--public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"

aws s3control get-public-access-block \
--account-id 999999999999