LoginSignup
0
1

環境変数を使わないで、Workload Identity連携でAWSからGCPを操作

Posted at

はじめに

GCPを、AWSからセキュアに操作するWorkload Identityという機能について、以前に何度か記事にしました。

その際、

  1. 認証情報が記述された構成ファイルを保存して
  2. 環境変数GOOGLE_APPLICATION_CREDENTIALSにファイルパスを記載する

という方法で行っていました。

今回は、"ファイル保存&環境変数"という方法を使わず、コードの中で実現する方法になります。

概要

以下のページにサンプルがありました。

json_config_info = json.loads("<ファイルの中身の文字列>")

# jsonの認証設定を読み込む
credentials = aws.Credentials.from_info(json_config_info)

# スコープを設定
## スコープに設定する内容は以下より
## https://developers.google.com/identity/protocols/oauth2/scopes
scoped_credentials = credentials.with_scopes([''])

# プロジェクト、認証を指定してクライアント作成
client = <任意のGCPサービス>.Client(
    project="<対象のGCPプロジェクトID>",
    credentials=scoped_credentials
)

またこの方法は、EC2などに限定されます。メタデータURLが異なるためとのことですので、他の環境で実装する方はご注意ください。

参考

やったこと

AWSの準備

  • Cloud9を使いました
  • アカウントIDをGCP側で設定しますので、要メモ

GCPの準備

IAM Service Account Credentals APIを有効化しておきます。無効のままでも後で有効化するようURLに誘導されます。

image.png

以降はCloudShellからやっていきます。

各種変数定義

許可する権限は、最も強いroles/ownerにしています。適宜変更ください。
変数セット直後に、変数の中身をechoしています。

# 先のAWSアカウントIDをセット
AWS_ACCOUND_ID="123456789012" && echo $AWS_ACCOUND_ID

# 以下、適宜変更していく
POOL="hogehoge-pool" && echo $POOL
PROVIDER="hogehoge-aws-provider" && echo $PROVIDER
SERVICE_ACCOUNT="access-from-hogehoge-aws" && echo $SERVICE_ACCOUNT
DESCRIPTION="Access from hogehoge env on AWS with workload identity federation" && echo $DESCRIPTION
BIND_ROLE="roles/owner" && echo $BIND_ROLE

# 以下二つは`gcloud projects list`で確認する
PROJECT_NUMBER="123456789012" && echo $PROJECT_NUMBER
PROJECT_ID="hogehpge-pj" && echo $PROJECT_ID

サービスアカウントの作成

削除用のコマンドも併記しておきます。

gcloud iam service-accounts create $SERVICE_ACCOUNT --description="${DESCRIPTION}"
# 削除時は以下
# gcloud iam service-accounts delete "${SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com"

Workload Identity Poolの作成

gcloud iam workload-identity-pools create $POOL --location="global"
# 削除時は以下
# gcloud iam workload-identity-pools delete $POOL --location="global"

Workload Identity Providerの作成

gcloud iam workload-identity-pools providers create-aws $PROVIDER \
  --location="global" \
  --workload-identity-pool=$POOL \
  --account-id=$AWS_ACCOUND_ID

# 削除
# gcloud iam workload-identity-pools providers delete $PROVIDER \
#  --location="global" \
#  --workload-identity-pool=$POOL

サービスアカウントに権限付与

# 権限の付与
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role=$BIND_ROLE

# 確認
gcloud projects get-iam-policy $PROJECT_ID

# 権限の削除
# gcloud projects remove-iam-policy-binding $PROJECT_ID \
#  --member="serviceAccount:${SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
#  --role=$BIND_ROLE

Workload Identity Poolとサービスアカウントの連携

AWS側に使用を許可する範囲を任意にしています。必要に応じて制限してください。

# 一旦全権限で付与してみる
gcloud iam service-accounts add-iam-policy-binding "${SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role="roles/iam.workloadIdentityUser" \
  --member="principalSet://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${POOL}/*"

# 確認
gcloud iam service-accounts get-iam-policy "${SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com"

# 削除
# gcloud iam service-accounts remove-iam-policy-binding "${SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
#  --role="roles/iam.workloadIdentityUser" \
#  --member="principalSet://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${POOL}/*"

認証構成ファイルの取得

gcloud iam workload-identity-pools create-cred-config \
  "projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${POOL}/providers/${PROVIDER}" \
  --service-account="${SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --aws \
  --output-file="config-aws-provider.json"

Pythonで操作(cloud9から)

環境は依然と同様に、virtualenvで仮想化環境で行いました。

mkdir aws-to-gcp
cd aws-to-gcp

# virtualenv上で環境構築
virtualenv a2genv
source a2genv/bin/activate

(a2genv) $ pip install google-cloud-storage

以前はCloud9のtemporary credentialを無効にして、IAMロールをアタッチしていましたが、今回やったときは特に必要なく実行できました。
このあたりのところは以前の状態もハッキリしないので、試す際はご留意ください。

Pythonスクリプトは以下です。今回はGCSのバケット一覧を取ってくる例です。

connect_gcp.py
from google.cloud import storage
import json
from google.auth import aws

json_config_info = json.loads("""
< 先ほどGCPで作成したファイルの中身をここにコピペ >
""")

credentials = aws.Credentials.from_info(json_config_info)
scoped_credentials = credentials.with_scopes(
    ['https://www.googleapis.com/auth/devstorage.full_control'])

storage_client = storage.Client(project="<対象のGCPプロジェクトID>",credentials=scoped_credentials)
print(list(storage_client.list_buckets()))

おわりに

今回はWorkload Identity連携の、別方法を記事にしました。
認証情報をコードに直に書いていますが、実際に使う場合はParameter Storeで保存してそこから取得する、という方法がセキュアかと思います。

どなたかのお役に立てれば幸いです。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1