Home > Net >  Bicep pass storage account connection string to key vault secret
Bicep pass storage account connection string to key vault secret

Time:10-23

I have been browsing about this but I couldn't find any practical or useful solution.

I am deploying a storage account using bicep. This works just fine, but I am trying to get the storage account connection string and store as a secret into a azure key vault.

So far I have the following code

param tenantCode array = [
  'dsec'
]

param storageAccounts string = 'sthrideveur'

resource storage_Accounts 'Microsoft.Storage/storageAccounts@2021-06-01' = [ for tenantcode in tenantCode :{
  name: 'stnmeur${tenantcode}'
  location: 'westeurope'
  sku: {
    name: 'Standard_RAGRS'
  }
  kind: 'StorageV2'
  properties: {
    allowCrossTenantReplication: true
    minimumTlsVersion: 'TLS1_2'
    allowBlobPublicAccess: false
    allowSharedKeyAccess: true
    networkAcls: {
      bypass: 'AzureServices'
      virtualNetworkRules: []
      ipRules: []
      defaultAction: 'Allow'
    }
    supportsHttpsTrafficOnly: true
    encryption: {
      services: {
        file: {
          keyType: 'Account'
          enabled: true
        }
        blob: {
          keyType: 'Account'
          enabled: true
        }
      }
      keySource: 'Microsoft.Storage'
    }
    accessTier: 'Cool'
  }
}]

resource devkeyvault 'Microsoft.KeyVault/vaults@2021-06-01-preview' existing = {
  name : 'keyvayltname'
}

I found this code but unfortunately it comes with no explanation and is not working for me

resource keyVault 'Microsoft.KeyVault/vaults@2019-09-01' existing = {
  name: last(split(keyVaultId, '/'))
  resource storageSecret 'secrets' = {
    name: 'StorageAccount-ConnectionString'
    properties: {
    value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccountName};AccountKey=${listKeys(storageAccount.id, storageAccount.apiVersion).keys[1].value}'
   }
  }
}

Can any one please explain me how to achieve this if its possible. thank you so much for any help

UPDATE:

So I did some update to my code:

param tenantCode array = [
  'dsec'
]

var storageName = [for item in tenantCode :{
  name: string('sthrideveur${item}')
}]


var connectionStringSecretName = [for n in storageName :{
  name: '${n.name}'
}]





resource storage_Accounts 'Microsoft.Storage/storageAccounts@2021-06-01' = [ for name in storageName :{
  name: '${name.name}'
  location: 'westeurope'
  sku: {
    name: 'Standard_RAGRS'
  }
  kind: 'StorageV2'
  properties: {
    allowCrossTenantReplication: true
    minimumTlsVersion: 'TLS1_2'
    allowBlobPublicAccess: false
    allowSharedKeyAccess: true
    networkAcls: {
      bypass: 'AzureServices'
      virtualNetworkRules: []
      ipRules: []
      defaultAction: 'Allow'
    }
    supportsHttpsTrafficOnly: true
    encryption: {
      services: {
        file: {
          keyType: 'Account'
          enabled: true
        }
        blob: {
          keyType: 'Account'
          enabled: true
        }
      }
      keySource: 'Microsoft.Storage'
    }
    accessTier: 'Cool'
  }
}]


resource keyVault 'Microsoft.KeyVault/vaults@2019-09-01' existing = {
  name : 'XXXX'
}

// Store the connection string in KV if specified
resource storageAccountConnectionString 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = {
  name: '${connectionStringSecretName[0].name}'
  properties: {
    value: 'DefaultEndpointsProtocol=https;AccountName=${storage_Accounts[0]};AccountKey=${listKeys('${storage_Accounts[0].id}', '${storage_Accounts[0].apiVersion}').keys[0].value};EndpointSuffix=${environment().suffixes.storage}'
  }
}

But when I run the template I get this error

InvalidTemplate - Deployment template validation failed: 'The template resource 'sthrideveurdsec' for type 'Microsoft.KeyVault/vaults/secrets' at line '1' and column '1378' has incorrect segment lengths. A nested resource type must have identical number of segments as its resource name. A root resource type must have segment length one greater than its resource name. Please see https://aka.ms/arm-template/#resources for usage details.'.

I see in the error that the name is correct but I don't fully understand what I am doing wrong with the segment length

CodePudding user response:

You need to make sure that the key vault has the Azure Resource Manager for template deployment option enable:

enter image description here

If you have networking enable on key vault, make sure the Allow trusted Microsoft services to bypass this firewall is enabe:

enter image description here

The user or service principal deploying the bicep file also need permission to create secrets in key vault.

You can then add the storage connectionstring like this:

param storageAccountName string
...
param keyVaultName string
param connectionStringSecretName string = '${storageAccountName}-connectionstring'

// Create storage account
resource storageAccount 'Microsoft.Storage/storageAccounts@2019-06-01' = {
  name: storageAccountName
  ...
}

// Get reference to KV
resource keyVault 'Microsoft.KeyVault/vaults@2019-09-01' existing = {
  name: keyVaultName
}

// Store the connection string in KV if specified
resource storageAccountConnectionString 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = {
  name: '${keyVault.name}/${connectionStringSecretName}'
  properties: {
    value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${listKeys(storageAccount.id, storageAccount.apiVersion).keys[0].value};EndpointSuffix=${environment().suffixes.storage}'
  }
}

if you're using an array, you could do something like that:

param storageAccountNames array
...
param keyVaultName string

// Create storage accounts
resource storageAccounts 'Microsoft.Storage/storageAccounts@2019-06-01' = [ for name in storageAccountNames :{
  name: name
  ...
}]

// Get reference to KV
resource keyVault 'Microsoft.KeyVault/vaults@2019-09-01' existing = {
  name: keyVaultName
}

// Store the connectionstrings in KV if specified
resource storageAccountConnectionStrings 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = [ for (name, i) in storageAccountNames :{
  name: '${keyVault.name}/${name}-connectionstring'
  properties: {
    value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccounts[i].name};AccountKey=${listKeys(storageAccounts[i].id, storageAccounts[i].apiVersion).keys[0].value};EndpointSuffix=${environment().suffixes.storage}'
  }
}]

  • Related