Azure DevOpsサービスコネクションのService Principal クライアント シークレットをWorkload Identity Federationに置き換える

Azure DevOpsのCICDサービスであるPipelinesを利用していたところ突然Pipelinesがエラーとなってしまい処理が中断していました。
エラーを確認したところ、Azure Pipelinesにおけるサービスコネクションの有効期限が切れていることが原因でした。

サービスコネクションとは、Azure Pipelinesから外部サービスやリソースに接続するための認証メカニズムです。これにより、パイプラインは必要な権限を持って外部サービスと安全に通信することができます。サービスコネクションは、資格情報や接続文字列などの機密情報を安全に管理し、パイプライン実行時に必要に応じて使用することができるものとなっており、Azure PipelinesでCICD構築の際には基本的に必要な要素となっています。

こちらのサービスコネクションの仕様上の有効期限が最長2年間であるため、有効期限が切れてパイプラインが失敗するということになっていたようです。

# サービスコネクションの有効期限更新

有効期限が切れてしまった場合は期限の更新をすれば良いため（本来は切れる前に更新をすべき）、Azure DevOps上のサービスコネクション管理画面を確認したところ、見慣れないメッセージを発見しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293404/e1a40439-5521-048e-8ff1-07e7c43d03e3.png)

>Convert your existing Azure Resource Manager service connections which use secrets to authenticate to leverage Workload identity federation instead, for improved security and simplified maintenance.
>認証にシークレットを使用する既存のAzure Resource Managerサービス接続を、代わりにWorkload Identity Federationを活用するように変換することで、セキュリティが向上し、メンテナンスが簡素化されます。

どうやら従来のサービスコネクションのクライアントシークレットとは別にWorkload Identity Federationというものを使用することでシークレットの生成・保存・更新が不要になるため、運用負荷を軽減できるようです。

Microsoftとしても従来のものよりWorkload Identity Federationを現在は推奨しているようです。


# 既存のサービスコネクションクライアントシークレットをWorkload Identity Federationに置き換えてみる

対象のサービスコネクション設定画面に行くと上部にWorkload Identity FederationへのConvertボタンが出現しておりこのボタンから簡単に切替られるようですが、いきなり本番稼働している環境では実行できないので検証環境で確認をしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293404/03fc62aa-c767-b3b0-4302-6ef4f26ca931.png)


Convertボタンを押すと以下のようなダイアログが表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293404/0e17fed0-9ad9-fbeb-0501-078e76be02ba.png)

>Converting will delete the secrets associated with this service connection from Azure DevOps in 7 days
In the meantime, you can revert to the original service connection if you encounter any issues. Azure DevOps will not delete secrets from Microsoft Entra. Learn more
>変換すると、Azure DevOps からこのサービス接続に関連付けられたシークレットが 7 日以内に削除されます。その間、問題が発生した場合は、元のサービス接続に戻すことができます。 Azure DevOps は Microsoft Entra からシークレットを削除しません。

なるほど7日以内であれば元のサービス接続に戻すことが可能なようです。

Convertボタンを実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293404/18784820-8552-3be4-d5b9-8ee1df08437c.png)

しばらくお待ちくださいの表示が出現

数秒待つと以下のメッセージが表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293404/708c62ae-34fa-59cb-1e99-0ad8440b16c1.png)



>Automatic authentication conversion failed. Your service connection was not modified. To continue the conversion manually, create a Federated Credential for the underlying Service Principal using the Federation Subject Identifier below and try again. Learn more
自動認証変換に失敗しました。 サービス接続が変更されていません。 手動で変換を続行するには、以下のフェデレーション・サブジェクト識別子を使用して、基盤となるサービス・プリンシパルのフェデレーション・クレデンシャルを作成し、再試行してください。

いきなり失敗してしまいました。
環境次第ではこの手順のみで簡単に変換が成功するのかもしれません。


エラーメッセージの内容から再試行する対応を探ったのですが、公式のドキュメントからも「手動で変換を続行」する旨の手段を見つけられなかったので
Convertは諦めて新規でWorkload Identity Federationを作成することにします。

# Workload Identity Federationの新規作成

右上のNew service connectionから新規作成します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293404/1a27749c-1615-cea5-1156-a183c8930b2d.png)


Azure Resource Managerを選択してNEXT
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293404/a4e8fa50-9e76-6475-0251-cb7815a5e576.png)


New Azure service connectionで必要事項を入力します
Identity type：App registration(automatic)
Credential：Workload identity federation
Scope level：[必要に応じて選択]
Subscription：[必要に応じて選択]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293404/523a864c-4f1f-6a19-1541-dc23695be7ed.png)


SaveするとWorkload identity federationを利用したサービスコネクションが作成されます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293404/c8c2e25b-7af5-134f-d4c9-823f967a4992.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293404/d4a200ad-0725-936f-6340-d9ed2f8c142b.png)


Azure DevOps側でサービスコネクション作成完了後AzureポータルのEntra IDを確認しに行きます。
Azureサービス側でDevOps接続用のIDが作成されていることが確認できました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293404/8af02106-5a8e-a4fc-075b-596082d8dff5.png)

そして右側の「証明書とシークレット」の列に注目してください！
有効となっているステータスや期限切れのステータスがある中、Workload identity federationを使用したサービスコネクションのIDはステータス「-」になっています。
ユーザー側での期限管理がないためにこのような表示になっているようです。

その後Azure Piplinesで接続が必要な各種リソースのアクセス制御（IAM）にも上記IDに必要な権限が付与されていることを確認し、Workload identity federationを使用したサービスコネクションでAzure Piplinesの実行が確認できれば元々使用していた従来のクライアントシークレットを使用したサービスコネクションは削除して置き換え完了です。

# Workload identity federation使用時の注意点
Workload identity federationを使用するとシークレットの期限管理が不要となったりシークレット値や証明書のような静的な認証情報を管理する必要もないためセキュリティと運用の両面でメリットが大きいですが、Azure Pipelinesを使用するうえでは注意点があることが判明しました。

2024 年 12 月時点では、Azure Pipelinesで定義するジョブのパイプライン タスクすべてをサポートしているわけではないようです。
対応しているパイプラインタスクの詳細については以下公式ドキュメントをご確認ください。

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/release/troubleshoot-workload-identity?view=azure-devops#review-pipeline-tasks



# まとめ

Workload Identity Federationは、Azure DevOpsユーザーにとってセキュリティと運用効率の両面で大きなメリットがあることが分かりました。
特に従来の認証方法で課題となっていたシークレット期限の管理の負担を解消し、セキュリティリスクも低減できます。
Azure DevOpsのサービスコネクション接続の有効期限が近付いてる場合や同じように期限切れでエラーとなってしまった場合にWorkload Identity Federationへの置き換えを検討してみてはいかがでしょうか。


### 参考リンク

https://learn.microsoft.com/ja-jp/entra/workload-id/workload-identity-federation

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/library/connect-to-azure?view=azure-devops#create-an-azure-resource-manager-app-registration-with-workload-identity-federation-automatic

https://jpdscore.github.io/blog/azuredevops/wif-service-connection/

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/release/troubleshoot-workload-identity?view=azure-devops#review-pipeline-tasks