朗報 BicepがMicrosft Graphのサポート
みなさんこんにちは。少し前の2024年5月20日、Bicep templateでMicrosoft Graphのpublic previewが公開されました。
本当に長いこと(といってもBicepが世に出てまだ数年ですが)待ち望んでいました。
BicepでAzure Resourceからそこで動くアプリケーションのデプロイまで実現しようとすると、どこかでEntra IDの「アプリ」を登録しなければならないことがあります。
また、様々なシステムをBicepでプロビジョニング・デプロイするとGitHub ActionsなどからCDができるようにするために、Federationを登録するなんてこともたびたび発生します。
いつもAzure Portalや az CLIを使ってやっていましたが、やっとBicepでもそれが実現できるようになります。
ということで今回は、やってみた系でBicepでEntra IDの「アプリの登録」を実現しようと思います。
やってみた
事前準備
まずは公式情報のありかです。
この投稿の最初にあるとおり、まだプレビューなので、 bicepconfig.json というファイルでプレビュー機能を有効にする必要があります。 bicepファイルと同じフォルダに作成してください。
{ "experimentalFeaturesEnabled": { "extensibility": true } }
Appの登録
それではまず、Entra IDに「アプリの登録」とAzure Contaiiner RegistryへのRoleの割当をやってみます。
provider microsoftGraph @description('Application name, unique globally. Can not change after create it') param appName string @description('Applicaton displayname, default value is same as appName') param displayName string = appName @description('Name for container registry') param acrName string resource app 'Microsoft.Graph/applications@v1.0' = { displayName: displayName uniqueName: appName } resource sp 'Microsoft.Graph/servicePrincipals@v1.0' = { appId: app.appId } resource acr 'Microsoft.ContainerRegistry/registries@2023-07-01' existing = { name: acrName } var acrRoles = [ '8311e382-0749-4cb8-b61a-304f252e45ec' // ACR push ] resource assignRolesToAcr 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for role in acrRoles: { name: guid(appName, resourceGroup().id, role) scope: acr properties: { principalId: sp.id principalType: 'ServicePrincipal' roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', role) } }]
解説その1
最初の行に provider microsoftGraph
とあります。これは Microsoft Graph型が含まれているということを宣言してるものです。
これがないと利用できません。
解説その2
resource app 'Microsoft.Graph/applications@v1.0' = { displayName: displayName uniqueName: appName } resource sp 'Microsoft.Graph/servicePrincipals@v1.0' = { appId: app.appId }
ロールを割り当てる場合、Service Principalが必要になります。Azure Portalで「Entra アプリ」を作成すると自動的に必要となるService Principalが作成されますが、Bicepでは「アプリ」と「Service Principal」が分かれているのでその両方をここで作成しています。
解説その3
これで「アプリの登録」は作成できました。あとは従来と同じようにService Principalにロールを割り当てるといった作業を行っていけます。
フェデレーションの作成
では、もう1つMicrosoft.Graphの例としてフェデレーションを登録していきます。 公式ドキュメントはこちらです。
GitHub ActionsなどからAzure Resourceにアクセスする際にフェデレーションを登録するケースも多いかと思います。
上記の投稿でAzure Portalで実行していた部分をBicepで実現していきます。
provider microsoftGraph @description('Application name, unique globally. Can not change after create it') param appName string @description('Federation name') param federationName string @description('Federaton description') param descriptoin string? @description('GitHub organization name') param organization string @description('GitHub repository name') param repository string @description('GitHub environment in repository') param environmentName string func generateDeployId(name string) string => substring(guid(name), 0, 8) resource app 'Microsoft.Graph/applications@v1.0' existing = { uniqueName: appName } var subjectIdentifier = 'repo:${organization}/${repository}:environment:${environmentName}' resource appliedApp 'Microsoft.Graph/applications@v1.0' = { displayName: app.displayName uniqueName: app.uniqueName resource fed 'federatedIdentityCredentials@v1.0' = { audiences: [ 'api://AzureADTokenExchange' ] description: descriptoin issuer: 'https://token.actions.githubusercontent.com' name: '${app.uniqueName}/${federationName}' subject: subjectIdentifier } }
解説その4
プレビュー版だからなのか、それともこれが正式になるのかわかりませんが、現時点では Microsoft.Graph/applications の子要素としてMicrosoft.Graph/applications/federatedIdentityCredentials を指定するようになっています。
Microsoft.Graph/applications/federatedIdentityCredentials を単独しようといくつか試みたのですが、私の試し方がわるかったのかうまくいきませんでした。ということで今回は上記のように入れ子の構造になっています。
解説その5
audienceは原則この内容固定です。issuerはGitHub固有のもの、subjectはGitHub Environmentを利用する際のものです。 どういった内容を指定すべきかはAzure Portalで作成した結果や、それぞれのProviderの資料をご確認ください。
解説その6
実はこの部分が今回の中で一番時間のかかった部分です。federatedIdentityCredentialsのなかの名前の指定方法です。
最初以下のように記述していました。
name: '${federationName}'
そうするとスクリプト実行時にIdentifierが不正とエラーになります。
ドキュメントなどにもあまり記載がないのですが、調べていく中で次のように <appの名前>/<federationの名前> と記載しなければならないことがわかりました。(この指定方法に気づくまでに1時間近くかかった)
name: '${app.uniqueName}/${federationName}'
このスクリプトを実行したらフェデレーションも作成できました。
実際にGitHub Actionsからこの指定を使ってACRへのPushもできました。めでたしめでたし。
最後に
Bicepを利用する際のミッシングリンクの1つ、Microsoft Graphがまだpublic previewではありますがやっとサポートされました。 これでIaC化もさらに一歩前進です。ぜひ皆さんお試しください。 そしてこの投稿が少しでも皆さんのご参考になれば幸いです。