GCE インスタンスにSSHするのに必要なロール

# 概要

GCEインスタンス構築の際に最低限 何のロールがあればいいのか試行錯誤したので、備忘録として書きます。

OWNER権限を持たないGoogleアカウントやサービスアカウントでGCEインスタンスにSSHするために必要なロールを想定します。各々で環境の差異で権限を継承している場合もあるので、構築対象の環境についてよく確認することを推奨します。

# 付与したロール

基本的に基本ロールやカスタムロールでなく、事前定義ロールを利用することを想定します。
必要なロールを設定するスコープ毎に書いていきます。
ロールは付与から反映まで1,2分かかるような気がするので注意が必要でした。

ロールが付与されているかの確認方法は以下のコマンドを利用しました。

`gcloud compute ssh <インスタンス名> --project <プロジェクト名> --zone <ゾーン名>  --tunnel-through-iap` 

## プロジェクトレベル

**Compute ネットワーク閲覧者（roles/compute.networkViewer）**

公式リファレンスではインスタンスレベルでの付与はベータ機能らしく、実際に試すとエラーになったためプロジェクトレベルで設定しました。

### ロールが付与されていないときのエラー

```
❯ gcloud compute ssh <インスタンス名> --project <プロジェクト名> --zone <ゾーン名>  --tunnel-through-iap
ERROR: (gcloud.compute.ssh) Could not fetch resource:
 - Required 'compute.projects.get' permission for 'projects/<プロジェクト名>'
```

## インスタンスレベル

**Compute OS 管理者ログイン（roles/compute.osAdminLogin）** or
**Compute OS Login（roles/compute.osLogin）**

管理者ログインだとパスワードなしでsudoできる権限となりますので注意してください。

### ロールが付与されていないときのエラー

```
❯ gcloud compute ssh <インスタンス名> --project <プロジェクト名> --zone <ゾーン名>  --tunnel-through-iap
<SSH時のユーザ名>@compute.<インスタンス ID>:: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

Recommendation: To check for possible causes of SSH connectivity issues and get
recommendations, rerun the ssh command with the --troubleshoot option.

gcloud compute ssh <インスタンス名> --project=<プロジェクト名> --zone=<ゾーン名> --troubleshoot

Or, to investigate an IAP tunneling issue:

gcloud compute ssh <インスタンス名> --project=<プロジェクト名> --zone=<ゾーン名> --troubleshoot --tunnel-through-iap

ERROR: (gcloud.compute.ssh) [/usr/bin/ssh] exited with return code [255].
 ```

**IAP で保護されたトンネル ユーザー（roles/iap.tunnelResourceAccessor)**

外部IPなしでインスタンスを構築した際は必要となります。

### ロールが付与されていないときのエラー

```
❯ gcloud compute ssh <インスタンス名> --project <プロジェクト名> --zone <ゾーン名>  --tunnel-through-iap
ERROR: (gcloud.compute.start-iap-tunnel) Error while connecting [4033: 'not authorized'].
kex_exchange_identification: Connection closed by remote host

Recommendation: To check for possible causes of SSH connectivity issues and get
recommendations, rerun the ssh command with the --troubleshoot option.

gcloud compute ssh <インスタンス名> --project=<プロジェクト名> --zone=<ゾーン名> --troubleshoot

Or, to investigate an IAP tunneling issue:

gcloud compute ssh <インスタンス名> --project=<プロジェクト名> --zone=<ゾーン名> --troubleshoot --tunnel-through-iap

ERROR: (gcloud.compute.ssh) [/usr/bin/ssh] exited with return code [255].
```

## GCEインスタンスに割り当てるサービスアカウントレベル

**サービス アカウント ユーザー (roles/iam.serviceAccountUser)**

SSHしようとするユーザは、GCEインスタンスに割り当てるサービスアカウントに対してこのロールが必要です。
デフォルトサービスアカウントやGoogleグループにプロジェクトレベルですでに付与していると普段意識しないため忘れがちです（筆者はこれを忘れていたため、結構ハマりました...）。

また補足ですが、デフォルトサービスアカウントについては以下の記事がわかりやすく参照になりました。
[GCEインスタンスの権限設定について - Qiita](https://qiita.com/atsumjp/items/152197b5039fe78c98ba)


### ロールが付与されていないときのエラー（roles/compute.osLoginと同じ）

```
❯ gcloud compute ssh <インスタンス名> --project <プロジェクト名> --zone <ゾーン名>  --tunnel-through-iap 
<SSH時のユーザ名>@compute.<インスタンス ID>: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

Recommendation: To check for possible causes of SSH connectivity issues and get
recommendations, rerun the ssh command with the --troubleshoot option.

gcloud compute ssh <インスタンス名> --project=<プロジェクト名> --zone=<ゾーン名> --troubleshoot

Or, to investigate an IAP tunneling issue:

gcloud compute ssh <インスタンス名> --project=<プロジェクト名> --zone=<ゾーン名> --troubleshoot --tunnel-through-iap

ERROR: (gcloud.compute.ssh) [/usr/bin/ssh] exited with return code [255].
```

## その他

SSH以外にインスタンスの編集などもする場合は、追加で **roles/compute.instanceAdmin**などのロールが必要となります。

権限以外の注意としては以下が挙げられれます。

- インスタンスのメタデータ`enable-oslogin`を`TRUE`に設定しておくこと
- TCP 22番ポートからアクセスを許可するファイアウォールルールを作成し、インスタンスにタグで指定しておくこと

# まとめ

GCEインスタンスへのSSHに必要なロールについてまとめました。
権限は必要最低限に調整したいものの１つずつ確認しながら試すのはなかなか面倒だと思い、今回執筆に至りました。この記事が誰かの役に立てれば幸いです。

# 参考

- [ロールについて | IAM のドキュメント | Google Cloud](https://cloud.google.com/iam/docs/understanding-roles#compute-engine-roles)