GCP スキルバッジをもらおう ~5.サービス アカウントと役割: 基礎〜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>」の一部として公開しています。
２５日にスキルバッジが獲得できるペースで公開していきます。
:::

##ラボの情報
ラボの名前：[サービス アカウントと役割: 基礎](https://www.cloudskillsboost.google/focuses/1038?parent=catalog)
所要時間：1時間15分　レベル：Fundamental　必要なクレジット:5
概要：
サービスアカウントについて実戦形式で学ぶ。
サービスアカウントを作って、役割を付与する。
サービス アカウントを使用して、インスタンスから BigQuery の一般公開データセットに対してクエリを実行する。

##学習に役立つリンク
参考URL：
[IAM](https://cloud.google.com/iam/docs/overview#concepts_related_to_identity)
[サービスアカウント](https://cloud.google.com/iam/docs/service-accounts#the_service_account_user_role)
[ロール](https://cloud.google.com/iam/docs/understanding-roles)

関連するSDK：
[IAM/Service-accounts](https://cloud.google.com/sdk/gcloud/reference/iam/service-accounts)
[projects/add-iam-policy-binding](https://cloud.google.com/sdk/gcloud/reference/projects/add-iam-policy-binding)

##ラボの実施記録

##サービス アカウントとは
学習メモ:writing_hand:：サービス アカウントとは
* 個々のエンドユーザーではなく、アプリケーションや仮想マシン（VM）に属している特別な Google アカウント
* アプリケーションはサービス アカウントを使用して、サービスの Google API を呼び出す
*  サービスがアクセスできるリソースが制御される
*  サービス アカウントは、アカウント固有のメールアドレスで識別される
*  プロジェクトでは最大 98 個のサービス アカウント

##サービス アカウントの種類
学習メモ:writing_hand:：サービス アカウントには３つの種類がある
**ユーザー管理サービスアカウント**
 新しいCloudProject作成時に、ComputeEngineとAppEnginが組み込まれているとデフォルトでひとつずつSAが作成される。 メールアドレスで識別される
ComputeEngine のサービスアカウント
```PROJECT_NUMBER-compute@developer.gserviceaccount.com```
AppEngineのサービスアカウント
 ```PROJECT_ID@appspot.gserviceaccount.com```

クラウドコンソールで見るとこんな感じ
ハンバーガー＞IAM&Admin>ServiceAccount
![Compute.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365170/aa8421c1-65dc-1e4b-10b2-0d9c1e5cb40e.png)
**Google管理サービスアカウント **
Google が作成し所有しているもので、さまざまな Google サービスを表す。
各アカウントには GCP プロジェクトにアクセスするための IAM の役割が自動的に付与されている。
<BR>
**Google API サービス アカウント**
```PROJECT_NUMBER@cloudservices.gserviceaccount.com```
 自動的に内部 Google プロセスを実行するように設計されており、GCP Console の [サービス アカウント] セクションには一覧表示されません。
 デフォルトでは、このアカウントには自動的にそのプロジェクトの編集者の役割が付与され、GCP Console の [IAM] セクションに表示されます。 このサービス アカウントは、プロジェクトが削除された場合にのみ削除されます。 

##サービス アカウントを作成して管理する
####サービスアカウントを作成する
次のコマンドを実行する。
「my-sa-123」アカウントを作成する。

```
$gcloud iam service-accounts create my-sa-123 --display-name "my service account"
```
```
Created service account [my-sa-123]
$
```
####サービスアカウントへ役割を付与する
学習メモ:writing_hand:：ロールの削除について
>IAM の役割を付与する際には、サービス アカウントをリソースまたは ID として扱うことができます。

>アプリケーションでは、Google Cloud Platform サービスに対する認証のためにサービス アカウントを ID として使用します。たとえば、Compute Engine 仮想マシン（VM）をサービス アカウントとして実行している場合は、プロジェクト（リソース）のサービス アカウント（ID）に編集者の役割を付与できます。

>それに加えて、誰が VM を起動できるかを制御することもできます。そのためには、サービス アカウント（リソース）に対する serviceAccountUser の役割をユーザー（ID）に付与します。

#####リソースに対する役割をサービス アカウントに付与する
次のコマンドを実行する。
この例では、前の手順で作成したサービスアカウント「my-sa-123」に基本の役割である「editor」ロールを付与している

```
$gcloud projects add-iam-policy-binding $DEVSHELL_PROJECT_ID \
    --member serviceAccount:my-sa-123@$DEVSHELL_PROJECT_ID.iam.gserviceaccount.com --role roles/editor
```
```
Updated IAM policy for project [qwiklabs-gcp-04-7df290d63571].
bindings:
- members:
  - serviceAccount:qwiklabs-gcp-04-7df290d63571@qwiklabs-gcp-04-7df290d63571.iam.gserviceaccount.com
  role: roles/bigquery.admin
- members:
・・・
・・・
- members:
  - user:student-03-8c15819f804e@qwiklabs.net
  role: roles/viewer
etag: BwXTfjTi_Ug=
version: 1
$
```

##役割を理解する
学習メモ:writing_hand:：役割＝ロールについて
先のラボでもやりましたが、ここでもおさらい。
ロールとは権限の組み合わせ
ロールはユーザー、グループ、またはサービス アカウントに付与します
ロールには基本のロールと、カスタムロールがあります。
基本のロールは次の４つ。

（「[ロールについて](https://cloud.google.com/iam/docs/understanding-roles#primitive_roles)」より抜粋）

| ロール名 | 説明 |
|:-:|:--|
|roles/viewer   | フォルダ、組織、Cloud IAM ポリシーなど、プロジェクトの階層を参照するための読み取りアクセス権。このロールには、プロジェクトのリソースを表示する権限は含まれていません。  |
|roles/editor   | すべての閲覧者権限と、状態を変更するアクション（既存のリソースの変更など）に必要な権限。  |
|roles/owner   | すべての編集者権限と、以下のアクションを実行するために必要な権限。プロジェクトおよびプロジェクト内のすべてのリソースの権限とロールを管理する。プロジェクトの課金情報を設定する。  |
|roles/browser   | フォルダ、組織、Cloud IAM ポリシーなど、プロジェクトの階層を参照するための読み取りアクセス権。このロールには、プロジェクトのリソースを表示する権限は含まれていません。  |


##クライアント ライブラリを使用して、サービス アカウントから BigQuery にアクセスする
####サービスアカウントを作成する
#####方法A：GoogleConsoleから
ラボで指示されているのはこちら。
ハンバーガー＞IAM＆Admin＞ServiceAccountで「＋CREATE SERVICE ACCOUNT」
￼
ラボの指示通りに入力する
Roleは、「＋ADD　ANOTHER　ROLE」をクリックして、
bigquery.Userとbigquery.dataViewerを指定する。
￼![Create service account.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365170/69b3685d-6423-bda2-9ea0-26051ce9c3c4.png)
￼
CloudConsoleで作成したアカウントを確認
￼![Description.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365170/ce0696b9-ca28-a26f-a473-294ee2ab1549.png)

#####方法B:CloudShellから
せっかくAPIを覚えたので使ってみたい（こちらでもスコアはあがりました）。

サービスアカウントを作る

```$gcloud iam service-accounts create bigquery-qwiklab --display-name "bigquery-qwiklab"
```
```
Created service account [bigquery-qwiklab].
```

サービスアカウントにロール（役割）を付与する。
？？一度に複数できないのかな。

```
$gcloud
 projects add-iam-policy-binding $DEVSHELL_PROJECT_ID \
    --member serviceAccount:bigquery-qwiklab@$DEVSHELL_PROJECT_ID.iam.gserviceaccount.com --role roles/bigquery.user
```
```
Updated IAM policy for project [qwiklabs-gcp-04-7df290d63571].
bindings:
- members:
・・・
・・・
- members:
  - user:student-03-8c15819f804e@qwiklabs.net
  role: roles/viewer
etag: BwXTfmws1Rg=
version: 1
$
```

```
$gcloud projects add-iam-policy-binding $DEVSHELL_PROJECT_ID \
    --member serviceAccount:bigquery-qwiklab@$DEVSHELL_PROJECT_ID.iam.gserviceaccount.com --role roles/bigquery.dataViewer
```
```
Updated IAM policy for project [qwiklabs-gcp-04-7df290d63571].
bindings:
- members:
・・・
・・・
- members:
  - user:student-03-8c15819f804e@qwiklabs.net
  role: roles/viewer
etag: BwXTfnCRQhE=
version: 1
$
```

CloudShellで確認する。

```
$ gcloud iam service-accounts describe bigquery-qwiklab@$DEVSHELL_PROJECT_ID.iam.gserviceaccount.com
```

```
displayName: bigquery-qwiklab
email: bigquery-qwiklab@qwiklabs-gcp-04-3d7536c0f5af.iam.gserviceaccount.com
etag: MDEwMjE5MjA=
name: projects/qwiklabs-gcp-04-3d7536c0f5af/serviceAccounts/bigquery-qwiklab@qwiklabs-gcp-04-3d7536c0f5af.iam.gserviceaccount.com
oauth2ClientId: '102331073109247295364'
projectId: qwiklabs-gcp-04-3d7536c0f5af

uniqueId: '102331073109247295364'
$
```
####VMインスタンスを作成する
ラボの指示通りに実施。
ServiceAccountを指定するところは、自分がラボで作ったServiceAccountを指定すること。
![Identity and API access.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365170/9999d3bc-f912-154d-d798-8518cd48cbbb.png)
￼
####サンプルコードを GCE インスタンスに配置する
ラボの指示どおりに実施。
作成したComputeEngineにSSHで接続する
（ハンバーガー>VM Instance>VMの一覧から「bigquery-instance 」のSSHボタンをクリックする）
ラボの手順通りにコマンドを貼れば問題なし

パッケージ リストをダウンロードして更新します。

```
$sudo apt-get update
```

Python 仮想環境を使用して、パッケージのインストール先をシステムとは別の場所にします。

```
$sudo apt-get install -y virtualenv
$virtualenv -p python3 venv
```

仮想環境をアクティブにします。

```
$source venv/bin/activate
```

必要な依存関係をインストールします。

```
$sudo apt-get install -y git python3-pip
$pip install google-cloud-bigquery
$pip install pyarrow
$pip install pandas
```

サンプルの Python ファイルを作成します。

```
echo "
from google.auth import compute_engine
from google.cloud import bigquery
credentials = compute_engine.Credentials(
    service_account_email='YOUR_SERVICE_ACCOUNT')
query = '''
SELECT
  year,
  COUNT(1) as num_babies
FROM
  publicdata.samples.natality
WHERE
  year > 2000
GROUP BY
  year
'''
client = bigquery.Client(
    project='YOUR_PROJECT_ID',
    credentials=credentials)
print(client.query(query).to_dataframe())
" > query.py
```

次のコマンドでプロジェクト ID を query.py に追加します。

```
sed -i -e "s/YOUR_PROJECT_ID/$(gcloud config get-value project)/g" query.py
```

次のコマンドでサービス アカウントのメールアドレスを query.py に追加します。

```
sed -i -e "s/YOUR_SERVICE_ACCOUNT/bigquery-qwiklab@$(gcloud config get-value project).iam.gserviceaccount.com/g" query.py
```

正しく更新されたか確認する
```YOUR_SERVICE_ACCOUNT```と```project='YOUR_PROJECT_ID’```の部分が変更されていること

```
cat query.py
```

作成したサービスアカウント「bigquery-qwiklab」でBigQueryにクエリを実行できるかどうかの確認

```
$python query.py
```
```
   year  num_babies
0  2003     4096092
1  2004     4118907
2  2008     4255156
3  2006     4273225
4  2002     4027376
5  2005     4145619
6  2001     4031531
7  2007     4324008
$
```

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