GCP コンソールから Compute Engine を初めて選択したとき、Compute Engine API を有効にするか聞かれます。有効を選択すると、Compute Engine のデフォルトのサービスアカウントが作成されます。GCE でインスタンスを作成するとサービスアカウントとしてこのデフォルトのサービスアカウントが指定されています。
デフォルトのサービスアカウントには基本ロールの編集者
が割り当てられていますが、基本ロールは強い権限を持っており本番環境で使用するのは非推奨になっています。
注意: 基本ロールには、すべての Google Cloud サービスにかかわる何千もの権限が含まれます。本番環境では、他に選択肢がない限り、基本ロールを付与しないでください。代わりに、ニーズに合わせて最も制限された事前定義ロールまたはカスタムロールを付与します。
今回は、インスタンスのサービスアカウントにデフォルトのサービスアカウントではなく自前で用意したサービスアカウントを指定して PHP で Cloud Storage にアクセスしてみます。
サービスアカウントを作成
まずは今回使用するサービスアカウントを作成します。
- [IAMと管理]から[IAM]を選択。[サービスアカウント]を選択し、[+サービスアカウントを選択]を選択。「1. サービスアカウントの詳細」の各項目に任意の名前を入力し[作成]を選択。
- 「2. このサービス アカウントにプロジェクトへのアクセスを許可する (省略可)」でサービスアカウントにロールを割り当てます。今回は Cloud Storage にアクセスしたいので、事前定義ロールの[ストレージ管理者]を割り当てます。
- [ロールを選択]を選択。
- [Type to filter]に「ストレージ」と入力。
- [ストレージ管理者]を選択
- ロールを割り当てたら[続行]を選択。
- [完了]を選択。
GCEインスタンスに割り当て
作成したサービスアカウントをインスタンスに割り当てます。
- 画面左側ペインの[Compute Engine]から[VMインスタンス]を選択。
- 画面上部にある[インスタンスを作成]を選択。
- 画面下部に[IDとAPIへのアクセス]という項目がありサービスアカウントを選択できるセレクトボックスがあるので、先ほど作成したサービスアカウントを選択します。サービスアカウントを選択したらその他の項目には任意の値を入力し[作成]を選択。
数分待つとインスタンスが作成されます。
ライブラリをインストール
インスタンスが作成できたら、動作検証のためphp
とcomposer
をインストールします。
composer
を使ってライブラリをインストールするので、まずはphp
をインストールしてその後composer
をインストールします。
https://getcomposer.org/download/
$ sudo apt-get update && sudo apt-get install -y php
$ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
$ php -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
$ php composer-setup.php
$ php -r "unlink('composer-setup.php');"
$ sudo mv composer.phar /usr/local/bin/composer
$ which composer
/usr/local/bin/composer
google-cloud-phpをインストール
composer
を使ってgoogle/cloud-storage
をインストールします。
https://github.com/googleapis/google-cloud-php/tree/master/Storage
composer
実行時に下記のエラーが発生したのでgit
を先にインストールしておきます。
[RuntimeException]
git was not found in your PATH, skipping source download
$ sudo apt-get install -y git
$ sudo composer require google/cloud-storage
検証
Cloud Storageにファイルをアップロードするコードを書いて、コードと環境変数にクレデンシャル情報を設定しないで動作するか試してみます。Google Cloud PHP
ライブラリはクレデンシャルをコード → 環境変数 → GCEインスタンス
の順に探しにいきます。
https://github.com/googleapis/google-cloud-php/blob/master/AUTHENTICATION.md#project-and-credential-lookup
下記のコードを用意してCloud Storageにアクセスできるか試してみます。
<?php
require_once 'vendor/autoroad.php';
use Google\Cloud\Storage\StorageClient;
$storage = new StorageClient();
$bucket = $storage->bucket('bucket-name');
$bucket->upload(fopen('file.txt', 'r'));
実行してみます。
$ php index.php
Cloud Storage内のバケットにfile.txt
があれば成功です。サービスアカウントのロールを「Storage オブジェクト閲覧者」に変更したらどうなるかも確認してみます。ロールの変更は[IAMと管理]の[IAM]から行います。ロールの変更をインスタンスに反映するために、インスタンスをリセットします。インスタンスがリセットされたら再度 PHP を実行してみると、
PHP Fatal error: Uncaught Google\Cloud\Core\Exception\ServiceException: {"error":{"code":403,"message":"gcs-access@xxx.iam.gserviceaccount.com does not have storage.buckets.get access to the Google Cloud Storage bucket.","errors":[{"message":"gcs-access@xxxx.iam.gserviceaccount.com does not have storage.buckets.get access to the Google Cloud Storage bucket.","domain":"global","reason":"forbidden"}]}} in /var/www/html/vendor/google/cloud-core/src/RequestWrapper.php:368
storage.buckets.get
の権限がなくてアクセスできなくなりました。ストレージオブジェクト閲覧者の権限は、
- resourcemanager.projects.get
- resourcemanager.projects.list
- storage.objects.get
- storage.objects.list
なので、storage.buckets.get
に対しては権限がないので正しく動いていることが確認できました。
参考