Deploying ARM Template for an API Connection that uses OnPrem Data Gateway succeeds but the authType and gateway parameters are missing - azure

I've been banging my head against a brick wall on this.
I'm trying to deploy via Azure DevOps pipeline, a bicep/ARM Template an API Connection that uses a Custom Connector that is linked to an On-prem API via a Data Gateway.
Here is my bicep file...
param connectionName string
param displayName string
param gatewayResourceGroup string
param gatewayName string
param connectorName string
param location string = resourceGroup().location
resource connector 'Microsoft.Web/customApis#2016-06-01' existing = {
name: connectorName
}
resource gatewayApi 'Microsoft.Web/connectionGateways#2016-06-01' existing = {
name: gatewayName
scope: resourceGroup(gatewayResourceGroup)
}
resource apiConnection 'Microsoft.Web/connections#2016-06-01' = {
name: connectionName
location: location
properties: {
displayName: displayName
nonSecretParameterValues: {
authType: 'anonymous'
#disable-next-line BCP036
gateway: {
name: gatewayName
id: gatewayApi.id
type: 'Microsoft.Web/connectionGateways'
}
}
api: {
name: connector.name
displayName: 'CONNECTOR ${connectorName}'
id: connector.id
type: 'Microsoft.Web/customApis'
}
}
}
I issue is the nonSecretParameterValues.
They don't go anywhere.
The API Connection is deployed like...
What makes this a little worse is the deployment is successful...
But if I drill into the Operation details I can see there were two issues...
"overallStatus": "Error",
"statuses": [
{
"status": "Error",
"target": "authType",
"error": {
"code": "ConfigurationNeeded",
"message": "Parameter value missing."
}
},
{
"status": "Error",
"target": "gateway",
"error": {
"code": "ConfigurationNeeded",
"message": "Parameter value missing."
}
}
],
Very frustrating.
Now I can manually add the values I intended to be there for the authType and gateway parameters after the deployment is "successful". Then my logic app that uses this API Connection and Custom Connector to Onprem Gateway works as expected.
But the exported template for the API Connection does not change between the connection having missing parameters (in the UI) or after I manually enter the values.
I have also tried added some Powershell after the deployment to pick up the connection and to try settings the "missing" values and updating the resource from there.
I can see another API Connection via Powershell which is correctly set with the authType and gateway parameters.
But when I try, to set these on the resource I need to "fix" it also complains...
I would really like to have the API Connection deployment fully via Azure DevOps pipeline.
NOTE: I find it very odd to have to use the #disable-next-line BCP036 to disable the warning in VSCode. And even opening the built ARM Template will give a warning on the "gateway" property name. I even tried replacing the "object" with just the resource id and that didn't help.

The parameters should be in a parameterValues property object:
resource apiConnection 'Microsoft.Web/connections#2016-06-01' = {
name: connectionName
location: location
properties: {
displayName: displayName
parameterValues: {
authType: 'anonymous'
gateway: {
id: gatewayApi.id
}
}
...
}
}

Suggestion:
The nonSecretParameterValues object must be in the format of a dictionary. I cannot find any hard documentation about this as a data structure, but it's mentioned several times.
nonSecretParameterValues: {
authType: 'anonymous'
gateway-name: gatewayName
gateway-id: gatewayApi.id
gateway-type: 'Microsoft.Web/connectionGateways'
}
Hope this helps.

Related

Failed to send query to service connection API when using Azure devops api serviceendpoint to create kubernetes service connection

I am trying to use the https://dev.azure.com/<orgname>/_apis/serviceendpoint/endpoints?api-version=6.0-preview.4 api to create a new kubernetes service connection.
I want to use AzureSubscription auth, and as far as I know, it creates the service account and role binding for you. I have done this in portal and it works fine, but am struggling to replicate through the api.
I am able to create the Service Connection, and it sits in my service connection list in the project settings no problem.
When I pull it back down to check the status (with the GET service endpoint) , I have an operation status of 'failed' with a status message of 'An error occurred while creating the service account. Internal error: Failed to query service connection API: 'https://management.azure.com/api/v1/namespaces/default/serviceaccounts?pretty=false'. Error Message: 'An error occurred while sending the request.'
Here is what I am sending in the body, I am using a PAT to auth.
{
"data": {
"authorizationType": "AzureSubscription",
"clusterAdmin": "true",
"azureSubscriptionId": "00000000-0000-0000-0000-000000000000",
"azureSubscriptionName": "SomeSubscriptionName",
"clusterId": "/subscriptions/"00000000-0000-0000-0000-000000000000"/resourceGroups/someresourcegroupname/providers/Microsoft.ContainerService/managedClusters/someclustername",
"namespace": "default"
},
"name": "TestK8sEndpoint",
"type": "Kubernetes",
"url": "https://management.azure.com/",
"authorization": {
"parameters": {
"azureTenantId": ""00000000-0000-0000-0000-000000000000"",
"azureEnvironment": "AzureCloud"
},
"scheme": "Kubernetes"
},
"isShared": false,
"isReady": true,
"serviceEndpointProjectReferences": [
{
"projectReference": {
"id": ""00000000-0000-0000-0000-000000000000"",
"name": "someprojectname"
},
"name": "TestK8sEndpoint"
}
]
}
Any help is much appreciated
I have since realised that I made a mistake in my body.
The 4th property url should have been the url of my cluster - aka, someclustername-dns-0a0a0a0a.hcp.northeurope.0a0a0a.io

Creating an Azure Queue action in a Logic App with bicep results in 'Connector not Found'

I try to create a Logic App with a Azure Queues Operation. I want to use a API connection resource to connect to the storage account. However
The API Connection resource and the Logic App itself are deployed without errors but after deployment the operation cannot find the API connection and the operation does not work.
When I manually create the operation in the portal after deployment it works.
Part of bicep for the action in logic app:
'Put_a_message_on_a_queue_(V2)' : {
runafter: {}
type: 'ApiConnection'
inputs: {
body: 'start'
host: {
connection: {
name: azureQueueConnectionId
}
}
method: 'post'
path: '/v2/storageAccounts/${storageAccountName}/queues/dailymaintenance/messages'
}
}
The API connection:
resource logicAppConnection 'Microsoft.Web/connections#2016-06-01' = {
name: name
location: resourceLocation
properties: {
displayName: 'connect-to-${externalResourceName}'
parameterValues: {
storageaccount: storageAccountReference.name
sharedkey: storageAccountReference.listKeys().keys[0].value
}
api: {
name: 'azurequeues'
displayName: 'Azure Queues'
description: 'Azure Queue storage provides cloud messaging between application components. Queue storage also supports managing asynchronous tasks and building process work flows.'
iconUri: 'https://connectoricons-prod.azureedge.net/releases/v1.0.1546/1.0.1546.2665/azurequeues/icon.png'
brandColor: '#0072C6'
id: '${subscription().id}/providers/Microsoft.Web/locations/${resourceLocation}/managedApis/azurequeues'
type: 'Microsoft.Web/locations/managedApis'
}
testLinks: [
{
requestUri: '${environment().resourceManager}/subscriptions/${subscription().id}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Web/connections/${name}/extensions/proxy/testConnection?api-version=2016-06-01'
method: 'get'
}
]
}
}
output id string = logicAppConnection.id
This is de error I get in the Logic App Designer: "Connector not found"
I am wondering why this is not working as expected and if someone already managed to do this with bicep?
Thanks in advance
AFAIK, It is believed that if you deploy the Template, both API Connections will be created, but you will have to manually update the connection inside logic apps by adding your service credentials. This is because, in order to complete the API connection, you must provide consent, which is not available in the template.
This script will retrieve a consent link for an OAuth Logic Apps connector connection. The consent link will then be opened, and authorization will be completed to allow a connection to be established.
For more inforation please refer this blog|BICEP-Create API connections for Logic Apps & Deploy Logic Apps & API Connection with ARM
It turned out the API connection name must be set as follows to make this work
actions: {
'Put_a_message_on_a_queue_(V2)' : {
runafter: {}
type: 'ApiConnection'
inputs: {
body: 'start'
host: {
connection: {
name: '#parameters(\'$connections\')[\'azurequeues\'][\'connectionId\']'
}
}
method: 'post'
path: '/v2/storageAccounts/${storageAccountName}/queues/dailymaintenance/messages'
}
}
}
}
parameters: {
'$connections': {
value: {
azurequeues: {
connectionId: logicAppConnection.id
connectionName: 'LogicAppConnection'
id: '/subscriptions/xxxxxxxxxxx/providers/Microsoft.Web/locations/westeurope/managedApis/azurequeues'
}
}
}
}
After I deployed this, it worked!

Azure generate URL for a standard Logic app with connection to CosmosDB

I have a workflow in a standard logic app, that have HTTP trigger. When the workflow is trigged, the workflow, retrieve some data from a CosmosDB. Something like:
The previous method will require to have an API connection. I have already created and deployed a 'V2' API connection. Let's call it myCosmosCon
Also in the ARM template for my logic app I have already added a connectionRuntimeUrl of my connection API (to myCosmosCon) to appSettings (configuration):
....
"siteConfig": {
"appSettings": [
{
"name": "subscriptionId",
"value": "[subscription().subscriptionId]"
},
{
"name": "resourceGroup_name",
"value": "[resourceGroup().name]"
},
{
"name": "location_name",
"value": "[resourceGroup().location]"
},
{
"name": "connectionRuntimeUrl",
"value": "[reference(resourceId('Microsoft.Web/connections', parameters('connection_name')),'2016-06-01', 'full').properties.connectionRuntimeUrl]"
},
.....
]
},
Then I wrote the following in the connections.json:
{
"managedApiConnections": {
"documentdb": {
"api": {
"id": "/subscriptions/#appsetting('subscriptionId')/providers/Microsoft.Web/locations/#appsetting('location_name')/managedApis/documentdb"
},
"connection": {
"id": "/subscriptions/#appsetting('subscriptionId')/resourceGroups/#appsetting('resourceGroup_name')/providers/Microsoft.Web/connections/myCosmosCon"
},
"connectionRuntimeUrl": "#appsetting('connection_runtimeUrl')",
"authentication": {
"type": "ManagedServiceIdentity"
}
}
}
}
Now, when I deploy the ARM template of my Logic app, workflow, ... etc. I see no errors, the workflow looks also good. The only problem is the URL link to the HTTP trigger is not generated, I can't run the program.
However, if I change the connection_runtimeUrl in the connections.json file to have the actual value; to look something like:
"connectionRuntimeUrl": "https://xxxxxxxxxxxxx.xx.common.logic-norwayeast.azure-apihub.net/apim/myCosmosCon/xxxxxxxxxxxxxxxxxxxxxxxx/",
The URL is generated directly and I can simply run the workflow. AFTER that, if I return the connection_runtimeUrl as it was (a call to appsettings()), it still working!! the link also stay there.
It looks like the when I deploy the Logic app and the workflow that the connections.json, do not compile or make the call, so Azure think that there is an error and do not generate the link.
Any idea about how to solve the problem??
Thanks!
Not sure but could be the issue:
When you create a connection api for a logic app standard, you also need to create an access policy at the connection api level for the system assigned identity running the logic app standard.
param location string = resourceGroup().location
param cosmosDbAccountName string
param connectorName string = '${cosmosDbAccountName}-connector'
// The principalid of the logic app standard system assigned identity
param principalId string
// get a reference to the cosmos db account
resource cosmosDbAccount 'Microsoft.DocumentDB/databaseAccounts#2021-06-15' existing = {
name: cosmosDbAccountName
}
// create the related connection api
resource cosmosDbConnector 'Microsoft.Web/connections#2016-06-01' = {
name: connectorName
location: location
kind: 'V2'
properties: {
displayName: connectorName
parameterValues: {
databaseAccount: cosmosDbAccount.name
accessKey: listKeys(cosmosDbAccount.id, cosmosDbAccount.apiVersion).primaryMasterKey
}
api: {
id: 'subscriptions/${subscription().subscriptionId}/providers/Microsoft.Web/locations/${location}/managedApis/documentdb'
}
}
}
// Grant permission to the logic app standard to access the connection api
resource cosmosDbConnectorAccessPolicy 'Microsoft.Web/connections/accessPolicies#2016-06-01' = {
name: '${cosmosDbConnector.name}/${principalId}'
location: location
properties: {
principal: {
type: 'ActiveDirectory'
identity: {
tenantId: subscription().tenantId
objectId: principalId
}
}
}
}
output connectionRuntimeUrl string = reference(cosmosDbConnector.id, cosmosDbConnector.apiVersion, 'full').properties.connectionRuntimeUrl
I'm having trouble with the exact same issue/bug. The only work around as I see it is to deploy the workflow twice. First time with an actual URL pointing to a dummy connection and the second time with the appsetting reference.

"The parameter LinuxFxVersion has an invalid value" when creating WebApp resource from Node.js

I am trying to create a simple WebApp using the Azure SDK for JS in a Node.js environment, but I keep getting the response:
{
"Code":"BadRequest",
"Message":"The parameter LinuxFxVersion has an invalid value.",
"Target":null,
"Details":[
{"Message":"The parameter LinuxFxVersion has an invalid value."},
{"Code":"BadRequest"},
{"ErrorEntity": {
"ExtendedCode":"01007",
"MessageTemplate":"The parameter {0} has an invalid value.",
"Parameters":["LinuxFxVersion"],
"Code":"BadRequest",
"Message":"The parameter LinuxFxVersion has an invalid value."}
}],
"Innererror":null
}
I've tried a variety of different sets of properties and environments with no success. I always get this error. Here's a snippet of the TypeScript code I am using:
const wsmClient: WebSiteManagementClient...
const webAppName: string...
const servicePlanId: string...
const rgName: string...
const envelope: Site = {
name: webAppName,
location: 'westus2',
kind: 'app,linux',
serverFarmId: servicePlanId,
siteConfig: {
linuxFxVersion: 'JAVA|11-java11'
}
};
const appResp = await wsmClient.webApps.createOrUpdate(
rgName,
webAppName,
envelope
);
What am I doing wrong?
Reason:
Your app service plan is not Linux, actually it's Windows. Windows host doesn't have parameter LinuxFxVersion.
If we create a site without explicitly configuring the host as Linux, it will be a Windows host/serverFarm/app service plan by default. Using {"kind":"linux"} is not enough.
Solution:
Explicitly define the app service plan in Linux, and make sure {"reserved": true} to set it as a Linux host (See documentation)
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2019-08-01",
"name": "[parameters('hostingPlanName')]",
"location": "[parameters('location')]",
"kind": "app,linux",
"properties": {
"reserved": true
},
"sku": {
"Tier": "[parameters('hostingPlanSkuTier')]",
"Name": "[parameters('hostingPlanSkuName')]"
}
}
I test your json data, it's caused your properties. Your json data has no "properties" property. If you want to create web with the json property check this web app Rest API request body:Web Apps - Create Or Update.
The correct format should be like the below sample:
{
"location": "CentralUS",
"kind":"app,linux",
"properties":{
"serverFarmId":"your Resource ID",
"siteConfig":{
"linuxFxVersion":"JAVA|11-java11"
}
}
}
#imwenyz answer helped me.
I am running as Azure DevOps pipeline, which has AzureWebApp#1 task. And the app service on Azure that I configured is windows based.
I am getting the error at this task as follows.
##[error]Error: Failed to patch App Service 'BasicReactApp' configuration. Error: BadRequest - The parameter LinuxFxVersion has an invalid value. (CODE: 400)
So I had to modify the task as follows.
- task: AzureWebApp#1
displayName: 'Azure Web App Deploy: '
inputs:
azureSubscription: $(azureSubscription)
#appType: webAppLinux # this is the cause for the error in my case.
appType: webApp
appName: $(webAppName)
runtimeStack: 'NODE|14.x'
package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
startUpCommand: 'npm run start'
Basically, as you can see, changed the appType from webAppLinux to webApp
I had the similar issue while deploying the webapp using Terraform.
resource "azurerm_linux_web_app" "app_service" {
name = "app-name"
location = azurerm_resource_group.resourcegroup.location
resource_group_name = azurerm_resource_group.resourcegroup.name
service_plan_id = azurerm_service_plan.plan.id
site_config {
application_stack {
docker_image = "<image-registry>"
docker_image_tag = var.GIT_VERSION
}
}
}
In my case, docker_image_tag version was not populated correctly. After providing the correct value, Terraform deployed successfully.

Unable to use Resource Functions for Azure Resource Manager Templates

My parameters file looks as follows:
{
"$schema":"http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion":"1.0.0.0",
"parameters":{
"siteName":{
"value":"my-api-application"
},
"appServicePlanName":{
"value":"MyServicePlan"
},
"siteLocation":{
"value":"West US"
},
"vaultResourceGroup": {
"value":"my-vault-res-group"
},
"vaultName": {
"value":"my-keyvault"
},
"nodeEnv": {
"value":"development"
},
"adminPassword": {
"reference": {
"keyVault": {
"id": "/subscriptions/yyyyyyyy-xxxx-xxxx-xxxx-yyyyyyyy/resourceGroups/my-vault-res-group/providers/Microsoft.KeyVault/vaults/my-keyvault"
},
"secretName": "adminPassword"
}
}
}
}
The adminPassword value will be picked up from the specified KeyVault, with the particular id. However, I have to hard code the "id" value.
According to this link, I could specify the id using some thing like this:
resourceId(subscription().subscriptionId, parameters('vaultResourceGroup'), 'Microsoft.KeyVault/vaults', parameters('vaultName'))]
However, when using the above syntax/Resource Functions, I receive an error while releasing and deploying my App Service using the VSTS (I used Azure Resource Group Deployment task for APP deployment). The error is some what like this:
The id must be of the following format:
/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
Not sure what am I doing wrong?
You're not doing anything wrong, that's intentional. You must use a literal resourceId in the parameters file (parameters files don't allow for function use).
If you have a scenario for a dynamic KeyVault id you can use a nested deployment:
https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-keyvault-parameter#reference-a-secret-with-dynamic-id

Resources