Publish Bot - Composer - Import from Existing Resources - azure

I had few permission related issues due to my account being a one from organization. So decided to make use of "Import using existing resources". Please find the .json below that was used to create the publishing profile.
{
"name": "convAISubAuto",
"environment": "dev",
"tenantId": "TENANT_ID",
"hostname": "subAutoConvAI", #Same as azure bot name
"runtimeIdentifier": "win-x64",
"resourceGroup": "chatbot",
"botName": "subAutoConvAI", #Same as azure bot name
"subscriptionId": "SUB_ID",
"region": "westus",
"appServiceOperatingSystem": "windows",
"scmHostDomain": "",
"luisResource": "convAIBoth",
"settings": {
"applicationInsights": {
"InstrumentationKey": "",
"connectionString": ""
},
"cosmosDb": {
"cosmosDBEndpoint": "",
"authKey": "",
"databaseId": "botstate-db",
"containerId": "botstate-container"
},
"blobStorage": {
"connectionString": "",
"container": ""
},
"luis": {
"authoringKey": "",
"authoringEndpoint": "",
"endpointKey": "",
"endpoint": "",
"region": "eastus"
},
"qna": {
"subscriptionKey": "",
"endpoint": ""
},
"MicrosoftAppId": "APP_ID", #Taken from Azure bot configurations screen
"MicrosoftAppPassword": "***" #Taken from secret generated during app registration
}
}
The bot is getting published successfully. However, when i click on "Test in Web Chat" option inside the Azure Bot Resource, i am getting blank screen.
Also, inside the configuration for Azure bot... The endpoint mentioned was https://host_name/api/messages. I had to mention it as the field was blank.
Is there any issue with my publishing profile's JSON file?

The solution is as follows.
Do a app registration and generate a secret.
Create an Azure bot and during the first step, there's an option for "Use existing app registration", inside it mention the app ID and secret (app password)
Use the same app ID and app Password on the above json file.
This solved the issue.

Related

What fields am I supposed to populate in test_configurations.json?

I am very new to Azure and cloud services in general. I am trying to experiment with the azure storage sdk (https://github.com/Azure/azure-storage-cpp) to use in my application and am trying to get used to it. I'm trying to run the tests to make sure that I built the library correctly.
Looking at the README it says to fill in the test_configurations.json file but I don't know what should be filled in or how to obtain the info that should actually be in there. I signed up for the free Azure account and create a storage account but I don't see client_id, tenant_id or client secret anywhere in the console. Here is the config file:
{
"target": "production",
"premium_target": "premium_account",
"blob_storage_target": "blob_storage_account",
"tenants": [
{
"name": "devstore",
"type": "devstore",
"connection_string": "UseDevelopmentStorage=true"
},
{
"name": "production",
"type": "cloud",
"connection_string": "DefaultEndpointsProtocol=https;"
},
{
"name": "premium_account",
"type": "cloud",
"connection_string": "DefaultEndpointsProtocol=https;"
},
{
"name": "blob_storage_account",
"type": "cloud",
"connection_string": "DefaultEndpointsProtocol=https;"
}
],
"token_information": {
"account_name": "",
"tenant_id": "",
"client_id": "",
"client_secret": "",
"resource": "https://storage.azure.com"
}
}
How do I obtain the ids and secrets that I need?
You need to register an application as storage client and then you can obtain those details
as mentioned here
The first step in using Azure AD to authorize access to storage
resources is registering your client application with an Azure AD

How to get the Azure subscription and resouce group from within a VM using REST API?

A lot of Azure API endpoints require you pass in the subscriptionID and resource group name of the resouce you want to work with.
From a bash script running on an Azure Linux VM, how can I get these info? I can't have the Azure CLI installed hence looking for some REST API.
There is this old answer which I found convoluted and requires the CLI anyway.
One answer even mentions this API to get all info of one given VM:
/subscriptions/[subscription-id]/resourceGroups/[resource-group-name]/providers/Microsoft.Compute/virtualMachines/[virtual-machine-name]
It seems to be a chicken and egg problem.
You could use this REST API - Subscriptions - List to list all the subscriptions the user can access for an Azure AD tenant.
GET https://management.azure.com/subscriptions?api-version=2019-06-01
For which tenant, it depends on the bearer token you got from, when you get the token, decode in https://jwt.io/, you will find that like below. If you use this token to call this API, it will get all the subscriptions the user can access in the tenant I hid in the screenshot.
If you want to get the resource group the VM is in, you can use this REST API - Virtual Machines - List All, no need to pass the resource-group-name, it can list all the VMs with the subscriptionId, you can get the subscriptionId from the Subscriptions - List.
GET https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.Compute/virtualMachines?api-version=2019-03-01
So in conclusion, if you already know the subscriptionId which the VM is in, you can list all the VMs in the subscription and find the VM in the result, then you will find the resource group name. If you don't know the subscriptionId, you can just list all the subscriptions the user can access in one tenant, and list all the VMs in every subscription. Besides, if you even don't know the tenant-id, you can use Tenants - List to gets all the tenants for your account.
I've found it. The Azure Instance Metadata Service returns a lot of metadata about the Azure VM where the request has made from. I used the following REST endpoint to retrieve the VM's subscriptionId and resourceGroupName:
curl -H Metadata:true "http://169.254.169.254/metadata/instance?api-version=2017-08-01"
{
"compute": {
"location": "",
"name": "",
"offer": "",
"osType": "",
"placementGroupId": "",
"platformFaultDomain": "",
"platformUpdateDomain": "",
"publisher": "",
"resourceGroupName": "",
"sku": "",
"subscriptionId": "",
"tags": "",
"version": "",
"vmId": "",
"vmScaleSetName": "",
"vmSize": "",
"zone": ""
},
"network": {
"interface": [
{
"ipv4": {
"ipAddress": [
{
"privateIpAddress": "",
"publicIpAddress": ""
}
],
"subnet": [
{
"address": "",
"prefix": ""
}
]
},
"ipv6": {
"ipAddress": []
},
"macAddress": ""
}
]
}
}

Pass Service Principal Client Id and Secret to ARM Template

I have an ARM template that creates an Azure Key Vault followed by an Azure Kubernetes service. The problem is that the Azure Kubernetes service needs a Service Principle's Client ID and Client Secret passed in the first time I create it. So I run the application.json without the kubernetes_servicePrincipalClientId and kubernetes_servicePrincipalClientSecret parameters in the production.parameters.json file:
application.json
{
"comments": "Kubernetes Service Principal Client ID",
"type": "Microsoft.KeyVault/vaults/secrets",
"name": "[concat(parameters('key_vault_name'), '/KubernetesServicePrincipalClientId')]",
"apiVersion": "2018-02-14",
"properties": {
"contentType": "text/plain",
"value": "[parameters('kubernetes_servicePrincipalClientId')]"
}
},
{
"comments": "Kubernetes Service Principal Client Secret",
"type": "Microsoft.KeyVault/vaults/secrets",
"name": "[concat(parameters('key_vault_name'), '/KubernetesServicePrincipalClientSecret')]",
"apiVersion": "2018-02-14",
"properties": {
"contentType": "text/plain",
"value": "[parameters('kubernetes_servicePrincipalClientSecret')]"
}
}
The second time I run the ARM template, I add the following lines to my production.parameters.json file, so that the Client ID and Client Secret are retrieved from Azure Key Vault where they were stored the first time I ran the ARM template.
production.parameters.json
"kubernetes_servicePrincipalClientId": {
"reference": {
"keyVault": {
"id": "/subscriptions/[Subscription Id]/resourcegroups/[Resource Group Name]/providers/Microsoft.KeyVault/vaults/[Vault Name]"
},
"secretName": "KubernetesServicePrincipalClientId"
}
},
"kubernetes_servicePrincipalClientSecret": {
"reference": {
"keyVault": {
"id": "/subscriptions/[Subscription Id]/resourcegroups/[Resource Group Name]/providers/Microsoft.KeyVault/vaults/[Vault Name]"
},
"secretName": "KubernetesServicePrincipalClientSecret"
}
}
Unfortunately it looks like you can't create a service principal in an ARM template. Is there a better way to configure all this in an automated way, so that regardless of whether or not I'm running the template the first time or second time, I don't have to perform any manual steps?
no, those apis are not exposed to arm, there is no way of managing a service principal with an ARM Template. you can however create a script that will provision the service principal and pass its details to the arm template, or you can use some sort of tool to handle all of this for you (pulumi\terraform\ansible)

MS Bot framework v4 - cannot add QnA maker to bot - hostname encrypted value is not a valid format

Current situation: I currently have a working web app bot with LUIS integration (NODE.js). I want to add a QnA maker to the bot. I have created a QnA maker via the Azure bot service and created a knowledge base for it to use.
Issue: When adding the qna maker details to the bot and running with nodemon ./index.js, I get the error "Error: The encrypted value is not a valid format". I've tested and this error is thrown when it tries to read the hostname value during
botConfig = BotConfiguration.loadSync(BOT_FILE, process.env.botFileSecret);
When pasting the hostname into the browser Azure shows me a "Your App Service app is up and running" page, indicating the hostname is fine.
Questions:
How do I debug this further? Could it be something to do with how the QnA maker is set up?
Both the QnA maker and Knoledge base is published - is there something I have to add manually to the config of the bot via the Azure portal to get it to recognise the QnA maker?
A lot of the documentation is based on v3 of the bot framework and have no idea if it's still applicable.
QnA snippet in Bot file (some values omitted, not sure how sensitive they are):
{
"type": "qna",
"name": "pathqna",
"KbId": "OMITTED",
"subscriptionId": "OMITTED",
"endpointKey": "OMITTED",
"hostname": "https://pathqna.azurewebsites.net",
"id": "7"
}
Documentation I've looked at:
https://learn.microsoft.com/en-gb/azure/bot-service/bot-builder-tutorial-dispatch?view=azure-bot-service-4.0&tabs=javascript
https://learn.microsoft.com/en-us/azure/cognitive-services/qnamaker/tutorials/create-qna-bot
https://github.com/Microsoft/botbuilder-tools/blob/master/packages/MSBot/docs/sample-bot-file.json
https://learn.microsoft.com/en-us/azure/cognitive-services/QnAMaker/how-to/troubleshooting-runtime#how-to-get-latest-qnamaker-runtime-updates
Full bot file with the empty padlock value (all OMITTED values have real keys and name has been changed to Test):
{
"name": “Test”,
"padlock": "",
"version": "2.0",
"services": [
{
"tenantId": "OMITTED",
"subscriptionId": "OMITTED",
"resourceGroup": OMITTED,
"serviceName": OMITTED,
"type": "abs",
"name": OMITTED,
"id": "1"
},
{
"connectionString": "OMITTED",
"tenantId": "OMITTED",
"subscriptionId": "OMITTED",
"resourceGroup": OMITTED,
"serviceName": "patha048",
"type": "blob",
"id": "2"
},
{
“appId": "OMITTED",
"appPassword": “OMITTED”,
"endpoint": "http://localhost:3978/api/messages",
"type": "endpoint",
"name": "development",
"id": "3"
},
{
"appId": "OMITTED",
"appPassword": “OMITTED”,
"endpoint": "https://path-a048.azurewebsites.net/api/messages",
"type": "endpoint",
"name": "production",
"id": "4"
},
{
"instrumentationKey": “OMITTED”,
"applicationId": “OMITTED”,
"apiKeys": {},
"tenantId": "OMITTED",
"subscriptionId": "OMITTED",
"resourceGroup": OMITTED,
"serviceName": "Patht6r6m4",
"type": "appInsights",
"id": "5"
},
{
"appId": “OMITTED”,
"authoringKey": “OMITTED”,
"version": "0.1",
"region": "westus",
"type": "luis",
"name": "BasicBotLuisApplication",
"id": "6"
},
{
"type": "qna",
"name": "pathqna",
"id": "7",
"kbId": “OMITTED”,
"subscriptionKey": "OMITTED",
"endpointKey": “OMITTED”,
"hostname": "https://pathqna.azurewebsites.net"
}
]
}
Found the solution - Use msbot cli to add the QnA maker instead of adding manually as the file is encrypted and loses it's decryption if you don't use the msbot/emulator shrug
I removed the qna snippet and ran this command (have added the generic values to preserve the real values):
msbot connect qna --secret <botFileSecret> --name pathqna --kbId <KB-ID> --subscriptionKey <SUB_KEY> --endpointKey <ENDPOINT_KEY> --hostname "https://pathqna.azurewebsites.net" --bot Path.bot
This preserved the padlock value and added it successfully.
Although the information you have provided is not enough to provide a solution, you may please check on the following steps.
"Error: The encrypted value is not a valid format"
*Please check your bot secret keys once again.
Then, in your bot file, try removing the padlock value.
"padlock": ""
Also, I assume in your actual code, you have replaced 'OMITTED' with the real time keys that you have obtained from QnAMaker portal.*
Provide a screenshot of the error if possible.

How to pass ConnectionString when deploying AzureRM Web App in TFS?

I am struggling to pass ConnectionString when deploying AzureRM Web App in TFS Release Manager. I have tried to put the ConnectionString in the "Additional Arguments" field and provided the correct variables from the "Variables" section. However, I am getting the following error:
[error] Error: Unrecognized argument '-connectionString'. Error count: 1.
Does someone have experience in how to set up ConnectionString when working with AzureRM Endpoint to deploy Web Apps? As far as I know, the approach described above works fine when using Azure Web App Deployment with Azure Classic Endpoint.
You could also try to use some 3-party extension such as Azure WebApp Configuration task.
This task reads VSTS/TFS variables and adds those as AppSettings and ConnectionStrings to an Azure WebApp.
You could inculcate the following sample, to fit your deployment via TFS.
{
"apiVersion": "2014-11-01",
"name": "appsettings",
"type": "config",
"dependsOn": [
"[resourceId('Microsoft.Web/Sites', parameters('siteName'))]"
],
"properties": {
"AppSettingKey1": "Some value",
"AppSettingKey2": "My second setting",
"AppSettingKey3": "My third setting"
}
},
{
"apiVersion": "2014-11-01",
"name": "connectionstrings",
"type": "config",
"dependsOn": [
"[resourceId('Microsoft.Web/Sites', parameters('siteName'))]"
],
"properties": {
"ConnString1": { "value": "My custom connection string", "type": "custom" },
"ConnString2": { "value": "My SQL connection string", "type": "SQLAzure" }
}
},
Refer the sample here for more details

Resources