AWSのCloudShellからGCPのWorkload Identity連携しようとしたけどダメだった話

# はじめに
GCPのサービスを外部から使う際、サービスアカウントキーを使って動かしていました。
しかし先日のGCPのイベントでWorkload Identityという機能を使えば、AWSとセキュアに連携が取れると知りました。

https://cloudonair.withgoogle.com/events/google-cloud-day-digital-22?talk=d1-sec-07

AWSのClooudShellから出来ないか試してみましたが、うまくいかなかったので、その旨記載しておこうと思います。

(2022.06.01追記)AWSのCloudShellがサポートされていない旨、GCPの公式に記載ありました。

https://cloud.google.com/iam/docs/using-workload-identity-federation#generate-automatic

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/2a5ecd2f-0eaf-de0e-7df8-f87edd0c8e07.png)

公式はちゃんと読みましょう…


# 結論
- AWSのCloudShellからは、GCPのWorkload Identity連携はうまくいかない
    - Cloud9からはできました。
        - インスタンスにIAMロールを紐づける必要あり

# 参考
知ったのはGCPイベントのアカツキさんのセッションでしたが、ブログのほうに詳しくありました。

https://hackerslab.aktsk.jp/2021/12/09/000429

Cloud9で動かす際の参考は以下

https://tech.nri-net.com/entry/2021/07/01/111020

# やったこと

## GCP側

「AWSのアカウントと連携します」という設定のWorkload Identityプールというのを作ります。また、そこで使わせるサービスアカウントを指定します。

### サービスアカウント作成
コンソールから「IAMと管理」-「サービスアカウント」-「サービスアカウントの作成」と遷移します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/d3290a3d-0355-ff78-1a7f-15dfd97d1261.png)

サービスアカウント名に任意の名前を入力。（IDは自動で入力されます）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/ad4309b4-28e3-0514-fa2d-6ed14afbbb72.png)

権限はオーナーにしましたが、本運用では必要十分にしておくのがよいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/1dd75251-d350-7e0d-0e59-b0c958d45ff9.png)

これで完了を押して作成します。


### Workload Identity設定
コンソール上でサービスアカウントの下で、Workload Identityの設定が行えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/c699098e-ec9b-e642-52da-941e9bcb2804.png)

説明を読んで「使ってみる」。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/9286d424-073e-ec53-7387-0c8daea4db9e.png)

プールの名前を決めます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/8e0eb595-7f08-072d-e78c-7bf5a2b24cc2.png)

プロバイダの設定で、「AWSの、特定のアカウントと連携」の設定を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/85f74137-748a-d100-0a3a-6de60fd7e0bd.png)

次の属性は、特に変更せず保存しました。詳細は参考のアカツキさんのページにあります。

### サービスアカウント紐づけ
作ったプールに、サービスアカウントを紐づけます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/d9d8cc70-a461-7e92-9534-7bf4b625771f.png)

先程作成したサービスアカウントを指定します。
IDに制限をかけることもできますが、今回はすべてのIDを設定しています。設定例はアカツキさんのページにて。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/0fdccfa6-7b0e-8d4b-3479-50b789528fe2.png)

以下の画面で「構成をダウンロード」を押します。ダウンロードされるファイルを、AWS側で使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/62c4ce38-62c1-cccb-edbc-a4ab065dcdd7.png)


## AWS側

### gcloudを展開
CloudShell上にあまりモノは入れたくないので、公式を参考にインストールしない形でgcloudを動かすようにしました。

https://cloud.google.com/sdk/docs/install?hl=ja

```
# ダウンロード
$ curl -O https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-385.0.0-linux-x86_64.tar.gz

# 展開して移動
$ tar -xf google-cloud-cli-385.0.0-linux-x86_64.tar.gz
$ cd google-cloud-sdk/bin/
```


### （事前確認）認証情報保存場所の、現時点の確認
この後セットする認証情報が保存される場所を、あらかじめチェックしておきます。以下の公式を参考にしました。

https://cloud.google.com/sdk/docs/authorizing?hl=ja#finding_your_credential_files

```
$ ./gcloud config
（略）
User Config Directory: ~~~~~~~~~~~~
（略）
```

自分の場合は`/home/cloudshell-user/.config`に保存されるようでした。最初の時点ではpowershellの設定のみでした。（powershellも動かせるんですね。。。）
```
$ ll /home/cloudshell-user/.config
total 4
drwxr-xr-x 2 cloudshell-user cloudshell-user 4096 Feb  8  2021 powershell
```

### 認証ファイルをセット
ここで先ほどダウンロードした認証ファイルをCloudShelにアップロードします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/578fa67c-32df-c310-931e-d885abf32fe3.png)

```
# 認証ファイルをわかりやすいところに移動
mv /home/cloudshell-user/clientLibraryConfig-awstogcp.json ./

# 認証
$ ./gcloud auth login --cred-file=clientLibraryConfig-awstogcp.json 

Authenticated with external account credentials for: [aco-for-aws-connect-20220524@xxxxxxxxxxxx.iam.gserviceaccount.com].
Your current project is [None].  You can change this setting by running:
  $ gcloud config set project PROJECT_ID
```

### （うまくいかない）実行
認証もセットできたので、実際にコマンドを打ってみたのですが、エラーになってうまくいきませんでした。
```
$ ./gcloud iam roles list

ERROR: gcloud crashed (TransportError): HTTPConnectionPool(host='169.254.169.254', port=80): Max retries exceeded with url: /latest/meta-data/iam/security-credentials (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0xfffffffffff>: Failed to establish a new connection: [Errno 22] Invalid argument'))

```
エラーに出てくる`169.254.169.254`というIPを調べてみると、インスタンスの情報を色々教えてくれるようです。

https://lance104.hatenablog.jp/entry/2014/03/09/235221

ですがこれをClooudShellから実行するとエラーになりました。
```
$ curl http://169.254.169.254/latest/meta-data/instance-id/
curl: (7) Couldn't connect to server
```
この情報が取得できないためか、CloudShellからWorkload Identity連携はダメでした。

### （うまくいく）Cloud9を使う方法
Cloud9だと、IAMロールをインスタンスに付与しておけば、先に説明した流れで実行できるようになりました。
方法は参考に挙げましたNRIさんの方のページをご確認ください。
`curl http://169.254.169.254/latest/meta-data/instance-id/`を実行すると、インスタンス名を返してくれました、こちらではうまくいくようです。

## 削除
gcloudをインストールしているわけではないので、解凍したファイルを削除します。
また、認証情報が（私の場合は）`/home/cloudshell-user/.config/gcloud/`というディレクトリ下に作られたので、ディレクトリごと削除しました。

GCP側の削除はコンソールから「プールを削除」になります。必要に応じてサービスアカウントも削除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/c087b04f-05d7-1230-337c-4e876e75f695.png)


# おわりに
今回はAWSのClooudShellからWorkload Identity連携に失敗した内容を紹介しました。
AWSのCloudShellからgcpが触れると色々便利と考えたのですが、本運用で使うこともないと思われるので、あまり詳細に調べていません。
同じようなことを試される方の参考になれば幸いです。

また、「実はできます」という話ありましたら教えてください。