Partager via


Gérer les secrets en Bicep

Les déploiements nécessitent souvent que les secrets soient stockés et propagés en toute sécurité dans votre environnement Azure. Bicep et Azure offrent de nombreuses fonctionnalités pour vous aider à gérer les secrets dans vos déploiements.

Éviter les secrets lorsque vous le pouvez

Dans de nombreuses situations, il est possible de ne pas utiliser de secrets du tout. De nombreuses ressources Azure prennent en charge les identités managées, ce qui leur permet de s’authentifier et d’être autorisées à accéder à d’autres ressources dans Azure, sans que vous ayez besoin de manipuler ou de gérer des informations d’identification. En outre, certains services Azure peuvent générer automatiquement des certificats HTTPS pour vous, ce qui vous évite de manipuler des certificats et des clés privées. Utilisez des identités managées et des certificats gérés par les services dans la mesure du possible.

Utiliser des paramètres sécurisés

Lorsque vous devez fournir des secrets à vos déploiements Bicep en tant que paramètres, utilisez l’élément décoratif @secure(). Lorsque vous marquez un paramètre comme sécurisé, Azure Resource Manager évite de consigner la valeur ou de l’afficher dans le portail Azure, Azure CLI ou Azure PowerShell.

Éviter les sorties pour les secrets

N’utilisez pas de sorties Bicep pour des données sécurisées. Les sorties sont consignées dans l’historique du déploiement et toute personne ayant accès au déploiement peut voir les valeurs des sorties d’un déploiement.

Si vous devez générer un secret dans un déploiement Bicep et le rendre accessible à l’appelant ou à d’autres ressources, envisagez d’utiliser l’une des approches suivantes.

Rechercher des secrets de façon dynamique

Parfois, vous devez accéder au secret d’une ressource pour configurer une autre ressource.

Par exemple, vous pouvez avoir créé un compte de stockage dans un autre déploiement et avoir besoin d’accéder à sa clé primaire pour configurer une application Azure Functions. Vous pouvez utiliser le mot-clé existing pour obtenir une référence fortement typée au compte de stockage précréé, puis utiliser la méthode listKeys() du compte de stockage pour créer une chaîne de connexion avec la clé primaire :

L’exemple suivant fait partie d’un exemple plus développé. Pour découvrir un fichier Bicep que vous pouvez déployer, consultez le fichier complet.

param location string = resourceGroup().location
param storageAccountName string
param functionAppName string = 'fn-${uniqueString(resourceGroup().id)}'

var appServicePlanName = 'MyPlan'
var applicationInsightsName = 'MyApplicationInsights'

resource storageAccount 'Microsoft.Storage/storageAccounts@2021-06-01' existing = {
  name: storageAccountName
}

var storageAccountConnectionString = 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};EndpointSuffix=${environment().suffixes.storage};AccountKey=${listKeys(storageAccount.id, storageAccount.apiVersion).keys[0].value}'

resource functionApp 'Microsoft.Web/sites@2023-12-01' = {
  name: functionAppName
  location: location
  kind: 'functionapp'
  properties: {
    httpsOnly: true
    serverFarmId: appServicePlan.id
    siteConfig: {
      appSettings: [
        {
          name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
          value: applicationInsights.properties.InstrumentationKey
        }
        {
          name: 'AzureWebJobsStorage'
          value: storageAccountConnectionString
        }
        {
          name: 'FUNCTIONS_EXTENSION_VERSION'
          value: '~3'
        }
        {
          name: 'FUNCTIONS_WORKER_RUNTIME'
          value: 'dotnet'
        }
        {
          name: 'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING'
          value: storageAccountConnectionString
        }
      ]
    }
  }
}

resource appServicePlan 'Microsoft.Web/serverfarms@2023-12-01' = {
  name: appServicePlanName
  location: location
  sku: {
    name: 'Y1' 
    tier: 'Dynamic'
  }
}

resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = {
  name: applicationInsightsName
  location: location
  kind: 'web'
  properties: { 
    Application_Type: 'web'
    publicNetworkAccessForIngestion: 'Enabled'
    publicNetworkAccessForQuery: 'Enabled'
  }
}

En utilisant cette approche, vous évitez de transmettre des secrets dans votre fichier Bicep ou en dehors.

Vous pouvez également utiliser cette approche pour stocker des secrets dans un coffre de clés.

Utiliser Key Vault

Azure Key Vault est conçu pour stocker et gérer des données sécurisées. Utilisez un coffre de clés pour gérer vos secrets, certificats, clés et autres données qui doivent être protégées et partagées.

Vous pouvez créer et gérer des coffres et des secrets en utilisant Bicep. Définissez vos coffres en créant une ressource du type Microsoft.KeyVault/vaults.

Lorsque vous créez un coffre, vous devez déterminer qui et quoi peut accéder à ses données. Si vous prévoyez de lire les secrets du coffre à partir d’un fichier Bicep, définissez la propriété enabledForTemplateDeployment sur true.

Ajouter des secrets à un coffre de clés

Les secrets sont une ressource enfant et peuvent être créés à l’aide du type Microsoft.KeyVault/vaults/secrets. L’exemple suivant montre comment créer un coffre et un secret :

L’exemple suivant fait partie d’un exemple plus développé. Pour découvrir un fichier Bicep que vous pouvez déployer, consultez le fichier complet.

param location string = resourceGroup().location
param keyVaultName string = 'mykv${uniqueString(resourceGroup().id)}'

resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = {
  name: keyVaultName
  location: location
  properties: {
    enabledForTemplateDeployment: true
    tenantId: tenant().tenantId
    accessPolicies: [
    ]
    sku: {
      name: 'standard'
      family: 'A'
    }
  }
}

resource keyVaultSecret 'Microsoft.KeyVault/vaults/secrets@2023-07-01' = {
  parent: keyVault
  name: 'MySecretName'
  properties: {
    value: 'MyVerySecretValue'
  }
}

Conseil

Lorsque vous utilisez des pipelines de déploiement automatisés, il peut parfois être difficile de déterminer comment démarrer les secrets de coffre de clés pour vos déploiements. Par exemple, si l’on vous a fourni une clé API à utiliser pour communiquer avec une API externe, le secret doit être ajouté à un coffre avant de pouvoir être utilisé dans vos déploiements.

Lorsque vous travaillez avec des secrets qui proviennent d’un tiers, vous devrez peut-être les ajouter manuellement à votre coffre, puis vous pourrez faire référence au secret pour toutes les utilisations ultérieures.

Utiliser un coffre de clés avec des modules

Lorsque vous utilisez des modules Bicep, vous pouvez fournir des paramètres sécurisés en utilisant la fonction getSecret.

Vous pouvez également faire référence à un coffre de clés défini dans un autre groupe de ressources en utilisant les mots clés existing et scope ensemble. Dans l’exemple suivant, le fichier Bicep est déployé dans un groupe de ressources nommé Networking. La valeur du paramètre mySecret du module est définie dans un coffre de clés nommé contosonetworkingsecrets situé dans le groupe de ressources Secrets :

resource networkingSecretsKeyVault 'Microsoft.KeyVault/vaults@2023-07-01' existing = {
  scope: resourceGroup('Secrets')
  name: 'contosonetworkingsecrets'
}

module exampleModule 'module.bicep' = {
  name: 'exampleModule'
  params: {
    mySecret: networkingSecretsKeyVault.getSecret('mySecret')
  }
}

Utiliser un coffre de clés dans un fichier .bicepparam

Quand vous utilisez le format de fichier .bicepparam, vous pouvez fournir des valeurs sécurisées aux paramètres en utilisant la fonction getSecret.

Référencez le coffre de clés en fournissant l’ID d’abonnement, le nom du groupe de ressources et le nom du coffre de clés. Vous pouvez obtenir la valeur du secret en fournissant le nom du secret. Vous pouvez éventuellement fournir la version du secret. Si vous ne fournissez pas la version du secret, la dernière version est utilisée.

using './main.bicep'

param secureUserName = az.getSecret('<subscriptionId>', '<resourceGroupName>', '<keyVaultName>', '<secretName>', '<secretVersion>')
param securePassword = az.getSecret('<subscriptionId>', '<resourceGroupName>', '<keyVaultName>', '<secretName>')

Travailler avec des secrets dans les pipelines

Lorsque vous déployez vos ressources Azure en utilisant un pipeline, vous devez veiller à gérer vos secrets de manière appropriée.

  • Évitez de stocker des secrets dans votre référentiel de codes. Par exemple, n’ajoutez pas de secrets aux fichiers de paramètres ou aux fichiers YAML de définition de votre pipeline.
  • Dans GitHub Actions, utilisez des secrets chiffrés pour stocker des données sécurisées. Utilisez l’analyse des secrets pour détecter toute validation accidentelle de secrets.
  • Dans Azure Pipelines, utilisez des variables de secret pour stocker des données sécurisées.