Udostępnij za pośrednictwem


Zarządzanie wpisami tajnymi przy użyciu Bicep

Wdrożenia często wymagają przechowywania i propagowania wpisów tajnych w całym środowisku platformy Azure. Platforma Bicep i platforma Azure udostępniają wiele funkcji ułatwiania zarządzania wpisami tajnymi we wdrożeniach.

Unikaj wpisów tajnych, w których można

W wielu sytuacjach można unikać używania w ogóle wpisów tajnych. Wiele zasobów platformy Azure obsługuje tożsamości zarządzane, które umożliwiają ich uwierzytelnianie i autoryzację dostępu do innych zasobów na platformie Azure bez konieczności obsługi poświadczeń ani zarządzania nimi. Ponadto niektóre usługi platformy Azure mogą automatycznie generować certyfikaty HTTPS, unikając obsługi certyfikatów i kluczy prywatnych. W miarę możliwości używaj tożsamości zarządzanych i certyfikatów zarządzanych przez usługę.

Używanie bezpiecznych parametrów

Jeśli musisz podać wpisy tajne do wdrożeń Bicep jako parametry, użyj dekoratora@secure(). Po oznaczeniu parametru jako bezpiecznego usługa Azure Resource Manager unika rejestrowania wartości lub wyświetlania jej w witrynie Azure Portal, interfejsie wiersza polecenia platformy Azure lub programie Azure PowerShell.

Unikaj danych wyjściowych dla wpisów tajnych

Nie używaj danych wyjściowych Bicep do bezpiecznych danych. Dane wyjściowe są rejestrowane w historii wdrożenia, a każda osoba mająca dostęp do wdrożenia może wyświetlać wartości danych wyjściowych wdrożenia.

Jeśli musisz wygenerować wpis tajny we wdrożeniu Bicep i udostępnić go obiektowi wywołującego lub innym zasobom, rozważ użycie jednego z poniższych metod.

Dynamiczne wyszukiwanie wpisów tajnych

Czasami należy uzyskać dostęp do wpisu tajnego z jednego zasobu, aby skonfigurować inny zasób.

Możesz na przykład utworzyć konto magazynu w innym wdrożeniu i mieć dostęp do jego klucza podstawowego w celu skonfigurowania aplikacji usługi Azure Functions. Za pomocą existing słowa kluczowego można uzyskać silnie typizowane odwołanie do wstępnie utworzonego konta magazynu, a następnie użyć metody konta listKeys() magazynu, aby utworzyć parametry połączenia przy użyciu klucza podstawowego:

Poniższy przykład jest częścią większego przykładu. Aby uzyskać plik Bicep, który można wdrożyć, zobacz kompletny plik.

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'
  }
}

Korzystając z tego podejścia, należy unikać przekazywania wpisów tajnych do pliku Bicep lub z tego pliku.

Można również użyć tego podejścia do przechowywania wpisów tajnych w magazynie kluczy.

Korzystanie z usługi Key Vault

Usługa Azure Key Vault została zaprojektowana do przechowywania bezpiecznych danych i zarządzania nimi. Magazyn kluczy umożliwia zarządzanie wpisami tajnymi, certyfikatami, kluczami i innymi danymi, które muszą być chronione i udostępniane.

Magazyny i wpisy tajne można tworzyć i zarządzać nimi przy użyciu Bicep. Zdefiniuj magazyny, tworząc zasób o typie Microsoft.KeyVault/vaults.

Podczas tworzenia magazynu należy określić, kto i co może uzyskać dostęp do jego danych. Jeśli planujesz odczytywanie wpisów tajnych magazynu z pliku Bicep, ustaw enabledForTemplateDeployment właściwość na truewartość .

Dodawanie wpisów tajnych do magazynu kluczy

Wpisy tajne są zasobem podrzędnym i można je utworzyć przy użyciu typu Microsoft.KeyVault/vaults/secrets. W poniższym przykładzie pokazano, jak utworzyć magazyn i wpis tajny:

Poniższy przykład jest częścią większego przykładu. Aby uzyskać plik Bicep, który można wdrożyć, zobacz kompletny plik.

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'
  }
}

Napiwek

W przypadku korzystania z potoków wdrażania automatycznego czasami może być trudne określenie sposobu uruchamiania wpisów tajnych magazynu kluczy dla wdrożeń. Jeśli na przykład użyto klucza interfejsu API do użycia podczas komunikowania się z zewnętrznym interfejsem API, wpis tajny musi zostać dodany do magazynu, zanim będzie można go używać we wdrożeniach.

Podczas pracy z wpisami tajnymi pochodzącymi z innej firmy może być konieczne ręczne dodanie ich do magazynu, a następnie odwołanie do wpisu tajnego dla wszystkich kolejnych zastosowań.

Używanie magazynu kluczy z modułami

W przypadku korzystania z modułów Bicep można zapewnić bezpieczne parametry przy użyciu getSecret funkcji .

Możesz również odwołać się do magazynu kluczy zdefiniowanego w innej grupie zasobów przy użyciu existing słów kluczowych i scope . W poniższym przykładzie plik Bicep jest wdrażany w grupie zasobów o nazwie Sieć. Wartość parametru modułu mySecret jest definiowana w magazynie kluczy o nazwie contosonetworkingsecrets znajdującym się w grupie zasobów Wpisy tajne:

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')
  }
}

Używanie magazynu kluczy w pliku bicepparam

W przypadku korzystania z .bicepparam formatu pliku można podać bezpieczne wartości parametrom przy użyciu getSecret funkcji .

Odwołaj się do usługi KeyVault, podając identyfikator subskrypcji, nazwę grupy zasobów i nazwę magazynu kluczy. Wartość wpisu tajnego można uzyskać, podając nazwę wpisu tajnego. Opcjonalnie możesz podać wersję wpisu tajnego. Jeśli nie podasz wersji wpisu tajnego, zostanie użyta najnowsza wersja.

using './main.bicep'

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

Praca z wpisami tajnymi w potokach

Podczas wdrażania zasobów platformy Azure przy użyciu potoku należy odpowiednio obsługiwać wpisy tajne.

  • Unikaj przechowywania wpisów tajnych w repozytorium kodu. Na przykład nie dodawaj wpisów tajnych do plików parametrów ani do plików YAML definicji potoku.
  • W funkcji GitHub Actions użyj zaszyfrowanych wpisów tajnych do przechowywania bezpiecznych danych. Użyj skanowania wpisów tajnych, aby wykryć wszelkie przypadkowe zatwierdzenia wpisów tajnych.
  • W usłudze Azure Pipelines użyj zmiennych tajnych do przechowywania bezpiecznych danych.