誤削除したデフォルト GSA の復元方法

# はじめに

GCP では各マネージドサービスを利用する際の権限管理としてサービスアカウント（GSA：Google Service Account）を用います。
GSA には、予め Google 側で用意しているデフォルト GSA と、利用者が自由に作成できる GSA が存在します。
一般に、前者のデフォルト GSA はプロジェクト作成時点や API を有効化した際に自動的に作成されます。
デフォルト GSA は削除してしまうと、その GSA を利用するマネージドサービスにアクセスできなくなってしまいます。
今回は、誤って削除してしまったデフォルト GSA の復元方法について紹介したいと思います。

# GSA：GCP Service Account

GCP では、各サービスアカウントに IAM 権限が割り当てられており、メールアドレスと紐付けられています。
具体的には、デフォルト GSA の場合は `@[サービス毎に異なる].gserviceaccount.com`、利用者が作成した GSA には `@[GCP_PROJECT_ID].iam.gserviceaccount.com` というドメインがそれぞれ付与されます。

前でも述べている通り、デフォルト GSA は Google 側で用意してくれているサービスアカウントです。
デフォルト GSA はコマンド一つで簡単に削除できてしまう上、誤って消してしまうと、その GSA を利用する全てのサービスへの接続が拒否されてしまうため慎重に管理する必要があります。
また、他のサービスアカウントをデフォルト GSA に変更することはできません。

ここで、Compute Engine のデフォルト GSA を例に挙げます。
通常、Compute Engine API を有効化すると、`[GCP_PROJECT_ID]-compute@developer.gserviceaccount.com` というデフォルト GSA が作成されます。
誤って削除してしまった場合、サービスアカウントタブから Compute Engine のデフォルト GSA が消えます。

![before-restore.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705806/23f7b8d4-a6fa-4498-8508-b63f6e8c19bd.png)

この状態で、例えば、Compute Engine API を内部で使用している GKE クラスタを作成しようとすると以下のようなエラーが発生します。（Terraform の場合）

```shell
│ Error: googleapi: Error 400: Failed precondition: failed to check status for "[GCP_PROJECT_ID]-compute@developer.gserviceaccount.com"; Verify if principal exists and is valid.
│ Details:
│ [
│   {
│     "@type": "type.googleapis.com/google.rpc.RequestInfo",
│     "requestId": "0xb8abb9dbe2ce55ea"
│   }
│ ]
│ , failedPrecondition
│
│   with google_container_cluster.gke,
│   on main.tf line 1, in resource "google_container_cluster" "gke":
│    1: resource "google_container_cluster" "gke" {
│
╵
```

`[GCP_PROJECT_ID]-compute@developer.gserviceaccount.com` プリンシパルが存在しないため、インスタンスを作成する際の API リクエストに失敗していることが分かります。

# デフォルト GSA の復元方法

デフォルト GSA を誤って削除してしまった際の復元方法について紹介します。

<u>**削除から 30 日以内であることが前提となります。**</u>

30 日を経過してしまった場合、正規の方法では復元することができないため、諦めてプロジェクトそのものを再作成するか、もしくは Google サポートケースを尋ねてください。

## gcloud CLI のインストール

[こちら](https://cloud.google.com/sdk/docs/install) を参考に `gcloud` コマンドをインストールしておいてください。

## beta サブコマンドの追加

```shell
$ gloud components install beta
$ gloud components update
```

`beta` サブコマンドでは、一般的な `gcloud` コマンドに加え、ベータ版として提供されているいくつかの機能を利用することができます。

## 削除ログの調査

Cloud Logging から対象の GSA の削除ログを確認します。

```shell
"DeleteServiceAccount"
resource.type="service_account"
resource.labels.email_id="[GCP_PROJECT_ID]-compute@developer.gserviceaccount.com"
```

みたいな条件を指定してあげれば引っかかると思います。

![deleted-log.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705806/4e67e7bd-251b-4e1b-995a-a992ca3c77f1.png)

ログを見つけたら、サービスアカウントの UID（OAuth 2.0 Client ID）を確認します。
この例では、`112520103360638233798` となります。

## 復元（リストア）

以下の `beta` サブコマンドを使用して GSA を復元します。

```shell
$ gloud beta iam service-accounts undelete [サービスアカウント UID]
```

```shell
$ gcloud beta iam service-accounts undelete 112520103360638233798
restoredAccount:
  email: [GCP_PROJECT_ID]-compute@developer.gserviceaccount.com
  etag: MDEwMjE5MjA=
  name: projects/[GCP_PROJECT_ID]/serviceAccounts/[GCP_PROJECT_ID]-compute@developer.gserviceaccount.com
  oauth2ClientId: '112520103360638233798'
  projectId: [GCP_PROJECT_ID]
  uniqueId: '112520103360638233798'
```

これで復元完了です。

![after-restore.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705806/2fe50dcc-fa54-4039-a2a5-07b53634aece.png)

# まとめ

今回は誤って削除してしまったデフォルト GSA の復元方法について紹介しました。
手元コンソールから復元できるのは、<u>**削除から 30 日 以内**</u> となります。

GCP プロダクトの中には一度削除してしまうと復元が困難なものや、復元されても有効化されるまでに期間を要するものが存在するため、削除処理は慎重に行なってください。