📦

Google Cloud StorageをAWS SDK for JavaScript v3で操作する

2022/05/17に公開

はじめに

おはようございます、加藤です。最近はWasabiCloudflare R2などオブジェクトストレージの話題で盛り上がっていますね。これらや今回のメインであるGoogle CloudのCloud StorageはAmazon S3との互換性があるとされています。

このこと自体は以前から知っていましたが、互換性を実際に生かすことができるのか?具体的に言うとAWS SDKで書かれたコードに対してどれぐらいの変更を加えることでCloud Storageを利用できるか気になってので試してみました。

ドキュメントを調査する

まずググって情報があるかを探してみました。すると公式ドキュメントで該当するものがヒットしました。 Amazon S3 から Cloud Storage への移行  |  Google Cloud
残念ながらJavaScript用のサンプルコードはありませんでしたがこのページからひとまず以下のことがわかりました。

  • AWS SDKを使ったままCloud Storageを使う場合は単純な移行完全な移行の2つのアプローチがある
  • 単純な移行は使える機能が制限される(OAuth2.0、アクセス制御)
  • 単純な移行は認証にはHMACキーを使用する

今回は単純な移行を試してみます。

HMACキーって何?

HMAC キー  |  Cloud Storage  |  Google Cloud

HMACキーはアクセスIDとシークレットの2つで構成される認証情報です。今回の様な既存のコードを再利用してCloud Storageへアクセスしたいといった限定的な場合に使用されるようです。
Cloud Storageに対する捜査が許可されたサービスアカウントを作成し、これに対してHMACキーの発行ができます。
つまりはAWSにおけるアクセスキーとシークレットアクセスキーに相当するものです。前述のとおり、限定的な場合においての話なのでご注意ください。

AWS SDKでCloud StorageをListとGetする

実際に書いてみました。最初にドキュメントで手順を確認してサービスアカウントとHMACキーを作成します。
HMACキーを作成する

今回はBucketをListとGetができる権限を与えればOKです。

抜粋したコードがこちらです。

async function listBuckets(client: S3): Promise<string[]> {
  const res = await client.send(new ListBucketsCommand({}));

  if (res.Buckets === undefined) {
    return [];
  }

  return res.Buckets.flatMap((bucket) =>
    bucket.Name === undefined ? [] : [bucket.Name]
  );
}

async function getObject(
  client: S3,
  bucket: string,
  key: string
): Promise<string> {
  const res = await client.send(
    new GetObjectCommand({ Bucket: bucket, Key: key })
  );

  return streamToString(res.Body);
}

function cloudStorage(): S3 {
  return new S3({
    credentials: {
      accessKeyId: process.env.GOOGLE_ACCESS_KEY_ID!,
      secretAccessKey: process.env.GOOGLE_ACCESS_KEY_SECRET!,
    },
    endpoint: "https://storage.googleapis.com",
  });
}

async function main(): Promise<void> {
  const gcs = cloudStorage();

  console.log(await listBuckets(gcs));
  console.log(await getObject(gcs, process.env.BUCKET!, process.env.KEY!));
}

クレデンシャルにHMACキーのセットとエンドポイントを指定してクライアント生成を行うことでCloud Storageのクライアントとして使えるようになります。今回はListとGetだけを試していますがドキュメントを読む限りCRUDは制約なく行えそうです。

あとがき

実は最近とあるプロジェクトで元々はCloud Storageを使っていたコードをS3へ置き換えるという今回と逆のような作業を行いました。そのプロジェクトはコードベースが大きくなかったのでSDKを差し替えてコードを書き直したのですが、これがS3互換を活用して差し替えたらどうだったのか?と気になって調べてみました。

きちんとしたドキュメントが用意されており想定されたユースケースと思われプロダクションレベルでも問題なく使えそうです。大抵の場合はGoogle CloudのSDKに差し替えると思います。ですが、徐々に移行したいなど状況に応じて今回紹介した方法が役に立てば幸いです。

Discussion