0

I am building an arm template that deploys a web app, sql database and a key vault.

The web app will be deployed with

1- System identity (which will be used to access the keyvault).

2- Connection string to the sql database that would be using the keyvault access way:

@Microsoft.KeyVault(SecretUri=https://', parameters('keyVaultName'),'.vault.azure.net/secrets/connectionString)')

The keyvault will be deployed with

1 - Access policy for the webapp above.

2 - Secret that contains the connection string (constructed in the pipeline while deploying).

The webapp needs to be deployed before the keyvault, so when the keyvault is deployed, it can find the webapp identity so it creates the access policy for it.

But the issue I am having with this approach is that when the connection string added as part of the webapp, the keyvault doesn't exist yet, so that @Microsoft.KeyVault way of accessing the secret doesn't work, even after the keyvault is deployed, and I get the below

enter image description here

But if I remove the connection string and add it manually after the deployment, keeping the exact same value, it works. enter image description here

How can I deploy the connection string containing the keyvault access way where the webapp is happy and can access the connection string in it?

I think the problem is clear and no need to include the template, but if you do need to look please leave a comment and will add to the question.

EDIT Template

2
  • 1
    Hello @Mocas , depends on condition on the nested arm template should resolve the issue but not sure if that will work in this case . Can you add the template here so that I can test it and check if it works or not ? Commented Sep 3, 2021 at 4:26
  • 1
    @AnsumanBal-MT link to the template added. Thanks. Commented Sep 3, 2021 at 20:16

1 Answer 1

2

You can use depends on condition on keyvault . I created a Keyvault first and added

"dependsOn": [
            "[resourceId('Microsoft.Web/sites', parameters('appBaseName'))]"

while setting the access policies.

So the complete template will be :

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "appBaseName": {
      "type": "string"
    },
    "sqlName": {
      "type": "string"
    },
    "adminLogin": {
      "type": "string"
    },
    "secretValue": {
      "type": "securestring"
    },
    "adminPassword": {
      "type": "securestring"
    },
    "appInsights": {
      "type": "string"
    },
    "collation": {
      "type": "string",
      "defaultValue": "Arabic_CI_AS"
    },
    "edition": {
      "type": "string",
      "defaultValue": "Basic"
    },
    "secretsPermissions": {
      "type": "array",
      "defaultValue": [
        "get",
        "list"
      ]
    },
    "objectiveName": {
      "type": "string",
      "defaultValue": "Basic"
    },
    "keyVaultName": {
      "type": "string"
    }
  },
  "resources": [
        {      
      "type": "Microsoft.KeyVault/vaults",
      "apiVersion": "2019-09-01",
      "name": "[parameters('keyVaultName')]",
      "location": "[resourceGroup().location]",
      "properties": {
        "enabledForDeployment": false,
        "enabledForDiskEncryption": false,
        "enabledForTemplateDeployment": false,
        "tenantId": "[subscription().tenantId]",
        "accessPolicies": [
          {
            "objectId": "[reference(concat('Microsoft.Web/sites/', parameters('appBaseName')), '2018-11-01','Full').identity.principalId]",
            "tenantId": "[subscription().tenantId]",
            "permissions": {
            "secrets": "[parameters('secretsPermissions')]"
            },
          "dependsOn": [
            "[resourceId('Microsoft.Web/sites', parameters('appBaseName'))]"
          ]
          }
        ],
        "sku": {
          "name": "Standard",
          "family": "A"
        },
        "networkAcls": {
          "bypass": "AzureServices",
          "defaultAction": "Allow"
        }
      }
    },
    {
      "type": "Microsoft.KeyVault/vaults/secrets",
      "apiVersion": "2019-09-01",
      "name": "[concat(parameters('keyVaultName'), '/', 'connectionString')]",
      "location": "[resourceGroup().location]",
      "dependsOn": [
        "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]"
      ],
      "properties": {
        "value": "[parameters('secretValue')]"
      }
    },
    {
      "name": "[parameters('appInsights')]",
      "type": "microsoft.insights/components",
      "location": "[resourceGroup().location]",
      "apiVersion": "2020-02-02",
      "kind": "web",
      "properties": {
        "ApplicationId": "[parameters('appInsights')]",
        "Application_Type": "web",
        "Flow_Type": "Bluefield",
        "Request_Source": "rest"
      }
    },
    {
      "name": "[parameters('appBaseName')]",
      "type": "Microsoft.Web/serverfarms",
      "location": "[resourceGroup().location]",
      "apiVersion": "2015-08-01",
      "sku": {
        "name": "F1"
      },
      "dependsOn": [],
      "tags": {
        "displayName": "appBaseName"
      },
      "properties": {
        "name": "[parameters('appBaseName')]",
        "numberOfWorkers": 1
      }
    },
    {
      "name": "[parameters('appBaseName')]",
      "type": "Microsoft.Web/sites",
      "location": "[resourceGroup().location]",
      "apiVersion": "2015-08-01",
      "identity": { "type": "SystemAssigned" },
      "dependsOn": [
        "[resourceId('Microsoft.Web/serverfarms', parameters('appBaseName'))]",
        "[resourceId('microsoft.insights/components', parameters('appInsights'))]"
      ],
      "tags": {
        "[concat('hidden-related:', resourceId('Microsoft.Web/serverfarms', parameters('appBaseName')))]": "Resource",
        "displayName": "appBaseName"
      },
      "properties": {
        "name": "[parameters('appBaseName')]",
        "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('appBaseName'))]",
        "siteConfig": {
          "location": "[resourceGroup().location]",
          "appSettings" : [
            {
              "name": "APPINSIGHTS_INSTRUMENTATIONKEY",
              "value": "[reference(concat('microsoft.insights/components/', parameters('appInsights')), '2015-05-01').InstrumentationKey]"
            }],
            "connectionStrings": [
            {
              "name": "connectionString",
              "connectionString": "[concat('@Microsoft.KeyVault(SecretUri=https://', parameters('keyVaultName'),'.vault.azure.net/secrets/connectionString)')]",
              "type": 1
            }
          ]
        }
      }
    },
    {
      "name": "[parameters('sqlName')]",
      "type": "Microsoft.Sql/servers",
      "location": "[resourceGroup().location]",
      "apiVersion": "2014-04-01",
      "dependsOn": [],
      "properties": {
        "administratorLogin": "[parameters('adminLogin')]",
        "administratorLoginPassword": "[parameters('adminPassword')]"
      },
      "resources": [
        {
          "name": "AllowAllWindowsAzureIps",
          "type": "firewallRules",
          "location": "[resourceGroup().location]",
          "apiVersion": "2014-04-01",
          "dependsOn": [
            "[resourceId('Microsoft.Sql/servers', parameters('sqlName'))]"
          ],
          "properties": {
            "startIpAddress": "0.0.0.0",
            "endIpAddress": "0.0.0.0"
          }
        },
        {
          "name": "[parameters('sqlName')]",
          "type": "databases",
          "location": "[resourceGroup().location]",
          "apiVersion": "2014-04-01",
          "dependsOn": [
            "[resourceId('Microsoft.Sql/servers', parameters('sqlName'))]"
          ],
          "properties": {
            "collation": "[parameters('collation')]",
            "edition": "[parameters('edition')]",
            "maxSizeBytes": "1073741824",
            "requestedServiceObjectiveName": "[parameters('objectiveName')]"
          }
        }
      ]
    }
  ],
"outputs": {}
}

Output:

(Successfully deployed)

enter image description here

enter image description here

(Keyvault reference is properly set)

enter image description here

(Vault Access Policy is properly set as well)

enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

Hello @Mocas , did some changes to your template and tested it on my environment and it works fine for me . So you can use above template I have added in answer.
Glad to hear that !!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.