Workload Identityを使ってサービスアカウントキー無しでTerraform cloud からのGoogle Cloud デプロイ環境をつくる

## 背景

Google Cloud Platform (GCP) 上でデプロイ環境を構築する際、通常はサービス アカウントキーを使用して Terraform などのインフラストラクチャ管理ツールを認証します。セキュリティを向上させ、鍵の管理を簡素化するために、Workload Identity を使用してサービス アカウント キーの発行を回避する方法があります。Workload Identityを使ってSAキー無しでTerraform cloud からのデプロイ環境をつくってみます。

## 事前準備
GCPとTerraform Cloudのセットアップが必要になります。詳細は割愛しますが、以下の流れで事前準備を行います。

### GCPアカウントのセットアップ
1. GCPアカウントを持っていない場合、GCP公式ウェブサイトでアカウントを作成します。
2. プロジェクトを作成し、必要なAPIやサービスを有効にします。
3. Google Cloud SDKをインストールして、コマンドラインからGCPにアクセスできるようにします。

### Terraform Cloudへのアクセス
1.Terraform Cloudのアカウントを作成またはログインします。アカウントがない場合は、[Terraform Cloudのウェブサイト](https://www.hashicorp.com/products/terraform)から登録できます。
2.Terraform Cloudのワークスペースを作成し、プロジェクトに関連付けます。

## 手順

以下は、Terraform Cloud を使用して GCP 上で Workload Identity をセットアップし、サービス アカウント キーなしでデプロイ環境を構築する基本的な手順です。

### Google CloudでWorkload Identityプールとプールプロバイダを作成する。
1. 「IAMと管理」にある、「Workload Identity連携」を選択すると、以下の画面がでてくるので、使ってみるを押す。
![スクリーンショット 2023-09-30 22.24.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12787/1b6dc779-ac5e-609b-db73-3fd7741eea91.png)

2. ウィザードが表示されるので、IDプールを作成するの中の、名前とプールIDを入力して続行を押す。
![スクリーンショット 2023-09-30 22.26.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12787/3f288f37-3a3a-4a9f-3008-cc8c8194da18.png)


3. プールにプロバイダを追加する箇所で、プロバイダの選択を`OpenID Connect (OIDC)`を選択して、プロバイダ名と、プロバイダIDを入力する。また、発行元（URL）には、`https://app.terraform.io`を入力するして、続行を押す。
![スクリーンショット 2023-09-30 22.30.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12787/cea60644-30f4-7929-63a6-e1e966f0b1e3.png)

4. プロバイダの属性を構成する箇所で、以下の属性マッピングを行う。

| Google | OIDC |
|--|--|
|google.subject|assertion.sub|
|attribute.terraform_full_workspace|assertion.terraform_full_workspace|
|attribute.terraform_workspace_id|assertion.terraform_workspace_id|

:::note warn
検証のため今回は属性条件を入力してないが、terraformのOrganization idやworkspace名などでCEL条件を入力することで認証を制限する。
:::

![スクリーンショット 2023-09-30 22.34.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12787/e242e8c1-58ff-5069-b8b0-4c8d847fff19.png)

作成したプロバイダが表示される。
![スクリーンショット 2023-09-30 22.35.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12787/d74cf231-562c-24d1-81c1-ff7632ea8a90.png)

### サービスアカウントの作成と権限付与
[サービスアカウントを作成](https://cloud.google.com/iam/docs/service-accounts-create?hl=ja)して、以下コマンドにて、IAMバインディングを追加します。

```
gcloud iam service-accounts add-iam-policy-binding [id]@[プロジェクトID].iam.gserviceaccount.com \
 --role="roles/iam.workloadIdentityUser" \
 --member="principalSet://iam.googleapis.com/projects/[プロジェクト番号]/locations/global/workloadIdentityPools/[プールID]/attribute.terraform_workspace_id/[terraformのworkspace ID]"
```
コマンド実行後、プールの詳細の接続済みサービスアカウントに表示されます。
![スクリーンショット 2023-09-30 23.00.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12787/9978339b-1ded-8129-ef04-452904f386de.png)


### Terraform Cloud のセットアップと実行

1. Terraform Cloud のWorkspace の Variables で3つの変数を定義する。

| key | value |
|--|--|
|TFC_GCP_PROVIDER_AUTH|true|
|TFC_GCP_RUN_SERVICE_ACCOUNT_EMAIL|[サービスアカウント]|
|TFC_GCP_WORKLOAD_PROVIDER_NAME|[Workload Identityプロバイダ名(*1)(*2)]|

(*1) 形式は`projects/[プロジェクト番号]/locations/global/workloadIdentityPools/[プールID]/providers/[プロバイダID]`
(*2) Sensitiveにチェックをいれる

![スクリーンショット 2023-09-30 23.05.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12787/b4b9bb3b-0c20-b4f2-4e71-2877f30fdc1b.png)

2.　Terraform コードを作成し、Terraform Cloud を使用してデプロイを実行します。Terraform は Workload Identity を介して GCP にアクセスし、サービス アカウント キーを使用せずにデプロイを行います。デプロイが成功するとTerraform Cloud上で以下のように表示されます。

![スクリーンショット 2023-09-30 23.56.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12787/34836065-6fbe-c48b-4ba2-ba4b06bc7177.png)