上記、「AWS Hands-on for Beginners Amazon CloudFrontおよびAWS WAFを用いて エッジサービスの活用方法を学ぼう | AWS Webinar」 をAWS CLIでやってみる
ハンズオンから引用
04 Amazon CloudFrontのハンズオン その1 (静的コンテンツの配信設定)
S3バケット作成
コマンド
# 変数設定
DATE_VAR=$(date +%Y%m%d) \
&& echo ${DATE_VAR}
S3_BUCKET_NAME=${DATE_VAR}-handson-sincere-networker \
&& echo ${S3_BUCKET_NAME}
REGION="us-east-1" \
&& echo ${REGION}
# バケット作成
aws s3api create-bucket \
--bucket ${S3_BUCKET_NAME} \
--region ${REGION}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # 変数設定
[cloudshell-user@ip-10-134-11-244 ~]$ DATE_VAR=$(date +%Y%m%d) \
> && echo ${DATE_VAR}
20240804
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ S3_BUCKET_NAME=${DATE_VAR}-handson-sincere-networker \
> && echo ${S3_BUCKET_NAME}
20240804-handson-sincere-networker
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ REGION="us-east-1" \
> && echo ${REGION}
us-east-1
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # バケット作成
[cloudshell-user@ip-10-134-11-244 ~]$ aws s3api create-bucket \
> --bucket ${S3_BUCKET_NAME} \
> --region ${REGION}
{
"Location": "/20240804-handson-sincere-networker"
}
ファイルのアップロード
コマンド
aws s3 cp forS3/. s3://${S3_BUCKET_NAME} --recursive
出力
[cloudshell-user@ip-10-134-11-244 ~]$ aws s3 cp forS3/. s3://${S3_BUCKET_NAME} --recursive
upload: forS3/static/js/script.js to s3://20240804-handson-sincere-networker/static/js/script.js
upload: forS3/static/css/styles.css to s3://20240804-handson-sincere-networker/static/css/styles.css
upload: forS3/index.html to s3://20240804-handson-sincere-networker/index.html
upload: forS3/static/image/cloudfront.png to s3://20240804-handson-sincere-networker/static/image/cloudfront.png
CloudFront作成
ディストリビューション作成
条件
Origin
- Origin Domain Name : 20240724-handson-sincere-networker.s3.us-east-1.amazonaws.com
- オリジンアクセス : Origin access control setting (recommended)
Behavior
- Redirect HTTP to HTTPS
- キャッシュポリシー:CachingDisabled
設定
デフォルトルートオブジェクト:index.html。
コマンド
# 変数
ORIGIN_DOMAIN_NAME="${S3_BUCKET_NAME}.s3.us-east-1.amazonaws.com" \
&& echo ${ORIGIN_DOMAIN_NAME}
DEFAULT_ROOT_OBJECT="index.html" \
&& echo ${DEFAULT_ROOT_OBJECT}
# ディストリビューションを作成
aws cloudfront create-distribution \
--origin-domain-name ${ORIGIN_DOMAIN_NAME} \
--default-root-object ${DEFAULT_ROOT_OBJECT} \
--no-cli-pager
# ディストリビューション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}
# オリジンIDを変数に保存
DISTRIBUTION_ORIGIN_ID=$(
aws cloudfront get-distribution \
--id ${DISTRIBUTION_ID} \
--query "Distribution.DistributionConfig.Origins.Items[?DomainName=='${ORIGIN_DOMAIN_NAME}'].Id" \
--output text
) \
&& echo ${DISTRIBUTION_ORIGIN_ID}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # 変数
[cloudshell-user@ip-10-134-11-244 ~]$ ORIGIN_DOMAIN_NAME="${S3_BUCKET_NAME}.s3.us-east-1.amazonaws.com" \
> && echo ${ORIGIN_DOMAIN_NAME}
20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ DEFAULT_ROOT_OBJECT="index.html" \
> && echo ${DEFAULT_ROOT_OBJECT}
index.html
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # ディストリビューションを作成
[cloudshell-user@ip-10-134-11-244 ~]$ aws cloudfront create-distribution \
> --origin-domain-name ${ORIGIN_DOMAIN_NAME} \
> --default-root-object ${DEFAULT_ROOT_OBJECT} \
> --no-cli-pager
{
"Location": "https://cloudfront.amazonaws.com/2020-05-31/distribution/EIN33GD07JLDT",
"ETag": "E34O58LV5JBI3M",
"Distribution": {
"Id": "EIN33GD07JLDT",
"ARN": "arn:aws:cloudfront::999999999999:distribution/EIN33GD07JLDT",
"Status": "InProgress",
"LastModifiedTime": "2024-08-04T10:32:35.088000+00:00",
"InProgressInvalidationBatches": 0,
"DomainName": "d18sbbratjvl6c.cloudfront.net",
"ActiveTrustedSigners": {
"Enabled": false,
"Quantity": 0
},
"ActiveTrustedKeyGroups": {
"Enabled": false,
"Quantity": 0
},
"DistributionConfig": {
"CallerReference": "cli-1722767554-44223",
"Aliases": {
"Quantity": 0
},
"DefaultRootObject": "index.html",
"Origins": {
"Quantity": 1,
"Items": [
{
"Id": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"DomainName": "20240804-handson-sincere-networker.s3.us-east-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": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"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
}
}
}
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # ディストリビューションIDを変数に保存
[cloudshell-user@ip-10-134-11-244 ~]$ DISTRIBUTION_ID=$(
> aws cloudfront list-distributions \
> --query "DistributionList.Items[?Origins.Items[?DomainName=='${ORIGIN_DOMAIN_NAME}']].Id" \
> --output text
> ) \
> && echo ${DISTRIBUTION_ID}
EIN33GD07JLDT
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # ディストリビューションドメイン名を変数に保存
[cloudshell-user@ip-10-134-11-244 ~]$ DISTRIBUTION_DOMAINNAME=$(
> aws cloudfront list-distributions \
> --query "DistributionList.Items[?Origins.Items[?DomainName=='${ORIGIN_DOMAIN_NAME}']].DomainName" \
> --output text
> ) \
> && echo ${DISTRIBUTION_DOMAINNAME}
d18sbbratjvl6c.cloudfront.net
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # ディストリビューションARNを変数に保存
[cloudshell-user@ip-10-134-11-244 ~]$ DISTRIBUTION_ARN=$(
> aws cloudfront get-distribution \
> --id ${DISTRIBUTION_ID} \
> --query "Distribution.ARN" \
> --output text
> ) \
> && echo ${DISTRIBUTION_ARN}
arn:aws:cloudfront::999999999999:distribution/EIN33GD07JLDT
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # オリジンIDを変数に保存
[cloudshell-user@ip-10-134-11-244 ~]$ DISTRIBUTION_ORIGIN_ID=$(
> aws cloudfront get-distribution \
> --id ${DISTRIBUTION_ID} \
> --query "Distribution.DistributionConfig.Origins.Items[?DomainName=='${ORIGIN_DOMAIN_NAME}'].Id" \
> --output text
> ) \
> && echo ${DISTRIBUTION_ORIGIN_ID}
20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934
オリジンアクセス作成
コマンド
# オリジンアクセス用JSON
ORIGIN_ACCESS_JSON=$(cat << EOF
{
"Name": "${ORIGIN_DOMAIN_NAME}",
"SigningProtocol": "sigv4",
"SigningBehavior": "always",
"OriginAccessControlOriginType": "s3"
}
EOF
) \
&& echo ${ORIGIN_ACCESS_JSON}
# JSONフォーマットの確認
echo ${ORIGIN_ACCESS_JSON} | python -m json.tool
# 作成
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=='${ORIGIN_DOMAIN_NAME}'].Id" \
--output text
) \
&& echo ${ORIGIN_ACCESS_CONTROL_ID}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # オリジンアクセス用JSON
[cloudshell-user@ip-10-134-11-244 ~]$ ORIGIN_ACCESS_JSON=$(cat << EOF
> {
> "Name": "${ORIGIN_DOMAIN_NAME}",
> "SigningProtocol": "sigv4",
> "SigningBehavior": "always",
> "OriginAccessControlOriginType": "s3"
> }
> EOF
> ) \
> && echo ${ORIGIN_ACCESS_JSON}
{ "Name": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com", "SigningProtocol": "sigv4", "SigningBehavior": "always", "OriginAccessControlOriginType": "s3" }
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-134-11-244 ~]$ echo ${ORIGIN_ACCESS_JSON} | python -m json.tool
{
"Name": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com",
"SigningProtocol": "sigv4",
"SigningBehavior": "always",
"OriginAccessControlOriginType": "s3"
}
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # 作成
[cloudshell-user@ip-10-134-11-244 ~]$ aws cloudfront create-origin-access-control \
> --origin-access-control-config "${ORIGIN_ACCESS_JSON}"
{
"Location": "https://cloudfront.amazonaws.com/2020-05-31/origin-access-control/E2G9MJEEXTOJC1",
"ETag": "ETVPDKIKX0DER",
"OriginAccessControl": {
"Id": "E2G9MJEEXTOJC1",
"OriginAccessControlConfig": {
"Name": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com",
"SigningProtocol": "sigv4",
"SigningBehavior": "always",
"OriginAccessControlOriginType": "s3"
}
}
}
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # ID取得
[cloudshell-user@ip-10-134-11-244 ~]$ ORIGIN_ACCESS_CONTROL_ID=$(
> aws cloudfront list-origin-access-controls \
> --query "OriginAccessControlList.Items[?Name=='${ORIGIN_DOMAIN_NAME}'].Id" \
> --output text
> ) \
> && echo ${ORIGIN_ACCESS_CONTROL_ID}
E2G9MJEEXTOJC1
ディストリビューション デフォルト設定バックアップ
コマンド
# デフォルト設定JSON
CONFIG_BEFORE=$(
aws cloudfront get-distribution-config \
--id ${DISTRIBUTION_ID} \
--query "DistributionConfig"
) \
&& echo ${CONFIG_BEFORE}
# JSONフォーマットの確認
echo ${CONFIG_BEFORE} | python -m json.tool
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # デフォルト設定JSON
[cloudshell-user@ip-10-134-11-244 ~]$ CONFIG_BEFORE=$(
> aws cloudfront get-distribution-config \
> --id ${DISTRIBUTION_ID} \
> --query "DistributionConfig"
> ) \
> && echo ${CONFIG_BEFORE}
{ "CallerReference": "cli-1722767554-44223", "Aliases": { "Quantity": 0 }, "DefaultRootObject": "index.html", "Origins": { "Quantity": 1, "Items": [ { "Id": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934", "DomainName": "20240804-handson-sincere-networker.s3.us-east-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": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934", "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 }
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-134-11-244 ~]$ echo ${CONFIG_BEFORE} | python -m json.tool
{
"CallerReference": "cli-1722767554-44223",
"Aliases": {
"Quantity": 0
},
"DefaultRootObject": "index.html",
"Origins": {
"Quantity": 1,
"Items": [
{
"Id": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"DomainName": "20240804-handson-sincere-networker.s3.us-east-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": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"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
}
キャッシュポリシー(Managed-CachingDisabled) ID取得
コマンド
# キャッシュポリシー名
CACHE_POLICYCONFIG_NAME="Managed-CachingDisabled" \
&& echo ${CACHEPOLICYCONFIG_NAME}
# キャッシュポリシー名を指定してId取得
MANAGED_CACHING_DISABLED_ID=$(
aws cloudfront list-cache-policies \
--query "CachePolicyList.Items[?CachePolicy.CachePolicyConfig.Name=='${CACHE_POLICYCONFIG_NAME}'].CachePolicy.Id" \
--output text
) \
&& echo ${MANAGED_CACHING_DISABLED_ID}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # キャッシュポリシー名
[cloudshell-user@ip-10-134-11-244 ~]$ CACHE_POLICYCONFIG_NAME="Managed-CachingDisabled" \
> && echo ${CACHEPOLICYCONFIG_NAME}
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # キャッシュポリシー名を指定してId取得
[cloudshell-user@ip-10-134-11-244 ~]$ MANAGED_CACHING_DISABLED_ID=$(
> aws cloudfront list-cache-policies \
> --query "CachePolicyList.Items[?CachePolicy.CachePolicyConfig.Name=='${CACHE_POLICYCONFIG_NAME}'].CachePolicy.Id" \
> --output text
> ) \
> && echo ${MANAGED_CACHING_DISABLED_ID}
4135ea2d-6df8-44a3-9df3-4b5a84be39ad
ディストリビューション変更用JSON
コマンド
# ディストリビューション変更用JSON
CONFIG=$(
aws cloudfront get-distribution-config \
--id ${DISTRIBUTION_ID} \
--query "DistributionConfig" \
| jq 'del(.DefaultCacheBehavior.ForwardedValues)' \
| jq 'del(.DefaultCacheBehavior.MinTTL)' \
| jq 'del(.DefaultCacheBehavior.DefaultTTL)' \
| jq 'del(.DefaultCacheBehavior.MaxTTL)' \
| jq '.DefaultCacheBehavior.ViewerProtocolPolicy = "redirect-to-https"' \
| jq '.DefaultCacheBehavior.Compress = true' \
| jq --arg cachepolicyId "${MANAGED_CACHING_DISABLED_ID}" '.DefaultCacheBehavior.CachePolicyId = $cachepolicyId' \
| jq 'del(.Origins.Items[].CustomOriginConfig)' \
| jq '.Origins.Items[].S3OriginConfig = {"OriginAccessIdentity": ""}' \
| jq --arg originId "${ORIGIN_ACCESS_CONTROL_ID}" '.Origins.Items.[].OriginAccessControlId = $originId'
) \
&& echo ${CONFIG}
# JSONフォーマットの確認
echo ${CONFIG} | python -m json.tool
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # ディストリビューション変更用JSON
[cloudshell-user@ip-10-134-11-244 ~]$ CONFIG=$(
> aws cloudfront get-distribution-config \
> --id ${DISTRIBUTION_ID} \
> --query "DistributionConfig" \
> | jq 'del(.DefaultCacheBehavior.ForwardedValues)' \
> | jq 'del(.DefaultCacheBehavior.MinTTL)' \
> | jq 'del(.DefaultCacheBehavior.DefaultTTL)' \
> | jq 'del(.DefaultCacheBehavior.MaxTTL)' \
> | jq '.DefaultCacheBehavior.ViewerProtocolPolicy = "redirect-to-https"' \
> | jq '.DefaultCacheBehavior.Compress = true' \
> | jq --arg cachepolicyId "${MANAGED_CACHING_DISABLED_ID}" '.DefaultCacheBehavior.CachePolicyId = $cachepolicyId' \
> | jq 'del(.Origins.Items[].CustomOriginConfig)' \
> | jq '.Origins.Items[].S3OriginConfig = {"OriginAccessIdentity": ""}' \
> | jq --arg originId "${ORIGIN_ACCESS_CONTROL_ID}" '.Origins.Items.[].OriginAccessControlId = $originId'
> ) \
> && echo ${CONFIG}
{ "CallerReference": "cli-1722767554-44223", "Aliases": { "Quantity": 0 }, "DefaultRootObject": "index.html", "Origins": { "Quantity": 1, "Items": [ { "Id": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934", "DomainName": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com", "OriginPath": "", "CustomHeaders": { "Quantity": 0 }, "ConnectionAttempts": 3, "ConnectionTimeout": 10, "OriginShield": { "Enabled": false }, "OriginAccessControlId": "E2G9MJEEXTOJC1", "S3OriginConfig": { "OriginAccessIdentity": "" } } ] }, "OriginGroups": { "Quantity": 0 }, "DefaultCacheBehavior": { "TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934", "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": true, "LambdaFunctionAssociations": { "Quantity": 0 }, "FunctionAssociations": { "Quantity": 0 }, "FieldLevelEncryptionId": "", "CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad" }, "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 }
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-134-11-244 ~]$ echo ${CONFIG} | python -m json.tool
{
"CallerReference": "cli-1722767554-44223",
"Aliases": {
"Quantity": 0
},
"DefaultRootObject": "index.html",
"Origins": {
"Quantity": 1,
"Items": [
{
"Id": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"DomainName": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": "E2G9MJEEXTOJC1",
"S3OriginConfig": {
"OriginAccessIdentity": ""
}
}
]
},
"OriginGroups": {
"Quantity": 0
},
"DefaultCacheBehavior": {
"TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad"
},
"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
}
ディストリビューション変更適用
コマンド
# 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}" \
--if-match ${ETAG} \
--no-cli-pager
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # ETagを取得
[cloudshell-user@ip-10-134-11-244 ~]$ ETAG=$(
> aws cloudfront get-distribution-config \
> --id ${DISTRIBUTION_ID} \
> --query ETag \
> --output text
> ) \
> && echo ${ETAG}
E34O58LV5JBI3M
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # CloudFrontディストリビューションの設定を更新
[cloudshell-user@ip-10-134-11-244 ~]$ aws cloudfront update-distribution \
> --id ${DISTRIBUTION_ID} \
> --distribution-config "${CONFIG}" \
> --if-match ${ETAG} \
> --no-cli-pager
{
"ETag": "EYFF12T0DBGKW",
"Distribution": {
"Id": "EIN33GD07JLDT",
"ARN": "arn:aws:cloudfront::999999999999:distribution/EIN33GD07JLDT",
"Status": "InProgress",
"LastModifiedTime": "2024-08-04T10:40:04.403000+00:00",
"InProgressInvalidationBatches": 0,
"DomainName": "d18sbbratjvl6c.cloudfront.net",
"ActiveTrustedSigners": {
"Enabled": false,
"Quantity": 0
},
"ActiveTrustedKeyGroups": {
"Enabled": false,
"Quantity": 0
},
"DistributionConfig": {
"CallerReference": "cli-1722767554-44223",
"Aliases": {
"Quantity": 0
},
"DefaultRootObject": "index.html",
"Origins": {
"Quantity": 1,
"Items": [
{
"Id": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"DomainName": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"S3OriginConfig": {
"OriginAccessIdentity": ""
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": "E2G9MJEEXTOJC1"
}
]
},
"OriginGroups": {
"Quantity": 0
},
"DefaultCacheBehavior": {
"TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad"
},
"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
}
}
}
S3変更
バケットポリシー追加
コマンド
# バケットポリシー(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
# バケットポリシー
aws s3api put-bucket-policy \
--bucket ${S3_BUCKET_NAME} \
--policy "${BACKET_POLICY}"
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # バケットポリシー(JSON)
[cloudshell-user@ip-10-134-11-244 ~]$ 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:::20240804-handson-sincere-networker/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::999999999999:distribution/EIN33GD07JLDT" } } } ] }
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-134-11-244 ~]$ 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:::20240804-handson-sincere-networker/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::999999999999:distribution/EIN33GD07JLDT"
}
}
}
]
}
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # バケットポリシー
[cloudshell-user@ip-10-134-11-244 ~]$ aws s3api put-bucket-policy \
> --bucket ${S3_BUCKET_NAME} \
> --policy "${BACKET_POLICY}"
アクセス確認
コマンド
curl https://${DISTRIBUTION_DOMAINNAME}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ curl https://${DISTRIBUTION_DOMAINNAME}
<!DOCTYPE html>
<html>
<head>
<link rel="icon" type="image/x-icon" href="static/image/cloudfront.png">
<link href="static/css/styles.css" rel="stylesheet" type="text/css">
<script src="static/js/script.js"></script>
</head>
<body>
<form id="form1" action="#">
<ul>
<li>
<img src="static/image/cloudfront.png" width="100" height="100">
</li>
<li>
<p>Input Message</p>
<textarea id="input_message" rows="4" cols="40"></textarea>
</li>
<li>
<input type="button" onclick="func1()" value="Send" />
<input type="button" onclick="func2()" value="All Clear" />
</li>
<li>
<br />
<p>Output Message</p>
<textarea id="output_message" rows="4" cols="40"></textarea>
</li>
</ul>
</form>
</body>
</html>
05 Amazon CloudFrontのハンズオン その2 (コンテンツキャッシュの設定)
キャッシュポリシー作成
設定JSON
コマンド
# キャッシュポリシー名
CACHEPOLICY_NAME="handson-cachepolicy" \
&& echo ${CACHEPOLICY_NAME}
# キャッシュポリシー設定JSON
CACHEPOLICY_JSON=$(cat << EOF
{
"Comment": "",
"Name": "handson-cachepolicy",
"DefaultTTL": 86400,
"MaxTTL": 31536000,
"MinTTL": 1,
"ParametersInCacheKeyAndForwardedToOrigin": {
"EnableAcceptEncodingGzip": true,
"EnableAcceptEncodingBrotli": true,
"HeadersConfig": {
"HeaderBehavior": "none"
},
"CookiesConfig": {
"CookieBehavior": "none"
},
"QueryStringsConfig": {
"QueryStringBehavior": "none"
}
}
}
EOF
) \
&& echo ${CACHEPOLICY_JSON}
# JSONフォーマットの確認
echo ${CACHEPOLICY_JSON} | python -m json.tool
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # キャッシュポリシー名
[cloudshell-user@ip-10-134-11-244 ~]$ CACHEPOLICY_NAME="handson-cachepolicy" \
> && echo ${CACHEPOLICY_NAME}
handson-cachepolicy
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # キャッシュポリシー設定JSON
[cloudshell-user@ip-10-134-11-244 ~]$ CACHEPOLICY_JSON=$(cat << EOF
> {
> "Comment": "",
> "Name": "handson-cachepolicy",
> "DefaultTTL": 86400,
> "MaxTTL": 31536000,
> "MinTTL": 1,
> "ParametersInCacheKeyAndForwardedToOrigin": {
> "EnableAcceptEncodingGzip": true,
> "EnableAcceptEncodingBrotli": true,
> "HeadersConfig": {
> "HeaderBehavior": "none"
> },
> "CookiesConfig": {
> "CookieBehavior": "none"
> },
> "QueryStringsConfig": {
> "QueryStringBehavior": "none"
> }
> }
> }
> EOF
> ) \
> && echo ${CACHEPOLICY_JSON}
{ "Comment": "", "Name": "handson-cachepolicy", "DefaultTTL": 86400, "MaxTTL": 31536000, "MinTTL": 1, "ParametersInCacheKeyAndForwardedToOrigin": { "EnableAcceptEncodingGzip": true, "EnableAcceptEncodingBrotli": true, "HeadersConfig": { "HeaderBehavior": "none" }, "CookiesConfig": { "CookieBehavior": "none" }, "QueryStringsConfig": { "QueryStringBehavior": "none" } } }
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-134-11-244 ~]$ echo ${CACHEPOLICY_JSON} | python -m json.tool
{
"Comment": "",
"Name": "handson-cachepolicy",
"DefaultTTL": 86400,
"MaxTTL": 31536000,
"MinTTL": 1,
"ParametersInCacheKeyAndForwardedToOrigin": {
"EnableAcceptEncodingGzip": true,
"EnableAcceptEncodingBrotli": true,
"HeadersConfig": {
"HeaderBehavior": "none"
},
"CookiesConfig": {
"CookieBehavior": "none"
},
"QueryStringsConfig": {
"QueryStringBehavior": "none"
}
}
}
キャッシュポリシー設定
コマンド
# キャッシュポリシー作成
aws cloudfront create-cache-policy \
--cache-policy-config "${CACHEPOLICY_JSON}"
# キャッシュポリシー名を指定してId取得
CACHEPOLICY_ID=$(
aws cloudfront list-cache-policies \
--query "CachePolicyList.Items[?CachePolicy.CachePolicyConfig.Name=='${CACHEPOLICY_NAME}'].CachePolicy.Id" \
--output text
) \
&& echo ${CACHEPOLICY_ID}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # キャッシュポリシー作成
[cloudshell-user@ip-10-134-11-244 ~]$ aws cloudfront create-cache-policy \
> --cache-policy-config "${CACHEPOLICY_JSON}"
{
"Location": "https://cloudfront.amazonaws.com/2020-05-31/cache-policy/fe0144f2-7815-4b78-9544-cc88b1e0fedf",
"ETag": "E23ZP02F085DFQ",
"CachePolicy": {
"Id": "fe0144f2-7815-4b78-9544-cc88b1e0fedf",
"LastModifiedTime": "2024-08-04T10:44:08.178000+00:00",
"CachePolicyConfig": {
"Comment": "",
"Name": "handson-cachepolicy",
"DefaultTTL": 86400,
"MaxTTL": 31536000,
"MinTTL": 1,
"ParametersInCacheKeyAndForwardedToOrigin": {
"EnableAcceptEncodingGzip": true,
"EnableAcceptEncodingBrotli": true,
"HeadersConfig": {
"HeaderBehavior": "none"
},
"CookiesConfig": {
"CookieBehavior": "none"
},
"QueryStringsConfig": {
"QueryStringBehavior": "none"
}
}
}
}
}
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # キャッシュポリシー名を指定してId取得
[cloudshell-user@ip-10-134-11-244 ~]$ CACHEPOLICY_ID=$(
> aws cloudfront list-cache-policies \
> --query "CachePolicyList.Items[?CachePolicy.CachePolicyConfig.Name=='${CACHEPOLICY_NAME}'].CachePolicy.Id" \
> --output text
> ) \
> && echo ${CACHEPOLICY_ID}
fe0144f2-7815-4b78-9544-cc88b1e0fedf
ビヘイビア追加
条件
- パスパターン:/static/*
- Redirect HTTP to HTTPS
- キャッシュポリシー:CachingDisabled
ビヘイビアJSON
コマンド
# ビヘイビア設定JSON
BEHAVIOR_JSON=$(cat << EOF
{
"Quantity": 1,
"Items": [
{
"PathPattern": "/static/*",
"TargetOriginId": "${DISTRIBUTION_ORIGIN_ID}",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "${CACHEPOLICY_ID}"
}
]
}
EOF
) \
&& echo ${BEHAVIOR_JSON}
# JSONフォーマットの確認
echo ${BEHAVIOR_JSON} | python -m json.tool
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # ビヘイビア設定JSON
[cloudshell-user@ip-10-134-11-244 ~]$ BEHAVIOR_JSON=$(cat << EOF
> {
> "Quantity": 1,
> "Items": [
> {
> "PathPattern": "/static/*",
> "TargetOriginId": "${DISTRIBUTION_ORIGIN_ID}",
> "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": true,
> "LambdaFunctionAssociations": {
> "Quantity": 0
> },
> "FunctionAssociations": {
> "Quantity": 0
> },
> "FieldLevelEncryptionId": "",
> "CachePolicyId": "${CACHEPOLICY_ID}"
> }
> ]
> }
> EOF
> ) \
> && echo ${BEHAVIOR_JSON}
{ "Quantity": 1, "Items": [ { "PathPattern": "/static/*", "TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934", "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": true, "LambdaFunctionAssociations": { "Quantity": 0 }, "FunctionAssociations": { "Quantity": 0 }, "FieldLevelEncryptionId": "", "CachePolicyId": "fe0144f2-7815-4b78-9544-cc88b1e0fedf" } ] }
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-134-11-244 ~]$ echo ${BEHAVIOR_JSON} | python -m json.tool
{
"Quantity": 1,
"Items": [
{
"PathPattern": "/static/*",
"TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "fe0144f2-7815-4b78-9544-cc88b1e0fedf"
}
]
}
ディストリビューションJSON (ビヘイビア追加)
ディストリビューションJSON
コマンド
# ディストリビューション変更用JSON
CONFIG=$(
aws cloudfront get-distribution-config \
--id ${DISTRIBUTION_ID} \
--query "DistributionConfig" \
| jq --argjson behavior "${BEHAVIOR_JSON}" '.CacheBehaviors = $behavior'
) \
&& echo ${CONFIG}
# JSONフォーマットの確認
echo ${CONFIG} | python -m json.tool
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # ディストリビューション変更用JSON
[cloudshell-user@ip-10-134-11-244 ~]$ CONFIG=$(
> aws cloudfront get-distribution-config \
> --id ${DISTRIBUTION_ID} \
> --query "DistributionConfig" \
> | jq --argjson behavior "${BEHAVIOR_JSON}" '.CacheBehaviors = $behavior'
> ) \
> && echo ${CONFIG}
{ "CallerReference": "cli-1722767554-44223", "Aliases": { "Quantity": 0 }, "DefaultRootObject": "index.html", "Origins": { "Quantity": 1, "Items": [ { "Id": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934", "DomainName": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com", "OriginPath": "", "CustomHeaders": { "Quantity": 0 }, "S3OriginConfig": { "OriginAccessIdentity": "" }, "ConnectionAttempts": 3, "ConnectionTimeout": 10, "OriginShield": { "Enabled": false }, "OriginAccessControlId": "E2G9MJEEXTOJC1" } ] }, "OriginGroups": { "Quantity": 0 }, "DefaultCacheBehavior": { "TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934", "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": true, "LambdaFunctionAssociations": { "Quantity": 0 }, "FunctionAssociations": { "Quantity": 0 }, "FieldLevelEncryptionId": "", "CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad" }, "CacheBehaviors": { "Quantity": 1, "Items": [ { "PathPattern": "/static/*", "TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934", "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": true, "LambdaFunctionAssociations": { "Quantity": 0 }, "FunctionAssociations": { "Quantity": 0 }, "FieldLevelEncryptionId": "", "CachePolicyId": "fe0144f2-7815-4b78-9544-cc88b1e0fedf" } ] }, "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 }
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-134-11-244 ~]$ echo ${CONFIG} | python -m json.tool
{
"CallerReference": "cli-1722767554-44223",
"Aliases": {
"Quantity": 0
},
"DefaultRootObject": "index.html",
"Origins": {
"Quantity": 1,
"Items": [
{
"Id": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"DomainName": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"S3OriginConfig": {
"OriginAccessIdentity": ""
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": "E2G9MJEEXTOJC1"
}
]
},
"OriginGroups": {
"Quantity": 0
},
"DefaultCacheBehavior": {
"TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad"
},
"CacheBehaviors": {
"Quantity": 1,
"Items": [
{
"PathPattern": "/static/*",
"TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "fe0144f2-7815-4b78-9544-cc88b1e0fedf"
}
]
},
"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
}
ディストリビューション適用
コマンド
# 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}" \
--if-match ${ETAG} \
--no-cli-pager
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # CloudFrontディストリビューションの設定を更新
[cloudshell-user@ip-10-134-11-244 ~]$ aws cloudfront update-distribution \
> --id ${DISTRIBUTION_ID} \
> --distribution-config "${CONFIG}" \
> --if-match ${ETAG} \
> --no-cli-pager
{
"ETag": "E3H7EIKSZ5KXEF",
"Distribution": {
"Id": "EIN33GD07JLDT",
"ARN": "arn:aws:cloudfront::999999999999:distribution/EIN33GD07JLDT",
"Status": "InProgress",
"LastModifiedTime": "2024-08-04T10:45:59.549000+00:00",
"InProgressInvalidationBatches": 0,
"DomainName": "d18sbbratjvl6c.cloudfront.net",
"ActiveTrustedSigners": {
"Enabled": false,
"Quantity": 0
},
"ActiveTrustedKeyGroups": {
"Enabled": false,
"Quantity": 0
},
"DistributionConfig": {
"CallerReference": "cli-1722767554-44223",
"Aliases": {
"Quantity": 0
},
"DefaultRootObject": "index.html",
"Origins": {
"Quantity": 1,
"Items": [
{
"Id": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"DomainName": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"S3OriginConfig": {
"OriginAccessIdentity": ""
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": "E2G9MJEEXTOJC1"
}
]
},
"OriginGroups": {
"Quantity": 0
},
"DefaultCacheBehavior": {
"TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad"
},
"CacheBehaviors": {
"Quantity": 1,
"Items": [
{
"PathPattern": "/static/*",
"TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "fe0144f2-7815-4b78-9544-cc88b1e0fedf"
}
]
},
"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
}
}
}
アクセス確認
コマンド
curl https://${DISTRIBUTION_DOMAINNAME}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ curl https://${DISTRIBUTION_DOMAINNAME}
<!DOCTYPE html>
<html>
<head>
<link rel="icon" type="image/x-icon" href="static/image/cloudfront.png">
<link href="static/css/styles.css" rel="stylesheet" type="text/css">
<script src="static/js/script.js"></script>
</head>
<body>
<form id="form1" action="#">
<ul>
<li>
<img src="static/image/cloudfront.png" width="100" height="100">
</li>
<li>
<p>Input Message</p>
<textarea id="input_message" rows="4" cols="40"></textarea>
</li>
<li>
<input type="button" onclick="func1()" value="Send" />
<input type="button" onclick="func2()" value="All Clear" />
</li>
<li>
<br />
<p>Output Message</p>
<textarea id="output_message" rows="4" cols="40"></textarea>
</li>
</ul>
</form>
</body>
</html>
06 Amazon CloudFrontのハンズオン その3 (動的コンテンツの配信設定①)
Lambda関数作成
条件
関数名:handson-lambda
ランタイム:Python 3.8
変数設定
コマンド
# 変数設定
FUNCTION_NAME="handson-lambda" \
&& echo ${FUNCTION_NAME}
RUNTIME="python3.8" \
&& echo ${RUNTIME}
POLICY_NAME="${FUNCTION_NAME}-policy" \
&& echo ${POLICY_NAME}
ROLE_NAME="${FUNCTION_NAME}-role" \
&& echo ${ROLE_NAME}
ATTACH_POLICY_NAME="TranslateReadOnly" \
&& echo ${ATTACH_POLICY_NAME}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # 変数設定
[cloudshell-user@ip-10-134-11-244 ~]$ FUNCTION_NAME="handson-lambda" \
> && echo ${FUNCTION_NAME}
handson-lambda
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ RUNTIME="python3.8" \
> && echo ${RUNTIME}
python3.8
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ POLICY_NAME="${FUNCTION_NAME}-policy" \
> && echo ${POLICY_NAME}
handson-lambda-policy
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ ROLE_NAME="${FUNCTION_NAME}-role" \
> && echo ${ROLE_NAME}
handson-lambda-role
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ ATTACH_POLICY_NAME="TranslateReadOnly" \
> && echo ${ATTACH_POLICY_NAME}
TranslateReadOnly
IAMポリシー作成
コマンド
# ポリシードキュメントの作成
POLICY_DOCUMENT_JSON=$(cat << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:${REGION}:999999999999:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:${REGION}:999999999999:log-group:/aws/lambda/${FUNCTION_NAME}:*"
]
}
]
}
EOF
) \
&& echo ${POLICY_DOCUMENT_JSON}
# JSONフォーマットの確認
echo ${POLICY_DOCUMENT_JSON} | python -m json.tool
# ポリシーの作成
aws iam create-policy \
--policy-name ${POLICY_NAME} \
--policy-document "${POLICY_DOCUMENT_JSON}"
# ARN取得
POLICY_ARN=$(
aws iam list-policies \
--query "Policies[?PolicyName=='${POLICY_NAME}'].Arn" \
--output text
) \
&& echo ${POLICY_ARN}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # ポリシードキュメントの作成
[cloudshell-user@ip-10-134-11-244 ~]$ POLICY_DOCUMENT_JSON=$(cat << EOF
> {
> "Version": "2012-10-17",
> "Statement": [
> {
> "Effect": "Allow",
> "Action": "logs:CreateLogGroup",
> "Resource": "arn:aws:logs:${REGION}:999999999999:*"
> },
> {
> "Effect": "Allow",
> "Action": [
> "logs:CreateLogStream",
> "logs:PutLogEvents"
> ],
> "Resource": [
> "arn:aws:logs:${REGION}:999999999999:log-group:/aws/lambda/${FUNCTION_NAME}:*"
> ]
> }
> ]
> }
> EOF
> ) \
> && echo ${POLICY_DOCUMENT_JSON}
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "logs:CreateLogGroup", "Resource": "arn:aws:logs:us-east-1:999999999999:*" }, { "Effect": "Allow", "Action": [ "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": [ "arn:aws:logs:us-east-1:999999999999:log-group:/aws/lambda/handson-lambda:*" ] } ] }
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-134-11-244 ~]$ echo ${POLICY_DOCUMENT_JSON} | python -m json.tool
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:us-east-1:999999999999:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:us-east-1:999999999999:log-group:/aws/lambda/handson-lambda:*"
]
}
]
}
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # ポリシーの作成
[cloudshell-user@ip-10-134-11-244 ~]$ aws iam create-policy \
> --policy-name ${POLICY_NAME} \
> --policy-document "${POLICY_DOCUMENT_JSON}"
{
"Policy": {
"PolicyName": "handson-lambda-policy",
"PolicyId": "ANPAWFKRCMKO4GTU36ISU",
"Arn": "arn:aws:iam::999999999999:policy/handson-lambda-policy",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 0,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2024-08-04T10:49:10+00:00",
"UpdateDate": "2024-08-04T10:49:10+00:00"
}
}
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # ARN取得
[cloudshell-user@ip-10-134-11-244 ~]$ POLICY_ARN=$(
> aws iam list-policies \
> --query "Policies[?PolicyName=='${POLICY_NAME}'].Arn" \
> --output text
> ) \
> && echo ${POLICY_ARN}
arn:aws:iam::999999999999:policy/handson-lambda-policy
IAMロール作成
コマンド
# 信頼関係ポリシードキュメントの作成
ASSUME_ROLE_POLICY_DOCUMENT=$(cat << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
) \
&& echo ${ASSUME_ROLE_POLICY_DOCUMENT}
# IAMロールの作成
aws iam create-role \
--role-name ${ROLE_NAME} \
--assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"
# IAMロールにポリシーをアタッチ
aws iam attach-role-policy \
--role-name ${ROLE_NAME} \
--policy-arn ${POLICY_ARN}
aws iam attach-role-policy \
--role-name ${ROLE_NAME} \
--policy-arn arn:aws:iam::aws:policy/${ATTACH_POLICY_NAME}
# ARN取得
ROLE_ARN=$(
aws iam get-role \
--role-name ${ROLE_NAME} \
--query 'Role.Arn' --output text
) \
&& echo ${ROLE_ARN}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # 信頼関係ポリシードキュメントの作成
[cloudshell-user@ip-10-134-11-244 ~]$ ASSUME_ROLE_POLICY_DOCUMENT=$(cat << EOF
> {
> "Version": "2012-10-17",
> "Statement": [
> {
> "Effect": "Allow",
> "Principal": {
> "Service": "lambda.amazonaws.com"
> },
> "Action": "sts:AssumeRole"
> }
> ]
> }
> EOF
> ) \
> && echo ${ASSUME_ROLE_POLICY_DOCUMENT}
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # IAMロールの作成
[cloudshell-user@ip-10-134-11-244 ~]$ aws iam create-role \
> --role-name ${ROLE_NAME} \
> --assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"
{
"Role": {
"Path": "/",
"RoleName": "handson-lambda-role",
"RoleId": "AROAWFKRCMKOZTTQSCLKD",
"Arn": "arn:aws:iam::999999999999:role/handson-lambda-role",
"CreateDate": "2024-08-04T10:49:56+00:00",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
}
}
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # IAMロールにポリシーをアタッチ
[cloudshell-user@ip-10-134-11-244 ~]$ aws iam attach-role-policy \
> --role-name ${ROLE_NAME} \
> --policy-arn ${POLICY_ARN}
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ aws iam attach-role-policy \
> --role-name ${ROLE_NAME} \
> --policy-arn arn:aws:iam::aws:policy/${ATTACH_POLICY_NAME}
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # ARN取得
[cloudshell-user@ip-10-134-11-244 ~]$ ROLE_ARN=$(
> aws iam get-role \
> --role-name ${ROLE_NAME} \
> --query 'Role.Arn' --output text
> ) \
> && echo ${ROLE_ARN}
arn:aws:iam::999999999999:role/handson-lambda-role
コードソースの作成
コマンド
# コードソースの作成
cat << EOF > lambda_function.py
import boto3
def lambda_handler(event, context):
translate = boto3.client(service_name='translate', use_ssl=True)
result = translate.translate_text(Text=event['queryStringParameters']['input_text'], SourceLanguageCode="ja", TargetLanguageCode="en").get('TranslatedText')
return {
'statusCode': 200,
'body': result
}
EOF
cat lambda_function.py
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # コードソースの作成
[cloudshell-user@ip-10-134-11-244 ~]$ cat << EOF > lambda_function.py
> import boto3
>
> def lambda_handler(event, context):
> translate = boto3.client(service_name='translate', use_ssl=True)
> result = translate.translate_text(Text=event['queryStringParameters']['input_text'], SourceLanguageCode="ja", TargetLanguageCode="en").get('TranslatedText')
> return {
> 'statusCode': 200,
> 'body': result
> }
> EOF
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ cat lambda_function.py
import boto3
def lambda_handler(event, context):
translate = boto3.client(service_name='translate', use_ssl=True)
result = translate.translate_text(Text=event['queryStringParameters']['input_text'], SourceLanguageCode="ja", TargetLanguageCode="en").get('TranslatedText')
return {
'statusCode': 200,
'body': result
}
デプロイパッケージの作成
コマンド
# デプロイパッケージの作成
zip function.zip lambda_function.py
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # デプロイパッケージの作成
[cloudshell-user@ip-10-134-11-244 ~]$ zip function.zip lambda_function.py
adding: lambda_function.py (deflated 35%)
Lambda関数の作成
コマンド
# Lambda関数の作成
aws lambda create-function \
--function-name ${FUNCTION_NAME} \
--runtime ${RUNTIME} \
--role $ROLE_ARN \
--handler lambda_function.lambda_handler \
--zip-file fileb://function.zip \
--region ${REGION}
# ARNの取得
FUNCTION_ARN=$(
aws lambda list-functions \
--query "Functions[?FunctionName=='${FUNCTION_NAME}'].FunctionArn" \
--output text \
--region ${REGION}
) \
&& echo ${FUNCTION_ARN}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # Lambda関数の作成
[cloudshell-user@ip-10-134-11-244 ~]$ aws lambda create-function \
> --function-name ${FUNCTION_NAME} \
> --runtime ${RUNTIME} \
> --role $ROLE_ARN \
> --handler lambda_function.lambda_handler \
> --zip-file fileb://function.zip \
> --region ${REGION}
{
"FunctionName": "handson-lambda",
"FunctionArn": "arn:aws:lambda:us-east-1:999999999999:function:handson-lambda",
"Runtime": "python3.8",
"Role": "arn:aws:iam::999999999999:role/handson-lambda-role",
"Handler": "lambda_function.lambda_handler",
"CodeSize": 413,
"Description": "",
"Timeout": 3,
"MemorySize": 128,
"LastModified": "2024-08-04T10:51:50.585+0000",
"CodeSha256": "nciDUmm7f23oZxnzby4PM+8ud73Fhoy62JGfBHofW3U=",
"Version": "$LATEST",
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "972d7ae7-0212-4b87-9971-f63890593325",
"State": "Pending",
"StateReason": "The function is being created.",
"StateReasonCode": "Creating",
"PackageType": "Zip",
"Architectures": [
"x86_64"
],
"EphemeralStorage": {
"Size": 512
},
"SnapStart": {
"ApplyOn": "None",
"OptimizationStatus": "Off"
},
"RuntimeVersionConfig": {
"RuntimeVersionArn": "arn:aws:lambda:us-east-1::runtime:d2da00eeedb26cf3d2faaca725b024098a35c6e8a9c894dfa7015d02f6659c0a"
},
"LoggingConfig": {
"LogFormat": "Text",
"LogGroup": "/aws/lambda/handson-lambda"
}
}
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # ARNの取得
[cloudshell-user@ip-10-134-11-244 ~]$ FUNCTION_ARN=$(
> aws lambda list-functions \
> --query "Functions[?FunctionName=='${FUNCTION_NAME}'].FunctionArn" \
> --output text \
> --region ${REGION}
> ) \
> && echo ${FUNCTION_ARN}
arn:aws:lambda:us-east-1:999999999999:function:handson-lambda
API Gateway作成
条件
- API名:handson-api
- APIエンドポイントタイプ:リージョン
- リージョン:バージニア北部
変数設定
コマンド
# API名
API_NAME="handson-api" \
&& echo ${API_NAME}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # API名
[cloudshell-user@ip-10-134-11-244 ~]$ API_NAME="handson-api" \
> && echo ${API_NAME}
handson-api
REST APIの作成
コマンド
# REST APIの作成
aws apigateway create-rest-api \
--name ${API_NAME} \
--endpoint-configuration types=REGIONAL \
--region ${REGION}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # REST APIの作成
[cloudshell-user@ip-10-134-11-244 ~]$ aws apigateway create-rest-api \
> --name ${API_NAME} \
> --endpoint-configuration types=REGIONAL \
> --region ${REGION}
{
"id": "4ad63asxjb",
"name": "handson-api",
"createdDate": "2024-08-04T10:52:48+00:00",
"apiKeySource": "HEADER",
"endpointConfiguration": {
"types": [
"REGIONAL"
]
},
"disableExecuteApiEndpoint": false,
"rootResourceId": "3vdr2wkvof"
}
IDの取得
コマンド
# API IDの取得
RESET_API_ID=$(
aws apigateway get-rest-apis \
--query "items[?name=='${API_NAME}'].id" \
--region ${REGION} \
--output text
) \
&& echo ${RESET_API_ID}
# ルートリソースIDの取得
PARENT_ID=$(
aws apigateway get-resources \
--rest-api-id ${RESET_API_ID} \
--query "items[?path=='/'].id" \
--region ${REGION} \
--output text
) \
&& echo ${PARENT_ID}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # API IDの取得
[cloudshell-user@ip-10-134-11-244 ~]$ RESET_API_ID=$(
> aws apigateway get-rest-apis \
> --query "items[?name=='${API_NAME}'].id" \
> --region ${REGION} \
> --output text
> ) \
> && echo ${RESET_API_ID}
4ad63asxjb
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # ルートリソースIDの取得
[cloudshell-user@ip-10-134-11-244 ~]$ PARENT_ID=$(
> aws apigateway get-resources \
> --rest-api-id ${RESET_API_ID} \
> --query "items[?path=='/'].id" \
> --region ${REGION} \
> --output text
> ) \
> && echo ${PARENT_ID}
3vdr2wkvof
GETメソッドの作成
条件
- 総合タイプ:Lambda関数
- Lambda プロキシ総合の使用:あり
- Lambdaリージョン:バージニア北部
- Lambda関数:handson-lambda
- デフォルトタイムアウトの使用:あり
コマンド
# GETメソッドの作成
aws apigateway put-method \
--rest-api-id ${RESET_API_ID} \
--resource-id ${PARENT_ID} \
--http-method GET \
--authorization-type NONE \
--no-api-key-required \
--request-parameters method.request.querystring.input_text=false \
--region ${REGION}
# メソッドレスポンスの設定
aws apigateway put-method-response \
--rest-api-id ${RESET_API_ID} \
--resource-id ${PARENT_ID} \
--http-method GET \
--status-code 200 \
--response-models application/json=Empty \
--region ${REGION}
# 統合の設定
aws apigateway put-integration \
--rest-api-id ${RESET_API_ID} \
--resource-id ${PARENT_ID} \
--http-method GET \
--type AWS_PROXY \
--integration-http-method POST \
--uri arn:aws:apigateway:${REGION}:lambda:path/2015-03-31/functions/${FUNCTION_ARN}/invocations \
--passthrough-behavior WHEN_NO_MATCH \
--content-handling CONVERT_TO_TEXT \
--timeout-in-millis 29000 \
--region ${REGION}
# 統合レスポンスの設定
aws apigateway put-integration-response \
--rest-api-id ${RESET_API_ID} \
--resource-id ${PARENT_ID} \
--http-method GET \
--status-code 200 \
--response-templates application/json="" \
--region ${REGION}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # GETメソッドの作成
[cloudshell-user@ip-10-134-11-244 ~]$ aws apigateway put-method \
> --rest-api-id ${RESET_API_ID} \
> --resource-id ${PARENT_ID} \
> --http-method GET \
> --authorization-type NONE \
> --no-api-key-required \
> --request-parameters method.request.querystring.input_text=false \
> --region ${REGION}
{
"httpMethod": "GET",
"authorizationType": "NONE",
"apiKeyRequired": false,
"requestParameters": {
"method.request.querystring.input_text": false
}
}
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # メソッドレスポンスの設定
[cloudshell-user@ip-10-134-11-244 ~]$ aws apigateway put-method-response \
> --rest-api-id ${RESET_API_ID} \
> --resource-id ${PARENT_ID} \
> --http-method GET \
> --status-code 200 \
> --response-models application/json=Empty \
> --region ${REGION}
{
"statusCode": "200",
"responseModels": {
"application/json": "Empty"
}
}
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # 統合の設定
[cloudshell-user@ip-10-134-11-244 ~]$ aws apigateway put-integration \
> --rest-api-id ${RESET_API_ID} \
> --resource-id ${PARENT_ID} \
> --http-method GET \
> --type AWS_PROXY \
> --integration-http-method POST \
> --uri arn:aws:apigateway:${REGION}:lambda:path/2015-03-31/functions/${FUNCTION_ARN}/invocations \
> --passthrough-behavior WHEN_NO_MATCH \
> --content-handling CONVERT_TO_TEXT \
> --timeout-in-millis 29000 \
> --region ${REGION}
{
"type": "AWS_PROXY",
"httpMethod": "POST",
"uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:999999999999:function:handson-lambda/invocations",
"passthroughBehavior": "WHEN_NO_MATCH",
"contentHandling": "CONVERT_TO_TEXT",
"timeoutInMillis": 29000,
"cacheNamespace": "3vdr2wkvof",
"cacheKeyParameters": []
}
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # 統合レスポンスの設定
[cloudshell-user@ip-10-134-11-244 ~]$ aws apigateway put-integration-response \
> --rest-api-id ${RESET_API_ID} \
> --resource-id ${PARENT_ID} \
> --http-method GET \
> --status-code 200 \
> --response-templates application/json="" \
> --region ${REGION}
{
"statusCode": "200",
"responseTemplates": {
"application/json": null
}
}
デプロイ
コマンド
# 変数
STAGE_NAME="api" \
&& echo ${STAGE_NAME}
# デプロイ
aws apigateway create-deployment \
--rest-api-id ${RESET_API_ID} \
--stage-name ${STAGE_NAME} \
--region ${REGION}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # 変数
[cloudshell-user@ip-10-134-11-244 ~]$ STAGE_NAME="api" \
> && echo ${STAGE_NAME}
api
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # デプロイ
[cloudshell-user@ip-10-134-11-244 ~]$ aws apigateway create-deployment \
> --rest-api-id ${RESET_API_ID} \
> --stage-name ${STAGE_NAME} \
> --region ${REGION}
{
"id": "jcg2z7",
"createdDate": "2024-08-04T10:54:14+00:00"
}
Lambdaへの権限追加
コマンド
RESOURCE_PATH=$(
aws apigateway get-resources \
--rest-api-id ${RESET_API_ID} \
--query items[].path \
--output text \
--region ${REGION}
) \
&& echo ${RESOURCE_PATH}
aws lambda add-permission \
--function-name ${FUNCTION_NAME} \
--statement-id ${FUNCTION_NAME}\
--action 'lambda:InvokeFunction' \
--principal apigateway.amazonaws.com \
--source-arn arn:aws:execute-api:${REGION}:999999999999:${RESET_API_ID}/*/GET${RESOURCE_PATH} \
--region ${REGION}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # パスの取得
[cloudshell-user@ip-10-134-11-244 ~]$ RESOURCE_PATH=$(
> aws apigateway get-resources \
> --rest-api-id ${RESET_API_ID} \
> --query items[].path \
> --output text \
> --region ${REGION}
> ) \
> && echo ${RESOURCE_PATH}
/
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # Lambdaへの権限追加
[cloudshell-user@ip-10-134-11-244 ~]$ aws lambda add-permission \
> --function-name ${FUNCTION_NAME} \
> --statement-id ${FUNCTION_NAME}\
> --action 'lambda:InvokeFunction' \
> --principal apigateway.amazonaws.com \
> --source-arn arn:aws:execute-api:${REGION}:999999999999:${RESET_API_ID}/*/GET${RESOURCE_PATH} \
> --region ${REGION}
{
"Statement": "{\"Sid\":\"handson-lambda\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:us-east-1:999999999999:function:handson-lambda\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:us-east-1:999999999999:4ad63asxjb/*/GET/\"}}}"
}
通信確認 (API Gateway直)
コマンド
# input_textオプションをつけないとエラーになる
curl https://${RESET_API_ID}.execute-api.${REGION}.amazonaws.com/${STAGE_NAME}
# input_textオプションをつけると翻訳される(日本語をURLエンコードでしてから渡す)
encoded_query=$(echo -n 'こんにちは世界' | jq -s -R -r @uri) \
&& echo ${encoded_query}
curl https://${RESET_API_ID}.execute-api.${REGION}.amazonaws.com/${STAGE_NAME}?input_text=${encoded_query}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # input_textオプションをつけないとエラーになる
[cloudshell-user@ip-10-134-11-244 ~]$ curl https://${RESET_API_ID}.execute-api.${REGION}.amazonaws.com/${STAGE_NAME}
{"message": "Internal server error"}
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # input_textオプションをつけると翻訳される(日本語をURLエンコードでしてから渡す)
[cloudshell-user@ip-10-134-11-244 ~]$ encoded_query=$(echo -n 'こんにちは世界' | jq -s -R -r @uri) \
> && echo ${encoded_query}
%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF%E4%B8%96%E7%95%8C
[cloudshell-user@ip-10-134-11-244 ~]$ curl https://${RESET_API_ID}.execute-api.${REGION}.amazonaws.com/${STAGE_NAME}?input_text=${encoded_query}
Hello world
07 Amazon CloudFrontのハンズオン その4 (動的コンテンツの配信設定②)
オリジンリクエストポリシー作成
設定JSON
コマンド
# オリジンリクエストポリシー名
ORIGIN_REQUESTPOLICY_NAME="handson-originrequestpolicy" \
&& echo ${ORIGIN_REQUESTPOLICY_NAME}
# オリジンリクエストポリシー設定JSON
ORIGIN_REQUESTPOLICY_JSON=$(cat << EOF
{
"Name": "${ORIGIN_REQUESTPOLICY_NAME}",
"HeadersConfig": {
"HeaderBehavior": "none"
},
"CookiesConfig": {
"CookieBehavior": "none"
},
"QueryStringsConfig": {
"QueryStringBehavior": "whitelist",
"QueryStrings": {
"Items": [
"input_text"
],
"Quantity": 1
}
}
}
EOF
) \
&& echo ${ORIGIN_REQUESTPOLICY_JSON}
# JSONフォーマットの確認
echo ${ORIGIN_REQUESTPOLICY_JSON} | python -m json.tool
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # オリジンリクエストポリシー名
[cloudshell-user@ip-10-134-11-244 ~]$ ORIGIN_REQUESTPOLICY_NAME="handson-originrequestpolicy" \
> && echo ${ORIGIN_REQUESTPOLICY_NAME}
handson-originrequestpolicy
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # オリジンリクエストポリシー設定JSON
[cloudshell-user@ip-10-134-11-244 ~]$ ORIGIN_REQUESTPOLICY_JSON=$(cat << EOF
> {
> "Name": "${ORIGIN_REQUESTPOLICY_NAME}",
> "HeadersConfig": {
> "HeaderBehavior": "none"
> },
> "CookiesConfig": {
> "CookieBehavior": "none"
> },
> "QueryStringsConfig": {
> "QueryStringBehavior": "whitelist",
> "QueryStrings": {
> "Items": [
> "input_text"
> ],
> "Quantity": 1
> }
> }
> }
> EOF
> ) \
> && echo ${ORIGIN_REQUESTPOLICY_JSON}
{ "Name": "handson-originrequestpolicy", "HeadersConfig": { "HeaderBehavior": "none" }, "CookiesConfig": { "CookieBehavior": "none" }, "QueryStringsConfig": { "QueryStringBehavior": "whitelist", "QueryStrings": { "Items": [ "input_text" ], "Quantity": 1 } } }
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-134-11-244 ~]$ echo ${ORIGIN_REQUESTPOLICY_JSON} | python -m json.tool
{
"Name": "handson-originrequestpolicy",
"HeadersConfig": {
"HeaderBehavior": "none"
},
"CookiesConfig": {
"CookieBehavior": "none"
},
"QueryStringsConfig": {
"QueryStringBehavior": "whitelist",
"QueryStrings": {
"Items": [
"input_text"
],
"Quantity": 1
}
}
}
オリジンリクエストポリシー設定
コマンド
# オリジンリクエストポリシー作成
aws cloudfront create-origin-request-policy \
--origin-request-policy-config "${ORIGIN_REQUESTPOLICY_JSON}"
# オリジンリクエストポリシー名を指定してId取得
ORIGIN_REQUESTPOLICY_ID=$(
aws cloudfront list-origin-request-policies \
--query "OriginRequestPolicyList.Items[?OriginRequestPolicy.OriginRequestPolicyConfig.Name=='${ORIGIN_REQUESTPOLICY_NAME}'].OriginRequestPolicy.Id" \
--output text
) \
&& echo ${ORIGIN_REQUESTPOLICY_ID}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # オリジンリクエストポリシー作成
[cloudshell-user@ip-10-134-11-244 ~]$ aws cloudfront create-origin-request-policy \
> --origin-request-policy-config "${ORIGIN_REQUESTPOLICY_JSON}"
{
"Location": "https://cloudfront.amazonaws.com/2020-05-31/origin-request-policy/8f0c7698-7ec2-42b7-9155-f1e2bc9418d0",
"ETag": "E23ZP02F085DFQ",
"OriginRequestPolicy": {
"Id": "8f0c7698-7ec2-42b7-9155-f1e2bc9418d0",
"LastModifiedTime": "2024-08-04T11:13:29.856000+00:00",
"OriginRequestPolicyConfig": {
"Name": "handson-originrequestpolicy",
"HeadersConfig": {
"HeaderBehavior": "none"
},
"CookiesConfig": {
"CookieBehavior": "none"
},
"QueryStringsConfig": {
"QueryStringBehavior": "whitelist",
"QueryStrings": {
"Quantity": 1,
"Items": [
"input_text"
]
}
}
}
}
}
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # オリジンリクエストポリシー名を指定してId取得
[cloudshell-user@ip-10-134-11-244 ~]$ ORIGIN_REQUESTPOLICY_ID=$(
> aws cloudfront list-origin-request-policies \
> --query "OriginRequestPolicyList.Items[?OriginRequestPolicy.OriginRequestPolicyConfig.Name=='${ORIGIN_REQUESTPOLICY_NAME}'].OriginRequestPolicy.Id" \
> --output text
> ) \
> && echo ${ORIGIN_REQUESTPOLICY_ID}
8f0c7698-7ec2-42b7-9155-f1e2bc9418d0
ディストリビューション変更
オリジン設定JSON
コマンド
# オリジン設定JSON
ORIGIN_JSON=$(cat << EOF
{
"Id": "${RESET_API_ID}.execute-api.${REGION}.amazonaws.com",
"DomainName": "${RESET_API_ID}.execute-api.${REGION}.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"CustomOriginConfig": {
"HTTPPort": 80,
"HTTPSPort": 443,
"OriginProtocolPolicy": "https-only",
"OriginSslProtocols": {
"Quantity": 1,
"Items": [
"TLSv1.2"
]
},
"OriginReadTimeout": 30,
"OriginKeepaliveTimeout": 5
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": ""
}
EOF
) \
&& echo ${ORIGIN_JSON}
# JSONフォーマットの確認
echo ${ORIGIN_JSON} | python -m json.tool
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # オリジン設定JSON
[cloudshell-user@ip-10-134-11-244 ~]$ ORIGIN_JSON=$(cat << EOF
> {
> "Id": "${RESET_API_ID}.execute-api.${REGION}.amazonaws.com",
> "DomainName": "${RESET_API_ID}.execute-api.${REGION}.amazonaws.com",
> "OriginPath": "",
> "CustomHeaders": {
> "Quantity": 0
> },
> "CustomOriginConfig": {
> "HTTPPort": 80,
> "HTTPSPort": 443,
> "OriginProtocolPolicy": "https-only",
> "OriginSslProtocols": {
> "Quantity": 1,
> "Items": [
> "TLSv1.2"
> ]
> },
> "OriginReadTimeout": 30,
> "OriginKeepaliveTimeout": 5
> },
> "ConnectionAttempts": 3,
> "ConnectionTimeout": 10,
> "OriginShield": {
> "Enabled": false
> },
> "OriginAccessControlId": ""
> }
> EOF
> ) \
> && echo ${ORIGIN_JSON}
{ "Id": "4ad63asxjb.execute-api.us-east-1.amazonaws.com", "DomainName": "4ad63asxjb.execute-api.us-east-1.amazonaws.com", "OriginPath": "", "CustomHeaders": { "Quantity": 0 }, "CustomOriginConfig": { "HTTPPort": 80, "HTTPSPort": 443, "OriginProtocolPolicy": "https-only", "OriginSslProtocols": { "Quantity": 1, "Items": [ "TLSv1.2" ] }, "OriginReadTimeout": 30, "OriginKeepaliveTimeout": 5 }, "ConnectionAttempts": 3, "ConnectionTimeout": 10, "OriginShield": { "Enabled": false }, "OriginAccessControlId": "" }
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-134-11-244 ~]$ echo ${ORIGIN_JSON} | python -m json.tool
{
"Id": "4ad63asxjb.execute-api.us-east-1.amazonaws.com",
"DomainName": "4ad63asxjb.execute-api.us-east-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"CustomOriginConfig": {
"HTTPPort": 80,
"HTTPSPort": 443,
"OriginProtocolPolicy": "https-only",
"OriginSslProtocols": {
"Quantity": 1,
"Items": [
"TLSv1.2"
]
},
"OriginReadTimeout": 30,
"OriginKeepaliveTimeout": 5
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": ""
}
ビヘイビア設定JSON
条件
- パスパターン:/${STAGE_NAME}/*
- Redirect HTTP to HTTPS
- キャッシュポリシー:CachingDisabled
コマンド
# ビヘイビア設定JSON
BEHAVIOR_JSON=$(cat << EOF
{
"PathPattern": "/api",
"TargetOriginId": "${RESET_API_ID}.execute-api.${REGION}.amazonaws.com",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "${MANAGED_CACHING_DISABLED_ID}",
"OriginRequestPolicyId": "${ORIGIN_REQUESTPOLICY_ID}"
}
EOF
) \
&& echo ${BEHAVIOR_JSON}
# JSONフォーマットの確認
echo ${BEHAVIOR_JSON} | python -m json.tool
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # ビヘイビア設定JSON
[cloudshell-user@ip-10-134-11-244 ~]$ BEHAVIOR_JSON=$(cat << EOF
> {
> "PathPattern": "/api",
> "TargetOriginId": "${RESET_API_ID}.execute-api.${REGION}.amazonaws.com",
> "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": true,
> "LambdaFunctionAssociations": {
> "Quantity": 0
> },
> "FunctionAssociations": {
> "Quantity": 0
> },
> "FieldLevelEncryptionId": "",
> "CachePolicyId": "${MANAGED_CACHING_DISABLED_ID}",
> "OriginRequestPolicyId": "${ORIGIN_REQUESTPOLICY_ID}"
> }
> EOF
> ) \
> && echo ${BEHAVIOR_JSON}
{ "PathPattern": "/api", "TargetOriginId": "4ad63asxjb.execute-api.us-east-1.amazonaws.com", "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": true, "LambdaFunctionAssociations": { "Quantity": 0 }, "FunctionAssociations": { "Quantity": 0 }, "FieldLevelEncryptionId": "", "CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad", "OriginRequestPolicyId": "8f0c7698-7ec2-42b7-9155-f1e2bc9418d0" }
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-134-11-244 ~]$ echo ${BEHAVIOR_JSON} | python -m json.tool
{
"PathPattern": "/api",
"TargetOriginId": "4ad63asxjb.execute-api.us-east-1.amazonaws.com",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad",
"OriginRequestPolicyId": "8f0c7698-7ec2-42b7-9155-f1e2bc9418d0"
}
ディストリビューションJSON
コマンド
# ディストリビューション変更用JSON
CONFIG=$(
aws cloudfront get-distribution-config \
--id ${DISTRIBUTION_ID} \
--query "DistributionConfig" \
| jq --argjson origin_after "${ORIGIN_JSON}" '.Origins.Items += [$origin_after]' \
| jq '.Origins.Quantity += 1' \
| jq --argjson behavior_after "${BEHAVIOR_JSON}" '.CacheBehaviors.Items += [$behavior_after]' \
| jq '.CacheBehaviors.Quantity += 1'
) \
&& echo ${CONFIG}
# JSONフォーマットの確認
echo ${CONFIG} | python -m json.tool
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # ディストリビューション変更用JSON
[cloudshell-user@ip-10-134-11-244 ~]$ CONFIG=$(
> aws cloudfront get-distribution-config \
> --id ${DISTRIBUTION_ID} \
> --query "DistributionConfig" \
> | jq --argjson origin_after "${ORIGIN_JSON}" '.Origins.Items += [$origin_after]' \
> | jq '.Origins.Quantity += 1' \
> | jq --argjson behavior_after "${BEHAVIOR_JSON}" '.CacheBehaviors.Items += [$behavior_after]' \
> | jq '.CacheBehaviors.Quantity += 1'
> ) \
> && echo ${CONFIG}
{ "CallerReference": "cli-1722767554-44223", "Aliases": { "Quantity": 0 }, "DefaultRootObject": "index.html", "Origins": { "Quantity": 2, "Items": [ { "Id": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934", "DomainName": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com", "OriginPath": "", "CustomHeaders": { "Quantity": 0 }, "S3OriginConfig": { "OriginAccessIdentity": "" }, "ConnectionAttempts": 3, "ConnectionTimeout": 10, "OriginShield": { "Enabled": false }, "OriginAccessControlId": "E2G9MJEEXTOJC1" }, { "Id": "4ad63asxjb.execute-api.us-east-1.amazonaws.com", "DomainName": "4ad63asxjb.execute-api.us-east-1.amazonaws.com", "OriginPath": "", "CustomHeaders": { "Quantity": 0 }, "CustomOriginConfig": { "HTTPPort": 80, "HTTPSPort": 443, "OriginProtocolPolicy": "https-only", "OriginSslProtocols": { "Quantity": 1, "Items": [ "TLSv1.2" ] }, "OriginReadTimeout": 30, "OriginKeepaliveTimeout": 5 }, "ConnectionAttempts": 3, "ConnectionTimeout": 10, "OriginShield": { "Enabled": false }, "OriginAccessControlId": "" } ] }, "OriginGroups": { "Quantity": 0 }, "DefaultCacheBehavior": { "TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934", "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": true, "LambdaFunctionAssociations": { "Quantity": 0 }, "FunctionAssociations": { "Quantity": 0 }, "FieldLevelEncryptionId": "", "CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad" }, "CacheBehaviors": { "Quantity": 2, "Items": [ { "PathPattern": "/static/*", "TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934", "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": true, "LambdaFunctionAssociations": { "Quantity": 0 }, "FunctionAssociations": { "Quantity": 0 }, "FieldLevelEncryptionId": "", "CachePolicyId": "fe0144f2-7815-4b78-9544-cc88b1e0fedf" }, { "PathPattern": "/api", "TargetOriginId": "4ad63asxjb.execute-api.us-east-1.amazonaws.com", "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": true, "LambdaFunctionAssociations": { "Quantity": 0 }, "FunctionAssociations": { "Quantity": 0 }, "FieldLevelEncryptionId": "", "CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad", "OriginRequestPolicyId": "8f0c7698-7ec2-42b7-9155-f1e2bc9418d0" } ] }, "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 }
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-134-11-244 ~]$ echo ${CONFIG} | python -m json.tool
{
"CallerReference": "cli-1722767554-44223",
"Aliases": {
"Quantity": 0
},
"DefaultRootObject": "index.html",
"Origins": {
"Quantity": 2,
"Items": [
{
"Id": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"DomainName": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"S3OriginConfig": {
"OriginAccessIdentity": ""
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": "E2G9MJEEXTOJC1"
},
{
"Id": "4ad63asxjb.execute-api.us-east-1.amazonaws.com",
"DomainName": "4ad63asxjb.execute-api.us-east-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"CustomOriginConfig": {
"HTTPPort": 80,
"HTTPSPort": 443,
"OriginProtocolPolicy": "https-only",
"OriginSslProtocols": {
"Quantity": 1,
"Items": [
"TLSv1.2"
]
},
"OriginReadTimeout": 30,
"OriginKeepaliveTimeout": 5
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": ""
}
]
},
"OriginGroups": {
"Quantity": 0
},
"DefaultCacheBehavior": {
"TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad"
},
"CacheBehaviors": {
"Quantity": 2,
"Items": [
{
"PathPattern": "/static/*",
"TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "fe0144f2-7815-4b78-9544-cc88b1e0fedf"
},
{
"PathPattern": "/api",
"TargetOriginId": "4ad63asxjb.execute-api.us-east-1.amazonaws.com",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad",
"OriginRequestPolicyId": "8f0c7698-7ec2-42b7-9155-f1e2bc9418d0"
}
]
},
"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
}
ディストリビューション変更適用
コマンド
# 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}" \
--if-match ${ETAG} \
--no-cli-pager
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # ETagを取得
[cloudshell-user@ip-10-134-11-244 ~]$ ETAG=$(
> aws cloudfront get-distribution-config \
> --id ${DISTRIBUTION_ID} \
> --query ETag \
> --output text
> ) \
> && echo ${ETAG}
E3H7EIKSZ5KXEF
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # CloudFrontディストリビューションの設定を更新
[cloudshell-user@ip-10-134-11-244 ~]$ aws cloudfront update-distribution \
> --id ${DISTRIBUTION_ID} \
> --distribution-config "${CONFIG}" \
> --if-match ${ETAG} \
> --no-cli-pager
{
"ETag": "E3EX4K76BA19NB",
"Distribution": {
"Id": "EIN33GD07JLDT",
"ARN": "arn:aws:cloudfront::999999999999:distribution/EIN33GD07JLDT",
"Status": "InProgress",
"LastModifiedTime": "2024-08-04T11:16:17.725000+00:00",
"InProgressInvalidationBatches": 0,
"DomainName": "d18sbbratjvl6c.cloudfront.net",
"ActiveTrustedSigners": {
"Enabled": false,
"Quantity": 0
},
"ActiveTrustedKeyGroups": {
"Enabled": false,
"Quantity": 0
},
"DistributionConfig": {
"CallerReference": "cli-1722767554-44223",
"Aliases": {
"Quantity": 0
},
"DefaultRootObject": "index.html",
"Origins": {
"Quantity": 2,
"Items": [
{
"Id": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"DomainName": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"S3OriginConfig": {
"OriginAccessIdentity": ""
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": "E2G9MJEEXTOJC1"
},
{
"Id": "4ad63asxjb.execute-api.us-east-1.amazonaws.com",
"DomainName": "4ad63asxjb.execute-api.us-east-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"CustomOriginConfig": {
"HTTPPort": 80,
"HTTPSPort": 443,
"OriginProtocolPolicy": "https-only",
"OriginSslProtocols": {
"Quantity": 1,
"Items": [
"TLSv1.2"
]
},
"OriginReadTimeout": 30,
"OriginKeepaliveTimeout": 5
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": ""
}
]
},
"OriginGroups": {
"Quantity": 0
},
"DefaultCacheBehavior": {
"TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad"
},
"CacheBehaviors": {
"Quantity": 2,
"Items": [
{
"PathPattern": "/static/*",
"TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "fe0144f2-7815-4b78-9544-cc88b1e0fedf"
},
{
"PathPattern": "/api",
"TargetOriginId": "4ad63asxjb.execute-api.us-east-1.amazonaws.com",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad",
"OriginRequestPolicyId": "8f0c7698-7ec2-42b7-9155-f1e2bc9418d0"
}
]
},
"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
}
}
}
通信確認 (CloudFront経由)
コマンド
# input_textオプションをつけないとエラーになる
curl https://${DISTRIBUTION_DOMAINNAME}/${STAGE_NAME}
# input_textオプションをつけると翻訳される(日本語をURLエンコードでしてから渡す)
encoded_query=$(echo -n 'こんにちは世界' | jq -s -R -r @uri) \
&& echo ${encoded_query}
curl https://${DISTRIBUTION_DOMAINNAME}/${STAGE_NAME}?input_text=${encoded_query}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # input_textオプションをつけないとエラーになる
[cloudshell-user@ip-10-134-11-244 ~]$ curl https://${DISTRIBUTION_DOMAINNAME}/${STAGE_NAME}
{"message": "Internal server error"}
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # input_textオプションをつけると翻訳される(日本語をURLエンコードでしてから渡す)
[cloudshell-user@ip-10-134-11-244 ~]$ encoded_query=$(echo -n 'こんにちは世界' | jq -s -R -r @uri) \
> && echo ${encoded_query}
%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF%E4%B8%96%E7%95%8C
[cloudshell-user@ip-10-134-11-244 ~]$ curl https://${DISTRIBUTION_DOMAINNAME}/${STAGE_NAME}?input_text=${encoded_query}
Hello world
09 AWS WAFのハンズオン
Web ACL 作成
条件
Web ACL details
- Resource type:Amazon CloudFront destributions
- Name:handson-waf
- CloudWatch metric name:handson-waf
Rule
Add my own rules and rule groups
- Rule type:Rule builder
- Name:handson-rule
- Type:Regular rule
- If a request:matches the statement
- Statement:Originates from country in
- Country codes:Japan
- IP address to use to determine the country of origin:Source IP address
- Action:Block
Default web ACL action for requests that don't match any rules
- Default action:Allow
Amazon CloudWatch metrics
- Rules:handson-rule
- CloudWatch metric name:handson-rule
Request sampling options
- Options:Enable samled requests
独自ルールJSON
コマンド
# ルール名
ACL_RULE_NAME="handson-rule" \
&& echo ${ACL_RULE_NAME}
# my own rules and rule groups
ACL_RULE_JSON=$(cat << EOF
{
"Name": "${ACL_RULE_NAME}",
"Priority": 0,
"Action": {
"Block": {}
},
"Statement": {
"GeoMatchStatement": {
"CountryCodes": ["JP"]
}
},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "${ACL_RULE_NAME}"
}
}
EOF
) \
&& echo ${ACL_RULE_JSON}
# JSONフォーマットの確認
echo ${ACL_RULE_JSON} | python -m json.tool
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # ルール名
[cloudshell-user@ip-10-134-11-244 ~]$ ACL_RULE_NAME="handson-rule" \
> && echo ${ACL_RULE_NAME}
handson-rule
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # my own rules and rule groups
[cloudshell-user@ip-10-134-11-244 ~]$ ACL_RULE_JSON=$(cat << EOF
> {
> "Name": "${ACL_RULE_NAME}",
> "Priority": 0,
> "Action": {
> "Block": {}
> },
> "Statement": {
> "GeoMatchStatement": {
> "CountryCodes": ["JP"]
> }
> },
> "VisibilityConfig": {
> "SampledRequestsEnabled": true,
> "CloudWatchMetricsEnabled": true,
> "MetricName": "${ACL_RULE_NAME}"
> }
> }
> EOF
> ) \
> && echo ${ACL_RULE_JSON}
{ "Name": "handson-rule", "Priority": 0, "Action": { "Block": {} }, "Statement": { "GeoMatchStatement": { "CountryCodes": ["JP"] } }, "VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "handson-rule" } }
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-134-11-244 ~]$ echo ${ACL_RULE_JSON} | python -m json.tool
{
"Name": "handson-rule",
"Priority": 0,
"Action": {
"Block": {}
},
"Statement": {
"GeoMatchStatement": {
"CountryCodes": [
"JP"
]
}
},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "handson-rule"
}
}
Web ACL作成
コマンド
# 変数
WEB_ACL_NAME="handson-waf" \
&& echo ${WEB_ACL_NAME}
# Web ACL作成
aws wafv2 create-web-acl \
--name ${WEB_ACL_NAME} \
--scope CLOUDFRONT \
--default-action Allow={} \
--rules "[${ACL_RULE}]" \
--visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=handson-rule \
--region ${REGION}
# ID取得
WEB_ACL_ID=$(
aws wafv2 list-web-acls \
--scope CLOUDFRONT \
--region ${REGION} \
--query "WebACLs[?Name=='${WEB_ACL_NAME}'].Id" \
--output text
) \
&& echo ${WEB_ACL_ID}
# ARN取得
WEB_ACL_ARN=$(
aws wafv2 list-web-acls \
--scope CLOUDFRONT \
--region ${REGION} \
--query "WebACLs[?Name=='${WEB_ACL_NAME}'].ARN" \
--output text
) \
&& echo ${WEB_ACL_ARN}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # 変数
[cloudshell-user@ip-10-134-11-244 ~]$ WEB_ACL_NAME="handson-waf" \
> && echo ${WEB_ACL_NAME}
handson-waf
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # Web ACL作成
[cloudshell-user@ip-10-134-11-244 ~]$ aws wafv2 create-web-acl \
> --name ${WEB_ACL_NAME} \
> --scope CLOUDFRONT \
> --default-action Allow={} \
> --rules "[${ACL_RULE_JSON}]" \
> --visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=handson-rule \
> --region ${REGION}
{
"Summary": {
"Name": "handson-waf",
"Id": "a471ff68-5aba-411d-b2af-7eb66f520b04",
"Description": "",
"LockToken": "55c562cc-403a-4c6e-a8d9-7fdba6a7178d",
"ARN": "arn:aws:wafv2:us-east-1:999999999999:global/webacl/handson-waf/a471ff68-5aba-411d-b2af-7eb66f520b04"
}
}
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # ID取得
[cloudshell-user@ip-10-134-11-244 ~]$ WEB_ACL_ID=$(
> aws wafv2 list-web-acls \
> --scope CLOUDFRONT \
> --region ${REGION} \
> --query "WebACLs[?Name=='${WEB_ACL_NAME}'].Id" \
> --output text
> ) \
> && echo ${WEB_ACL_ID}
a471ff68-5aba-411d-b2af-7eb66f520b04
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # ARN取得
[cloudshell-user@ip-10-134-11-244 ~]$ WEB_ACL_ARN=$(
> aws wafv2 list-web-acls \
> --scope CLOUDFRONT \
> --region ${REGION} \
> --query "WebACLs[?Name=='${WEB_ACL_NAME}'].ARN" \
> --output text
> ) \
> && echo ${WEB_ACL_ARN}
arn:aws:wafv2:us-east-1:999999999999:global/webacl/handson-waf/a471ff68-5aba-411d-b2af-7eb66f520b04
CloudFrontディストリビューションにWeb ACLを関連付け
ディストリビューション変更用JSON
コマンド
# ディストリビューション変更用JSON
CONFIG=$(
aws cloudfront get-distribution-config \
--id ${DISTRIBUTION_ID} \
--query "DistributionConfig" \
| jq --arg web_acl "${WEB_ACL_ARN}" '."WebACLId" = $web_acl'
) \
&& echo ${CONFIG}
# JSONフォーマットの確認
echo ${CONFIG} | python -m json.tool
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # ディストリビューション変更用JSON
[cloudshell-user@ip-10-134-11-244 ~]$ CONFIG=$(
> aws cloudfront get-distribution-config \
> --id ${DISTRIBUTION_ID} \
> --query "DistributionConfig" \
> | jq --arg web_acl "${WEB_ACL_ARN}" '."WebACLId" = $web_acl'
> ) \
> && echo ${CONFIG}
{ "CallerReference": "cli-1722767554-44223", "Aliases": { "Quantity": 0 }, "DefaultRootObject": "index.html", "Origins": { "Quantity": 2, "Items": [ { "Id": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934", "DomainName": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com", "OriginPath": "", "CustomHeaders": { "Quantity": 0 }, "S3OriginConfig": { "OriginAccessIdentity": "" }, "ConnectionAttempts": 3, "ConnectionTimeout": 10, "OriginShield": { "Enabled": false }, "OriginAccessControlId": "E2G9MJEEXTOJC1" }, { "Id": "4ad63asxjb.execute-api.us-east-1.amazonaws.com", "DomainName": "4ad63asxjb.execute-api.us-east-1.amazonaws.com", "OriginPath": "", "CustomHeaders": { "Quantity": 0 }, "CustomOriginConfig": { "HTTPPort": 80, "HTTPSPort": 443, "OriginProtocolPolicy": "https-only", "OriginSslProtocols": { "Quantity": 1, "Items": [ "TLSv1.2" ] }, "OriginReadTimeout": 30, "OriginKeepaliveTimeout": 5 }, "ConnectionAttempts": 3, "ConnectionTimeout": 10, "OriginShield": { "Enabled": false }, "OriginAccessControlId": "" } ] }, "OriginGroups": { "Quantity": 0 }, "DefaultCacheBehavior": { "TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934", "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": true, "LambdaFunctionAssociations": { "Quantity": 0 }, "FunctionAssociations": { "Quantity": 0 }, "FieldLevelEncryptionId": "", "CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad" }, "CacheBehaviors": { "Quantity": 2, "Items": [ { "PathPattern": "/static/*", "TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934", "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": true, "LambdaFunctionAssociations": { "Quantity": 0 }, "FunctionAssociations": { "Quantity": 0 }, "FieldLevelEncryptionId": "", "CachePolicyId": "fe0144f2-7815-4b78-9544-cc88b1e0fedf" }, { "PathPattern": "/api", "TargetOriginId": "4ad63asxjb.execute-api.us-east-1.amazonaws.com", "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": true, "LambdaFunctionAssociations": { "Quantity": 0 }, "FunctionAssociations": { "Quantity": 0 }, "FieldLevelEncryptionId": "", "CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad", "OriginRequestPolicyId": "8f0c7698-7ec2-42b7-9155-f1e2bc9418d0" } ] }, "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": "arn:aws:wafv2:us-east-1:999999999999:global/webacl/handson-waf/a471ff68-5aba-411d-b2af-7eb66f520b04", "HttpVersion": "http2", "IsIPV6Enabled": true, "ContinuousDeploymentPolicyId": "", "Staging": false }
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-134-11-244 ~]$ echo ${CONFIG} | python -m json.tool
{
"CallerReference": "cli-1722767554-44223",
"Aliases": {
"Quantity": 0
},
"DefaultRootObject": "index.html",
"Origins": {
"Quantity": 2,
"Items": [
{
"Id": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"DomainName": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"S3OriginConfig": {
"OriginAccessIdentity": ""
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": "E2G9MJEEXTOJC1"
},
{
"Id": "4ad63asxjb.execute-api.us-east-1.amazonaws.com",
"DomainName": "4ad63asxjb.execute-api.us-east-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"CustomOriginConfig": {
"HTTPPort": 80,
"HTTPSPort": 443,
"OriginProtocolPolicy": "https-only",
"OriginSslProtocols": {
"Quantity": 1,
"Items": [
"TLSv1.2"
]
},
"OriginReadTimeout": 30,
"OriginKeepaliveTimeout": 5
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": ""
}
]
},
"OriginGroups": {
"Quantity": 0
},
"DefaultCacheBehavior": {
"TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad"
},
"CacheBehaviors": {
"Quantity": 2,
"Items": [
{
"PathPattern": "/static/*",
"TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "fe0144f2-7815-4b78-9544-cc88b1e0fedf"
},
{
"PathPattern": "/api",
"TargetOriginId": "4ad63asxjb.execute-api.us-east-1.amazonaws.com",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad",
"OriginRequestPolicyId": "8f0c7698-7ec2-42b7-9155-f1e2bc9418d0"
}
]
},
"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": "arn:aws:wafv2:us-east-1:999999999999:global/webacl/handson-waf/a471ff68-5aba-411d-b2af-7eb66f520b04",
"HttpVersion": "http2",
"IsIPV6Enabled": true,
"ContinuousDeploymentPolicyId": "",
"Staging": false
}
ディストリビューション変更適用
コマンド
# ETagを取得
ETAG=$(
aws cloudfront get-distribution-config \
--id ${DISTRIBUTION_ID} \
--query ETag \
--output text
) \
&& echo ${ETAG}
# CloudFrontディストリビューションにWeb ACLを関連付け
aws cloudfront update-distribution \
--id ${DISTRIBUTION_ID} \
--distribution-config "${CONFIG}" \
--if-match ${ETAG} \
--no-cli-pager
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # ETagを取得
[cloudshell-user@ip-10-134-11-244 ~]$ ETAG=$(
> aws cloudfront get-distribution-config \
> --id ${DISTRIBUTION_ID} \
> --query ETag \
> --output text
> ) \
> && echo ${ETAG}
E3EX4K76BA19NB
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # CloudFrontディストリビューションにWeb ACLを関連付け
[cloudshell-user@ip-10-134-11-244 ~]$ aws cloudfront update-distribution \
> --id ${DISTRIBUTION_ID} \
> --distribution-config "${CONFIG}" \
> --if-match ${ETAG} \
> --no-cli-pager
{
"ETag": "E1FXQ683ZR0G6S",
"Distribution": {
"Id": "EIN33GD07JLDT",
"ARN": "arn:aws:cloudfront::999999999999:distribution/EIN33GD07JLDT",
"Status": "InProgress",
"LastModifiedTime": "2024-08-04T11:22:48.237000+00:00",
"InProgressInvalidationBatches": 0,
"DomainName": "d18sbbratjvl6c.cloudfront.net",
"ActiveTrustedSigners": {
"Enabled": false,
"Quantity": 0
},
"ActiveTrustedKeyGroups": {
"Enabled": false,
"Quantity": 0
},
"DistributionConfig": {
"CallerReference": "cli-1722767554-44223",
"Aliases": {
"Quantity": 0
},
"DefaultRootObject": "index.html",
"Origins": {
"Quantity": 2,
"Items": [
{
"Id": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"DomainName": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"S3OriginConfig": {
"OriginAccessIdentity": ""
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": "E2G9MJEEXTOJC1"
},
{
"Id": "4ad63asxjb.execute-api.us-east-1.amazonaws.com",
"DomainName": "4ad63asxjb.execute-api.us-east-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"CustomOriginConfig": {
"HTTPPort": 80,
"HTTPSPort": 443,
"OriginProtocolPolicy": "https-only",
"OriginSslProtocols": {
"Quantity": 1,
"Items": [
"TLSv1.2"
]
},
"OriginReadTimeout": 30,
"OriginKeepaliveTimeout": 5
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": ""
}
]
},
"OriginGroups": {
"Quantity": 0
},
"DefaultCacheBehavior": {
"TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad"
},
"CacheBehaviors": {
"Quantity": 2,
"Items": [
{
"PathPattern": "/static/*",
"TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "fe0144f2-7815-4b78-9544-cc88b1e0fedf"
},
{
"PathPattern": "/api",
"TargetOriginId": "4ad63asxjb.execute-api.us-east-1.amazonaws.com",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad",
"OriginRequestPolicyId": "8f0c7698-7ec2-42b7-9155-f1e2bc9418d0"
}
]
},
"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": "arn:aws:wafv2:us-east-1:999999999999:global/webacl/handson-waf/a471ff68-5aba-411d-b2af-7eb66f520b04",
"HttpVersion": "http2",
"IsIPV6Enabled": true,
"ContinuousDeploymentPolicyId": "",
"Staging": false
}
}
}
通信確認
東京リージョン
コマンド
# 東京リージョンのCloudShellから実施 (WAFによってブロック(403 ERROR)になる)
# input_textオプションをつけると翻訳される(日本語をURLエンコードでしてから渡す)
encoded_query=$(echo -n 'こんにちは世界' | jq -s -R -r @uri) \
&& echo ${encoded_query}
echo "https://${DISTRIBUTION_DOMAINNAME}/${STAGE_NAME}?input_text=${encoded_query}"
curl https://${DISTRIBUTION_DOMAINNAME}/${STAGE_NAME}?input_text=${encoded_query}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # 東京リージョンのCloudShellから実施 (WAFによってブロック(403 ERROR)になる)
[cloudshell-user@ip-10-134-11-244 ~]$ # input_textオプションをつけると翻訳される(日本語をURLエンコードでしてから渡す)
[cloudshell-user@ip-10-134-11-244 ~]$ encoded_query=$(echo -n 'こんにちは世界' | jq -s -R -r @uri) \
> && echo ${encoded_query}
%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF%E4%B8%96%E7%95%8C
[cloudshell-user@ip-10-134-11-244 ~]$ echo "https://${DISTRIBUTION_DOMAINNAME}/${STAGE_NAME}?input_text=${encoded_query}"
https://d18sbbratjvl6c.cloudfront.net/api?input_text=%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF%E4%B8%96%E7%95%8C
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ curl https://${DISTRIBUTION_DOMAINNAME}/${STAGE_NAME}?input_text=${encoded_query}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE>ERROR: The request could not be satisfied</TITLE>
</HEAD><BODY>
<H1>403 ERROR</H1>
<H2>The request could not be satisfied.</H2>
<HR noshade size="1px">
Request blocked.
We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
<BR clear="all">
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
<BR clear="all">
<HR noshade size="1px">
<PRE>
Generated by cloudfront (CloudFront)
Request ID: w627KZyxEfPMufk0OQAimR6E1Jx-h1OX1Id-kVon6oJ4l_eNNzq7kA==
</PRE>
<ADDRESS>
</ADDRESS>
</BODY></HTML>
バージニア北部リージョン
東京リージョンのCloudShellで実行した同じURLをバージニア北部リージョンから実施
コマンド
# バージニア北部リージョンのCloudShellから実施 (アクセス可能)
curl https://d18sbbratjvl6c.cloudfront.net/api?input_text=%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF%E4%B8%96%E7%95%8C
出力
[cloudshell-user@ip-10-130-92-135 ~]$ # バージニア北部リージョンのCloudShellから実施 (アクセス可能)
[cloudshell-user@ip-10-130-92-135 ~]$ curl https://d18sbbratjvl6c.cloudfront.net/api?input_text=%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF%E4%B8%96%E7%95%8C
Hello world
Web ACL追加 (マネージメントルール)
条件
Add managed rule groups:Core rule set
マネージドルールJSON
コマンド
# マネージドルール (CoreRuleSet)
ACL_CORE_RULE_SET_JSON=$(cat << EOF
{
"Name": "AWS-AWSManagedRulesCommonRuleSet",
"Priority": 1,
"OverrideAction": {
"None": {}
},
"Statement": {
"ManagedRuleGroupStatement": {
"VendorName": "AWS",
"Name": "AWSManagedRulesCommonRuleSet"
}
},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "AWS-AWSManagedRulesCommonRuleSet"
}
}
EOF
) \
&& echo ${ACL_CORE_RULE_SET_JSON}
# JSONフォーマットの確認
echo ${ACL_CORE_RULE_SET_JSON} | python -m json.tool
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # マネージドルール (CoreRuleSet)
[cloudshell-user@ip-10-134-11-244 ~]$ ACL_CORE_RULE_SET_JSON=$(cat << EOF
> {
> "Name": "AWS-AWSManagedRulesCommonRuleSet",
> "Priority": 1,
> "OverrideAction": {
> "None": {}
> },
> "Statement": {
> "ManagedRuleGroupStatement": {
> "VendorName": "AWS",
> "Name": "AWSManagedRulesCommonRuleSet"
> }
> },
> "VisibilityConfig": {
> "SampledRequestsEnabled": true,
> "CloudWatchMetricsEnabled": true,
> "MetricName": "AWS-AWSManagedRulesCommonRuleSet"
> }
> }
> EOF
> ) \
> && echo ${ACL_CORE_RULE_SET_JSON}
{ "Name": "AWS-AWSManagedRulesCommonRuleSet", "Priority": 1, "OverrideAction": { "None": {} }, "Statement": { "ManagedRuleGroupStatement": { "VendorName": "AWS", "Name": "AWSManagedRulesCommonRuleSet" } }, "VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "AWS-AWSManagedRulesCommonRuleSet" } }
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-134-11-244 ~]$ echo ${ACL_CORE_RULE_SET_JSON} | python -m json.tool
{
"Name": "AWS-AWSManagedRulesCommonRuleSet",
"Priority": 1,
"OverrideAction": {
"None": {}
},
"Statement": {
"ManagedRuleGroupStatement": {
"VendorName": "AWS",
"Name": "AWSManagedRulesCommonRuleSet"
}
},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "AWS-AWSManagedRulesCommonRuleSet"
}
}
マネージドルール追加
コマンド
# マネージドルール (CoreRuleSet) 追加
WAFV2_LOCKTOKEN=$(
aws wafv2 get-web-acl \
--name handson-waf \
--scope CLOUDFRONT \
--id ${WEB_ACL_ID} \
--no-cli-pager \
--region ${REGION} \
--query LockToken \
--output text
) \
&& echo ${WAFV2_LOCKTOKEN}
aws wafv2 update-web-acl \
--name handson-waf \
--scope CLOUDFRONT \
--id ${WEB_ACL_ID} \
--lock-token ${WAFV2_LOCKTOKEN} \
--default-action Allow={} \
--rules "[${ACL_RULE_JSON},${ACL_CORE_RULE_SET_JSON}]" \
--visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=handson-waf \
--region ${REGION}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # マネージドルール (CoreRuleSet) 追加
[cloudshell-user@ip-10-134-11-244 ~]$ WAFV2_LOCKTOKEN=$(
> aws wafv2 get-web-acl \
> --name handson-waf \
> --scope CLOUDFRONT \
> --id ${WEB_ACL_ID} \
> --no-cli-pager \
> --region ${REGION} \
> --query LockToken \
> --output text
> ) \
> && echo ${WAFV2_LOCKTOKEN}
55c562cc-403a-4c6e-a8d9-7fdba6a7178d
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ aws wafv2 update-web-acl \
> --name handson-waf \
> --scope CLOUDFRONT \
> --id ${WEB_ACL_ID} \
> --lock-token ${WAFV2_LOCKTOKEN} \
> --default-action Allow={} \
> --rules "[${ACL_RULE_JSON},${ACL_CORE_RULE_SET_JSON}]" \
> --visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=handson-waf \
> --region ${REGION}
{
"NextLockToken": "e31659be-da5b-4393-bce2-256623335626"
}
10 シリーズのまとめ、リソースの削除
Amazon 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-134-11-244 ~]$ # ディストリビューション無効化用JSON
[cloudshell-user@ip-10-134-11-244 ~]$ DELL_CONFIG=$(
> aws cloudfront get-distribution-config \
> --id ${DISTRIBUTION_ID} \
> | jq .DistributionConfig \
> | jq '.Enabled = false'
> ) \
> && echo ${DELL_CONFIG}
{ "CallerReference": "cli-1722767554-44223", "Aliases": { "Quantity": 0 }, "DefaultRootObject": "index.html", "Origins": { "Quantity": 2, "Items": [ { "Id": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934", "DomainName": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com", "OriginPath": "", "CustomHeaders": { "Quantity": 0 }, "S3OriginConfig": { "OriginAccessIdentity": "" }, "ConnectionAttempts": 3, "ConnectionTimeout": 10, "OriginShield": { "Enabled": false }, "OriginAccessControlId": "E2G9MJEEXTOJC1" }, { "Id": "4ad63asxjb.execute-api.us-east-1.amazonaws.com", "DomainName": "4ad63asxjb.execute-api.us-east-1.amazonaws.com", "OriginPath": "", "CustomHeaders": { "Quantity": 0 }, "CustomOriginConfig": { "HTTPPort": 80, "HTTPSPort": 443, "OriginProtocolPolicy": "https-only", "OriginSslProtocols": { "Quantity": 1, "Items": [ "TLSv1.2" ] }, "OriginReadTimeout": 30, "OriginKeepaliveTimeout": 5 }, "ConnectionAttempts": 3, "ConnectionTimeout": 10, "OriginShield": { "Enabled": false }, "OriginAccessControlId": "" } ] }, "OriginGroups": { "Quantity": 0 }, "DefaultCacheBehavior": { "TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934", "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": true, "LambdaFunctionAssociations": { "Quantity": 0 }, "FunctionAssociations": { "Quantity": 0 }, "FieldLevelEncryptionId": "", "CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad" }, "CacheBehaviors": { "Quantity": 2, "Items": [ { "PathPattern": "/static/*", "TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934", "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": true, "LambdaFunctionAssociations": { "Quantity": 0 }, "FunctionAssociations": { "Quantity": 0 }, "FieldLevelEncryptionId": "", "CachePolicyId": "fe0144f2-7815-4b78-9544-cc88b1e0fedf" }, { "PathPattern": "/api", "TargetOriginId": "4ad63asxjb.execute-api.us-east-1.amazonaws.com", "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": true, "LambdaFunctionAssociations": { "Quantity": 0 }, "FunctionAssociations": { "Quantity": 0 }, "FieldLevelEncryptionId": "", "CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad", "OriginRequestPolicyId": "8f0c7698-7ec2-42b7-9155-f1e2bc9418d0" } ] }, "CustomErrorResponses": { "Quantity": 0 }, "Comment": "", "Logging": { "Enabled": false, "IncludeCookies": false, "Bucket": "", "Prefix": "" }, "PriceClass": "PriceClass_All", "Enabled": false, "ViewerCertificate": { "CloudFrontDefaultCertificate": true, "SSLSupportMethod": "vip", "MinimumProtocolVersion": "TLSv1", "CertificateSource": "cloudfront" }, "Restrictions": { "GeoRestriction": { "RestrictionType": "none", "Quantity": 0 } }, "WebACLId": "arn:aws:wafv2:us-east-1:999999999999:global/webacl/handson-waf/a471ff68-5aba-411d-b2af-7eb66f520b04", "HttpVersion": "http2", "IsIPV6Enabled": true, "ContinuousDeploymentPolicyId": "", "Staging": false }
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-134-11-244 ~]$ echo ${DELL_CONFIG} | python -m json.tool
{
"CallerReference": "cli-1722767554-44223",
"Aliases": {
"Quantity": 0
},
"DefaultRootObject": "index.html",
"Origins": {
"Quantity": 2,
"Items": [
{
"Id": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"DomainName": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"S3OriginConfig": {
"OriginAccessIdentity": ""
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": "E2G9MJEEXTOJC1"
},
{
"Id": "4ad63asxjb.execute-api.us-east-1.amazonaws.com",
"DomainName": "4ad63asxjb.execute-api.us-east-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"CustomOriginConfig": {
"HTTPPort": 80,
"HTTPSPort": 443,
"OriginProtocolPolicy": "https-only",
"OriginSslProtocols": {
"Quantity": 1,
"Items": [
"TLSv1.2"
]
},
"OriginReadTimeout": 30,
"OriginKeepaliveTimeout": 5
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": ""
}
]
},
"OriginGroups": {
"Quantity": 0
},
"DefaultCacheBehavior": {
"TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad"
},
"CacheBehaviors": {
"Quantity": 2,
"Items": [
{
"PathPattern": "/static/*",
"TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "fe0144f2-7815-4b78-9544-cc88b1e0fedf"
},
{
"PathPattern": "/api",
"TargetOriginId": "4ad63asxjb.execute-api.us-east-1.amazonaws.com",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad",
"OriginRequestPolicyId": "8f0c7698-7ec2-42b7-9155-f1e2bc9418d0"
}
]
},
"CustomErrorResponses": {
"Quantity": 0
},
"Comment": "",
"Logging": {
"Enabled": false,
"IncludeCookies": false,
"Bucket": "",
"Prefix": ""
},
"PriceClass": "PriceClass_All",
"Enabled": false,
"ViewerCertificate": {
"CloudFrontDefaultCertificate": true,
"SSLSupportMethod": "vip",
"MinimumProtocolVersion": "TLSv1",
"CertificateSource": "cloudfront"
},
"Restrictions": {
"GeoRestriction": {
"RestrictionType": "none",
"Quantity": 0
}
},
"WebACLId": "arn:aws:wafv2:us-east-1:999999999999:global/webacl/handson-waf/a471ff68-5aba-411d-b2af-7eb66f520b04",
"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} \
--region ${REGION} \
--no-cli-pager
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # ETagを取得
[cloudshell-user@ip-10-134-11-244 ~]$ ETAG=$(
> aws cloudfront get-distribution-config \
> --id ${DISTRIBUTION_ID} \
> --query ETag \
> --output text
> ) \
> && echo ${ETAG}
E1FXQ683ZR0G6S
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # ディストリビューションを無効化
[cloudshell-user@ip-10-134-11-244 ~]$ aws cloudfront update-distribution \
> --id ${DISTRIBUTION_ID} \
> --distribution-config "${DELL_CONFIG}" \
> --if-match ${ETAG} \
> --region ${REGION} \
> --no-cli-pager
{
"ETag": "EVX7PAPE16URX",
"Distribution": {
"Id": "EIN33GD07JLDT",
"ARN": "arn:aws:cloudfront::999999999999:distribution/EIN33GD07JLDT",
"Status": "InProgress",
"LastModifiedTime": "2024-08-04T11:54:36.649000+00:00",
"InProgressInvalidationBatches": 0,
"DomainName": "d18sbbratjvl6c.cloudfront.net",
"ActiveTrustedSigners": {
"Enabled": false,
"Quantity": 0
},
"ActiveTrustedKeyGroups": {
"Enabled": false,
"Quantity": 0
},
"DistributionConfig": {
"CallerReference": "cli-1722767554-44223",
"Aliases": {
"Quantity": 0
},
"DefaultRootObject": "index.html",
"Origins": {
"Quantity": 2,
"Items": [
{
"Id": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"DomainName": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"S3OriginConfig": {
"OriginAccessIdentity": ""
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": "E2G9MJEEXTOJC1"
},
{
"Id": "4ad63asxjb.execute-api.us-east-1.amazonaws.com",
"DomainName": "4ad63asxjb.execute-api.us-east-1.amazonaws.com",
"OriginPath": "",
"CustomHeaders": {
"Quantity": 0
},
"CustomOriginConfig": {
"HTTPPort": 80,
"HTTPSPort": 443,
"OriginProtocolPolicy": "https-only",
"OriginSslProtocols": {
"Quantity": 1,
"Items": [
"TLSv1.2"
]
},
"OriginReadTimeout": 30,
"OriginKeepaliveTimeout": 5
},
"ConnectionAttempts": 3,
"ConnectionTimeout": 10,
"OriginShield": {
"Enabled": false
},
"OriginAccessControlId": ""
}
]
},
"OriginGroups": {
"Quantity": 0
},
"DefaultCacheBehavior": {
"TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad"
},
"CacheBehaviors": {
"Quantity": 2,
"Items": [
{
"PathPattern": "/static/*",
"TargetOriginId": "20240804-handson-sincere-networker.s3.us-east-1.amazonaws.com-1722767554-972934",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "fe0144f2-7815-4b78-9544-cc88b1e0fedf"
},
{
"PathPattern": "/api",
"TargetOriginId": "4ad63asxjb.execute-api.us-east-1.amazonaws.com",
"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": true,
"LambdaFunctionAssociations": {
"Quantity": 0
},
"FunctionAssociations": {
"Quantity": 0
},
"FieldLevelEncryptionId": "",
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad",
"OriginRequestPolicyId": "8f0c7698-7ec2-42b7-9155-f1e2bc9418d0"
}
]
},
"CustomErrorResponses": {
"Quantity": 0
},
"Comment": "",
"Logging": {
"Enabled": false,
"IncludeCookies": false,
"Bucket": "",
"Prefix": ""
},
"PriceClass": "PriceClass_All",
"Enabled": false,
"ViewerCertificate": {
"CloudFrontDefaultCertificate": true,
"SSLSupportMethod": "vip",
"MinimumProtocolVersion": "TLSv1",
"CertificateSource": "cloudfront"
},
"Restrictions": {
"GeoRestriction": {
"RestrictionType": "none",
"Quantity": 0
}
},
"WebACLId": "arn:aws:wafv2:us-east-1:999999999999:global/webacl/handson-waf/a471ff68-5aba-411d-b2af-7eb66f520b04",
"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 delete-distribution \
--id ${DISTRIBUTION_ID} \
--if-match ${ETAG} \
--region ${REGION}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # ETagを取得
[cloudshell-user@ip-10-134-11-244 ~]$ ETAG=$(
> aws cloudfront get-distribution-config \
> --id ${DISTRIBUTION_ID} \
> --query ETag \
> --output text
> ) \
> && echo ${ETAG}
EVX7PAPE16URX
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # ディストリビューションを削除
[cloudshell-user@ip-10-134-11-244 ~]$ aws cloudfront delete-distribution \
> --id ${DISTRIBUTION_ID} \
> --if-match ${ETAG} \
> --region ${REGION}
オリジンアクセス削除
コマンド
# 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} \
--region ${REGION}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # ETagを取得
[cloudshell-user@ip-10-134-11-244 ~]$ ETAG=$(
> aws cloudfront get-origin-access-control \
> --id ${ORIGIN_ACCESS_CONTROL_ID} \
> --query ETag \
> --output text
> ) \
> && echo ${ETAG}
ETVPDKIKX0DER
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ aws cloudfront delete-origin-access-control \
> --id ${ORIGIN_ACCESS_CONTROL_ID} \
> --if-match ${ETAG} \
> --region ${REGION}
キャッシュポリシー削除
コマンド
# ETagを取得
ETAG=$(
aws cloudfront get-cache-policy \
--id ${CACHEPOLICY_ID} \
--query ETag \
--output text
) \
&& echo ${ETAG}
# キャッシュポリシー削除
aws cloudfront delete-cache-policy \
--id ${CACHEPOLICY_ID} \
--if-match ${ETAG}\
--region ${REGION}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # ETagを取得
[cloudshell-user@ip-10-134-11-244 ~]$ ETAG=$(
> aws cloudfront get-cache-policy \
> --id ${CACHEPOLICY_ID} \
> --query ETag \
> --output text
> ) \
> && echo ${ETAG}
E23ZP02F085DFQ
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # キャッシュポリシー削除
[cloudshell-user@ip-10-134-11-244 ~]$ aws cloudfront delete-cache-policy \
> --id ${CACHEPOLICY_ID} \
> --if-match ${ETAG}\
> --region ${REGION}
オリジンリクエストポリシー削除
コマンド
# ETagを取得
ETAG=$(
aws cloudfront get-origin-request-policy \
--id ${ORIGIN_REQUESTPOLICY_ID} \
--query ETag \
--output text
) \
&& echo ${ETAG}
# オリジンリクエストポリシー削除
aws cloudfront delete-origin-request-policy \
--id ${ORIGIN_REQUESTPOLICY_ID} \
--if-match ${ETAG}\
--region ${REGION}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # ETagを取得
[cloudshell-user@ip-10-134-11-244 ~]$ ETAG=$(
> aws cloudfront get-origin-request-policy \
> --id ${ORIGIN_REQUESTPOLICY_ID} \
> --query ETag \
> --output text
> ) \
> && echo ${ETAG}
E23ZP02F085DFQ
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # オリジンリクエストポリシー削除
[cloudshell-user@ip-10-134-11-244 ~]$ aws cloudfront delete-origin-request-policy \
> --id ${ORIGIN_REQUESTPOLICY_ID} \
> --if-match ${ETAG}\
> --region ${REGION}
AWS WAFの削除
Web ACL削除
コマンド
# 変数
WEB_ACL_NAME="handson-waf" \
&& echo ${WEB_ACL_NAME}
# lock-token取得
WAFV2_LOCKTOKEN=$(
aws wafv2 get-web-acl \
--name handson-waf \
--scope CLOUDFRONT \
--id ${WEB_ACL_ID} \
--no-cli-pager \
--region ${REGION} \
--query LockToken \
--output text
) \
&& echo ${WAFV2_LOCKTOKEN}
# Web ACL削除
aws wafv2 delete-web-acl \
--name ${WEB_ACL_NAME} \
--scope CLOUDFRONT \
--id ${WEB_ACL_ID} \
--lock-token ${WAFV2_LOCKTOKEN} \
--region ${REGION}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # 変数
[cloudshell-user@ip-10-134-11-244 ~]$ WEB_ACL_NAME="handson-waf" \
> && echo ${WEB_ACL_NAME}
handson-waf
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # lock-token取得
[cloudshell-user@ip-10-134-11-244 ~]$ WAFV2_LOCKTOKEN=$(
> aws wafv2 get-web-acl \
> --name handson-waf \
> --scope CLOUDFRONT \
> --id ${WEB_ACL_ID} \
> --no-cli-pager \
> --region ${REGION} \
> --query LockToken \
> --output text
> ) \
> && echo ${WAFV2_LOCKTOKEN}
e31659be-da5b-4393-bce2-256623335626
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # Web ACL削除
[cloudshell-user@ip-10-134-11-244 ~]$ aws wafv2 delete-web-acl \
> --name ${WEB_ACL_NAME} \
> --scope CLOUDFRONT \
> --id ${WEB_ACL_ID} \
> --lock-token ${WAFV2_LOCKTOKEN} \
> --region ${REGION}
Amazon API Gatewayの削除
コマンド
aws apigateway delete-rest-api \
--rest-api-id ${RESET_API_ID} \
--region ${REGION}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ aws apigateway delete-rest-api \
> --rest-api-id ${RESET_API_ID} \
> --region ${REGION}
AWS Lambdaの削除
コマンド
aws lambda delete-function \
--function-name ${FUNCTION_NAME} \
--region ${REGION}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ aws lambda delete-function \
> --function-name ${FUNCTION_NAME} \
> --region ${REGION}
S3バケットの削除
コマンド
# S3バケット内のすべてのオブジェクトを削除
aws s3 rm s3://${S3_BUCKET_NAME} \
--recursive \
--region ${REGION}
# S3バケットを削除
aws s3api delete-bucket \
--bucket ${S3_BUCKET_NAME} \
--region ${REGION}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # S3バケット内のすべてのオブジェクトを削除
[cloudshell-user@ip-10-134-11-244 ~]$ aws s3 rm s3://${S3_BUCKET_NAME} \
> --recursive \
> --region ${REGION}
delete: s3://20240804-handson-sincere-networker/static/js/script.js
delete: s3://20240804-handson-sincere-networker/static/image/cloudfront.png
delete: s3://20240804-handson-sincere-networker/static/css/styles.css
delete: s3://20240804-handson-sincere-networker/index.html
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # S3バケットを削除
[cloudshell-user@ip-10-134-11-244 ~]$ aws s3api delete-bucket \
> --bucket ${S3_BUCKET_NAME} \
> --region ${REGION}
IAM
IAMロール削除
コマンド
# ロールにアタッチされているポリシーをリスト
POLICIES=$(
aws iam list-attached-role-policies \
--role-name ${ROLE_NAME} \
--query 'AttachedPolicies[*].PolicyArn' \
--output text
) \
&& echo ${POLICIES}
# リスト内のポリシーをデタッチする
for POLICY in ${POLICIES}; do
aws iam detach-role-policy \
--role-name ${ROLE_NAME} \
--policy-arn ${POLICY}
done
# IAMロールの削除
aws iam delete-role \
--role-name ${ROLE_NAME}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # ロールにアタッチされているポリシーをリスト
[cloudshell-user@ip-10-134-11-244 ~]$ POLICIES=$(
> aws iam list-attached-role-policies \
> --role-name ${ROLE_NAME} \
> --query 'AttachedPolicies[*].PolicyArn' \
> --output text
> ) \
> && echo ${POLICIES}
arn:aws:iam::999999999999:policy/handson-lambda-policy arn:aws:iam::aws:policy/TranslateReadOnly
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # リスト内のポリシーをデタッチする
[cloudshell-user@ip-10-134-11-244 ~]$ for POLICY in ${POLICIES}; do
> aws iam detach-role-policy \
> --role-name ${ROLE_NAME} \
> --policy-arn ${POLICY}
> done
[cloudshell-user@ip-10-134-11-244 ~]$
[cloudshell-user@ip-10-134-11-244 ~]$ # IAMロールの削除
[cloudshell-user@ip-10-134-11-244 ~]$ aws iam delete-role \
> --role-name ${ROLE_NAME}
IAMポリシー削除
コマンド
# IAMポリシーの削除
aws iam delete-policy \
--policy-arn ${POLICY_ARN}
出力
[cloudshell-user@ip-10-134-11-244 ~]$ # IAMポリシーの削除
[cloudshell-user@ip-10-134-11-244 ~]$ aws iam delete-policy \
> --policy-arn ${POLICY_ARN}