Amazon Lightsail バケットから S3 バケットに CLI で同期させてみた

2022.10.18

いわさです。

Amazon Lightsail にはオブジェクトストレージサービスである「バケット」という機能があります。

こちらは S3 バケットに類似しているのですが、構成は Lightsail からのみ行うことが出来るので S3 バケットで利用できるいくつかの機能がサポートされていなかったりします。
そういった点から S3 バケットの利用を検討する必要があったのですが、Amazon Lightsail バケットから Amazon S3 バケットへデータのコピーなどを試しましたので共有します。

Lightsail バケットは S3 と同等の機能がサポートされているわけではない

Amazon Lightsail バケットは以下から作成を行います。

作成後はストレージメニュー上からオブジェクトのアップロードをしたり追加の構成を行うことが出来ます。
追加構成可能なオプションとしていくつか用意されていてバケットの公開・共有やメトリクスの確認、バージョニング設定などを行うことが出来ます。

上記のようにバージョニングなど S3 でも利用が出来るいくつかのオプションが設定出来るのですが、一方でイベント通知機能やクロスリージョンレプリケーションなどの機能は無く S3 バケットの全てのオプションが利用出来るというわけではありません。

また Lightsail バケットは S3 バケットコンソール上では表示されないので S3 バケットとしての追加設定を行うことも出来ません。

それでもどうにか Lightsail バケットのオブジェクトアップロードタイミングでカスタム処理を実行したい

上記のようにイベント通知機能を使いたかったのですが残念ながら本日時点では機能として提供されていません。 念の為以下のようにイベント通知の設定が出来るか確認してみましたが Access Denied となりました。

% aws lightsail get-buckets --profile hoge
{
    "buckets": [
        {
            "resourceType": "Bucket",
            "accessRules": {
                "getObject": "private",
                "allowPublicOverrides": false
            },
            "arn": "arn:aws:lightsail:ap-northeast-1:123456789012:Bucket/ac1bcc8a-d50f-4d1d-850f-c8bdb4eaa260",
            "bundleId": "small_1_0",
            "createdAt": "2022-10-18T06:23:39.187000+09:00",
            "url": "https://hoge1018iwasa.s3.ap-northeast-1.amazonaws.com",
            "location": {
                "availabilityZone": "all",
                "regionName": "ap-northeast-1"
            },
            "name": "hoge1018iwasa",
            "supportCode": "173033923990/hoge1018iwasa/small_1_0",
            "tags": [],
            "objectVersioning": "NeverEnabled",
            "ableToUpdateBundle": true,
            "readonlyAccessAccounts": [],
            "state": {
                "code": "OK"
            }
        }
    ],
    "accountLevelBpaSync": {
        "status": "NeverSynced",
        "lastSyncedAt": "1970-01-01T09:00:00+09:00",
        "message": "",
        "bpaImpactsLightsail": false
    }
% aws s3api put-bucket-notification-configuration --bucket hoge1018iwasa --notification-configuration "{}" --profile hoge

An error occurred (AccessDenied) when calling the PutBucketNotificationConfiguration operation: Access Denied

さらに EventBridge でのイベントの取得も出来ません。
バケットの作成などについてはイベントソースとして lightsail.amazonaws.com を指定することで取得出来ますが、オブジェクトの操作レベルでは取得が出来ません。

Lightsail バケットでのイベントをトリガーに処理を実行することは難しくて、ポーリングするような形になりそうです。
今回は簡易的に実現したかったので、ストレージ利用料金が冗長ではあるのですが Lightsail バケットから S3 へ同期してイベント通知をそちらで構成して検知するというのを試しにやってみました。
これが出来そうであれば一定間隔で同期コマンドを実行するだけでもイベント通知に近いことが実現出来そうです。

まず、Lightsail バケットも S3 コマンドで操作が出来ます。
注意点として書き込み時は acl パラメータを指定するかあるいは Lightsail コンソールからアクセスキーを発行して使う必要があります。

% aws s3 cp ./hoge.txt s3://hoge1018iwasa/ --profile hoge                                   
upload failed: ./hoge.txt to s3://hoge1018iwasa/hoge.txt An error occurred (AccessDenied) when calling the PutObject operation: Access Denied

% aws s3 cp ./hoge.txt s3://hoge1018iwasa/ --acl bucket-owner-full-control --profile hoge
upload: ./hoge.txt to s3://hoge1018iwasa/hoge.txt

% aws s3 cp ./hoge.txt s3://hoge1018iwasa/ --profile accesskey
upload: ./hoge.txt to s3://hoge1018iwasa/hoge.txt

ただし、ここで発行するアクセスキーは IAM アクセスアナライザーなどで管理が出来てい無さそうです。
よって他の環境からアクセスさせたい場合は、クロスアカウント共有機能を使ったほうがセキュリティリスク上良さそうに感じました。

クロスアカウントアクセスは以下から設定が可能ですが、自分のアカウントは追加する必要はありません。(出来ない)

同期コマンドは意識せずに使える

作成・更新については権限を意識する必要がありましたが、試したところ ls や sync でソースとして指定するような参照系の機能はデフォルトで自信にアカウント共有されている関係で無意識に自分のバケットのように扱うことが出来ました。

ここでは以下のように sync コマンドで Lightsail バケットから S3 バケットへのコピーに成功しています。

% aws s3 sync s3://hoge1018iwasa s3://hoge1018lightsail --profile hoge
copy: s3://hoge1018iwasa/hoge2.txt to s3://hoge1018lightsail/hoge2.txt

あとは送信先のバケットでイベント通知を構成し、念の為 sync でも発生するのかを確認してみます。

{
    "Records": [
        {
            "eventVersion": "2.1",
            "eventSource": "aws:s3",
            "awsRegion": "ap-northeast-1",
            "eventTime": "2022-10-17T22:16:54.504Z",
            "eventName": "ObjectCreated:Copy",
            "userIdentity": {
                "principalId": "AWS:AIDAYANTVHXIN24QP7L6D"
            },
            "requestParameters": {
                "sourceIPAddress": "203.0.113.1"
            },
            "responseElements": {
                "x-amz-request-id": "7AMEMYTVRGFJD9A9",
                "x-amz-id-2": "5VVog3jc9o7N1W3cRDuJGlPOLOATluoFlQF3AYfzZUqlibRNsnaCKl63a8k1EoKrzMwmHEJoueh/vvyXun/wII00Us5t0Jpa"
            },
            "s3": {
                "s3SchemaVersion": "1.0",
                "configurationId": "hoge1018event",
                "bucket": {
                    "name": "hoge1018lightsail",
                    "ownerIdentity": {
                        "principalId": "A3LHEVODN85DDG"
                    },
                    "arn": "arn:aws:s3:::hoge1018lightsail"
                },
                "object": {
                    "key": "hoge2.txt",
                    "size": 0,
                    "eTag": "d41d8cd98f00b204e9800998ecf8427e",
                    "sequencer": "00634DD4567664F9B3"
                }
            }
        }
    ]
}

通知を受信することが出来ました。
sync を使った際のオブジェクト階層はバケット間で同じなので、カスタム処理側でバケット名だけ置き換えれれば Lightsail バケットの操作に拡張することも出来そうです。

さいごに

本日は Amazon Lightsail バケットから S3 バケットに CLI で同期させてみました。

残念ながら本日時点では標準のイベント通知機能で Lightsail バケットから直接検知出来ないことを確認しました。
そこで代替案として sync コマンドで S3 へ転送し、そちらで S3 イベント通知を使う方法を試してみました。

ストレージオブジェクトの数やサイズなど考慮するべき点はいくつかあると思いますが更新頻度によってはニアリアルタイムに近い使い方も出来そうなので、代替案のひとつとして検討出来そうかなと思いました。