GCP スキルバッジをもらおう4.IAM のカスタムの役割〜Security & Identity Fundamentals

実際にラボを実施した際の記録を載せていきます。
学習の助けになったリンクや、後に見るための学習メモ、ちょっと迷った手順を書いていきます。
あと、コマンドも忘れたくないのでログしていきます。

* 学習の助けになったリンクは、「学習に役立つリンク」にまとめて書いてあります。
* 学習メモは:writing_hand:アイコンをつけてます。
* 迷った手順は箇条書きでつらつら書いてます。
実際の手順については、[Google Cloud Skills Boost](https://www.cloudskillsboost.google/)のラボの手順を参照してください。

クエスト「[Security & Identity Fundamentals](https://www.cloudskillsboost.google/quests/40)」のふたつめのラボです。
SkillBoostの始め方は記事「[GCP スキルバッジをもらおう　1Google Cloud Skill Boostをはじめよう](https://qiita.com/orange-tora/items/57d5fe3486f4c7e1a58a)」をどうぞ。

:::note info
この記事は「<a href="https://qiita.com/advent-calendar/2021/gcp-skill-boost-sif">GCP スキルバッジをもらおう！　〜Security & Identity Fundamentals Advent Calendar 2021</a>」の一部として公開しています。
２５日にスキルバッジが獲得できるペースで公開していきます。
:::

##ラボの情報
ラボの名前：[IAM のカスタムの役割](https://www.cloudskillsboost.google/focuses/1035?parent=catalog)
所要時間：1時間　レベル：Fundamental　必要なクレジット:5
概要：
カスタムの役割の作成、更新、削除をCloudSDKで実施する。

##学習に役立つリンク
参考URL：
[IAM](https://cloud.google.com/iam/docs/overview#concepts_related_to_identity)
[ロールについて](https://cloud.google.com/iam/docs/understanding-roles#primitive_roles)
関連SDK：
[IAM](https://cloud.google.com/sdk/gcloud/reference/iam)
[Role](https://cloud.google.com/sdk/gcloud/reference/iam/roles/)

##ラボの実施記録
###IAM のカスタムの役割について理解する
学習メモ:writing_hand:：役割＝ロール
ロールとは```権限```の組み合わせ
ロールは```ユーザー```、```グループ```、または```サービス アカウント```に付与します
ロールには```基本のロール```と、```カスタムロール```があります。

学習メモ:writing_hand:：権限
次の形式で表せられる。
```<service>.<resource>.<verb>```
たとえば、
```compute.instances.list``` 権限を持つユーザーは所有する Google Compute Engine インスタンスを一覧表示できる。

権限は REST メソッドと一対一で対応している。
GCP の各サービスには、各 REST メソッドに対して関連付けられている権限があり、メソッドを呼び出すには、呼び出し元にその権限が必要。

###必要な権限と役割
学習メモ:writing_hand:：カスタムの役割を作成するための権限
呼び出し元に```iam.roles.create```権限が必要

* プロジェクトの場合
デフォルトでは、プロジェクト オーナーのみが新しい役割を作成できる。オーナーは、同じプロジェクトの他のユーザーに「IAM 役割の管理者」の役割（```roles/iam.roleAdmin```）を付与して管理する

* 組織の場合
組織管理者のみが「組織の役割の管理者」の役割（```roles/iam.organizationRoleAdmin```

* カスタムの役割を表示するだけで管理はできない。
IAM セキュリティ レビュー担当者の役割（```roles/iam.securityReviewer```）

###カスタムの役割を作成する準備を行う
####リソースで使用可能な権限を表示する

```
$gcloud iam list-testable-permissions //cloudresourcemanager.googleapis.com/projects/$DEVSHELL_PROJECT_ID
name: appengine.applications.create
stage: GA
---
name: appengine.applications.get
stage: GA
---
...
...
customRolesSupportLevel: TESTING
name: appengine.memcache.flush
stage: BETA
---
$
```
####リソースに対して付与できる役割を表示する
ラボでは、こちらの手順は後ろですが、
メタデータの確認をする際に指定するロールネームを確認したいので先にこちらを実行します。

```
$gcloud iam list-grantable-roles //cloudresourcemanager.googleapis.com/projects/$DEVSHELL_PROJECT_ID
---
description: Access to edit and deploy an action
name: roles/actions.Admin
title: Actions Admin
---
...
...
---
description: Gives Cloud Workflows service account access to managed resources.
name: roles/workflows.serviceAgent
title: Cloud Workflows Service Agent
$

```

####役割メタデータを取得する
構文

```
$gcloud iam roles describe [ROLE_NAME]
```

[ROLE_NAME]にいれるものは先に```list-grantable-roles```で確認したロールの```name```を指定できます。
ラボの手順にある「roles/editor」などで可。

```
$ gcloud iam roles describe roles/dialogflow.aamAdmin
description: An admin has access to all resources and can perform all administrative
  actions in an AAM project.
etag: AA==
includedPermissions:
- dialogflow.agents.export
- dialogflow.agents.get
...
...
- resourcemanager.projects.list
name: roles/dialogflow.aamAdmin
stage: GA
title: AAM Admin
$
```

###カスタムの役割を作成する
新しいカスタムの役割を作成するには、```gcloud iam roles create``` コマンドを使用する。
このコマンドは次の 2 つの方法で使用できる。

* 役割の定義が含まれる YAML ファイルを使用する```--file```で指定。
* フラグを使用して役割の定義を指定する 
（カスタムの役割を作成する場合は``` --organization [ORGANIZATION_ID] ```フラグまたは ```--project [PROJECT_ID] ```フラグを使用して、組織レベルまたはプロジェクト レベルのどちらに適用するかを指定する必要があります）。

ラボでは、プロジェクト レベルでカスタム役割を作成します。

####YAML ファイルを使用してカスタムの役割を作成する
#####構文

```
title: [ROLE_TITLE]
description: [ROLE_DESCRIPTION]
stage: [LAUNCH_STAGE]
includedPermissions:
- [PERMISSION_1]
- [PERMISSION_2]
```
学習メモ:writing_hand:：

| プレースホルダ名 | 説明 | 例 |
|:-:|:--|:--|
|[ROLE-TITLE]|役割のわかりやすいタイトル|Role Viewer|
|[ROLE_DESCRIPTION]|役割についての短い説明|My custom role description|
|[LAUNCH-STAGE] |リリースのライフサイクルにおける役割の段階|ALPHA、BETA、GA|
|includedPermissions|カスタムの役割に含める権限（複数可）のリストを指定| iam.roles.get|

#####演習で使うYamlを次の内容で作成して保存します。
nanoを使う場合、保存して閉じるときは、ctrl+X>Y>Enterの順に押せばOK。
「Role Editor」という名前の役割を作成している。
ファイル名：role-definition.yaml
内容：

```
title: "Role Editor"
description: "Edit access for App Versions"
stage: "ALPHA"
includedPermissions:
- appengine.versions.create
- appengine.versions.delete
```

#####作成したyamlファイルを指定して権限を作成する
次のコマンドを実行する。

```
$gcloud iam roles create editor --project $DEVSHELL_PROJECT_ID \
--file role-definition.yaml
```

####フラグを使用してカスタムの役割を作成する
次のコマンドを実行する。
「Role Viewer」という名前の役割を作成している。
```
$gcloud iam roles create viewer --project $DEVSHELL_PROJECT_ID \
--title "Role Viewer" --description "Custom role description." \
--permissions compute.instances.get,compute.instances.list --stage ALPHA
```

####カスタムの役割を一覧表示する
作成した役割を確認する。
次のコマンドを実行する。

```
$gcloud iam roles list --project $DEVSHELL_PROJECT_ID
---
description: Edit access for App Versions
etag: BwVxLgrnawQ=
name: projects/[PROJECT_ID]/roles/editor
title: Role Editor
---
description: Custom role description.
etag: BwVxLg18IQg=
name: projects/[PROJECT_ID]/roles/viewer
title: Role Viewer
```

CloudConsoleでも確認してみた。
ハンバーガー > IAM＆Admin > Role　で一覧表示。そこで、作ったカスタムロールの名前「Viewer」でフィルタしてみる。
![Enter property name or value.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365170/e444bdf6-525f-efc3-deec-784281bb5ff7.png)
できてる！

###既存のカスタムの役割を編集する
学習メモ:writing_hand:：競合について
>たとえば、プロジェクトの 2 人のオーナーが、1 つの役割に対して相反する変更を同時に行うと、一部の変更が失敗する可能性があります。
>
>Cloud IAM では、カスタムの役割の etag プロパティを使用してこの問題を解決します。このプロパティは、カスタムの役割が最後のリクエスト以降に変更されているかどうかを確認するために使用されます。etag 値を保持している Cloud IAM にリクエストを出すと、Cloud IAM はリクエスト内の etag 値と、カスタムの役割に関連付けられている既存の etag 値を比較します。etag 値が一致した場合にのみ変更を書き込みます。

役割の編集は```gcloud iam roles update```コマンドを使う。こちらもYamlとフラグの２パターンでできる。
```describe ```コマンドは役割の定義を返し、その定義には役割の現在のバージョンを一意に特定する etag 値が含まれます。役割の同時変更が上書きされないように、更新された役割の定義に etag 値を指定する必要があります。

####YAML ファイルを使用してカスタムの役割を更新する
#####更新用のYAMLファイルを作る
etag値をとりたいので、まず```describe```コマンドをつかって値を取得する。

```
gcloud iam roles describe editor --project $DEVSHELL_PROJECT_ID
```
出力をコピーします。
次の内容で新しいyamlファイルを作成して保存します。

ファイル名：new-role-definition.yaml
内容：
describeコマンドの内容をコピーし、```includedPermissions:```セクションに権限を二つ追加する。

```
- storage.buckets.get
- storage.buckets.list
```

こんな感じになる。

```
description: Edit access for App Versions
etag: BwVxIAbRq_I=
includedPermissions:
- appengine.versions.create
- appengine.versions.delete
- storage.buckets.get
- storage.buckets.list
name: projects/[PROJECT_ID]/roles/editor
stage: ALPHA
title: Role Editor
```
#####作成したyamlファイルでロールの更新をおこなう
作成したyamlファイルを指定して、```gcloud iam rloes update```コマンドを実行する。

```
$gcloud iam roles update editor --project $DEVSHELL_PROJECT_ID \
--file new-role-definition.yaml
```

####フラグを使用してカスタムの役割を更新する
学習メモ:writing_hand:：フラグの内容
>次のフラグを使用して、権限を追加または削除できます。
>
>--add-permissions [PERMISSIONS]: 権限（複数の場合はカンマで区切る）を役割に追加します。
>--remove-permissions [PERMISSIONS]: 権限（複数の場合はカンマで区切る）を役割から削除します。
>または、--permissions [PERMISSIONS] フラグを使用して新しい権限を指定することもできます。権限のカンマ区切りのリストを指定すると、既存の権限のリストが置き換えられます。

次のコマンドを実行する

```
gcloud iam roles update viewer --project $DEVSHELL_PROJECT_ID \
--add-permissions storage.buckets.get,storage.buckets.list
```

###カスタムの役割を無効化する
--stage フラグを使用して役割を DISABLED に設定する。
次の gcloud コマンドを実行して viewer 役割を無効にする。

```
$gcloud iam roles update viewer --project $DEVSHELL_PROJECT_ID \
--stage DISABLED
```

###カスタムの役割を削除する
学習メモ:writing_hand:：ロールの削除してもしばらくは論理削除状態
>カスタムの役割を削除するには、gcloud iam roles delete コマンドを使用します。削除された役割は無効になり、新しい IAM ポリシー バインディングの作成に使用できなくなります。

>役割が削除された後、既存のバインディングは残りますが無効になります。7 日以内であれば、役割の削除を取り消すことができます。7 日間後に役割の完全削除プロセスが開始され、そのプロセスが 30 日間続きます。37 日後に、役割 ID は再び使用可能になります。

学習メモ:writing_hand:：段階的な削除
>注: 役割を段階的に廃止する場合は、role.stage プロパティを DEPRECATED に変更し、deprecation_message を設定して、使用する必要がある代替の役割や詳細情報の入手場所をユーザーに知らせます。

次のコマンドを実行する

```
gcloud iam roles delete viewer --project $DEVSHELL_PROJECT_ID
```

クラウドコンソールでも確認してみる。
Statusが変わっている。
![Enter property name or value.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365170/25897a53-af29-f895-344f-fc69fe42901b.png)


###カスタムの役割の削除を取り消す
>7 日以内ならば、役割を元に戻すことができます。削除された役割は DISABLED 状態にあります。以下のように --stage フラグを更新することで再び利用可能にすることができます。
次のコマンドを実行する。

```
gcloud iam roles undelete viewer --project $DEVSHELL_PROJECT_ID
```

##お疲れさまでした
これでラボの手順は終了。
右上のスコア表示が「100/100」になっていることを確認して、「ラボを終了」を押します。