AWS CLI で CloudFront の OAI を OAC に移行する
2022-08-30CloudFront から S3 へのアクセスを制御する方法として Origin Access Identity (OAI) という機能がありましたが、それに代わる機能として Origin Access Control (OAC) という機能が発表されました。今回は、 AWS CLI を使って OAI を利用していたものを OAC に移行する方法について書きます。
- 移行方法
-
AWS CLI でやっていく
- 1. 対象の S3 Bucket の Bucket Policy に、 Origin Access Identity の Statement を残したまま Origin Access Control の Statement を追記する
- 2. Origin Access Control のリソースを作成する
- 3. 対象の Distribution に設定する
- 4. 対象の S3 Bucket の Bucket Policy から Origin Access Identity の Statement を削除する
- 5. 不要になった Origin Access Identity のリソースを削除する
- まとめ
移行方法
基本的には下記の公式ドキュメントに沿って移行していきます。
Restricting access to an Amazon S3 origin - Amazon CloudFront
具体的な手順としては、
- 対象の S3 Bucket の Bucket Policy に、 Origin Access Identity の Statement を残したまま Origin Access Control の Statement を追記する
- Origin Access Control のリソースを作成する
- 対象の Distribution に設定する
- 対象の S3 Bucket の Bucket Policy から Origin Access Identity の Statement を削除する
-
- 不要になった Origin Access Identity のリソースを削除する
となります。
AWS CLI でやっていく
今回は、上記の手順を AWS CLI を使ってやってみます。
必要な AWS CLI のバージョンは、 v1 は 1.25.60
以降、 v2 は 2.7.27
以降です。今回は v2 を使います。
❯ aws --version
aws-cli/2.7.27 Python/3.9.11 Darwin/21.6.0 exe/x86_64 prompt/off
作業するにあたっては、対象の S3 Bucket の名前と CloudFront の Distribution ID が必要なので、それぞれ環境変数に設定しておきます。
BUCKET_NAME='your-bucket-name'
DIST_ID='your-distribution-id'
1. 対象の S3 Bucket の Bucket Policy に、 Origin Access Identity の Statement を残したまま Origin Access Control の Statement を追記する
現在の Bucket Policy ドキュメントを取得する
aws s3api get-bucket-policy \
--bucket "${BUCKET_NAME}" \
--output text \
| jq . > bucket-policy.json
OAI による制御の Statement として下記のような設定がされています。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "OriginAccessIdentityStatement",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity your-distribution-id"
},
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::your-bucket-name/*",
"arn:aws:s3:::your-bucket-name"
]
}
]
}
Origin Access Control による制御の Statement を追記する
上記の JSON を下記のように編集します。(Distribution ARN のアカウント ID は読み替えてください)
{
"Version": "2012-10-17",
"Statement": [
+ {
+ "Sid": "OriginAccessControlStatement",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": "cloudfront.amazonaws.com"
+ },
+ "Action": [
+ "s3:GetObject",
+ "s3:ListBucket"
+ ],
+ "Resource": [
+ "arn:aws:s3:::your-bucket-name/*",
+ "arn:aws:s3:::your-bucket-name"
+ ],
+ "Condition": {
+ "StringEquals": {
+ "AWS:SourceArn": "arn:aws:cloudfront::000000000000:distribution/your-distribution-id"
+ }
+ }
+ },
{
"Sid": "OriginAccessIdentityStatement",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity your-origin-access-identity-id"
},
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::your-bucket-name/*",
"arn:aws:s3:::your-bucket-name"
]
}
]
}
Bucket Policy を更新する
aws s3api put-bucket-policy \
--bucket "${BUCKET_NAME}" \
--policy file://bucket-policy.json
問題ないはずですが、一応この時点でちゃんとアクセスできることを確認します。
2. Origin Access Control のリソースを作成する
Origin Access Control リソースの作成には、新たに追加された cloudfront
コマンドの create-origin-access-control
サブコマンドを使います。
❯ aws cloudfront create-origin-access-control help
...
SYNOPSIS
create-origin-access-control
--origin-access-control-config <value>
[--cli-input-json | --cli-input-yaml]
[--generate-cli-skeleton <value>]
[--debug]
[--endpoint-url <value>]
[--no-verify-ssl]
[--no-paginate]
[--output <value>]
[--query <value>]
[--profile <value>]
[--region <value>]
[--version <value>]
[--color <value>]
[--no-sign-request]
[--ca-bundle <value>]
[--cli-read-timeout <value>]
[--cli-connect-timeout <value>]
[--cli-binary-format <value>]
[--no-cli-pager]
[--cli-auto-prompt]
[--no-cli-auto-prompt]
...
パラメータがいくつかありますが、今回は yaml ファイルを作って --cli-input-yaml
で渡してリソースを作ってみます。
そのために、ベースとなる yaml を生成します。
aws cloudfront create-origin-access-control \
--generate-cli-skeleton yaml-input > oac.yaml
中身はこんな感じで、必須のパラメータのみ記載されています。
OriginAccessControlConfig: # [REQUIRED] Contains the origin access control.
Name: '' # [REQUIRED] A name to identify the origin access control.
Description: '' # [REQUIRED] A description of the origin access control.
SigningProtocol: sigv4 # [REQUIRED] The signing protocol of the origin access control, which determines how CloudFront signs (authenticates) requests. Valid values are: sigv4.
SigningBehavior: never # [REQUIRED] Specifies which requests CloudFront signs (adds authentication information to). Valid values are: never, always, no-override.
OriginAccessControlOriginType: s3 # [REQUIRED] The type of origin that this origin access control is for. Valid values are: s3.
なので、中身を埋めます。
OriginAccessControlConfig:
Name: 'OriginAccessControlForMyBlog'
Description: 'Origin Access Control for my blog.'
SigningProtocol: sigv4
SigningBehavior: always
OriginAccessControlOriginType: s3
Name
, Description
については任意の文字列を入れます。
SigningProtocol
にはそのまま sigv4
を、 OriginAccessControlOriginType
にもそのまま s3
を入れます。
SigningBehavior
については、下記公式ドキュメントの Advanced settings for origin access control の部分を確認し、 always
, never
, no-override
のいずれかを入れます。
それぞれの設定について、公式ドキュメントの内容を要約してみます。
always (推奨設定)
CloudFront が Origin (S3 Bucket) に送信するすべてのリクエストに署名します。
never
CloudFront が Origin (S3 Bucket) に送信するすべてのリクエストに署名しません。これはつまり、この Origin Access Control を使用する Distribution のすべての Origin に対して アクセスコントロールをオフにします。
この設定をする場合、 Originとなる S3 Bucket には Public に公開されている必要があります。公開されていない Bucket に対してこの設定を行うと、 CloudFront は Origin にアクセスできず、 Viewer にはエラーを返します。
no-override
Viewer リクエストに Authorization ヘッダが存在する場合はそれを Origin リクエストに使用し、含まれていない場合は CloudFront が署名します。
この設定を使用する場合、 Viewer からの Authorization ヘッダを Origin リクエストで使用するためにキャッシュポリシーで Authorization ヘッダを許可する必要があります。
以上から、基本的には always
で設定しておけば良さそうです。
作った yaml をもとに、 Origin Access Control のリソースを作成します。作成結果として ID が後に必要になるので控えておきます。
aws cloudfront create-origin-access-control \
--cli-input-yaml file://oac.yaml \
--query 'OriginAccessControl.Id' \
--output text
3. 対象の Distribution に設定する
続いて、作成した Origin Access Control を Distribution に設定します。
これは cloudfront
の update-distribution
という、どデカイ更新を行うサブコマンドで実施します。
まずは現状の Distribution の設定を yaml で取得し、中身を変更して update-distribution
で投げます。
aws cloudfront get-distribution-config \
--id "${DIST_ID}" \
--output yaml \
> dist-config.yaml
100 行を超える yaml が生成されるので、その中の Origins
の設定を下記のように変更します。このとき、 Origin Access Identity のリソースは後に削除するので、 your-oai-id の部分を環境変数に設定しておきます。 (OAI_ID='your-oai-id'
)
+ OriginAccessControlId: your-oac-id
S3OriginConfig:
- OriginAccessIdentity: origin-access-identity/cloudfront/your-oai-id
+ OriginAccessIdentity: ''
また、 ETag
フィールドの 値はそのままで フィールド名を IfMatch
に変更します。
- ETag: HOGEHOGEVALUE
+ IfMatch: HOGEHOGEVALUE
下記コマンドで更新します。
aws cloudfront update-distribution \
--id "${DIST_ID}" \
--cli-input-yaml file://dist-config.yaml
この時点でアクセスできていれば、既に Origin Access Control による制御への移行は成功しています。
4. 対象の S3 Bucket の Bucket Policy から Origin Access Identity の Statement を削除する
Bucket Policy 内の Origin Access Identity の Statement は不要になったので削除します。
1
の手順で使った bucket-policy.json
を下記のように変更し、 put-bucket-policy
で更新します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "OriginAccessControlStatement",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::your-bucket-name/*",
"arn:aws:s3:::your-bucket-name"
],
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::000000000000:distribution/your-distribution-id"
}
}
- },
- {
- "Sid": "OriginAccessIdentityStatement",
- "Effect": "Allow",
- "Principal": {
- "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity your-origin-access-identity-id"
- },
- "Action": [
- "s3:GetObject",
- "s3:ListBucket"
- ],
- "Resource": [
- "arn:aws:s3:::your-bucket-name/*",
- "arn:aws:s3:::your-bucket-name"
- ]
}
]
}
aws s3api put-bucket-policy \
--bucket "${BUCKET_NAME}" \
--policy file://bucket-policy.json
5. 不要になった Origin Access Identity のリソースを削除する
不要になった Origin Access Identity のリソースは cloudfront
コマンドの delete-cloud-front-origin-access-identity
コマンドで削除します。
aws cloudfront delete-cloud-front-origin-access-identity \
--id "${OAI_ID}" \
--if-match $(
aws cloudfront get-cloud-front-origin-access-identity \
--id ${OAI_ID} \
--query 'ETag' \
--output text)
まとめ
Amazon CloudFront の新しいアクセスコントロール機能である Origin Access Control への移行を AWS CLI でやってみた話でした。
Terraform も次の 4.29.0
で対応されそうなので、対応されたら試してみます。
comments powered by Disqus