配置ADAL时Pulumi中AD应用与Azure函数的循环依赖问题
解决Pulumi部署Azure Function与AD App的循环依赖问题
这种循环依赖确实很常见——Function App需要AD应用的Client ID来配置认证,而AD应用又需要Function App的回调URL来设置回复地址。下面给你两种可行的解决方案,根据你的场景选择:
方法一:提前构造默认域名(最简单,适用于默认Azure域名)
如果你的Function App使用的是Azure默认的*.azurewebsites.net域名,那你完全可以提前通过Function App的名称构造出回调URL,不需要等资源创建完成。因为Function App的名称是你自己定义的(${projectName}-${env}),默认域名就是https://{app-name}.azurewebsites.net。
修改后的代码如下:
const projectName = "your-project"; // 替换为你的项目名 const env = "dev"; // 替换为你的环境名 const adAppName = `${projectName}-${env}`; const appFunctionName = `${projectName}-${env}`; // 提前构造Function App的回调URL(默认域名) const functionCallbackUrl = `https://${appFunctionName}.azurewebsites.net/.auth/login/aad/callback`; // 1. 先创建AD应用,用提前构造好的回调URL const adApp = new azuread.Application(adAppName, { name: adAppName, requiredResourceAccesses: [ { resourceAccesses: [ { id: "311a71cc-e848-46a1-bdf8-97ff7156d8e6", type: "Scope", }, ], resourceAppId: "00000002-0000-0000-c000-000000000000", } ], replyUrls: [functionCallbackUrl] }); // 2. 创建Function App,依赖AD应用的Client ID const appFunction = new azure.appservice.FunctionApp(appFunctionName, { ...resourceGroupArgs, name: appFunctionName, appServicePlanId: appServicePlan.id, authSettings: { enabled: true, unauthenticatedClientAction: 'RedirectToLoginPage', defaultProvider: 'AzureActiveDirectory', issuer: `https://sts.windows.net/${azure.config.tenantId}/`, activeDirectory: { clientId: adApp.applicationId } }, storageConnectionString: storageAccount.primaryConnectionString, version: '~2', appSettings: appSettings, });
优点:代码简洁,没有额外的资源操作,部署流程更顺畅。
缺点:仅适用于默认Azure域名,如果后续要使用自定义域名,这个方法就不适用了。
方法二:分阶段更新AD应用(灵活支持自定义域名)
如果需要支持自定义域名,或者你不想依赖提前构造的URL,可以分三步打破循环:
- 先创建AD应用,初始时不设置回复URL(或设置一个临时占位URL);
- 创建Function App,获取它实际的域名输出;
- 用Function App的域名更新AD应用的回复URL。
修改后的代码如下:
const projectName = "your-project"; const env = "dev"; const adAppName = `${projectName}-${env}`; const appFunctionName = `${projectName}-${env}`; // 1. 创建AD应用,初始回复URL设为空数组 const adApp = new azuread.Application(adAppName, { name: adAppName, requiredResourceAccesses: [ { resourceAccesses: [ { id: "311a71cc-e848-46a1-bdf8-97ff7156d8e6", type: "Scope", }, ], resourceAppId: "00000002-0000-0000-c000-000000000000", } ], replyUrls: [] }); // 2. 创建Function App,依赖AD应用的Client ID const appFunction = new azure.appservice.FunctionApp(appFunctionName, { ...resourceGroupArgs, name: appFunctionName, appServicePlanId: appServicePlan.id, authSettings: { enabled: true, unauthenticatedClientAction: 'RedirectToLoginPage', defaultProvider: 'AzureActiveDirectory', issuer: `https://sts.windows.net/${azure.config.tenantId}/`, activeDirectory: { clientId: adApp.applicationId } }, storageConnectionString: storageAccount.primaryConnectionString, version: '~2', appSettings: appSettings, }); // 3. 更新AD应用的回复URL,使用Function App实际的域名 const adAppWithCallbackUrl = new azuread.Application(`${adAppName}-update`, { id: adApp.id, // 引用已创建的AD应用ID replyUrls: appFunction.defaultHostname.apply(hostname => [ `https://${hostname}/.auth/login/aad/callback` ]) });
优点:完全动态获取Function App的域名,支持自定义域名场景,不受默认域名限制。
缺点:多了一个AD应用的更新操作,不过Pulumi会自动处理资源依赖顺序,不会影响部署结果。
额外注意事项
- 确保Azure AD应用的
requiredResourceAccesses配置正确,你当前设置的是Microsoft Graph的User.Read权限(对应ID311a71cc-e848-46a1-bdf8-97ff7156d8e6),如果需要其他权限可以按需调整。 - 部署完成后,建议在Azure Portal中验证AD应用的回复URL和Function App的认证配置是否匹配,避免出现登录回调失败的问题。
内容的提问来源于stack exchange,提问作者JuChom
相关产品推荐
相关产品推荐

