GKE で稼働している Atlantis で Azure に OIDC 認証を行う
目標
GKE 上で稼働している Atlantis で Azure のリソースを操作するために OIDC 認証する方法をまとめます。
はじめに
Terraform の CD ツールの 1 つとして Atlantis というツールが存在します。
このツールを利用することで GitHub の PR などから Terraform を実行できます。
他のツールとは異なり、 PR をマージする前に Terraform を実行することで main
ブランチ上では常に正常な状態なコードが管理されることになります。
また、 Atlantis 側でロック機構や、ポリシーチェック機能を備えておりチーム開発での利用にも適しています。
この Atlantis ですが、便利な反面、色々なクラウドリソースを操作するため強力な権限を持ちがちです。
そのため ODIC 認証のような安全な認証方式を利用することが推奨されます。
今回の記事では GKE 上で稼働している Atlantis が Azure 上のリソースを操作するための権限を OIDC 認証経由で取得するまでの方法を解説します。
前提
Atlantis は v0.27.1
を利用しています。
GitHub との接続は GitHub App を利用しています。
Azure への認証するところまでを目標としているため、実際の Azure provider の利用方法などは記載していません。
手順
Azure App を登録する
Azure ポータルからアプリケーションを登録します。
Name
に適当な名前を設定します。
Supported account types
は Accounts in this organizational directory only (XXX only - Single tenant)
を選択します。
作成後 Overview 画面から Application (client) ID
/ Directory (tenant) ID
をコピーしておきます。
Azure App に OIDC の設定を行う
まずは Atlantis を稼働している GKE から OIDC 用の情報を集めます。
GKE クラスタの ODIC 用の Issure URL は以下の情報から構成されます。
https://container.googleapis.com/v1/projects/< GCP プロジェクト名 >/locations/< GKE クラスタが稼働しているリージョン or ゾーン >/clusters/< GKE クラスタ名 >
先ほど作成した Azure App の詳細画面に戻ります。
Client credentials
の Add a certificate or secret
から OIDC 用の情報を登録します。
項目をそれぞれ入力していきます。
Federated credentials
タブから Add credential
をクリックします。
フォームに以下の情報を記載します。
-
Federated credential scenario
:Kubernetes accessing Azure resources
-
Cluster issuer URL
:GKE クラスタの OIDC 用の Issuer URL
-
Namespace
:Atlantis が稼働している GKE Namespace
-
Service account name
:Atlantis が利用している GKE ServiceAccount
-
Audience
:GKE クラスタの OIDC 用の Issuer URL
Atlantis で利用する Azure provider の設定を行う
今回は以下の provider を利用します。
Provider 用環境変数
まずは provider に必要な以下の環境変数を Azure ポータルからコピーします。
ARM_CLIENT_ID
/ ARM_SUBSCRIPTION_ID
/ ARM_TENANT_ID
OIDC 用環境変数
GKE 上で稼働している Pod が利用している ServiceAccount 用のトークンのファイルパスを以下の環境変数を用いて設定します。
ARM_OIDC_TOKEN_FILE_PATH
この環境変数に設定するファイルパスには一工夫する必要があります。
デフォルトでは GKE は /var/run/secrets/kubernetes.io/serviceaccount/token
に ServiceAccount 用のトークンが格納されています。
しかし Azure へ OIDC 認証する場合にはこちらのトークンは利用できません。
Azure への OIDC 認証する際のトークンは有効期限が 1 日以下のものを利用する必要があります。
GKE がデフォルトで発行する ServiceAccount 用のトークンは有効期限が 1 年に設定されているため以下のようなエラーとなります。
External OIDC Provider token must have a lifetime of less than or equal to 1.01:00:00.
そのため、デフォルトで発行されるトークンとは別に有効期限が短く設定されるトークンを利用します。
以下のように projected volume を利用することで ServiceAccount 用のトークンに有効期限を設定しながらボリュームマウントできます。
以下の例では 50 分の有効期限を持ったトークンを azure-token
という名前で volume を作成しています。
volumes:
- name: azure-token
projected:
defaultMode: 420
sources:
- serviceAccountToken:
expirationSeconds: 3000
path: token
上記で作成した volume を volumeMounts
で Pod にマウントします。
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/azure-token
name: azure-token
ARM_OIDC_TOKEN_FILE_PATH
にはここでマウントしたパスを設定します。
上記の場合は /var/run/secrets/kubernetes.io/azure-token/token
を設定します。
以上の設定することで GKE 上で稼働している Atlantis から OIDC 認証を用いて Azure へアクセスできます。
Discussion