【AWS】【GCP】AWSとGCP間のキーなし認証を試みる(2) AWS→GCP

# 1. はじめに
本編は以下記事の続編になります。

https://qiita.com/hyj624117615/items/ca4a8bc8c269098aaeef

前の記事ではAWS側のロールを経由して、GCP側からAWSへキーなし認証を実現することができました。

本編ではその逆で、AWS側からGCPへキーなし認証を実現していきます。
AWSとGCP間はよいお友達笑笑

# 2. 構成図
GCP側のWorkload IdentityがAWS側のIAMとマッピングします。
マッピング後、Service Accountと連携します。Service Account側でアクセスできるロールを制御しています。
AWS側のEC2が、IAM Roleを利用して、Workloan Identity→Service Account経由し、最終的にCloud Storageを作ることになります。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/f8a6e66d-03f3-491f-0a57-39d2a2ee37df.png)

# 3. AWS側構築
１．IAM Roleを作成
- ユースケース：EC2
- 権限：`AmazonSSMFullAccess`（EC2にSSMエージェントがあり、セッションマネージャー接続のため）
![截屏2022-08-22 23.34.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/081efab3-1b76-be43-13ab-2d06e22dea82.png)

２．EC2を作成
- OS：Amazon Linux 2
- ミドルウェアのインストール：
```text
#google-cloud-skdをインストール
$ curl https://sdk.cloud.google.com | bash

#上記インストール完了後に、下記のコマンドを実行
$ source .bash_profile

#下記のコマンドを叩いて、gcloudのバージョンが表示されていればOK
$ gcloud version
Google Cloud SDK 398.0.0
bq 2.0.75
core 2022.08.12
gcloud-crc32c 1.0.0
gsutil 5.12
```

# 4. GCP側構築
１．APIs へのアクセスの有効化
[こちらのURLを開き](API有効化：https://console.cloud.google.com/flows/enableapi?apiid=iam.googleapis.com%2Ccloudresourcemanager.googleapis.com%2Ciamcredentials.googleapis.com%2Csts.googleapis.com&%3Bredirect=https%3A%2F%2Fconsole.cloud.google.com&hl=ja&_ga=2.37108000.1836426031.1659312089-1250514199.1649206381)、APIを有効化しておきます。
- Identity and Access Management (IAM) API
- Cloud Resource Manager API
- IAM Service Account Credentials API
- Security Token Service API

２．サービスアカウントを作成。
`サービスアカウントを作成`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/ac6faf08-1147-2361-d33c-59b9db68f851.png)

３．`サービスアカウント名`と`サービスアカウントID`を入力の上、`作成して続行を押下`を押下します。
![截屏2022-08-22 23.57.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/db244d5d-07b0-d0a9-a559-f088989589cb.png)

４．Cloud Storage作成するため、ロールに`ストレージ管理者`権限を付与し、`完了`を押下します。
![截屏2022-08-22 23.57.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/50715df3-d800-64bb-d368-d25d329ba5da.png)

５．`IAMと管理`配下の`Workload Identity`に遷移し、ワークロードプロバイダーとプールを作成します。
![截屏2022-08-22 23.42.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/cbf61fbe-b5dd-30cd-84c6-d41d09673d64.png)

６．以下を入力します。
- `プロバイダの選択`に`AWS`を選択
- `プロバイダ名`に設定したい名前を入力
- `AWSアカウントID`にAWSの12桁アカウントIDを入力
![截屏2022-08-22 23.44.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/bf623efd-8ecd-e8f5-32c9-8ba1c4850600.png)

７．こちらは自動的にAWSの認証情報を、GCP側とマッピングすることになりますので、基本は追加不要なので、`保存`ボタンをクリックします。
※詳細は[プロバイダの属性](https://cloud.google.com/iam/docs/workload-identity-federation?_ga=2.149382326.-1026012267.1661173300#mapping)にご参照ください。
![截屏2022-08-22 23.50.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/a543e68a-8864-cdd2-64e3-b197754b7875.png)

８．作ったプロバイダーを選択し、`GRANT ACCESS`を押下します。
![截屏2022-08-23 0.01.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/d452e88e-7e07-406d-6fce-51cabfffba35.png)

９．先ほど作成したサービスアカウントを選択して、`保存`をクリックします。
※今回テストのため、`プリンシパル`はすべてのIDを選択しているが、実際の業務要件によって、プリンシパルIDを絞ることができます。
![截屏2022-08-23 0.03.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/b505c768-8cbe-4429-6327-6a17ddb7d460.png)

１０．上記作成したプロバイダを選択の上、configファイル(json)をダウンロードします。
![截屏2022-08-23 0.05.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/d0052005-78e5-6ab9-3872-cd68c6a6ca95.png)

１１．jsonファイルの中身を見ていると、以下のような構成になっています。
```json
{
  "type": "external_account",
  "audience": "//iam.googleapis.com/projects/xxxxxxxxxxx/locations/global/workloadIdentityPools/aws-gcp-id-pool/providers/aws-provider-01",
  "subject_token_type": "urn:ietf:params:aws:token-type:aws4_request",
  "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/sa-allow-aws-access@creating-and-xxxxxxxxxxxxxx.iam.gserviceaccount.com:generateAccessToken",
  "token_url": "https://sts.googleapis.com/v1/token",
  "credential_source": {
    "environment_id": "aws1",
    "region_url": "http://169.254.169.254/latest/meta-data/placement/availability-zone",
    "url": "http://169.254.169.254/latest/meta-data/iam/security-credentials",
    "regional_cred_verification_url": "https://sts.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15"
  }
}
```

# 5. AWS上EC2での操作
１．上記のjsonファイルを、`vi`コマンドを利用して、EC2内に貼り付けしておきます。
```text
$ cat clientLibraryConfig-aws-provider-01.json
{
  "type": "external_account",
  "audience": "//iam.googleapis.com/projects/xxxxxxxxxxx/locations/global/workloadIdentityPools/aws-gcp-id-pool/providers/aws-provider-01",
  "subject_token_type": "urn:ietf:params:aws:token-type:aws4_request",
  "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/sa-allow-aws-access@creating-and-xxxxxxxxxxxxxx.iam.gserviceaccount.com:generateAccessToken",
  "token_url": "https://sts.googleapis.com/v1/token",
  "credential_source": {
    "environment_id": "aws1",
    "region_url": "http://169.254.169.254/latest/meta-data/placement/availability-zone",
    "url": "http://169.254.169.254/latest/meta-data/iam/security-credentials",
    "regional_cred_verification_url": "https://sts.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15"
  }
}
```
２．以下のコマンドを叩いて、認証を取り込みます。
```text
#コマンド
gcloud auth login --cred-file=[jsonファイル名] --project [GCPのプロジェクト]
#例：
gcloud auth login --cred-file=clientLibraryConfig-aws-provider-01.json --project xxxxxxxx
```

３．Cloud Storageを作成します。
```text
$ gsutil mb gs://skjdfkjsafjllsajglkXXXXX
Creating gs://skjdfkjsafjllsajglkXXXXX/...
$ gsutil ls
gs://skjdfkjsafjllsajglXXXXX/
```
上記Cloud Storageが作成されたことを確認できました。

# 6. GCP側トークンの取得仕組みについて
Workload IdendityはどうやってSTSトークン情報を取得してくるかというと、[公式ドキュメント](https://cloud.google.com/iam/docs/using-workload-identity-federation)は以下のように説明しています。
>Workload Identity プールとプロバイダを使用して、有効期間の短い認証情報を取得する方法について説明します。このプロセスは次のとおりです。
>1. 信頼できる ID プロバイダから認証情報を取得します。
>2. Security Token Service から取得したトークンと認証情報を交換します。
>3. Security Token Service のトークンを使用してサービス アカウントの権限を借用し、有効期間の短い Google アクセス トークンを取得します。

つまり、GCPからAWSのIAMに認証情報を取得し、その上、Security Token Service から取得したトークンと認証情報を交換します。交換後、Security Token Service のトークンを使用してサービス アカウントの権限を借用し、有効期間の短い Google アクセス トークンを取得することになります。


# 参考資料
１．キーなしの API 認証 - サービス アカウント キーを必要としない Workload Identity 連携によるクラウド セキュリティの向上

https://cloud.google.com/blog/ja/products/identity-security/enable-keyless-access-to-gcp-with-workload-identity-federation

２．AWS IAM Role を GCP から STS 認証で利用する設定例

https://www.qoosky.io/techs/30f7c61cfa

３．GCP Service Account を AWS から STS 認証で利用する設定例

https://www.qoosky.io/techs/fb1efc43bf

４．gcp-sa-to-aws-iam-role

https://github.com/cevoaustralia/gcp-sa-to-aws-iam-role/archive/master.zip