diff --git a/samples/bot-conversation/python/infra/azure.bicep b/samples/bot-conversation/python/infra/azure.bicep index 8734cb547b..230fada895 100644 --- a/samples/bot-conversation/python/infra/azure.bicep +++ b/samples/bot-conversation/python/infra/azure.bicep @@ -3,17 +3,20 @@ @description('Used to generate names for all resources in this file') param resourceBaseName string -@description('Required when create Azure Bot service') -param botAadAppClientId string - param botAppDomain string @maxLength(42) param botDisplayName string param botServiceName string = resourceBaseName +param identityName string = resourceBaseName param botServiceSku string = 'F0' +resource identity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { + location: location + name: identityName +} + // Register your web service as a bot with the Bot Framework resource botService 'Microsoft.BotService/botServices@2021-03-01' = { kind: 'azurebot' @@ -22,7 +25,12 @@ resource botService 'Microsoft.BotService/botServices@2021-03-01' = { properties: { displayName: botDisplayName endpoint: 'https://${botAppDomain}/api/messages' - msaAppId: botAadAppClientId + + msaAppId: identity.properties.clientId + msaAppMSIResourceId: identity.id + msaAppTenantId:identity.properties.tenantId + msaAppType:'UserAssignedMSI' + msaAppType: 'MultiTenant' msaAppTenantId: '' } diff --git a/samples/bot-conversation/python/infra/azure.parameters.json b/samples/bot-conversation/python/infra/azure.parameters.json index 7474499bdb..5428d8701b 100644 --- a/samples/bot-conversation/python/infra/azure.parameters.json +++ b/samples/bot-conversation/python/infra/azure.parameters.json @@ -5,9 +5,6 @@ "resourceBaseName": { "value": "bot${{RESOURCE_SUFFIX}}" }, - "botAadAppClientId": { - "value": "${{AAD_APP_CLIENT_ID}}" - }, "botAppDomain": { "value": "${{BOT_DOMAIN}}" }, diff --git a/samples/bot-conversation/python/teamsapp.local.yml b/samples/bot-conversation/python/teamsapp.local.yml index 53a5bf5219..14bb2e0f40 100644 --- a/samples/bot-conversation/python/teamsapp.local.yml +++ b/samples/bot-conversation/python/teamsapp.local.yml @@ -75,4 +75,5 @@ deploy: target: ./.env envs: MicrosoftAppId: ${{AAD_APP_CLIENT_ID}} - MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} \ No newline at end of file + MicrosoftAppPassword: ${{SECRET_AAD_APP_CLIENT_SECRET}} + BOT_TYPE: 'MultiTenant' \ No newline at end of file diff --git a/samples/bot-proactive-messaging-teamsfx/teamsapp.local.yml b/samples/bot-proactive-messaging-teamsfx/teamsapp.local.yml index 6d6991327c..f68d81a7f4 100644 --- a/samples/bot-proactive-messaging-teamsfx/teamsapp.local.yml +++ b/samples/bot-proactive-messaging-teamsfx/teamsapp.local.yml @@ -53,6 +53,7 @@ deploy: envs: BOT_ID: ${{BOT_ID}} BOT_PASSWORD: ${{SECRET_BOT_PASSWORD}} + BOT_TYPE: 'MultiTenant' # Generate runtime environment variables - uses: file/createOrUpdateEnvironmentFile diff --git a/samples/bot-proactive-messaging-teamsfx/teamsapp.yml b/samples/bot-proactive-messaging-teamsfx/teamsapp.yml index 45332b7407..732dc5c628 100644 --- a/samples/bot-proactive-messaging-teamsfx/teamsapp.yml +++ b/samples/bot-proactive-messaging-teamsfx/teamsapp.yml @@ -16,12 +16,6 @@ provision: writeToEnvironmentFile: # Write the information of created resources into environment file for the specified environment variable(s). teamsAppId: TEAMS_APP_ID - - uses: botAadApp/create # Creates a new AAD app for Bot Registration. - with: - name: ProactiveMessagesTeamsFxbt${{RESOURCE_SUFFIX}} - writeToEnvironmentFile: - botId: BOT_ID - botPassword: SECRET_BOT_PASSWORD - uses: arm/deploy # Deploy given ARM templates parallelly. with: subscriptionId: ${{AZURE_SUBSCRIPTION_ID}} # The AZURE_SUBSCRIPTION_ID is a built-in environment variable. TeamsFx will ask you select one subscription if its value is empty. You're free to reference other environment varialbe here, but TeamsFx will not ask you to select subscription if it's empty in this case. diff --git a/samples/bot-proactive-messaging-teamsfx/templates/azure/provision.bicep b/samples/bot-proactive-messaging-teamsfx/templates/azure/provision.bicep index ba7ebd3180..84579aef68 100644 --- a/samples/bot-proactive-messaging-teamsfx/templates/azure/provision.bicep +++ b/samples/bot-proactive-messaging-teamsfx/templates/azure/provision.bicep @@ -20,6 +20,9 @@ module botProvision './provision/bot.bicep' = { params: { provisionParameters: provisionParameters userAssignedIdentityId: userAssignedIdentityProvision.outputs.identityResourceId + identityClientId: userAssignedIdentityProvision.outputs.identityClientId + identityResourceId: userAssignedIdentityProvision.outputs.identityResourceId + identityTenantId: userAssignedIdentityProvision.outputs.identityPrincipalId } } diff --git a/samples/bot-proactive-messaging-teamsfx/templates/azure/provision/bot.bicep b/samples/bot-proactive-messaging-teamsfx/templates/azure/provision/bot.bicep index eee9aef49a..979718048d 100644 --- a/samples/bot-proactive-messaging-teamsfx/templates/azure/provision/bot.bicep +++ b/samples/bot-proactive-messaging-teamsfx/templates/azure/provision/bot.bicep @@ -1,9 +1,12 @@ @secure() param provisionParameters object param userAssignedIdentityId string +param identityName string = provisionParameters.resourceBaseName +param identityResourceId string +param identityClientId string +param identityTenantId string var resourceBaseName = provisionParameters.resourceBaseName -var botAadAppClientId = provisionParameters['botAadAppClientId'] // Read AAD app client id for Azure Bot Service from parameters var botServiceName = contains(provisionParameters, 'botServiceName') ? provisionParameters['botServiceName'] : '${resourceBaseName}' // Try to read name for Azure Bot Service from parameters var botServiceSku = contains(provisionParameters, 'botServiceSku') ? provisionParameters['botServiceSku'] : 'F0' // Try to read SKU for Azure Bot Service from parameters var botDisplayName = contains(provisionParameters, 'botDisplayName') ? provisionParameters['botDisplayName'] : '${resourceBaseName}' // Try to read display name for Azure Bot Service from parameters @@ -19,13 +22,22 @@ resource botService 'Microsoft.BotService/botServices@2021-03-01' = { properties: { displayName: botDisplayName endpoint: uri('https://${webApp.properties.defaultHostName}', '/api/messages') - msaAppId: botAadAppClientId + msaAppId: identityClientId + msaAppMSIResourceId: identityResourceId + msaAppTenantId:identityTenantId + msaAppType:'UserAssignedMSI' } sku: { name: botServiceSku // You can follow https://aka.ms/teamsfx-bicep-add-param-tutorial to add botServiceSku property to provisionParameters to override the default value "F0". } } +// Managed Identity resource +resource identity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { + location: resourceGroup().location + name: identityName +} + // Connect the bot service to Microsoft Teams resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@2021-03-01' = { parent: botService @@ -78,6 +90,8 @@ resource webApp 'Microsoft.Web/sites@2021-02-01' = { output botWebAppSKU string = webAppSKU output botWebAppName string = webAppName output botDomain string = webApp.properties.defaultHostName +output BOT_ID string = identity.properties.clientId +output BOT_TENANT_ID string = identity.properties.tenantId output appServicePlanName string = serverfarmsName output botServiceName string = botServiceName output botWebAppResourceId string = webApp.id diff --git a/samples/bot-proactive-messaging-teamsfx/templates/azure/teamsFx/bot.bicep b/samples/bot-proactive-messaging-teamsfx/templates/azure/teamsFx/bot.bicep index 8b6ac28eb8..f8c9de53bb 100644 --- a/samples/bot-proactive-messaging-teamsfx/templates/azure/teamsFx/bot.bicep +++ b/samples/bot-proactive-messaging-teamsfx/templates/azure/teamsFx/bot.bicep @@ -6,18 +6,22 @@ param provisionOutputs object @secure() param currentAppSettings object -var botWebAppName = split(provisionOutputs.botOutput.value.botWebAppResourceId, '/')[8] +param identityName string = provisionParameters.resourceBaseName -var botAadAppClientSecret = provisionParameters['botAadAppClientSecret'] +var botWebAppName = split(provisionOutputs.botOutput.value.botWebAppResourceId, '/')[8] -var botId = provisionParameters['botAadAppClientId'] +// Managed Identity resource +resource identity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { + location: resourceGroup().location + name: identityName +} resource botWebAppSettings 'Microsoft.Web/sites/config@2021-02-01' = { name: '${botWebAppName}/appsettings' properties: union({ INITIATE_LOGIN_ENDPOINT: uri(provisionOutputs.botOutput.value.siteEndpoint, 'auth-start.html') // The page is used to let users consent required OAuth permissions during bot SSO process - BOT_ID: botId // ID of your bot - BOT_PASSWORD: botAadAppClientSecret // Secret of your bot + BOT_ID: identity.properties.clientId // ID of your bot + BOT_TENANT_ID: identity.properties.tenantId // Secret of your bot IDENTITY_ID: provisionOutputs.identityOutput.value.identityClientId // User assigned identity id, the identity is used to access other Azure resources PROVISIONOUTPUT__BOTOUTPUT__SITEENDPOINT : provisionOutputs.botOutput.value.siteEndpoint // Site endpoint of AAD application }, currentAppSettings) diff --git a/samples/msgext-unfurling-ac-loop-components/nodejs/config.js b/samples/msgext-unfurling-ac-loop-components/nodejs/config.js index df88c39871..c2eb3c0604 100644 --- a/samples/msgext-unfurling-ac-loop-components/nodejs/config.js +++ b/samples/msgext-unfurling-ac-loop-components/nodejs/config.js @@ -1,6 +1,8 @@ const config = { + botType: process.env.BOT_TYPE, botId: process.env.BOT_ID, botPassword: process.env.BOT_PASSWORD, + botTenantId: process.env.BOT_TENANT_ID }; module.exports = config; diff --git a/samples/msgext-unfurling-ac-loop-components/nodejs/index.js b/samples/msgext-unfurling-ac-loop-components/nodejs/index.js index d7430c63bc..cb38825523 100644 --- a/samples/msgext-unfurling-ac-loop-components/nodejs/index.js +++ b/samples/msgext-unfurling-ac-loop-components/nodejs/index.js @@ -18,7 +18,8 @@ const config = require("./config"); const credentialsFactory = new ConfigurationServiceClientCredentialFactory({ MicrosoftAppId: config.botId, MicrosoftAppPassword: config.botPassword, - MicrosoftAppType: "MultiTenant", + MicrosoftAppType: config.botType, + MicrosoftAppTenantId: config.botTenantId }); const botFrameworkAuthentication = new ConfigurationBotFrameworkAuthentication( diff --git a/samples/msgext-unfurling-ac-loop-components/nodejs/infra/azure.bicep b/samples/msgext-unfurling-ac-loop-components/nodejs/infra/azure.bicep index 41cf99a692..03a5e04d82 100644 --- a/samples/msgext-unfurling-ac-loop-components/nodejs/infra/azure.bicep +++ b/samples/msgext-unfurling-ac-loop-components/nodejs/infra/azure.bicep @@ -3,13 +3,6 @@ @description('Used to generate names for all resources in this file') param resourceBaseName string -@description('Required when create Azure Bot service') -param botAadAppClientId string - -@secure() -@description('Required by Bot Framework package in your bot project') -param botAadAppClientSecret string - param webAppSKU string @maxLength(42) @@ -17,8 +10,14 @@ param botDisplayName string param serverfarmsName string = resourceBaseName param webAppName string = resourceBaseName +param identityName string = resourceBaseName param location string = resourceGroup().location +resource identity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { + location: location + name: identityName +} + // Compute resources for your Web App resource serverfarm 'Microsoft.Web/serverfarms@2021-02-01' = { kind: 'app' @@ -54,11 +53,15 @@ resource webApp 'Microsoft.Web/sites@2021-02-01' = { } { name: 'BOT_ID' - value: botAadAppClientId + value: identity.properties.clientId + } + { + name: 'BOT_TENANT_ID' + value: identity.properties.tenantId } { - name: 'BOT_PASSWORD' - value: botAadAppClientSecret + name: 'BOT_TYPE' + value: 'UserAssignedMsi' } ] ftpsState: 'FtpsOnly' @@ -71,7 +74,9 @@ module azureBotRegistration './botRegistration/azurebot.bicep' = { name: 'Azure-Bot-registration' params: { resourceBaseName: resourceBaseName - botAadAppClientId: botAadAppClientId + identityClientId: identity.properties.clientId + identityResourceId: identity.id + identityTenantId: identity.properties.tenantId botAppDomain: webApp.properties.defaultHostName botDisplayName: botDisplayName } @@ -80,3 +85,5 @@ module azureBotRegistration './botRegistration/azurebot.bicep' = { // The output will be persisted in .env.{envName}. Visit https://aka.ms/teamsfx-actions/arm-deploy for more details. output BOT_AZURE_APP_SERVICE_RESOURCE_ID string = webApp.id output BOT_DOMAIN string = webApp.properties.defaultHostName +output BOT_ID string = identity.properties.clientId +output BOT_TENANT_ID string = identity.properties.tenantId diff --git a/samples/msgext-unfurling-ac-loop-components/nodejs/infra/azure.parameters.json b/samples/msgext-unfurling-ac-loop-components/nodejs/infra/azure.parameters.json index 00c1291644..1998e915cb 100644 --- a/samples/msgext-unfurling-ac-loop-components/nodejs/infra/azure.parameters.json +++ b/samples/msgext-unfurling-ac-loop-components/nodejs/infra/azure.parameters.json @@ -5,12 +5,6 @@ "resourceBaseName": { "value": "ME${{RESOURCE_SUFFIX}}" }, - "botAadAppClientId": { - "value": "${{BOT_ID}}" - }, - "botAadAppClientSecret": { - "value": "${{SECRET_BOT_PASSWORD}}" - }, "webAppSKU": { "value": "B1" }, diff --git a/samples/msgext-unfurling-ac-loop-components/nodejs/infra/botRegistration/azurebot.bicep b/samples/msgext-unfurling-ac-loop-components/nodejs/infra/botRegistration/azurebot.bicep index 4450c8dfe6..b4f7ce314a 100644 --- a/samples/msgext-unfurling-ac-loop-components/nodejs/infra/botRegistration/azurebot.bicep +++ b/samples/msgext-unfurling-ac-loop-components/nodejs/infra/botRegistration/azurebot.bicep @@ -6,7 +6,9 @@ param resourceBaseName string @maxLength(42) param botDisplayName string -param botServiceName string = resourceBaseName +param botServiceName string = resourceBaseNameparam identityResourceId string +param identityClientId string +param identityTenantId string param botServiceSku string = 'F0' param botAadAppClientId string param botAppDomain string @@ -19,7 +21,10 @@ resource botService 'Microsoft.BotService/botServices@2021-03-01' = { properties: { displayName: botDisplayName endpoint: 'https://${botAppDomain}/api/messages' - msaAppId: botAadAppClientId + msaAppId: identityClientId + msaAppMSIResourceId: identityResourceId + msaAppTenantId:identityTenantId + msaAppType:'UserAssignedMSI' } sku: { name: botServiceSku diff --git a/samples/msgext-unfurling-ac-loop-components/nodejs/teamsapp.local.yml b/samples/msgext-unfurling-ac-loop-components/nodejs/teamsapp.local.yml index 8ec9a49891..3b61fa4151 100644 --- a/samples/msgext-unfurling-ac-loop-components/nodejs/teamsapp.local.yml +++ b/samples/msgext-unfurling-ac-loop-components/nodejs/teamsapp.local.yml @@ -89,4 +89,5 @@ deploy: target: ./.localConfigs envs: BOT_ID: ${{BOT_ID}} - BOT_PASSWORD: ${{SECRET_BOT_PASSWORD}} \ No newline at end of file + BOT_PASSWORD: ${{SECRET_BOT_PASSWORD}} + BOT_TYPE: 'MultiTenant' \ No newline at end of file