S3のリダイレクト機能をAWS CLIで設定してみた

「S3のリダイレクト機能を改めて整理してみた」際には設定をマネジメントコンソールから行なっていましたが、今度はこれをAWS CLIで設定してみます。まずAWS CLIでの情報取得を行い、続いて実際に設定を行うというステップを踏みました。
2021.07.31

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

清水です。先ほど「S3のリダイレクト機能を改めて整理してみた」というエントリをまとめてみました。ウェブサイトエンドポイント自体にリダイレクト設定を行う方法、ウェブサイトホスティングをしながらリダイレクトルールを使って設定する方法、オブジェクト自体にリダイレクトを設定する方法、3つの方法について実際にS3にリダイレクトの設定を行い動作を確認しています。これらの設定は確認などの意味も込めてS3マネジメントコンソールから行ったのですが、これをAWS CLIで設定してみよう、というのが本エントリの趣旨となります。具体的なリダイレクト機能の詳細などは先のエントリをご参照ください。本エントリでは3つのパターンについて、S3マネジメントコンソールから設定した内容をまずAWS CLIで情報を取得、その内容を新たなS3バケットに設定していくことでS3のリダイレクト機能をAWS CLIで設定していく手順をまとめます。

なお、本エントリで使用したAWS CLIのバージョン等は下記になります。

% aws --version
aws-cli/2.2.14 Python/3.8.8 Darwin/19.6.0 exe/x86_64 prompt/off

また特別記載がない限り、S3バケットは東京リージョンのリソースとなります。

リダイレクト機能が設定されたS3バケットの情報をAWS CLIで取得する

まずは先のエントリでリダイレクトを設定したS3バケットの情報を確認していきます。情報の確認は基本的にはs3api get-bucket-websiteコマンドを使用します。

S3ウェブサイトエンドポイントへのリダイレクト設定の確認

まずは静的ウェブサイトホスティングのエンドポイント全体にリダイレクト設定が行われているパターンです。HTTPS指定でwww.example.comにリダイレクトするように設定しています。s3api get-bucket-websiteコマンドの実行結果は下記になります。

% aws s3api get-bucket-website \
    --bucket s3-redirect-1-XXXXXX
{
    "RedirectAllRequestsTo": {
        "HostName": "www.example.com",
        "Protocol": "https"
    }
}

RedirectAllRequestsToという要素にHostNameProtocolの情報がまとまっている具合ですね。

マネジメントコンソールの表示と比較すると下記となります。

リダイレクトルールを使った設定の確認

続いてリダイレクトルールを使った設定です。すべてのパスについてnew.example.comにリダイレクト、その際のリダイレクトコードは301、プロコトルはHTTPSという設定をしています。s3api get-bucket-websiteコマンドの実行結果は下記になります。

% aws s3api get-bucket-website \
    --bucket s3-redirect-2-XXXXXX
{
    "IndexDocument": {
        "Suffix": "index.html"
    },
    "ErrorDocument": {
        "Key": "error.html"
    },
    "RoutingRules": [
        {
            "Redirect": {
                "HostName": "new.example.com",
                "HttpRedirectCode": "301",
                "Protocol": "https",
                "ReplaceKeyWith": ""
            }
        }
    ]
}

IndexDocumentErrorDocumentという要素はリダイレクト自体ではなく、静的ウェブサイトホスティング自体の設定ですね。RoutingRulesという要素にリダイレクトルールで指定した内容が記載されています。

先ほどのS3ウェブサイトエンドポイントへのリダイレクト設定と比べると、RedirectAllRequestsTo要素の場合はRedirect requestの設定になり、IndeDocument要素の場合は通常のBucket Hostingの設定、そこに任意でRoutingRules要素でルーティングルールによるリダイレクト設定を行う、という具合かと思います。

マネジメントコンソールでの設定内容を比較用に掲載しておきます。

設定したRedirection rulesは以下の内容です。s3api get-bucket-websiteコマンドの出力の内容と一致しますね。

[
    {
        "Redirect": {
            "HostName": "new.example.com",
            "HttpRedirectCode": "301",
            "Protocol": "https",
            "ReplaceKeyWith": ""
        }
    }
]

オブジェクト単位でのリダイレクト設定の確認

個々のオブジェクトに対してリダイレクトを設定するパターンです。こちらはバケットへの設定確認に加えて、s3api head-objectでオブジェクトのメタデータを確認します。

S3バケット配下のspecialpage.htmlというオブジェクトに対し、specialpage.example.comにリダイレクトするよう設定しています。

% aws s3api get-bucket-website \
    --bucket s3-redirect-3-XXXXXX
{
    "IndexDocument": {
        "Suffix": "index.html"
    },
    "ErrorDocument": {
        "Key": "error.html"
    }
}
% aws s3api head-object \
    --bucket s3-redirect-3-XXXXXX \
    --key specialpage.html
{
    "AcceptRanges": "bytes",
    "LastModified": "2021-07-31T05:17:28+00:00",
    "ContentLength": 111,
    "ETag": "\"7a07xxxxxxxxxxxxxxxxxxxxxxxxxxxx\"",
    "ContentType": "text/html",
    "WebsiteRedirectLocation": "https://specialpage.example.com/",
    "Metadata": {}
}

こちらもS3マネジメントコンソールでの設定内容を確認しておきましょう。

AWS CLIでS3バケットにリダイレクト機能を設定する

リダイレクト機能の設定状況がAWS CLIの情報で取得できました。続いて、本題のAWS CLIでのS3バケットリダイレクト設定を行なっていきます。リダイレクト設定はs3api put-bucket-websiteコマンドを使用します。

S3ウェブサイトエンドポイントへのリダイレクト設定

まずはS3ウェブサイトエンドポイントへのリダイレクト設定です。RedirectAllRequestsTo要素を使うことがキモですね。

まずはS3バケットを作成します。

% aws s3api create-bucket \
    --bucket s3-redirect-awscli-1-XXXXXX \
    --create-bucket-configuration LocationConstraint=ap-northeast-1
{
    "Location": "http://s3-redirect-awscli-1-XXXXXX.s3.amazonaws.com/"
}

続いてパブリックアクセスができるようバケットポリシーを設定します。(先のエントリで扱ったように、この設定がなくてもS3ウェブサイトエンドポイントへのリダイレクトは可能です。)

% cat bucket-policy-1.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::s3-redirect-awscli-1-XXXXXX/*"
        }
    ]
}

% aws s3api put-bucket-policy \
    --bucket s3-redirect-awscli-1-XXXXXX \
    --policy file://bucket-policy-1.json

それではリダイレクトの設定です。内容は確認したものと同じ、HTTPS指定でwww.example.comにリダイレクトとします。リダイレクト設定はwebsite-config-1.jsonというファイルにまとめました。s3api put-bucket-websiteコマンドの返り値はありませんので、実行後にs3api get-bucket-websiteコマンドで設定内容を確認しています。

% cat website-config-1.json
{
    "RedirectAllRequestsTo": {
        "HostName": "www.example.com",
        "Protocol": "https"
    }
}

% aws s3api put-bucket-website \
    --bucket s3-redirect-awscli-1-XXXXXX \
    --website-configuration file://website-config-1.json

% aws s3api get-bucket-website \
    --bucket s3-redirect-awscli-1-XXXXXX
{
    "RedirectAllRequestsTo": {
        "HostName": "www.example.com",
        "Protocol": "https"
    }
}

リダイレクトのレスポンスも確認してみます。意図したリダイレクト設定が行えていますね。

% curl -I http://s3-redirect-awscli-1-XXXXXX.s3-website-ap-northeast-1.amazonaws.com
HTTP/1.1 301 Moved Permanently
x-amz-id-2: tUoKxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
x-amz-request-id: B513xxxxxxxxxxxx
Date: Sat, 31 Jul 2021 12:23:10 GMT
Location: https://www.example.com/
Content-Length: 0
Server: AmazonS3
% curl -I "http://s3-redirect-awscli-1-XXXXXX.s3-website-ap-northeast-1.amazonaws.com/path/to/file.html?query=string&key=value"
HTTP/1.1 301 Moved Permanently
x-amz-id-2: 6k+Wxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
x-amz-request-id: 0DMVxxxxxxxxxxxx
Date: Sun, 01 Aug 2021 14:55:08 GMT
Location: https://www.example.com/path/to/file.html?query=string&key=value
Server: AmazonS3
Content-Length: 0

リダイレクトルールを使った設定

続いてリダイレクトルールを使った設定です。S3バケットの作成とパケットポリシーの設定をS3ウェブサイトエンドポイントへのリダイレクト設定と同様に設定します。

% aws s3api create-bucket \
    --bucket s3-redirect-awscli-2-XXXXXX \
    --create-bucket-configuration LocationConstraint=ap-northeast-1
{
    "Location": "http://s3-redirect-awscli-2-XXXXXX.s3.amazonaws.com/"
}

% cat bucket-policy-2.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::s3-redirect-awscli-2-XXXXXX/*"
        }
    ]
}

% aws s3api put-bucket-policy \
    --bucket s3-redirect-awscli-2-XXXXXX \
    --policy file://bucket-policy-2.json

リダイレクトルールは確認したものと同じ、以下の内容とします。

[
    {
        "Redirect": {
            "HostName": "new.example.com",
            "HttpRedirectCode": "301",
            "Protocol": "https",
            "ReplaceKeyWith": ""
        }
    }
]

設定内容としてwebsite-config-2.jsonというファイルにまとめます。

% cat website-config-2.json
{
    "IndexDocument": {
        "Suffix": "index.html"
    },
    "ErrorDocument": {
        "Key": "error.html"
    },
    "RoutingRules": [
        {
            "Redirect": {
                "HostName": "new.example.com",
                "HttpRedirectCode": "301",
                "Protocol": "https",
                "ReplaceKeyWith": ""
            }
        }
    ]
}

ファイル中の設定内容が変わるだけで、s3api put-bucket-websiteコマンドの実行方法はS3ウェブサイトエンドポイントへのリダイレクト設定と変わりありません。

% aws s3api put-bucket-website \
    --bucket s3-redirect-awscli-2-XXXXXX \
    --website-configuration file://website-config-2.json

% aws s3api get-bucket-website \
    --bucket s3-redirect-awscli-2-XXXXXX
{
    "IndexDocument": {
        "Suffix": "index.html"
    },
    "ErrorDocument": {
        "Key": "error.html"
    },
    "RoutingRules": [
        {
            "Redirect": {
                "HostName": "new.example.com",
                "HttpRedirectCode": "301",
                "Protocol": "https",
                "ReplaceKeyWith": ""
            }
        }
    ]
}

リダイレクトのレスポンスは下記のようになり、意図した設定ができていることが確認できました。

% curl -I http://s3-redirect-awscli-2-XXXXXX.s3-website-ap-northeast-1.amazonaws.com
HTTP/1.1 301 Moved Permanently
x-amz-id-2: AHpUxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
x-amz-request-id: JDK2xxxxxxxxxxxx
Date: Sat, 31 Jul 2021 12:25:58 GMT
Location: https://new.example.com/
Server: AmazonS3
Content-Length: 0
% curl -I "http://s3-redirect-awscli-2-XXXXXX.s3-website-ap-northeast-1.amazonaws.com/path/to/file.html?query=string&key=value"
HTTP/1.1 301 Moved Permanently
x-amz-id-2: 9Xpvxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
x-amz-request-id: YFSMxxxxxxxxxxxx
Date: Sun, 01 Aug 2021 14:56:31 GMT
Location: https://new.example.com/
Server: AmazonS3
Content-Length: 0

オブジェクト単位でのリダイレクト設定

最後にオブジェクト単位でのリダイレクト設定です。S3バケットの作成とバケットポリシーの設定までは同様の手順ですので割愛します。S3ウェブサイトホスティングの設定をまずは行います。

% cat website-config-3.json
{
    "IndexDocument": {
        "Suffix": "index.html"
    },
    "ErrorDocument": {
        "Key": "error.html"
    }
}

% aws s3api put-bucket-website \
    --bucket s3-redirect-awscli-3-XXXXXX \
    --website-configuration file://website-config-3.json
 
% aws s3api get-bucket-website \
    --bucket s3-redirect-awscli-3-XXXXXX
{
    "IndexDocument": {
        "Suffix": "index.html"
    },
    "ErrorDocument": {
        "Key": "error.html"
    }
}

続いてオブジェクトへのリダイレクトの設定です。こちらも内容は先ほど確認した状態と同じ、specialpage.htmlというオブジェクトに対しspecialpage.example.comにリダイレクトする、という設定にします。今回は新たに0バイトのオブジェクトをアップロード、その際にx-amz-website-redirect-location (WebsiteRedirectLocation要素)を付与するようにします。オブジェクトのアップロードにはs3api put-objectコマンドを利用します。

% aws s3api put-object \
    --bucket s3-redirect-awscli-3-XXXXXX \
    --key specialpage.html \
    --body specialpage.html \
    --website-redirect-location "https://specialpage.example.com/"
{
    "ETag": "\"d41dxxxxxxxxxxxxxxxxxxxxxxxxxxx\""
}

% aws s3api head-object \
    --bucket s3-redirect-awscli-3-XXXXXX
    --key specialpage.html
{    
    "AcceptRanges": "bytes",
    "LastModified": "2021-07-31T12:14:00+00:00",
    "ContentLength": 0,
    "ETag": "\"d41dxxxxxxxxxxxxxxxxxxxxxxxxxxx\"",
    "ContentType": "binary/octet-stream",
    "WebsiteRedirectLocation": "https://specialpage.example.com/",
    "Metadata": {}
}

リダイレクトのレスポンスを確認します。こちらも意図した通りの設定ができました。

% curl -i http://s3-redirect-awscli-3-XXXXXX.s3-website-ap-northeast-1.amazonaws.com/specialpage.html
HTTP/1.1 301 Moved Permanently
x-amz-id-2: pZfJxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
x-amz-request-id: 6WRKxxxxxxxxxxxx
Date: Sat, 31 Jul 2021 12:16:58 GMT
Location: https://specialpage.example.com/
Server: AmazonS3
Content-Length: 0

まとめ

S3のリダイレクト機能をAWS CLIで設定してみました。S3ウェブサイトエンドポイントでリダイレクト設定を行う場合は、静的ウェブサイトホスティング設定時にIndexDocument要素ではなくRedirectAllRequestsTo要素で設定を行います。リダイレクトルールを使用する場合は静的ウェブサイトホスティング設定の際にIndexDocument要素に加えRoutingRules要素を追加、この中にRedirect要素でルールを記載します。オブジェクト単位でリダイレクトを設定する場合は静的ウェブサイトホスティングの設定に加えて、オブジェクトにx-amz-website-redirect-locationプロパティ(WebsiteRedirectLocation要素)を追加します。バケットに対して使用するコマンドはput-bucket-websiteで同じですが、その中身が異なるという具合ですね。AWS CLIで設定してみることにより、設定方法について一段と理解が深まったと思います。