【GCP/GCE】VMインスタンスに自動デプロイ


VMインスタンスに自動デプロイを実装す際、想定と少し違ったので備忘録として記載しておきます。
※GCPへの認証部分だけです

手順

  1. サービスアカウト作成
  2. サービスアカウントユーザーを適応
  3. CircleCI実装

サービスアカウント作成

下記の権限でCircleCI用のサービスアカウントを作成しました。

サービスアカウントユーザーを適応

ここが少し厄介でした。
上記のサービスアカウントだけでデプロイしてみると、下記のエラーが出ます。

The user does not have access to service account '{PROJECT_NUMBER}[email protected]'.
User: 'circleci-for-auto-deploy@*************.iam.gserviceaccount.com'.
Ask a project owner to grant you the iam.serviceAccountUser role on the service account

つまり自分たちが作成したサービスアカウント(User)が、サービスアカウント ([email protected])にアクセスする権限がないということでした。

解決策

Compute Engine default service accountで管理されている
{PROJECT_NUMBER}[email protected]に上記で作成したサービスアカウントをサービスアカウントユーザーとして追加する必要があります。

google cloud platform - gcloud: The user does not have access to service account "default" - Stack Overflow
サービス アカウントへの役割の付与  |  Cloud IAM のドキュメント  |  Google Cloud

デフォルトのサービスアカウント

プロジェクトで Compute Engine API が有効になっていると、デフォルトで Compute Engine サービス アカウントが作成されます。

上記の{PROJECT_NUMBER}[email protected]は、APIを有効にすると自動で作成されるみたいですね。
サービス アカウント  |  Cloud IAM のドキュメント  |  Google Cloud

サービスアカウントユーザー

サービス アカウント ユーザーのロール(roles/iam.serviceAccountUser)は、プロジェクト内のすべてのサービス アカウントのプロジェクト単位またはサービス アカウント単位で指定できます。

ユーザーでもサービスアカウントでも追加できるようです。

特定のサービス アカウントでユーザーにサービス アカウント ユーザーのロールを付与した場合、ユーザーにはそのサービス アカウントのみへのアクセス権が付与されます。

今回CircleCIのサービスアカウントをGCEのサービスアカウント に付与するので、こちらに該当するようです。
サービス アカウント  |  Cloud IAM のドキュメント  |  Google Cloud

なんでわざわざこんな面倒なことをするのか。

なぜサービスアカウントユーザーが必要なのかというところです。
デフォルトのアカウントをCircleCIのサービスキーにするという方法もあるけれども、それじゃあ権限が大きすぎるから適切ではないし。

デフォルトのサービスアカウントを削除して、GCE用のサービスアカウントを新しく作り直すという方法も思いついたけど、そもそもデフォルトのサービスアカウントを削除することがよくないみたい。
Google Compute Engineで作成されるdefault service accountの注意点 - あめも

うーん、GCEへの自動デプロイの際はみなさんどのようにしているんだろうか。。。。。

CircleCIの実装

認証は下記のような感じで実装した。

make gcp-auth
GCLOUD_AUTH = gcloud auth

## 認証
gcp-auth:
  echo -n ${GCE_SERVICE_KEY} | base64 --decode > gcloud-service-key.json
  @$(GCLOUD_AUTH) activate-service-account --key-file gcloud-service-key.json
  @$(GCLOUD_AUTH) configure-docker