Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a KeyVault secret in an existing keyvault

Within an ARM template, I want to write a secret in a pre-exising KeyVault - that I have not created as part of the current template.

I am using this code

 {
        "dependsOn": [
            "/subscriptions/<my-subscription-id>/resourceGroups/<my-resource-group>/providers/Microsoft.KeyVault/vaults/keyvaulttest"
        ],
        "type": "Microsoft.KeyVault/vaults/secrets",
        "name": "keyvaulttest/test",
        "apiVersion": "2015-06-01",
        "tags": {
            "displayName": "secret"
        },
        "properties": {
            "value": "value1"
        }
    }

When deploying this I am getting the following exception ( on the dependsOn item)

Deployment template validation failed: 'The resource 'Microsoft.KeyVault/vaults/keyvaulttest' is not defined in the template. Please see https://aka.ms/arm-template for usage details.'. (Code: InvalidTemplate)

I've also tried replacing the value in dependsOn with this (getting the resource Id dynamically) but I'm getting the same exception

[resourceId('<resourceGroup>','Microsoft.KeyVault/vaults','keyvaulttest')]

Any other way that I can use to save a secret in a keyvalult from an ARM template?

like image 335
AlexDrenea Avatar asked Jun 14 '17 19:06

AlexDrenea


3 Answers

For me this worked with the 'nested template' inside the same ARM template. This gives the option to select a different resource group if the KeyVault does not exists in the same Resource Group as you are deploying to.

This also doesn't overwrite the current KeyVault Config from the solution given above. My example is base on the Servicequeue quick template

{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
    "serviceBusNamespaceName": {
        "type": "string",
        "metadata": {
            "description": "Name of the Service Bus namespace"
        }
    },
    "serviceBusQueueName1": {
        "type": "string",
        "metadata": {
            "description": "Name of the Queue"
        }
    },
    "serviceBusQueueName2": {
        "type": "string",
        "metadata": {
            "description": "Name of the Queue"
        }
    },
    "location": {
        "type": "string",
        "defaultValue": "[resourceGroup().location]",
        "metadata": {
            "description": "Location for all resources."
        }
    }
},
"variables": {
    "defaultSASKeyName": "RootManageSharedAccessKey",
    "authRuleResourceId": "[resourceId('Microsoft.ServiceBus/namespaces/authorizationRules', parameters('serviceBusNamespaceName'), variables('defaultSASKeyName'))]"
},
"resources": [
    {
        "apiVersion": "2017-04-01",
        "name": "[parameters('serviceBusNamespaceName')]",
        "type": "Microsoft.ServiceBus/namespaces",
        "location": "[parameters('location')]",
        "sku": {
            "name": "Standard"
        },
        "properties": {},
        "resources": [
            {
                "apiVersion": "2017-04-01",
                "name": "[parameters('serviceBusQueueName1')]",
                "type": "Queues",
                "dependsOn": [
                    "[concat('Microsoft.ServiceBus/namespaces/', parameters('serviceBusNamespaceName'))]"
                ],
                "properties": {
                    "lockDuration": "PT5M",
                    "maxSizeInMegabytes": "1024",
                    "requiresDuplicateDetection": "false",
                    "requiresSession": "false",
                    "defaultMessageTimeToLive": "P10675199DT2H48M5.4775807S",
                    "deadLetteringOnMessageExpiration": "false",
                    "duplicateDetectionHistoryTimeWindow": "PT10M",
                    "maxDeliveryCount": "10",
                    "autoDeleteOnIdle": "P10675199DT2H48M5.4775807S",
                    "enablePartitioning": "false",
                    "enableExpress": "false"
                }
            },
            {
                "apiVersion": "2017-04-01",
                "name": "[parameters('serviceBusQueueName2')]",
                "type": "Queues",
                "dependsOn": [
                    "[concat('Microsoft.ServiceBus/namespaces/', parameters('serviceBusNamespaceName'))]",
                    "[concat(concat('Microsoft.ServiceBus/namespaces/', parameters('serviceBusNamespaceName')), concat('/Queues/', parameters('serviceBusQueueName1')))]"
                ],
                "properties": {
                    "lockDuration": "PT5M",
                    "maxSizeInMegabytes": "1024",
                    "requiresDuplicateDetection": "false",
                    "requiresSession": "false",
                    "defaultMessageTimeToLive": "P10675199DT2H48M5.4775807S",
                    "deadLetteringOnMessageExpiration": "false",
                    "duplicateDetectionHistoryTimeWindow": "PT10M",
                    "maxDeliveryCount": "10",
                    "autoDeleteOnIdle": "P10675199DT2H48M5.4775807S",
                    "enablePartitioning": "false",
                    "enableExpress": "false",
                    "forwardTo": "[parameters('serviceBusQueueName1')]",
                    "forwardDeadLetteredMessagesTo": "[parameters('serviceBusQueueName1')]"
                }
            }
        ]
    },
    {
        "apiVersion": "2017-05-10",
        "name": "nestedTemplate",
        "type": "Microsoft.Resources/deployments",
        "resourceGroup": "keyvaultSubscriptionResourceGroup",
        "subscriptionId": "keyvaultSubscriptionId",
        "properties": {
            "mode": "Incremental",
            "template": {
                "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
                "contentVersion": "1.0.0.0",
                "parameters": {},
                "variables": {},
                "resources": [
                    {
                        "type": "Microsoft.KeyVault/vaults/secrets",
                        "name": "[concat(parameters('keyvaultName'), '/ServiceBus-primaryConnectionString')]",
                        "apiVersion": "2018-02-14",
                        "properties": {
                            "value": "[listkeys(variables('authRuleResourceId'), '2017-04-01').primaryConnectionString]"
                        }
                    },
                    {
                        "type": "Microsoft.KeyVault/vaults/secrets",
                        "name": "[concat(parameters('keyvaultName'), '/ServiceBus-primaryKey')]",
                        "apiVersion": "2018-02-14",
                        "properties": {
                            "value": "[listkeys(variables('authRuleResourceId'), '2017-04-01').primaryKey]"
                        }
                    }
                ]
            }
        }
    }
]

}

like image 80
Carlos Avatar answered Oct 23 '22 09:10

Carlos


You need add resource Microsoft.KeyVault/vaults to your template. When your key vault has been created, it will use your key vault not create new key vault. The following template works for me.

 "resources": [
    {
        "type": "Microsoft.KeyVault/vaults",
        "name": "shui",
        "apiVersion": "2015-06-01",
        "location": "[resourceGroup().location]",
        "properties": {
        "sku": {
        "family": "A",
        "name": "Standard"
        },
        "tenantId": "[subscription().tenantId]",
        "accessPolicies": [
      {
        "tenantId": "[subscription().tenantId]",
        "objectId": "<your Azure account objectID>",
        "permissions": {
          "keys": [ "All" ],
          "secrets": [ "All" ]
        }
      }
    ]
  }
},
        {
        "type": "Microsoft.KeyVault/vaults/secrets",
        "name": "shui/SomeSecret",
        "apiVersion": "2015-06-01",
        "properties": {
        "contentType": "text/plain",
        "value": "ThisIpsemIsSecret"
  },
        "dependsOn": [
            "[resourceId('Microsoft.KeyVault/vaults', 'shui')]"
            ]
        }

    ]  

This blog (Add secrets to your Azure Key Vault using ARM templates) will be helpful.

You could find your key vault json file on Azure Portal.enter image description here

Add the resource "type": "Microsoft.KeyVault/vaults/secrets", to the json file. The following is the cmdlet that I use to add secrets, it works for me.

PS C:\Users\v-shshui> New-AzureRmResourceGroupDeployment -Name shuitest -ResourceGroupName shui -TemplateFile "D:\vault.json"

cmdlet New-AzureRmResourceGroupDeployment at command pipeline position 1
Supply values for the following parameters:
(Type !? for Help.)
keyVaultName: shui


DeploymentName          : shuitest
ResourceGroupName       : shui
ProvisioningState       : Succeeded
Timestamp               : 6/16/2017 3:15:27 AM
Mode                    : Incremental
TemplateLink            :
Parameters              :
                          Name             Type                       Value
                          ===============  =========================  ==========
                          keyVaultName     String                     shui

Outputs                 :
DeploymentDebugLogLevel :
like image 4
Shui shengbao Avatar answered Oct 23 '22 08:10

Shui shengbao


You only need to include the secrets in the ARM template, not the vault itself.

ARM template

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "name": {
      "type": "string"
    },
    "secretsObject": {
      "type": "secureObject",
      "defaultValue": "{}",
      "metadata": {
        "description": "all secrets {\"secretName\":\"\",\"secretValue\":\"\"} wrapped in a secure object"
      }
    }
  },
  "resources": [
    {
      "type": "Microsoft.KeyVault/vaults/secrets",
      "name": "[concat(parameters('name'), '/', parameters('secretsObject').secrets[copyIndex()].secretName)]",
      "apiVersion": "2015-06-01",
      "properties": {
        "value": "[parameters('secretsObject').secrets[copyIndex()].secretValue]"
      },
      "copy": {
        "name": "secretsCopy",
        "count": "[length(parameters('secretsObject').secrets)]"
      }
    }
  ]
}

POSH example

#Requires -Version 3.0
#Requires -Modules AzureRM

#---------------------------------------
# INPUT PARAMETERS
#---------------------------------------

Param(
    [Parameter(Mandatory=$true)]
    [String] $secretName,
    [Parameter(Mandatory=$true)]
    [String] $secretValue,
    [Parameter(Mandatory=$true)]
    [String] $keyVaultName,
    [Parameter(Mandatory=$true)]
    [String] $resourceGroupName
)

$secretsObject = @{ # wrap secrets array in hashtable so it can be cast to secureObject
    secrets = @(@{ secretName=$secretName; secretValue=$secretValue })
}
$deployKvSecretConfig = @{
    nameFromTemplate=$keyVaultName
    ResourceGroupName=$resourceGroupName
    secretsObject=$secretsObject
}

$deployResult = New-AzureRmResourceGroupDeployment -TemplateFile ("\.\deploy_keyvault_secret.template.json") @deployKvSecretConfig

If ($deployResult.ProvisioningState -eq "Failed") {
    throw ("Deployment ""{0}"" failed, please check the deployment logs for resource group ""{1}""!" -f $deployResult.DeploymentName, $deployResult.ResourceGroupName)
}
like image 2
PhilChuang Avatar answered Oct 23 '22 09:10

PhilChuang