こんにちは、グローバルシステム本部の岡崎です。
今日はGCPのWorkload Identityを使ってAWSのRoleとGCPのサービスアカウントを連携させる方法について紹介していきます。
動機と解決法
- サービスアカウントのシークレットキーjsonをEC2上に置くのやだなー(何かの拍子に流出とかしたらめんどいなー)
- アクセス元のバッチがAWSにあるんだから、asumerole的なことがAWSとGCPをまたいでできれば便利なんだけどなー
という動機から、表題の通り Workload Identity を使って、AWS IAM Role と GCP Service Account を連携させました。
Workload Identity連携 とは?
Workload Identity 連携は、キーなしの新しいアプリケーション認証メカニズムであり、オンプレミス、AWS、Azure で実行するワークロードは、外部 ID プロバイダ(IdP)と連携し、サービス アカウント キーを使用せずに Google Cloud リソースを呼び出すことができます。
(引用:キーなしの API 認証 – サービス アカウント キーを必要としない Workload Identity 連携によるクラウド セキュリティの向上)

今回は AWS 上にあるIAM-Roleを持つEC2インスタンスからGCP上のBigQueryにアクセスします。
この際に、SecretKeyを持つJsonは使用せず、Workload Identiry を使用して、EC2に紐づくIAM-RoleでGCP上のサービスアカウントになりすまして、BigQueryへアクセスします。
実際の手順紹介
実際にやったときネットにあまり情報がなく、公式ドキュメントもかなり分かりづらかったので、備忘録的に手順を書いてみます。
AWSのアプリでGCPのリソースを使う場合はこんな感じになります的な内容になります。
(2022/11/10 に画面をキャプチャしています)
AWS側
EC2にIAM-Roleを割り当て
とりあえず、EC2にIAM-Roleを割り当てます。
今回は [embulk-gcp-access] というロールをつけてみます。
このロールは通常の EC2 Role として作ったロールです。変わったことは何もしていません。

GCP側
Workload Identity プール作成
Workload Identity プールを作ります。
a.IAM 管理 → Workload Identity プール 画面から[プールを作成]を選択し新しいプールを作ります。
名前を入れて続行。
b.プロバイダに [AWS] を選択、プロバイダ名と、AWSアカウントIDを入力します。
アカウントIDはAWSのアカウントの12桁の数値です。入力したら続行。
c.プロバイダの属性は何も変更せず続行します。
プロバイダにAWSを選択した場合、デフォルトのマッピングがすでに入力されていますので、そのまま保存します。
これで、プロバイダとプールの設定は完了です。
ちなみにマッピングの内容はこちらになります。

サービスアカウントを追加
Workload Identity pool にアクセスを許可するサービスアカウントを追加します。
d.[アクセス許可] をクリック
e.アクセス元AWSのRoleを限定したい場合は以下のように入力します。
特にRokeを限定しない場合、ラジオボタンを上の[プール内のすべてのID]を選択します。
aws_role の属性値に入力する値は
“arn:aws:sts::<<awsアカウントid>>:assumed-role/<<Role名>>”\
で、保存します。
f.構成ファイル(json)をダウンロードします。
このjsonファイルはこれまで使用していたcredencialファイルの代わりに使用します。中を見るとわかると思いますが、secret keyが存在しません。secret key は sts(Security token service), Workload identity を介して短時間のみ使用可能な secret key が作られるようになります。
(アプリ内では意識する必要がなくなります)
中身はこんな感じです。(xxxxxの部分は念の為伏せてあります)
secret key がなくて安心(笑)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ "type": "external_account", "audience": "//iam.googleapis.com/projects/xxxxx/locations/global/workloadIdentityPools/embulk-aws-access-pool/providers/embulk-aws-access-provider", "subject_token_type": "urn:ietf:params:aws:token-type:aws4_request", "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/embulk-aws-access@xxxxx.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" } } |
g.これで設定は完了です。
最後にサービスアカウントのプリンシパルに以下のような背亭が追加されていることを確認します。この設定で、AWSからの特定のロールからの権限の借用ができるようになります。
1 |
principalSet://iam.googleapis.com/projects/<<gcp project id>>/locations/global/workloadIdentityPools/embulk-aws-access-pool/attribute.aws_role/arn:aws:sts::123456789012:assumed-role/embulk-gcp-access |
以上となります。
終わりに
これでマルチクラウド環境で、よりセキュアな権限の管理が実現できます。
ぜひご利用を検討してみてください。
secret key をサーバに置かなくて済むので、漏洩問題を気にしなくて済むようになりました。
今後はGCPを使っているアプリ全てに展開をしていこうと思います。