上記、「AWS 上で静的な Web サイトを公開しよう!」 をAWS CLIでやってみる
1. S3 の静的ホスティング機能を使ってみる
S3バケット作成
# S3バケット名
S3_BUCKET_NAME="handson.example.com" \
&& echo ${S3_BUCKET_NAME}
# S3バケット作成
aws s3api create-bucket \
--bucket ${S3_BUCKET_NAME} \
--create-bucket-configuration LocationConstraint=ap-northeast-1
# パブリックアクセスをすべてブロック:オフ
aws s3api put-public-access-block \
--bucket ${S3_BUCKET_NAME} \
--public-access-block-configuration 'BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false'
# 静的ウェブサイトホスティング
aws s3 website s3://${S3_BUCKET_NAME}/ \
--index-document index.html
[cloudshell-user@ip-10-130-61-60 ~]$ # S3バケット名
[cloudshell-user@ip-10-130-61-60 ~]$ S3_BUCKET_NAME="handson.example.com" \
> && echo ${S3_BUCKET_NAME}
handson.example.com
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # S3バケット作成
[cloudshell-user@ip-10-130-61-60 ~]$ aws s3api create-bucket \
> --bucket ${S3_BUCKET_NAME} \
> --create-bucket-configuration LocationConstraint=ap-northeast-1
{
"Location": "http://handson.example.com.s3.amazonaws.com/"
}
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # パブリックアクセスをすべてブロック:オフ
[cloudshell-user@ip-10-130-61-60 ~]$ aws s3api put-public-access-block \
> --bucket ${S3_BUCKET_NAME} \
> --public-access-block-configuration 'BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false'
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # 静的ウェブサイトホスティング
[cloudshell-user@ip-10-130-61-60 ~]$ aws s3 website s3://${S3_BUCKET_NAME}/ \
> --index-document index.html
バケットポリシー適用
# バケットポリシー(JSON)
BACKET_POLICY=$(cat << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::${S3_BUCKET_NAME}/*"
]
}
]
}
EOF
) \
&& echo ${BACKET_POLICY}
# JSONフォーマットの確認
echo ${BACKET_POLICY} | python -m json.tool
# バケットポリシー
aws s3api put-bucket-policy \
--bucket ${S3_BUCKET_NAME} \
--policy "${BACKET_POLICY}"
[cloudshell-user@ip-10-130-61-60 ~]$ # バケットポリシー(JSON)
[cloudshell-user@ip-10-130-61-60 ~]$ BACKET_POLICY=$(cat << EOF
> {
> "Version": "2012-10-17",
> "Statement": [
> {
> "Sid": "PublicReadGetObject",
> "Effect": "Allow",
> "Principal": "*",
> "Action": [
> "s3:GetObject"
> ],
> "Resource": [
> "arn:aws:s3:::${S3_BUCKET_NAME}/*"
> ]
> }
> ]
> }
> EOF
> ) \
> && echo ${BACKET_POLICY}
{ "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": [ "s3:GetObject" ], "Resource": [ "arn:aws:s3:::handson.example.com/*" ] } ] }
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-130-61-60 ~]$ echo ${BACKET_POLICY} | python -m json.tool
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::handson.example.com/*"
]
}
]
}
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # バケットポリシー
[cloudshell-user@ip-10-130-61-60 ~]$ aws s3api put-bucket-policy \
> --bucket ${S3_BUCKET_NAME} \
> --policy "${BACKET_POLICY}"
index.htmlのアップロード
aws s3 cp index.html s3://${S3_BUCKET_NAME}/
[cloudshell-user@ip-10-130-61-60 ~]$ aws s3 cp index.html s3://${S3_BUCKET_NAME}/
upload: ./index.html to s3://handson.example.com/index.html
アクセス確認
curl http://handson.example.com.s3-website-ap-northeast-1.amazonaws.com/
[cloudshell-user@ip-10-130-61-60 ~]$ curl http://handson.example.com.s3-website-ap-northeast-1.amazonaws.com/
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>はじめての S3 静的 Web サイトホスティング</title>
</head>
<body>
<div>
<div class="msg">
Hello, AWS World!!
</div>
</div>
</body>
2. Cloud9 環境を立ち上げて静的コンテンツを開発する + AWS CLI で S3 にファイルアップロードする
Cloud9環境作成
# Cloud9環境名
CLOUD9_ENVIRONMENT_NAME="hands-on" \
&& echo ${CLOUD9_ENVIRONMENT_NAME}
# Cloud9環境作成
CLOUD9_ENVIRONMENT_ID=$(
aws cloud9 create-environment-ec2 \
--name ${CLOUD9_ENVIRONMENT_NAME} \
--instance-type t2.micro \
--image-id resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2-x86_64 \
--connection-type CONNECT_SSM \
--automatic-stop-time-minutes 30 \
--query environmentId \
--output text
) \
&& echo ${CLOUD9_ENVIRONMENT_ID}
[cloudshell-user@ip-10-130-61-60 ~]$ # Cloud9環境名
[cloudshell-user@ip-10-130-61-60 ~]$ CLOUD9_ENVIRONMENT_NAME="hands-on" \
> && echo ${CLOUD9_ENVIRONMENT_NAME}
hands-on
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # Cloud9環境作成
[cloudshell-user@ip-10-130-61-60 ~]$ CLOUD9_ENVIRONMENT_ID=$(
> aws cloud9 create-environment-ec2 \
> --name ${CLOUD9_ENVIRONMENT_NAME} \
> --instance-type t2.micro \
> --image-id resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2-x86_64 \
> --connection-type CONNECT_SSM \
> --automatic-stop-time-minutes 30 \
> --query environmentId \
> --output text
> ) \
> && echo ${CLOUD9_ENVIRONMENT_ID}
1fab01bdfd684c26afbc4bf5e60af558
作業用ディレクトリ作成
mkdir my-webpage
cd my-webpage/
admin:~/environment $ mkdir my-webpage
admin:~/environment $ cd my-webpage/
静的コンテンツを開発
cat << EOF > index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>はじめての AWS</title>
</head>
<body>
<div>
<div class="msg">
このページでは、AWS について学んだことを書いていきます。
</div>
</div>
</body>
</html>
EOF
cat index.html
admin:~/environment/my-webpage $ cat << EOF > index.html
> <!DOCTYPE html>
>
> <html lang="ja">
> <head>
> <meta charset="utf-8">
> <title>はじめての AWS</title>
> </head>
> <body>
> <div>
> <div class="msg">
> このページでは、AWS について学んだことを書いていきます。
> </div>
> </div>
> </body>
> </html>
> EOF
admin:~/environment/my-webpage $ cat index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>はじめての AWS</title>
</head>
<body>
<div>
<div class="msg">
このページでは、AWS について学んだことを書いていきます。
</div>
</div>
</body>
</html>
index.htmlのアップロード
aws s3 cp index.html s3://handson.example.com
admin:~/environment/my-webpage $ aws s3 cp index.html s3://handson.example.com
upload: ./index.html to s3://handson.example.com/index.html
アクセス確認
curl http://handson.example.com.s3-website-ap-northeast-1.amazonaws.com/
admin:~/environment/my-webpage $ curl http://handson.example.com.s3-website-ap-northeast-1.amazonaws.com/
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>はじめての AWS</title>
</head>
<body>
<div>
<div class="msg">
このページでは、AWS について学んだことを書いていきます。
</div>
</div>
</body>
</html>
3. 続・静的コンテンツの開発 + AWS CLI で S3 に複数のファイルを一括アップロードする
ディレクトリ作成
mkdir img
mkdir css
touch css/styles.css
admin:~/environment/my-webpage $ mkdir img
admin:~/environment/my-webpage $ mkdir css
admin:~/environment/my-webpage $ touch css/styles.css
ハンズオンからダウンロードしたファイルをCloud9環境にアップロード
lambda.png : /home/ec2-user/environment/my-webpage/img
favicon.ico : /home/ec2-user/environment/my-webpage
index.html修正
cat << EOF > index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>はじめての AWS</title>
<link rel="icon" href="favicon.ico">
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<div>
<div class="icon">
<img src="img/lambda.png">
</div>
<div class="msg">
このページでは、AWS について学んだことを書いていきます。
</div>
</div>
</body>
</html>
EOF
cat index.html
admin:~/environment/my-webpage $ cat << EOF > index.html
> <!DOCTYPE html>
>
> <html lang="ja">
> <head>
> <meta charset="utf-8">
> <title>はじめての AWS</title>
> <link rel="icon" href="favicon.ico">
> <link rel="stylesheet" href="css/styles.css">
> </head>
> <body>
> <div>
> <div class="icon">
> <img src="img/lambda.png">
> </div>
> <div class="msg">
> このページでは、AWS について学んだことを書いていきます。
> </div>
> </div>
> </body>
> </html>
> EOF
admin:~/environment/my-webpage $ cat index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>はじめての AWS</title>
<link rel="icon" href="favicon.ico">
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<div>
<div class="icon">
<img src="img/lambda.png">
</div>
<div class="msg">
このページでは、AWS について学んだことを書いていきます。
</div>
</div>
</body>
</html>
styles.css作成
cat << EOF > css/styles.css
body {
width: 300px;
margin-left: auto;
margin-right: auto;
}
.icon img {
padding-top: 16px;
padding-bottom: 16px;
}
EOF
cat css/styles.css
admin:~/environment/my-webpage $ cat << EOF > css/styles.css
> body {
> width: 300px;
> margin-left: auto;
> margin-right: auto;
> }
>
> .icon img {
> padding-top: 16px;
> padding-bottom: 16px;
> }
> EOF
admin:~/environment/my-webpage $ cat css/styles.css
body {
width: 300px;
margin-left: auto;
margin-right: auto;
}
.icon img {
padding-top: 16px;
padding-bottom: 16px;
}
ファイルのアップロード
aws s3 cp . s3://handson.example.com --recursive
admin:~/environment/my-webpage $ aws s3 cp . s3://handson.example.com --recursive
upload: css/styles.css to s3://handson.example.com/css/styles.css
upload: ./favicon.ico to s3://handson.example.com/favicon.ico
upload: img/lambda.png to s3://handson.example.com/img/lambda.png
upload: ./index.html to s3://handson.example.com/index.html
アクセス確認
curl http://handson.example.com.s3-website-ap-northeast-1.amazonaws.com/
admin:~/environment/my-webpage $ curl http://handson.example.com.s3-website-ap-northeast-1.amazonaws.com/
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>はじめての AWS</title>
<link rel="icon" href="favicon.ico">
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<div>
<div class="icon">
<img src="img/lambda.png">
</div>
<div class="msg">
このページでは、AWS について学んだことを書いていきます。
</div>
</div>
</body>
</html>
4. CloudFront を使って、画像をキャッシュさせる
CloudFront作成
# 変数
ORIGIN_DOMAIN_NAME="${S3_BUCKET_NAME}.s3-website-ap-northeast-1.amazonaws.com" \
&& echo ${ORIGIN_DOMAIN_NAME}
# ディストリビューションを作成
aws cloudfront create-distribution \
--origin-domain-name ${ORIGIN_DOMAIN_NAME}
[cloudshell-user@ip-10-130-61-60 ~]$ # 変数
[cloudshell-user@ip-10-130-61-60 ~]$ ORIGIN_DOMAIN_NAME="${S3_BUCKET_NAME}.s3-website-ap-northeast-1.amazonaws.com" \
> && echo ${ORIGIN_DOMAIN_NAME}
handson.example.com.s3-website-ap-northeast-1.amazonaws.com
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # ディストリビューションを作成
[cloudshell-user@ip-10-130-61-60 ~]$ aws cloudfront create-distribution \
> --origin-domain-name ${ORIGIN_DOMAIN_NAME}
{
"Location": "https://cloudfront.amazonaws.com/2020-05-31/distribution/E4GYIQL4T0TP0",
"ETag": "E95HZYNGU9MLI",
"Distribution": {
"Id": "E4GYIQL4T0TP0",
"ARN": "arn:aws:cloudfront::999999999999:distribution/E4GYIQL4T0TP0",
"Status": "InProgress",
"LastModifiedTime": "2024-07-21T09:57:38.143000+00:00",
"InProgressInvalidationBatches": 0,
"DomainName": "d2xpr76fxshx5q.cloudfront.net",
"ActiveTrustedSigners": {
"Enabled": false,
"Quantity": 0
},
"ActiveTrustedKeyGroups": {
"Enabled": false,
"Quantity": 0
},
"DistributionConfig": {
"CallerReference": "cli-1721555857-121159",
"Aliases": {
"Quantity": 0
},
"DefaultRootObject": "",
"Origins": {
"Quantity": 1,
"Items": [
{
"Id": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com-1721555857-565971",
"DomainName": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"CustomOriginConfig": {
"HTTPPort": 80,
"HTTPSPort": 443,
"OriginProtocolPolicy": "http-only",
"OriginSslProtocols": {
"Quantity": 3,
"Items": [
"TLSv1",
"TLSv1.1",
"TLSv1.2"
]
},
"OriginReadTimeout": 30,
"OriginKeepaliveTimeout": 5
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": ""
}
]
},
"OriginGroups": {
"Quantity": 0
},
"DefaultCacheBehavior": {
"TargetOriginId": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com-1721555857-565971",
"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": 86400,
"MaxTTL": 31536000
},
"CacheBehaviors": {
"Quantity": 0
},
"CustomErrorResponses": {
"Quantity": 0
},
"Comment": "",
"Logging": {
"Enabled": false,
"IncludeCookies": false,
"Bucket": "",
"Prefix": ""
},
"PriceClass": "PriceClass_All",
"Enabled": true,
"ViewerCertificate": {
"CloudFrontDefaultCertificate": true,
"SSLSupportMethod": "vip",
"MinimumProtocolVersion": "TLSv1",
"CertificateSource": "cloudfront"
},
"Restrictions": {
"GeoRestriction": {
"RestrictionType": "none",
"Quantity": 0
}
},
"WebACLId": "",
"HttpVersion": "http2",
"IsIPV6Enabled": true,
"ContinuousDeploymentPolicyId": "",
"Staging": false
}
}
}
変数取得
# ディストリビューションIDを変数に保存
DISTRIBUTION_ID=$(
aws cloudfront list-distributions \
--query "DistributionList.Items[?Origins.Items[?DomainName=='${ORIGIN_DOMAIN_NAME}']].Id" \
--output text
) \
&& echo ${DISTRIBUTION_ID}
# ディストリビューションドメイン名を変数に保存
DISTRIBUTION_DOMAINNAME=$(
aws cloudfront list-distributions \
--query "DistributionList.Items[?Origins.Items[?DomainName=='${ORIGIN_DOMAIN_NAME}']].DomainName" \
--output text
) \
&& echo ${DISTRIBUTION_DOMAINNAME}
# ディストリビューションARNを変数に保存
DISTRIBUTION_ARN=$(
aws cloudfront get-distribution \
--id ${DISTRIBUTION_ID} \
--query "Distribution.ARN" \
--output text
) \
&& echo ${DISTRIBUTION_ARN}
[cloudshell-user@ip-10-130-61-60 ~]$ # ディストリビューションIDを変数に保存
[cloudshell-user@ip-10-130-61-60 ~]$ DISTRIBUTION_ID=$(
> aws cloudfront list-distributions \
> --query "DistributionList.Items[?Origins.Items[?DomainName=='${ORIGIN_DOMAIN_NAME}']].Id" \
> --output text
> ) \
> && echo ${DISTRIBUTION_ID}
E4GYIQL4T0TP0
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # ディストリビューションドメイン名を変数に保存
[cloudshell-user@ip-10-130-61-60 ~]$ DISTRIBUTION_DOMAINNAME=$(
> aws cloudfront list-distributions \
> --query "DistributionList.Items[?Origins.Items[?DomainName=='${ORIGIN_DOMAIN_NAME}']].DomainName" \
> --output text
> ) \
> && echo ${DISTRIBUTION_DOMAINNAME}
d2xpr76fxshx5q.cloudfront.net
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # ディストリビューションARNを変数に保存
[cloudshell-user@ip-10-130-61-60 ~]$ DISTRIBUTION_ARN=$(
> aws cloudfront get-distribution \
> --id ${DISTRIBUTION_ID} \
> --query "Distribution.ARN" \
> --output text
> ) \
> && echo ${DISTRIBUTION_ARN}
arn:aws:cloudfront::999999999999:distribution/E4GYIQL4T0TP0
アクセス確認
curl http://d2xpr76fxshx5q.cloudfront.net/
[cloudshell-user@ip-10-130-61-60 ~]$ curl http://d2xpr76fxshx5q.cloudfront.net/
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>はじめての AWS</title>
<link rel="icon" href="favicon.ico">
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<div>
<div class="icon">
<img src="img/lambda.png">
</div>
<div class="msg">
このページでは、AWS について学んだことを書いていきます。
</div>
</div>
</body>
</html>
5. [Option / Demo] Route 53 で独自ドメインを取得し、S3 に HTTP アクセスする
ハンズオン内ではAWSでドメインの取得を行っていたが、Googleドメイン(Squarespace)で取得していたテスト用ドメインがあったため、サブドメインを設定してそれで代用
ホストゾーン登録
AWSで取得したドメインではないため、手動でホストゾーンを登録
# ドメイン名
HOSTED_ZONE_NAME="handson.example.com" \
&& echo ${HOSTED_ZONE_NAME}
aws route53 create-hosted-zone \
--name ${HOSTED_ZONE_NAME} \
--caller-reference `date +"%Y-%m-%d-%H-%M"`
# ホストゾーンIDを取得
HOSTED_ZONE_ID=$(\
aws route53 list-hosted-zones \
--query "HostedZones[?Name=='${HOSTED_ZONE_NAME}.'].Id" \
--output text
) \
&& echo ${HOSTED_ZONE_ID}
[cloudshell-user@ip-10-130-61-60 ~]$ # ドメイン名
[cloudshell-user@ip-10-130-61-60 ~]$ HOSTED_ZONE_NAME="handson.example.com" \
> && echo ${HOSTED_ZONE_NAME}
handson.example.com
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ aws route53 create-hosted-zone \
> --name ${HOSTED_ZONE_NAME} \
> --caller-reference `date +"%Y-%m-%d-%H-%M"`
{
"Location": "https://route53.amazonaws.com/2013-04-01/hostedzone/Z0649758FK3WFRRBZQNW",
"HostedZone": {
"Id": "/hostedzone/Z0649758FK3WFRRBZQNW",
"Name": "handson.example.com.",
"CallerReference": "2024-07-21-10-25",
"Config": {
"PrivateZone": false
},
"ResourceRecordSetCount": 2
},
"ChangeInfo": {
"Id": "/change/C00350601ZVV4NNFDA7CG",
"Status": "PENDING",
"SubmittedAt": "2024-07-21T10:25:39.064000+00:00"
},
"DelegationSet": {
"NameServers": [
"ns-1260.awsdns-29.org",
"ns-902.awsdns-48.net",
"ns-1560.awsdns-03.co.uk",
"ns-461.awsdns-57.com"
]
}
}
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # ホストゾーンIDを取得
[cloudshell-user@ip-10-130-61-60 ~]$ HOSTED_ZONE_ID=$(\
> aws route53 list-hosted-zones \
> --query "HostedZones[?Name=='${HOSTED_ZONE_NAME}.'].Id" \
> --output text
> ) \
> && echo ${HOSTED_ZONE_ID}
/hostedzone/Z0649758FK3WFRRBZQNW
表示されたNameSersをサブドメインのNSレコードとして登録する
# レコード登録用JSON
RECORD_JSON=$(cat << EOF
{
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "${HOSTED_ZONE_NAME}",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "Z2M4EHUR26P7ZW",
"DNSName": "s3-website-ap-northeast-1.amazonaws.com.",
"EvaluateTargetHealth": true
}
}
}
]
}
EOF
) \
&& echo ${RECORD_JSON}
# JSONフォーマットの確認
echo ${RECORD_JSON} | python -m json.tool
# レコード作成
aws route53 change-resource-record-sets \
--hosted-zone-id ${HOSTED_ZONE_ID} \
--change-batch "${RECORD_JSON}"
"HostedZoneId": "Z2M4EHUR26P7ZW",
// S3のウェブサイトホスティング用の固定Hosted Zone ID
"DNSName": "s3-website-ap-northeast-1.amazonaws.com.",
// S3バケットのリージョンに対応するエンドポイント
[cloudshell-user@ip-10-130-61-60 ~]$ # レコード登録用JSON
[cloudshell-user@ip-10-130-61-60 ~]$ RECORD_JSON=$(cat << EOF
> {
> "Changes": [
> {
> "Action": "UPSERT",
> "ResourceRecordSet": {
> "Name": "${HOSTED_ZONE_NAME}",
> "Type": "A",
> "AliasTarget": {
> "HostedZoneId": "Z2M4EHUR26P7ZW",
> "DNSName": "s3-website-ap-northeast-1.amazonaws.com.",
> "EvaluateTargetHealth": true
> }
> }
> }
> ]
> }
> EOF
> ) \
> && echo ${RECORD_JSON}
{ "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name": "handson.example.com", "Type": "A", "AliasTarget": { "HostedZoneId": "Z2M4EHUR26P7ZW", "DNSName": "s3-website-ap-northeast-1.amazonaws.com.", "EvaluateTargetHealth": true } } } ] }
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-130-61-60 ~]$ echo ${RECORD_JSON} | python -m json.tool
{
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "handson.example.com",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "Z2M4EHUR26P7ZW",
"DNSName": "s3-website-ap-northeast-1.amazonaws.com.",
"EvaluateTargetHealth": true
}
}
}
]
}
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # レコード作成
[cloudshell-user@ip-10-130-61-60 ~]$ aws route53 change-resource-record-sets \
> --hosted-zone-id ${HOSTED_ZONE_ID} \
> --change-batch "${RECORD_JSON}"
{
"ChangeInfo": {
"Id": "/change/C0988662NXJC47I5XS7H",
"Status": "PENDING",
"SubmittedAt": "2024-07-21T10:29:15.797000+00:00"
}
}
アクセス確認
curl http://handson.example.com/
[cloudshell-user@ip-10-130-61-60 ~]$ curl http://handson.example.com/
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>はじめての AWS</title>
<link rel="icon" href="favicon.ico">
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<div>
<div class="icon">
<img src="img/lambda.png">
</div>
<div class="msg">
このページでは、AWS について学んだことを書いていきます。
</div>
</div>
</body>
</html>
6. [Option / Demo] ACM を使い、Route 53 - CloudFront - S3 で HTTPS アクセスする
証明書はus-east-1リージョン(バージニア北部)に作成する
証明書の作成 (ACM)
証明書の作成
# 証明書の作成
aws acm request-certificate \
--domain-name ${HOSTED_ZONE_NAME} \
--validation-method DNS \
--region us-east-1
# 証明書のARN取得
CERTIFICATE_ARN=$(
aws acm list-certificates \
--region us-east-1 \
--query "CertificateSummaryList[?DomainName=='${HOSTED_ZONE_NAME}'].CertificateArn" \
--output text
) &&
echo ${CERTIFICATE_ARN}
[cloudshell-user@ip-10-130-61-60 ~]$ # 証明書の作成
[cloudshell-user@ip-10-130-61-60 ~]$ aws acm request-certificate \
> --domain-name ${HOSTED_ZONE_NAME} \
> --validation-method DNS \
> --region us-east-1
{
"CertificateArn": "arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56"
}
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # 証明書のARN取得
[cloudshell-user@ip-10-130-61-60 ~]$ CERTIFICATE_ARN=$(
> aws acm list-certificates \
> --region us-east-1 \
> --query "CertificateSummaryList[?DomainName=='${HOSTED_ZONE_NAME}'].CertificateArn" \
> --output text
> ) &&
> echo ${CERTIFICATE_ARN}
arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56
証明書の確認
aws acm describe-certificate \
--certificate-arn ${CERTIFICATE_ARN} \
--region us-east-1
[cloudshell-user@ip-10-130-61-60 ~]$ aws acm describe-certificate \
> --certificate-arn ${CERTIFICATE_ARN} \
> --region us-east-1
{
"Certificate": {
"CertificateArn": "arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56",
"DomainName": "handson.example.com",
"SubjectAlternativeNames": [
"handson.example.com"
],
"DomainValidationOptions": [
{
"DomainName": "handson.example.com",
"ValidationDomain": "handson.example.com",
"ValidationStatus": "PENDING_VALIDATION",
"ResourceRecord": {
"Name": "_e049795f32552612c6135c8d935dd7e5.handson.example.com.",
"Type": "CNAME",
"Value": "_386e01e1ba95af93def7ed60e3413159.sdgjtdhdhz.acm-validations.aws."
},
"ValidationMethod": "DNS"
}
],
"Subject": "CN=handson.example.com",
"Issuer": "Amazon",
"CreatedAt": "2024-07-21T10:40:17.771000+00:00",
"Status": "PENDING_VALIDATION",
"KeyAlgorithm": "RSA-2048",
"SignatureAlgorithm": "SHA256WITHRSA",
"InUseBy": [],
"Type": "AMAZON_ISSUED",
"KeyUsages": [],
"ExtendedKeyUsages": [],
"RenewalEligibility": "INELIGIBLE",
"Options": {
"CertificateTransparencyLoggingPreference": "ENABLED"
}
}
}
証明書検証用のDNS登録 (Route53)
レコード登録用JSON
# 変数
VALIDATION_OPTIONS_NAME=$(
aws acm describe-certificate \
--region us-east-1 \
--certificate-arn ${CERTIFICATE_ARN} \
--query "Certificate.DomainValidationOptions[?DomainName=='${HOSTED_ZONE_NAME}'].ResourceRecord.Name" \
--output text
) \
&& echo ${VALIDATION_OPTIONS_NAME}
VALIDATION_OPTIONS_TYPE=$(
aws acm describe-certificate \
--region us-east-1 \
--certificate-arn ${CERTIFICATE_ARN} \
--query "Certificate.DomainValidationOptions[?DomainName=='${HOSTED_ZONE_NAME}'].ResourceRecord.Type" \
--output text
) \
&& echo ${VALIDATION_OPTIONS_TYPE}
VALIDATION_OPTIONS_VALUE=$(
aws acm describe-certificate \
--region us-east-1 \
--certificate-arn ${CERTIFICATE_ARN} \
--query "Certificate.DomainValidationOptions[?DomainName=='${HOSTED_ZONE_NAME}'].ResourceRecord.Value" \
--output text
) \
&& echo ${VALIDATION_OPTIONS_VALUE}
# レコード登録用JSON
RECORD_JSON=$(cat << EOF
{
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "${VALIDATION_OPTIONS_NAME}",
"Type": "${VALIDATION_OPTIONS_TYPE}",
"TTL": 300,
"ResourceRecords": [
{
"Value": "${VALIDATION_OPTIONS_VALUE}"
}
]
}
}
]
}
EOF
) \
&& echo ${RECORD_JSON}
# JSONフォーマットの確認
echo ${RECORD_JSON} | python -m json.tool
[cloudshell-user@ip-10-130-61-60 ~]$ # 変数
[cloudshell-user@ip-10-130-61-60 ~]$ VALIDATION_OPTIONS_NAME=$(
> aws acm describe-certificate \
> --region us-east-1 \
> --certificate-arn ${CERTIFICATE_ARN} \
> --query "Certificate.DomainValidationOptions[?DomainName=='${HOSTED_ZONE_NAME}'].ResourceRecord.Name" \
> --output text
> ) \
> && echo ${VALIDATION_OPTIONS_NAME}
_e049795f32552612c6135c8d935dd7e5.handson.example.com.
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ VALIDATION_OPTIONS_TYPE=$(
> aws acm describe-certificate \
> --region us-east-1 \
> --certificate-arn ${CERTIFICATE_ARN} \
> --query "Certificate.DomainValidationOptions[?DomainName=='${HOSTED_ZONE_NAME}'].ResourceRecord.Type" \
> --output text
> ) \
> && echo ${VALIDATION_OPTIONS_TYPE}
CNAME
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ VALIDATION_OPTIONS_VALUE=$(
> aws acm describe-certificate \
> --region us-east-1 \
> --certificate-arn ${CERTIFICATE_ARN} \
> --query "Certificate.DomainValidationOptions[?DomainName=='${HOSTED_ZONE_NAME}'].ResourceRecord.Value" \
> --output text
> ) \
> && echo ${VALIDATION_OPTIONS_VALUE}
_386e01e1ba95af93def7ed60e3413159.sdgjtdhdhz.acm-validations.aws.
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # レコード登録用JSON
[cloudshell-user@ip-10-130-61-60 ~]$ RECORD_JSON=$(cat << EOF
> {
> "Changes": [
> {
> "Action": "UPSERT",
> "ResourceRecordSet": {
> "Name": "${VALIDATION_OPTIONS_NAME}",
> "Type": "${VALIDATION_OPTIONS_TYPE}",
> "TTL": 300,
> "ResourceRecords": [
> {
> "Value": "${VALIDATION_OPTIONS_VALUE}"
> }
> ]
> }
> }
> ]
> }
> EOF
> ) \
> && echo ${RECORD_JSON}
{ "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name": "_e049795f32552612c6135c8d935dd7e5.handson.example.com.", "Type": "CNAME", "TTL": 300, "ResourceRecords": [ { "Value": "_386e01e1ba95af93def7ed60e3413159.sdgjtdhdhz.acm-validations.aws." } ] } } ] }
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-130-61-60 ~]$ echo ${RECORD_JSON} | python -m json.tool
{
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "_e049795f32552612c6135c8d935dd7e5.handson.example.com.",
"Type": "CNAME",
"TTL": 300,
"ResourceRecords": [
{
"Value": "_386e01e1ba95af93def7ed60e3413159.sdgjtdhdhz.acm-validations.aws."
}
]
}
}
]
}
レコード作成
# レコード作成
aws route53 change-resource-record-sets \
--hosted-zone-id ${HOSTED_ZONE_ID} \
--change-batch "${RECORD_JSON}"
[cloudshell-user@ip-10-130-61-60 ~]$ # レコード作成
[cloudshell-user@ip-10-130-61-60 ~]$ aws route53 change-resource-record-sets \
> --hosted-zone-id ${HOSTED_ZONE_ID} \
> --change-batch "${RECORD_JSON}"
{
"ChangeInfo": {
"Id": "/change/C07224581TG0MDCQJIMIL",
"Status": "PENDING",
"SubmittedAt": "2024-07-21T10:52:02.673000+00:00"
}
}
証明書検証の確認
DNSレコード登録後、"Status": "ISSUED"になるまで時間がかかる
aws acm describe-certificate \
--certificate-arn ${CERTIFICATE_ARN} \
--region us-east-1
[cloudshell-user@ip-10-130-61-60 ~]$ aws acm describe-certificate \
> --certificate-arn ${CERTIFICATE_ARN} \
> --region us-east-1
{
"Certificate": {
"CertificateArn": "arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56",
"DomainName": "handson.example.com",
"SubjectAlternativeNames": [
"handson.example.com"
],
"DomainValidationOptions": [
{
"DomainName": "handson.example.com",
"ValidationDomain": "handson.example.com",
"ValidationStatus": "SUCCESS",
"ResourceRecord": {
"Name": "_e049795f32552612c6135c8d935dd7e5.handson.example.com.",
"Type": "CNAME",
"Value": "_386e01e1ba95af93def7ed60e3413159.sdgjtdhdhz.acm-validations.aws."
},
"ValidationMethod": "DNS"
}
],
"Serial": "04:c3:b1:2b:2c:68:d4:ab:28:1f:f8:aa:f0:8e:05:3b",
"Subject": "CN=handson.example.com",
"Issuer": "Amazon",
"CreatedAt": "2024-07-21T10:40:17.771000+00:00",
"IssuedAt": "2024-07-21T10:57:36.229000+00:00",
"Status": "ISSUED",
"NotBefore": "2024-07-21T00:00:00+00:00",
"NotAfter": "2025-08-19T23:59:59+00:00",
"KeyAlgorithm": "RSA-2048",
"SignatureAlgorithm": "SHA256WITHRSA",
"InUseBy": [],
"Type": "AMAZON_ISSUED",
"KeyUsages": [
{
"Name": "DIGITAL_SIGNATURE"
},
{
"Name": "KEY_ENCIPHERMENT"
}
],
"ExtendedKeyUsages": [
{
"Name": "TLS_WEB_SERVER_AUTHENTICATION",
"OID": "1.3.6.1.5.5.7.3.1"
},
{
"Name": "TLS_WEB_CLIENT_AUTHENTICATION",
"OID": "1.3.6.1.5.5.7.3.2"
}
],
"RenewalEligibility": "INELIGIBLE",
"Options": {
"CertificateTransparencyLoggingPreference": "ENABLED"
}
}
}
CloudFrontへの証明書の適用
CloudFront設定用JSON
# ビヘイビア設定、CNAME設定、証明書適用
CONFIG_JSON=$(
aws cloudfront get-distribution-config \
--id ${DISTRIBUTION_ID} \
| jq .DistributionConfig \
| jq '.DefaultCacheBehavior.ViewerProtocolPolicy = "redirect-to-https"' \
| jq --arg certArn "${CERTIFICATE_ARN}" '.ViewerCertificate |= . + {"ACMCertificateArn": $certArn, "Certificate": $certArn, "CloudFrontDefaultCertificate": false, "SSLSupportMethod": "sni-only", "MinimumProtocolVersion": "TLSv1.2_2021", "CertificateSource": "acm"}' \
| jq --arg new_domain "${HOSTED_ZONE_NAME}" '.Aliases.Items += [$new_domain] | .Aliases.Quantity += 1'
) \
&& echo ${CONFIG_JSON}
# JSONフォーマットの確認
echo ${CONFIG_JSON} | python -m json.tool
[cloudshell-user@ip-10-130-61-60 ~]$ # ビヘイビア設定、CNAME設定、証明書適用
[cloudshell-user@ip-10-130-61-60 ~]$ CONFIG_JSON=$(
> aws cloudfront get-distribution-config \
> --id ${DISTRIBUTION_ID} \
> | jq .DistributionConfig \
> | jq '.DefaultCacheBehavior.ViewerProtocolPolicy = "redirect-to-https"' \
> | jq --arg certArn "${CERTIFICATE_ARN}" '.ViewerCertificate |= . + {"ACMCertificateArn": $certArn, "Certificate": $certArn, "CloudFrontDefaultCertificate": false, "SSLSupportMethod": "sni-only", "MinimumProtocolVersion": "TLSv1.2_2021", "CertificateSource": "acm"}' \
> | jq --arg new_domain "${HOSTED_ZONE_NAME}" '.Aliases.Items += [$new_domain] | .Aliases.Quantity += 1'
> ) \
> && echo ${CONFIG_JSON}
{ "CallerReference": "cli-1721555857-121159", "Aliases": { "Quantity": 1, "Items": [ "handson.example.com" ] }, "DefaultRootObject": "", "Origins": { "Quantity": 1, "Items": [ { "Id": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com-1721555857-565971", "DomainName": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com", "OriginPath": "", "CustomHeaders": { "Quantity": 0 }, "CustomOriginConfig": { "HTTPPort": 80, "HTTPSPort": 443, "OriginProtocolPolicy": "http-only", "OriginSslProtocols": { "Quantity": 3, "Items": [ "TLSv1", "TLSv1.1", "TLSv1.2" ] }, "OriginReadTimeout": 30, "OriginKeepaliveTimeout": 5 }, "ConnectionAttempts": 3, "ConnectionTimeout": 10, "OriginShield": { "Enabled": false }, "OriginAccessControlId": "" } ] }, "OriginGroups": { "Quantity": 0 }, "DefaultCacheBehavior": { "TargetOriginId": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com-1721555857-565971", "TrustedSigners": { "Enabled": false, "Quantity": 0 }, "TrustedKeyGroups": { "Enabled": false, "Quantity": 0 }, "ViewerProtocolPolicy": "redirect-to-https", "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": 86400, "MaxTTL": 31536000 }, "CacheBehaviors": { "Quantity": 0 }, "CustomErrorResponses": { "Quantity": 0 }, "Comment": "", "Logging": { "Enabled": false, "IncludeCookies": false, "Bucket": "", "Prefix": "" }, "PriceClass": "PriceClass_All", "Enabled": true, "ViewerCertificate": { "CloudFrontDefaultCertificate": false, "SSLSupportMethod": "sni-only", "MinimumProtocolVersion": "TLSv1.2_2021", "CertificateSource": "acm", "ACMCertificateArn": "arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56", "Certificate": "arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56" }, "Restrictions": { "GeoRestriction": { "RestrictionType": "none", "Quantity": 0 } }, "WebACLId": "", "HttpVersion": "http2", "IsIPV6Enabled": true, "ContinuousDeploymentPolicyId": "", "Staging": false }
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-130-61-60 ~]$ echo ${CONFIG_JSON} | python -m json.tool
{
"CallerReference": "cli-1721555857-121159",
"Aliases": {
"Quantity": 1,
"Items": [
"handson.example.com"
]
},
"DefaultRootObject": "",
"Origins": {
"Quantity": 1,
"Items": [
{
"Id": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com-1721555857-565971",
"DomainName": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"CustomOriginConfig": {
"HTTPPort": 80,
"HTTPSPort": 443,
"OriginProtocolPolicy": "http-only",
"OriginSslProtocols": {
"Quantity": 3,
"Items": [
"TLSv1",
"TLSv1.1",
"TLSv1.2"
]
},
"OriginReadTimeout": 30,
"OriginKeepaliveTimeout": 5
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": ""
}
]
},
"OriginGroups": {
"Quantity": 0
},
"DefaultCacheBehavior": {
"TargetOriginId": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com-1721555857-565971",
"TrustedSigners": {
"Enabled": false,
"Quantity": 0
},
"TrustedKeyGroups": {
"Enabled": false,
"Quantity": 0
},
"ViewerProtocolPolicy": "redirect-to-https",
"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": 86400,
"MaxTTL": 31536000
},
"CacheBehaviors": {
"Quantity": 0
},
"CustomErrorResponses": {
"Quantity": 0
},
"Comment": "",
"Logging": {
"Enabled": false,
"IncludeCookies": false,
"Bucket": "",
"Prefix": ""
},
"PriceClass": "PriceClass_All",
"Enabled": true,
"ViewerCertificate": {
"CloudFrontDefaultCertificate": false,
"SSLSupportMethod": "sni-only",
"MinimumProtocolVersion": "TLSv1.2_2021",
"CertificateSource": "acm",
"ACMCertificateArn": "arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56",
"Certificate": "arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56"
},
"Restrictions": {
"GeoRestriction": {
"RestrictionType": "none",
"Quantity": 0
}
},
"WebACLId": "",
"HttpVersion": "http2",
"IsIPV6Enabled": true,
"ContinuousDeploymentPolicyId": "",
"Staging": false
}
CloudFrontディストリビューションの設定を更新
# ETagを取得
ETAG=$(
aws cloudfront get-distribution-config \
--id ${DISTRIBUTION_ID} \
--query ETag \
--output text
) \
&& echo ${ETAG}
# CloudFrontディストリビューションの設定を更新
aws cloudfront update-distribution \
--id ${DISTRIBUTION_ID} \
--distribution-config "${CONFIG_JSON}" \
--if-match ${ETAG}
[cloudshell-user@ip-10-130-61-60 ~]$ # ETagを取得
[cloudshell-user@ip-10-130-61-60 ~]$ ETAG=$(
> aws cloudfront get-distribution-config \
> --id ${DISTRIBUTION_ID} \
> --query ETag \
> --output text
> ) \
> && echo ${ETAG}
E95HZYNGU9MLI
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # CloudFrontディストリビューションの設定を更新
[cloudshell-user@ip-10-130-61-60 ~]$ aws cloudfront update-distribution \
> --id ${DISTRIBUTION_ID} \
> --distribution-config "${CONFIG_JSON}" \
> --if-match ${ETAG}
{
"ETag": "EO48TEFCWS75N",
"Distribution": {
"Id": "E4GYIQL4T0TP0",
"ARN": "arn:aws:cloudfront::999999999999:distribution/E4GYIQL4T0TP0",
"Status": "InProgress",
"LastModifiedTime": "2024-07-21T11:32:31.733000+00:00",
"InProgressInvalidationBatches": 0,
"DomainName": "d2xpr76fxshx5q.cloudfront.net",
"ActiveTrustedSigners": {
"Enabled": false,
"Quantity": 0
},
"ActiveTrustedKeyGroups": {
"Enabled": false,
"Quantity": 0
},
"DistributionConfig": {
"CallerReference": "cli-1721555857-121159",
"Aliases": {
"Quantity": 1,
"Items": [
"handson.example.com"
]
},
"DefaultRootObject": "",
"Origins": {
"Quantity": 1,
"Items": [
{
"Id": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com-1721555857-565971",
"DomainName": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"CustomOriginConfig": {
"HTTPPort": 80,
"HTTPSPort": 443,
"OriginProtocolPolicy": "http-only",
"OriginSslProtocols": {
"Quantity": 3,
"Items": [
"TLSv1",
"TLSv1.1",
"TLSv1.2"
]
},
"OriginReadTimeout": 30,
"OriginKeepaliveTimeout": 5
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": ""
}
]
},
"OriginGroups": {
"Quantity": 0
},
"DefaultCacheBehavior": {
"TargetOriginId": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com-1721555857-565971",
"TrustedSigners": {
"Enabled": false,
"Quantity": 0
},
"TrustedKeyGroups": {
"Enabled": false,
"Quantity": 0
},
"ViewerProtocolPolicy": "redirect-to-https",
"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": 86400,
"MaxTTL": 31536000
},
"CacheBehaviors": {
"Quantity": 0
},
"CustomErrorResponses": {
"Quantity": 0
},
"Comment": "",
"Logging": {
"Enabled": false,
"IncludeCookies": false,
"Bucket": "",
"Prefix": ""
},
"PriceClass": "PriceClass_All",
"Enabled": true,
"ViewerCertificate": {
"CloudFrontDefaultCertificate": false,
"ACMCertificateArn": "arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56",
"SSLSupportMethod": "sni-only",
"MinimumProtocolVersion": "TLSv1.2_2021",
"Certificate": "arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56",
"CertificateSource": "acm"
},
"Restrictions": {
"GeoRestriction": {
"RestrictionType": "none",
"Quantity": 0
}
},
"WebACLId": "",
"HttpVersion": "http2",
"IsIPV6Enabled": true,
"ContinuousDeploymentPolicyId": "",
"Staging": false
},
"AliasICPRecordals": [
{
"CNAME": "handson.example.com",
"ICPRecordalStatus": "APPROVED"
}
]
}
}
DNSの向き先をCloudFrontに変更
レコード登録用JSON
"HostedZoneId": "Z2FDTNDATAQYW2", # CloudFrontのホストゾーンID
# レコード登録用JSON
RECORD_JSON=$(cat << EOF
{
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "${HOSTED_ZONE_NAME}",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "Z2FDTNDATAQYW2",
"DNSName": "${DISTRIBUTION_DOMAINNAME}.",
"EvaluateTargetHealth": true
}
}
}
]
}
EOF
) \
&& echo ${RECORD_JSON}
# JSONフォーマットの確認
echo ${RECORD_JSON} | python -m json.tool
[cloudshell-user@ip-10-130-61-60 ~]$ # レコード登録用JSON
[cloudshell-user@ip-10-130-61-60 ~]$ RECORD_JSON=$(cat << EOF
> {
> "Changes": [
> {
> "Action": "UPSERT",
> "ResourceRecordSet": {
> "Name": "${HOSTED_ZONE_NAME}",
> "Type": "A",
> "AliasTarget": {
> "HostedZoneId": "Z2FDTNDATAQYW2",
> "DNSName": "${DISTRIBUTION_DOMAINNAME}.",
> "EvaluateTargetHealth": true
> }
> }
> }
> ]
> }
> EOF
> ) \
> && echo ${RECORD_JSON}
{ "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name": "handson.example.com", "Type": "A", "AliasTarget": { "HostedZoneId": "Z2FDTNDATAQYW2", "DNSName": "d2xpr76fxshx5q.cloudfront.net.", "EvaluateTargetHealth": true } } } ] }
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-130-61-60 ~]$ echo ${RECORD_JSON} | python -m json.tool
{
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "handson.example.com",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "Z2FDTNDATAQYW2",
"DNSName": "d2xpr76fxshx5q.cloudfront.net.",
"EvaluateTargetHealth": true
}
}
}
]
}
レコード登録
# レコード登録
aws route53 change-resource-record-sets \
--hosted-zone-id ${HOSTED_ZONE_ID} \
--change-batch "${RECORD_JSON}"
[cloudshell-user@ip-10-130-61-60 ~]$ # レコード登録
[cloudshell-user@ip-10-130-61-60 ~]$ aws route53 change-resource-record-sets \
> --hosted-zone-id ${HOSTED_ZONE_ID} \
> --change-batch "${RECORD_JSON}"
{
"ChangeInfo": {
"Id": "/change/C09392093S1UD5VZ0Z50C",
"Status": "PENDING",
"SubmittedAt": "2024-07-21T11:36:23.424000+00:00"
}
}
アクセス確認 (https)
curl https://handson.example.com/
[cloudshell-user@ip-10-130-61-60 ~]$ curl https://handson.example.com/
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>はじめての AWS</title>
<link rel="icon" href="favicon.ico">
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<div>
<div class="icon">
<img src="img/lambda.png">
</div>
<div class="msg">
このページでは、AWS について学んだことを書いていきます。
</div>
</div>
</body>
</html>
アクセス確認 (http)
curl http://handson.example.com/
[cloudshell-user@ip-10-130-61-60 ~]$ curl http://handson.example.com/
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>CloudFront</center>
</body>
</html>
S3への直接アクセス禁止
S3設定変更
# バケットポリシー削除
aws s3api delete-bucket-policy \
--bucket ${S3_BUCKET_NAME}
# 静的ホスティング無効化
aws s3api delete-bucket-website \
--bucket ${S3_BUCKET_NAME}
[cloudshell-user@ip-10-130-61-60 ~]$ # バケットポリシー削除
[cloudshell-user@ip-10-130-61-60 ~]$ aws s3api delete-bucket-policy \
> --bucket ${S3_BUCKET_NAME}
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # 静的ホスティング無効化
[cloudshell-user@ip-10-130-61-60 ~]$ aws s3api delete-bucket-website \
> --bucket ${S3_BUCKET_NAME}
CloudFrontオリジンアクセス作成
オリジンアクセス用JSON
# オリジンアクセス用JSON
ORIGIN_ACCESS_JSON=$(cat << EOF
{
"Name": "${HOSTED_ZONE_NAME}.s3.ap-northeast-1.amazonaws.com",
"SigningProtocol": "sigv4",
"SigningBehavior": "always",
"OriginAccessControlOriginType": "s3"
}
EOF
) \
&& echo ${ORIGIN_ACCESS_JSON}
# JSONフォーマットの確認
echo ${ORIGIN_ACCESS_JSON} | python -m json.tool
cloudshell-user@ip-10-130-61-60 ~]$ # オリジンアクセス用JSON
[cloudshell-user@ip-10-130-61-60 ~]$ ORIGIN_ACCESS_JSON=$(cat << EOF
> {
> "Name": "${HOSTED_ZONE_NAME}.s3.ap-northeast-1.amazonaws.com",
> "SigningProtocol": "sigv4",
> "SigningBehavior": "always",
> "OriginAccessControlOriginType": "s3"
> }
> EOF
> ) \
> && echo ${ORIGIN_ACCESS_JSON}
{ "Name": "handson.example.com.s3.ap-northeast-1.amazonaws.com", "SigningProtocol": "sigv4", "SigningBehavior": "always", "OriginAccessControlOriginType": "s3" }
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-130-61-60 ~]$ echo ${ORIGIN_ACCESS_JSON} | python -m json.tool
{
"Name": "handson.example.com.s3.ap-northeast-1.amazonaws.com",
"SigningProtocol": "sigv4",
"SigningBehavior": "always",
"OriginAccessControlOriginType": "s3"
}
オリジンアクセス作成
# 作成
aws cloudfront create-origin-access-control \
--origin-access-control-config "${ORIGIN_ACCESS_JSON}"
# ID取得
ORIGIN_ACCESS_CONTROL_ID=$(
aws cloudfront list-origin-access-controls \
--query "OriginAccessControlList.Items[?Name=='${HOSTED_ZONE_NAME}.s3.ap-northeast-1.amazonaws.com'].Id" \
--output text
) \
&& echo ${ORIGIN_ACCESS_CONTROL_ID}
[cloudshell-user@ip-10-130-61-60 ~]$ # 作成
[cloudshell-user@ip-10-130-61-60 ~]$ aws cloudfront create-origin-access-control \
> --origin-access-control-config "${ORIGIN_ACCESS_JSON}"
{
"Location": "https://cloudfront.amazonaws.com/2020-05-31/origin-access-control/E1BJDY9OECT8GB",
"ETag": "ETVPDKIKX0DER",
"OriginAccessControl": {
"Id": "E1BJDY9OECT8GB",
"OriginAccessControlConfig": {
"Name": "handson.example.com.s3.ap-northeast-1.amazonaws.com",
"SigningProtocol": "sigv4",
"SigningBehavior": "always",
"OriginAccessControlOriginType": "s3"
}
}
}
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # ID取得
[cloudshell-user@ip-10-130-61-60 ~]$ ORIGIN_ACCESS_CONTROL_ID=$(
> aws cloudfront list-origin-access-controls \
> --query "OriginAccessControlList.Items[?Name=='${HOSTED_ZONE_NAME}.s3.ap-northeast-1.amazonaws.com'].Id" \
> --output text
> ) \
> && echo ${ORIGIN_ACCESS_CONTROL_ID}
E1BJDY9OECT8GB
S3 オリジンアクセス用バケットポリシーJSON
# バケットポリシー(JSON)
BACKET_POLICY=$(cat << EOF
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::${S3_BUCKET_NAME}/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "${DISTRIBUTION_ARN}"
}
}
}
]
}
EOF
) \
&& echo ${BACKET_POLICY}
# JSONフォーマットの確認
echo ${BACKET_POLICY} | python -m json.tool
[cloudshell-user@ip-10-130-61-60 ~]$ # バケットポリシー(JSON)
[cloudshell-user@ip-10-130-61-60 ~]$ BACKET_POLICY=$(cat << EOF
> {
> "Version": "2008-10-17",
> "Id": "PolicyForCloudFrontPrivateContent",
> "Statement": [
> {
> "Sid": "AllowCloudFrontServicePrincipal",
> "Effect": "Allow",
> "Principal": {
> "Service": "cloudfront.amazonaws.com"
> },
> "Action": "s3:GetObject",
> "Resource": "arn:aws:s3:::${S3_BUCKET_NAME}/*",
> "Condition": {
> "StringEquals": {
> "AWS:SourceArn": "${DISTRIBUTION_ARN}"
> }
> }
> }
> ]
> }
> EOF
> ) \
> && echo ${BACKET_POLICY}
{ "Version": "2008-10-17", "Id": "PolicyForCloudFrontPrivateContent", "Statement": [ { "Sid": "AllowCloudFrontServicePrincipal", "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::handson.example.com/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::999999999999:distribution/E4GYIQL4T0TP0" } } } ] }
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-130-61-60 ~]$ echo ${BACKET_POLICY} | python -m json.tool
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::handson.example.com/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::999999999999:distribution/E4GYIQL4T0TP0"
}
}
}
]
}
S3 オリジンアクセス用バケットポリシー適用
# バケットポリシー
aws s3api put-bucket-policy \
--bucket ${S3_BUCKET_NAME} \
--policy "${BACKET_POLICY}"
[cloudshell-user@ip-10-130-61-60 ~]$ # バケットポリシー
[cloudshell-user@ip-10-130-61-60 ~]$ aws s3api put-bucket-policy \
> --bucket ${S3_BUCKET_NAME} \
> --policy "${BACKET_POLICY}"
CloudFrontオリジンドメイン用JSON
# CloudFrontオリジンドメイン用JSON
CONFIG_JSON=$(
aws cloudfront get-distribution-config \
--id ${DISTRIBUTION_ID} \
| jq .DistributionConfig \
| jq --arg new_domain "${HOSTED_ZONE_NAME}.s3.ap-northeast-1.amazonaws.com" '.Origins.Items.[].DomainName = $new_domain' \
| jq 'del(.Origins.Items[].CustomOriginConfig)' \
| jq '.Origins.Items[].S3OriginConfig = {"OriginAccessIdentity": ""}' \
| jq --arg originId "${ORIGIN_ACCESS_CONTROL_ID}" '.Origins.Items.[].OriginAccessControlId = $originId'
) \
&& echo ${CONFIG_JSON}
# JSONフォーマットの確認
echo ${CONFIG_JSON} | python -m json.tool
[cloudshell-user@ip-10-130-61-60 ~]$ # CloudFrontオリジンドメイン用JSON
[cloudshell-user@ip-10-130-61-60 ~]$ CONFIG_JSON=$(
> aws cloudfront get-distribution-config \
> --id ${DISTRIBUTION_ID} \
> | jq .DistributionConfig \
> | jq --arg new_domain "${HOSTED_ZONE_NAME}.s3.ap-northeast-1.amazonaws.com" '.Origins.Items.[].DomainName = $new_domain' \
> | jq 'del(.Origins.Items[].CustomOriginConfig)' \
> | jq '.Origins.Items[].S3OriginConfig = {"OriginAccessIdentity": ""}' \
> | jq --arg originId "${ORIGIN_ACCESS_CONTROL_ID}" '.Origins.Items.[].OriginAccessControlId = $originId'
> ) \
> && echo ${CONFIG_JSON}
{ "CallerReference": "cli-1721555857-121159", "Aliases": { "Quantity": 1, "Items": [ "handson.example.com" ] }, "DefaultRootObject": "", "Origins": { "Quantity": 1, "Items": [ { "Id": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com-1721555857-565971", "DomainName": "handson.example.com.s3.ap-northeast-1.amazonaws.com", "OriginPath": "", "CustomHeaders": { "Quantity": 0 }, "ConnectionAttempts": 3, "ConnectionTimeout": 10, "OriginShield": { "Enabled": false }, "OriginAccessControlId": "E1BJDY9OECT8GB", "S3OriginConfig": { "OriginAccessIdentity": "" } } ] }, "OriginGroups": { "Quantity": 0 }, "DefaultCacheBehavior": { "TargetOriginId": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com-1721555857-565971", "TrustedSigners": { "Enabled": false, "Quantity": 0 }, "TrustedKeyGroups": { "Enabled": false, "Quantity": 0 }, "ViewerProtocolPolicy": "redirect-to-https", "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": 86400, "MaxTTL": 31536000 }, "CacheBehaviors": { "Quantity": 0 }, "CustomErrorResponses": { "Quantity": 0 }, "Comment": "", "Logging": { "Enabled": false, "IncludeCookies": false, "Bucket": "", "Prefix": "" }, "PriceClass": "PriceClass_All", "Enabled": true, "ViewerCertificate": { "CloudFrontDefaultCertificate": false, "ACMCertificateArn": "arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56", "SSLSupportMethod": "sni-only", "MinimumProtocolVersion": "TLSv1.2_2021", "Certificate": "arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56", "CertificateSource": "acm" }, "Restrictions": { "GeoRestriction": { "RestrictionType": "none", "Quantity": 0 } }, "WebACLId": "", "HttpVersion": "http2", "IsIPV6Enabled": true, "ContinuousDeploymentPolicyId": "", "Staging": false }
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-130-61-60 ~]$ echo ${CONFIG_JSON} | python -m json.tool
{
"CallerReference": "cli-1721555857-121159",
"Aliases": {
"Quantity": 1,
"Items": [
"handson.example.com"
]
},
"DefaultRootObject": "",
"Origins": {
"Quantity": 1,
"Items": [
{
"Id": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com-1721555857-565971",
"DomainName": "handson.example.com.s3.ap-northeast-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": "E1BJDY9OECT8GB",
"S3OriginConfig": {
"OriginAccessIdentity": ""
}
}
]
},
"OriginGroups": {
"Quantity": 0
},
"DefaultCacheBehavior": {
"TargetOriginId": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com-1721555857-565971",
"TrustedSigners": {
"Enabled": false,
"Quantity": 0
},
"TrustedKeyGroups": {
"Enabled": false,
"Quantity": 0
},
"ViewerProtocolPolicy": "redirect-to-https",
"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": 86400,
"MaxTTL": 31536000
},
"CacheBehaviors": {
"Quantity": 0
},
"CustomErrorResponses": {
"Quantity": 0
},
"Comment": "",
"Logging": {
"Enabled": false,
"IncludeCookies": false,
"Bucket": "",
"Prefix": ""
},
"PriceClass": "PriceClass_All",
"Enabled": true,
"ViewerCertificate": {
"CloudFrontDefaultCertificate": false,
"ACMCertificateArn": "arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56",
"SSLSupportMethod": "sni-only",
"MinimumProtocolVersion": "TLSv1.2_2021",
"Certificate": "arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56",
"CertificateSource": "acm"
},
"Restrictions": {
"GeoRestriction": {
"RestrictionType": "none",
"Quantity": 0
}
},
"WebACLId": "",
"HttpVersion": "http2",
"IsIPV6Enabled": true,
"ContinuousDeploymentPolicyId": "",
"Staging": false
}
CloudFrontオリジンドメイン適用
# ETagを取得
ETAG=$(
aws cloudfront get-distribution-config \
--id ${DISTRIBUTION_ID} \
--query ETag \
--output text
) \
&& echo ${ETAG}
# CloudFrontディストリビューションの設定を更新
aws cloudfront update-distribution \
--id ${DISTRIBUTION_ID} \
--distribution-config "${CONFIG_JSON}" \
--if-match ${ETAG}
[cloudshell-user@ip-10-130-61-60 ~]$ # ETagを取得
[cloudshell-user@ip-10-130-61-60 ~]$ ETAG=$(
> aws cloudfront get-distribution-config \
> --id ${DISTRIBUTION_ID} \
> --query ETag \
> --output text
> ) \
> && echo ${ETAG}
E3IIY12J06X0JQ
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # CloudFrontディストリビューションの設定を更新
[cloudshell-user@ip-10-130-61-60 ~]$ aws cloudfront update-distribution \
> --id ${DISTRIBUTION_ID} \
> --distribution-config "${CONFIG_JSON}" \
> --if-match ${ETAG}
{
"ETag": "E2WT6WS7I8YN8T",
"Distribution": {
"Id": "E4GYIQL4T0TP0",
"ARN": "arn:aws:cloudfront::999999999999:distribution/E4GYIQL4T0TP0",
"Status": "InProgress",
"LastModifiedTime": "2024-07-21T12:26:44.447000+00:00",
"InProgressInvalidationBatches": 0,
"DomainName": "d2xpr76fxshx5q.cloudfront.net",
"ActiveTrustedSigners": {
"Enabled": false,
"Quantity": 0
},
"ActiveTrustedKeyGroups": {
"Enabled": false,
"Quantity": 0
},
"DistributionConfig": {
"CallerReference": "cli-1721555857-121159",
"Aliases": {
"Quantity": 1,
"Items": [
"handson.example.com"
]
},
"DefaultRootObject": "",
"Origins": {
"Quantity": 1,
"Items": [
{
"Id": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com-1721555857-565971",
"DomainName": "handson.example.com.s3.ap-northeast-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"S3OriginConfig": {
"OriginAccessIdentity": ""
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": "E1BJDY9OECT8GB"
}
]
},
"OriginGroups": {
"Quantity": 0
},
"DefaultCacheBehavior": {
"TargetOriginId": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com-1721555857-565971",
"TrustedSigners": {
"Enabled": false,
"Quantity": 0
},
"TrustedKeyGroups": {
"Enabled": false,
"Quantity": 0
},
"ViewerProtocolPolicy": "redirect-to-https",
"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": 86400,
"MaxTTL": 31536000
},
"CacheBehaviors": {
"Quantity": 0
},
"CustomErrorResponses": {
"Quantity": 0
},
"Comment": "",
"Logging": {
"Enabled": false,
"IncludeCookies": false,
"Bucket": "",
"Prefix": ""
},
"PriceClass": "PriceClass_All",
"Enabled": true,
"ViewerCertificate": {
"CloudFrontDefaultCertificate": false,
"ACMCertificateArn": "arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56",
"SSLSupportMethod": "sni-only",
"MinimumProtocolVersion": "TLSv1.2_2021",
"Certificate": "arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56",
"CertificateSource": "acm"
},
"Restrictions": {
"GeoRestriction": {
"RestrictionType": "none",
"Quantity": 0
}
},
"WebACLId": "",
"HttpVersion": "http2",
"IsIPV6Enabled": true,
"ContinuousDeploymentPolicyId": "",
"Staging": false
},
"AliasICPRecordals": [
{
"CNAME": "handson.example.com",
"ICPRecordalStatus": "APPROVED"
}
]
}
}
アクセス確認 (S3)
curl http://handson.example.com.s3-website-ap-northeast-1.amazonaws.com//
[cloudshell-user@ip-10-130-61-60 ~]$ curl http://handson.example.com.s3-website-ap-northeast-1.amazonaws.com//
<html>
<head><title>404 Not Found</title></head>
<body>
<h1>404 Not Found</h1>
<ul>
<li>Code: NoSuchWebsiteConfiguration</li>
<li>Message: The specified bucket does not have a website configuration</li>
<li>BucketName: handson.example.com</li>
<li>RequestId: YZT6SA38C2HSMA89</li>
<li>HostId: CR5DgqQYM/MbOCmLkCUynwGTqnvH2MCNKEI08vHz3Ol/MUzVtAWPkbtlEiy+Q7OshtziSqq0hKs=</li>
</ul>
<hr/>
</body>
</html>
アクセス確認 (CloudFront)
curl https://handson.example.com/
[cloudshell-user@ip-10-130-61-60 ~]$ curl https://handson.example.com/
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>はじめての AWS</title>
<link rel="icon" href="favicon.ico">
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<div>
<div class="icon">
<img src="img/lambda.png">
</div>
<div class="msg">
このページでは、AWS について学んだことを書いていきます。
</div>
</div>
</body>
</html>
7. 削除
CloudFront
ディストリビューション無効化用JSON
# ディストリビューション無効化用JSON
DELL_CONFIG=$(
aws cloudfront get-distribution-config \
--id ${DISTRIBUTION_ID} \
| jq .DistributionConfig \
| jq '.Enabled = false'
) \
&& echo ${DELL_CONFIG}
# JSONフォーマットの確認
echo ${DELL_CONFIG} | python -m json.tool
[cloudshell-user@ip-10-130-61-60 ~]$ # ディストリビューション無効化用JSON
[cloudshell-user@ip-10-130-61-60 ~]$ DELL_CONFIG=$(
> aws cloudfront get-distribution-config \
> --id ${DISTRIBUTION_ID} \
> | jq .DistributionConfig \
> | jq '.Enabled = false'
> ) \
> && echo ${DELL_CONFIG}
{ "CallerReference": "cli-1721555857-121159", "Aliases": { "Quantity": 1, "Items": [ "handson.example.com" ] }, "DefaultRootObject": "", "Origins": { "Quantity": 1, "Items": [ { "Id": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com-1721555857-565971", "DomainName": "handson.example.com.s3.ap-northeast-1.amazonaws.com", "OriginPath": "", "CustomHeaders": { "Quantity": 0 }, "S3OriginConfig": { "OriginAccessIdentity": "" }, "ConnectionAttempts": 3, "ConnectionTimeout": 10, "OriginShield": { "Enabled": false }, "OriginAccessControlId": "E1BJDY9OECT8GB" } ] }, "OriginGroups": { "Quantity": 0 }, "DefaultCacheBehavior": { "TargetOriginId": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com-1721555857-565971", "TrustedSigners": { "Enabled": false, "Quantity": 0 }, "TrustedKeyGroups": { "Enabled": false, "Quantity": 0 }, "ViewerProtocolPolicy": "redirect-to-https", "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": 86400, "MaxTTL": 31536000 }, "CacheBehaviors": { "Quantity": 0 }, "CustomErrorResponses": { "Quantity": 0 }, "Comment": "", "Logging": { "Enabled": false, "IncludeCookies": false, "Bucket": "", "Prefix": "" }, "PriceClass": "PriceClass_All", "Enabled": false, "ViewerCertificate": { "CloudFrontDefaultCertificate": false, "ACMCertificateArn": "arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56", "SSLSupportMethod": "sni-only", "MinimumProtocolVersion": "TLSv1.2_2021", "Certificate": "arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56", "CertificateSource": "acm" }, "Restrictions": { "GeoRestriction": { "RestrictionType": "none", "Quantity": 0 } }, "WebACLId": "", "HttpVersion": "http2", "IsIPV6Enabled": true, "ContinuousDeploymentPolicyId": "", "Staging": false }
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-130-61-60 ~]$ echo ${DELL_CONFIG} | python -m json.tool
{
"CallerReference": "cli-1721555857-121159",
"Aliases": {
"Quantity": 1,
"Items": [
"handson.example.com"
]
},
"DefaultRootObject": "",
"Origins": {
"Quantity": 1,
"Items": [
{
"Id": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com-1721555857-565971",
"DomainName": "handson.example.com.s3.ap-northeast-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"S3OriginConfig": {
"OriginAccessIdentity": ""
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": "E1BJDY9OECT8GB"
}
]
},
"OriginGroups": {
"Quantity": 0
},
"DefaultCacheBehavior": {
"TargetOriginId": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com-1721555857-565971",
"TrustedSigners": {
"Enabled": false,
"Quantity": 0
},
"TrustedKeyGroups": {
"Enabled": false,
"Quantity": 0
},
"ViewerProtocolPolicy": "redirect-to-https",
"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": 86400,
"MaxTTL": 31536000
},
"CacheBehaviors": {
"Quantity": 0
},
"CustomErrorResponses": {
"Quantity": 0
},
"Comment": "",
"Logging": {
"Enabled": false,
"IncludeCookies": false,
"Bucket": "",
"Prefix": ""
},
"PriceClass": "PriceClass_All",
"Enabled": false,
"ViewerCertificate": {
"CloudFrontDefaultCertificate": false,
"ACMCertificateArn": "arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56",
"SSLSupportMethod": "sni-only",
"MinimumProtocolVersion": "TLSv1.2_2021",
"Certificate": "arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56",
"CertificateSource": "acm"
},
"Restrictions": {
"GeoRestriction": {
"RestrictionType": "none",
"Quantity": 0
}
},
"WebACLId": "",
"HttpVersion": "http2",
"IsIPV6Enabled": true,
"ContinuousDeploymentPolicyId": "",
"Staging": false
}
ディストリビューション無効化
# ETagを取得
ETAG=$(
aws cloudfront get-distribution-config \
--id ${DISTRIBUTION_ID} \
--query ETag \
--output text
) \
&& echo ${ETAG}
# ディストリビューションを無効化
aws cloudfront update-distribution \
--id ${DISTRIBUTION_ID} \
--distribution-config "${DELL_CONFIG}" \
--if-match ${ETAG}
[cloudshell-user@ip-10-130-61-60 ~]$ # ETagを取得
[cloudshell-user@ip-10-130-61-60 ~]$ ETAG=$(
> aws cloudfront get-distribution-config \
> --id ${DISTRIBUTION_ID} \
> --query ETag \
> --output text
> ) \
> && echo ${ETAG}
E2WT6WS7I8YN8T
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # ディストリビューションを無効化
[cloudshell-user@ip-10-130-61-60 ~]$ aws cloudfront update-distribution \
> --id ${DISTRIBUTION_ID} \
> --distribution-config "${DELL_CONFIG}" \
> --if-match ${ETAG}
{
"ETag": "E1STJVVBU7V2HO",
"Distribution": {
"Id": "E4GYIQL4T0TP0",
"ARN": "arn:aws:cloudfront::999999999999:distribution/E4GYIQL4T0TP0",
"Status": "InProgress",
"LastModifiedTime": "2024-07-21T12:39:01.911000+00:00",
"InProgressInvalidationBatches": 0,
"DomainName": "d2xpr76fxshx5q.cloudfront.net",
"ActiveTrustedSigners": {
"Enabled": false,
"Quantity": 0
},
"ActiveTrustedKeyGroups": {
"Enabled": false,
"Quantity": 0
},
"DistributionConfig": {
"CallerReference": "cli-1721555857-121159",
"Aliases": {
"Quantity": 1,
"Items": [
"handson.example.com"
]
},
"DefaultRootObject": "",
"Origins": {
"Quantity": 1,
"Items": [
{
"Id": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com-1721555857-565971",
"DomainName": "handson.example.com.s3.ap-northeast-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"S3OriginConfig": {
"OriginAccessIdentity": ""
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": "E1BJDY9OECT8GB"
}
]
},
"OriginGroups": {
"Quantity": 0
},
"DefaultCacheBehavior": {
"TargetOriginId": "handson.example.com.s3-website-ap-northeast-1.amazonaws.com-1721555857-565971",
"TrustedSigners": {
"Enabled": false,
"Quantity": 0
},
"TrustedKeyGroups": {
"Enabled": false,
"Quantity": 0
},
"ViewerProtocolPolicy": "redirect-to-https",
"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": 86400,
"MaxTTL": 31536000
},
"CacheBehaviors": {
"Quantity": 0
},
"CustomErrorResponses": {
"Quantity": 0
},
"Comment": "",
"Logging": {
"Enabled": false,
"IncludeCookies": false,
"Bucket": "",
"Prefix": ""
},
"PriceClass": "PriceClass_All",
"Enabled": false,
"ViewerCertificate": {
"CloudFrontDefaultCertificate": false,
"ACMCertificateArn": "arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56",
"SSLSupportMethod": "sni-only",
"MinimumProtocolVersion": "TLSv1.2_2021",
"Certificate": "arn:aws:acm:us-east-1:999999999999:certificate/ff02e147-6b72-4856-916c-fc0dcb5c6a56",
"CertificateSource": "acm"
},
"Restrictions": {
"GeoRestriction": {
"RestrictionType": "none",
"Quantity": 0
}
},
"WebACLId": "",
"HttpVersion": "http2",
"IsIPV6Enabled": true,
"ContinuousDeploymentPolicyId": "",
"Staging": false
},
"AliasICPRecordals": [
{
"CNAME": "handson.example.com",
"ICPRecordalStatus": "APPROVED"
}
]
}
}
ディストリビューション削除
# ETagを取得
ETAG=$(
aws cloudfront get-distribution-config \
--id ${DISTRIBUTION_ID} \
--query ETag \
--output text
) \
&& echo ${ETAG}
# ディストリビューションを削除
aws cloudfront delete-distribution \
--id ${DISTRIBUTION_ID} \
--if-match ${ETAG}
[cloudshell-user@ip-10-130-61-60 ~]$ # ETagを取得
[cloudshell-user@ip-10-130-61-60 ~]$ ETAG=$(
> aws cloudfront get-distribution-config \
> --id ${DISTRIBUTION_ID} \
> --query ETag \
> --output text
> ) \
> && echo ${ETAG}
E1STJVVBU7V2HO
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # ディストリビューションを削除
[cloudshell-user@ip-10-130-61-60 ~]$ aws cloudfront delete-distribution \
> --id ${DISTRIBUTION_ID} \
> --if-match ${ETAG}
オリジンアクセス削除
# ETagを取得
ETAG=$(
aws cloudfront get-origin-access-control \
--id ${ORIGIN_ACCESS_CONTROL_ID} \
--query ETag \
--output text
) \
&& echo ${ETAG}
aws cloudfront delete-origin-access-control \
--id ${ORIGIN_ACCESS_CONTROL_ID} \
--if-match ${ETAG}
[cloudshell-user@ip-10-130-61-60 ~]$ # ETagを取得
[cloudshell-user@ip-10-130-61-60 ~]$ ETAG=$(
> aws cloudfront get-origin-access-control \
> --id ${ORIGIN_ACCESS_CONTROL_ID} \
> --query ETag \
> --output text
> ) \
> && echo ${ETAG}
ETVPDKIKX0DER
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ aws cloudfront delete-origin-access-control \
> --id ${ORIGIN_ACCESS_CONTROL_ID} \
> --if-match ${ETAG}
Route53
Hosted Zone内のレコードセットを取得
# レコードセットリストの取得
RECORDSETS_JSON=$(
aws route53 list-resource-record-sets \
--hosted-zone-id ${HOSTED_ZONE_ID}
) \
&& echo ${RECORDSETS_JSON}
# JSONフォーマットの確認
echo ${RECORDSETS_JSON} | python -m json.tool
[cloudshell-user@ip-10-130-61-60 ~]$ # レコードセットリストの取得
[cloudshell-user@ip-10-130-61-60 ~]$ RECORDSETS_JSON=$(
> aws route53 list-resource-record-sets \
> --hosted-zone-id ${HOSTED_ZONE_ID}
> ) \
> && echo ${RECORDSETS_JSON}
{ "ResourceRecordSets": [ { "Name": "handson.example.com.", "Type": "A", "AliasTarget": { "HostedZoneId": "Z2FDTNDATAQYW2", "DNSName": "d2xpr76fxshx5q.cloudfront.net.", "EvaluateTargetHealth": true } }, { "Name": "handson.example.com.", "Type": "NS", "TTL": 172800, "ResourceRecords": [ { "Value": "ns-1260.awsdns-29.org." }, { "Value": "ns-902.awsdns-48.net." }, { "Value": "ns-1560.awsdns-03.co.uk." }, { "Value": "ns-461.awsdns-57.com." } ] }, { "Name": "handson.example.com.", "Type": "SOA", "TTL": 900, "ResourceRecords": [ { "Value": "ns-1260.awsdns-29.org. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400" } ] }, { "Name": "_e049795f32552612c6135c8d935dd7e5.handson.example.com.", "Type": "CNAME", "TTL": 300, "ResourceRecords": [ { "Value": "_386e01e1ba95af93def7ed60e3413159.sdgjtdhdhz.acm-validations.aws." } ] } ] }
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-130-61-60 ~]$ echo ${RECORDSETS_JSON} | python -m json.tool
{
"ResourceRecordSets": [
{
"Name": "handson.example.com.",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "Z2FDTNDATAQYW2",
"DNSName": "d2xpr76fxshx5q.cloudfront.net.",
"EvaluateTargetHealth": true
}
},
{
"Name": "handson.example.com.",
"Type": "NS",
"TTL": 172800,
"ResourceRecords": [
{
"Value": "ns-1260.awsdns-29.org."
},
{
"Value": "ns-902.awsdns-48.net."
},
{
"Value": "ns-1560.awsdns-03.co.uk."
},
{
"Value": "ns-461.awsdns-57.com."
}
]
},
{
"Name": "handson.example.com.",
"Type": "SOA",
"TTL": 900,
"ResourceRecords": [
{
"Value": "ns-1260.awsdns-29.org. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"
}
]
},
{
"Name": "_e049795f32552612c6135c8d935dd7e5.handson.example.com.",
"Type": "CNAME",
"TTL": 300,
"ResourceRecords": [
{
"Value": "_386e01e1ba95af93def7ed60e3413159.sdgjtdhdhz.acm-validations.aws."
}
]
}
]
}
レコード削除用JSON
DELETE_RECORD_JSON=$(cat << EOF
{
"Comment": "Deleting a record set",
"Changes": [
{
"Action": "DELETE",
"ResourceRecordSet": {
"Name": "handson.example.com.",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "Z2FDTNDATAQYW2",
"DNSName": "d2xpr76fxshx5q.cloudfront.net.",
"EvaluateTargetHealth": true
}
}
},
{
"Action": "DELETE",
"ResourceRecordSet": {
"Name": "_e049795f32552612c6135c8d935dd7e5.handson.example.com.",
"Type": "CNAME",
"TTL": 300,
"ResourceRecords": [
{
"Value": "_386e01e1ba95af93def7ed60e3413159.sdgjtdhdhz.acm-validations.aws."
}
]
}
}
]
}
EOF
) \
&& echo ${DELETE_RECORD_JSON}
# JSONフォーマットの確認
echo ${DELETE_RECORD_JSON} | python -m json.tool
[cloudshell-user@ip-10-130-61-60 ~]$ DELETE_RECORD_JSON=$(cat << EOF
> {
> "Comment": "Deleting a record set",
> "Changes": [
> {
> "Action": "DELETE",
> "ResourceRecordSet": {
> "Name": "handson.example.com.",
> "Type": "A",
> "AliasTarget": {
> "HostedZoneId": "Z2FDTNDATAQYW2",
> "DNSName": "d2xpr76fxshx5q.cloudfront.net.",
> "EvaluateTargetHealth": true
> }
> }
> },
> {
> "Action": "DELETE",
> "ResourceRecordSet": {
> "Name": "_e049795f32552612c6135c8d935dd7e5.handson.example.com.",
> "Type": "CNAME",
> "TTL": 300,
> "ResourceRecords": [
> {
> "Value": "_386e01e1ba95af93def7ed60e3413159.sdgjtdhdhz.acm-validations.aws."
> }
> ]
> }
> }
> ]
> }
> EOF
> ) \
> && echo ${DELETE_RECORD_JSON}
{ "Comment": "Deleting a record set", "Changes": [ { "Action": "DELETE", "ResourceRecordSet": { "Name": "handson.example.com.", "Type": "A", "AliasTarget": { "HostedZoneId": "Z2FDTNDATAQYW2", "DNSName": "d2xpr76fxshx5q.cloudfront.net.", "EvaluateTargetHealth": true } } }, { "Action": "DELETE", "ResourceRecordSet": { "Name": "_e049795f32552612c6135c8d935dd7e5.handson.example.com.", "Type": "CNAME", "TTL": 300, "ResourceRecords": [ { "Value": "_386e01e1ba95af93def7ed60e3413159.sdgjtdhdhz.acm-validations.aws." } ] } } ] }
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-130-61-60 ~]$ echo ${DELETE_RECORD_JSON} | python -m json.tool
{
"Comment": "Deleting a record set",
"Changes": [
{
"Action": "DELETE",
"ResourceRecordSet": {
"Name": "handson.example.com.",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "Z2FDTNDATAQYW2",
"DNSName": "d2xpr76fxshx5q.cloudfront.net.",
"EvaluateTargetHealth": true
}
}
},
{
"Action": "DELETE",
"ResourceRecordSet": {
"Name": "_e049795f32552612c6135c8d935dd7e5.handson.example.com.",
"Type": "CNAME",
"TTL": 300,
"ResourceRecords": [
{
"Value": "_386e01e1ba95af93def7ed60e3413159.sdgjtdhdhz.acm-validations.aws."
}
]
}
}
]
}
レコードセットを削除
aws route53 change-resource-record-sets \
--hosted-zone-id ${HOSTED_ZONE_ID} \
--change-batch "${DELETE_RECORD_JSON}"
[cloudshell-user@ip-10-130-61-60 ~]$ aws route53 change-resource-record-sets \
> --hosted-zone-id ${HOSTED_ZONE_ID} \
> --change-batch "${DELETE_RECORD_JSON}"
{
"ChangeInfo": {
"Id": "/change/C03490542FN7OOWE8GZDW",
"Status": "PENDING",
"SubmittedAt": "2024-07-21T12:53:20.504000+00:00",
"Comment": "Deleting a record set"
}
}
ホストゾーンを削除
aws route53 delete-hosted-zone \
--id ${HOSTED_ZONE_ID}
[cloudshell-user@ip-10-130-61-60 ~]$ aws route53 delete-hosted-zone \
> --id ${HOSTED_ZONE_ID}
{
"ChangeInfo": {
"Id": "/change/C03626171CRT9GFIP49U0",
"Status": "PENDING",
"SubmittedAt": "2024-07-21T12:54:15.947000+00:00"
}
}
S3バケット
aws s3 rm s3://${S3_BUCKET_NAME} \
--recursive
# S3バケットを削除
aws s3api delete-bucket \
--bucket ${S3_BUCKET_NAME}
[cloudshell-user@ip-10-130-61-60 ~]$ aws s3 rm s3://${S3_BUCKET_NAME} \
> --recursive
delete: s3://handson.example.com/css/styles.css
delete: s3://handson.example.com/img/lambda.png
delete: s3://handson.example.com/favicon.ico
delete: s3://handson.example.com/index.html
[cloudshell-user@ip-10-130-61-60 ~]$
[cloudshell-user@ip-10-130-61-60 ~]$ # S3バケットを削除
[cloudshell-user@ip-10-130-61-60 ~]$ aws s3api delete-bucket \
> --bucket ${S3_BUCKET_NAME}
Cloud9
aws cloud9 delete-environment \
--environment-id ${CLOUD9_ENVIRONMENT_ID}
[cloudshell-user@ip-10-130-61-60 ~]$ aws cloud9 delete-environment \
> --environment-id ${CLOUD9_ENVIRONMENT_ID}
ACM
# ACM証明書の削除
aws acm delete-certificate \
--certificate-arn ${CERTIFICATE_ARN} \
--region us-east-1
[cloudshell-user@ip-10-130-61-60 ~]$ # ACM証明書の削除
[cloudshell-user@ip-10-130-61-60 ~]$ aws acm delete-certificate \
> --certificate-arn ${CERTIFICATE_ARN} \
> --region us-east-1