EC2上のRubyでWorkloadIdentity連携を用いてBigQueryを呼び出す

不動産・住宅情報サービス[LIFULL HOME'S](https://www.homes.co.jp/)を運営しております、株式会社LIFULLでデジタルマーケティング領域を担当しております、Ystgです。

# はじめに
この記事は[LIFULL Advent Calendar 2023](https://qiita.com/advent-calendar/2023/lifull)の6日目の記事です。

# Workload Identity連携のおさらい
Workload Identity連携とは、Google Cloudリソースへのアクセス権を別のクラウドのワークロードに付与できるしくみのことでした。
（詳しくは[去年のLIFULL Advent Calenderの5日目の記事](https://qiita.com/s13bp5-ystg/items/69e13b6fd1850d631264)を参照ください）

# Rubyの場合
Google公式の[認証情報の構成を使用してGoogleCloudにアクセスする](https://cloud.google.com/iam/docs/workload-identity-federation-with-other-clouds?hl=ja#use_the_credential_configuration_to_access)を第2項を参照いただくと、rubyがないことにお気づきかと思います。rubyはサポートされていない？

## googleauth1.5以降
色々調べた結果、googleauthの1.5以降なら対応しているとのこと。（[参考にしたサイト](https://hackerslab.aktsk.jp/2023/03/24/180041)）
ですが、下記のような注意点が。。
> ただし注意点として、googleauth 1.5.0 の時点では IMDSv2にうまく対応できないバグがあるようです。EC2で試す際は IMDSv1 が使えるように設定し、認証情報構成ファイル作成の際にも --enable-imdsv2 をつけない (つけてしまった場合はJSONから imdsv2_session_token_url キーを削除する )必要があります。
([AWS上の fluentd から BigQuery への認証に Workload Identity を利用する](https://hackerslab.aktsk.jp/2023/03/24/180041)から引用）

と、とりあえずやってみるか。

任意のディレクトリで下記のファイルを作成しました。
```ruby:bq_access.rb
require 'google/cloud/bigquery'

class HelloBq
    def initialize
      @project_id = 'myproject'
      @bq_prj = Google::Cloud::Bigquery.new(project: @project_id)
    end

    def run
      table_name = 'tbl_20231205'
      ds = @bq_prj.dataset('mydataset')
      tbl = ds.table(table_name)
      if tbl.nil?
        p "no table: ${table_name}"
      else
        p tbl.table_id
        p tbl.headers
      end
    end
end

if __FILE__ == $0
  instance = HelloBq.new
  instance.run
end
```

googleauthは1.8が最新のようなので1.8を投入。
```ruby
source 'https://rubygems.org'

gem 'google-cloud-bigquery', '~> 1.45'
gem 'googleauth', '~> 1.8'
```

実行用のシェルスクリプト。
```bash:run_bq_access.sh
base_dir='.'
# auth configuration file
file_name='clientLibraryConfig.json'

export GOOGLE_APPLICATION_CREDENTIALS=${base_dir}/${file_name}

if ! [ -e vendor/bundle/ruby ]; then
    bundle install --path=vendor/bundle
fi

bundle exec ruby bq_access.rb
```

実行すると実行エラー。
```bash
./run_bq_access.sh
#(略)
vendor/bundle/ruby/2.6.0/gems/googleauth-1.8.1/lib/googleauth/external_account/aws_credentials.rb:111:in `imdsv2_session_token': IMDSV2 token url must be provided (RuntimeError)
```

あれ？ IMDSV2じゃないとダメって言われてる。
前回の記事で作ったJSON(clientLibraryConfig.json)を利用していたのですが、IMDSV1になってしまうのか。そしてさきほどの注意点が気になる。バグはすぐに直っているといいけどなぁ。

## 構成ファイルの更新
とりあえず、AWS IMDSV2に対応したJSONを作成する必要があるので、作成します。
```bash
gcloud iam workload-identity-pools create-cred-config \
    projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID \
    --service-account=SERVICE_ACCOUNT_EMAIL \
    --aws \
    --enable-imdsv2 \
    --output-file=FILEPATH.json
```
PROJECT_NUMBER, PROVIDER_ID, SERVICE_ACCOUNT_EMAILは適宜読み替えてください。
FILEPATHは任意のファイル名にします。(今回は`clientLibraryConfigV2.json`にしました)
肝は`--enable-imdsv2`です。当たり前か。

ファイルが作成されたら、それをさきほどのソースを書いたディレクトリに配置します。
再度実行。
```bash
 ./run_bq_access.sh 

"tbl_20231205"
[:column1, :column2, :column3]
```
成功しました！

つまり、IMDSV2で構成ファイルを作成すればOK！（バグは直ってたんだね！）

## 補足
google-cloud-bigqueryの依存関係でgoogleauthはインストールされるので、Gemfileは下記で十分でした。

```ruby:Gemfile
gem 'google-cloud-bigquery', '~> 1.45'
```