仅当在 ARM 模板中更改或检查它是否存在时,如何更新 Azure Key Vault 中的秘密

How to update a Secret in Azure Key Vault only if changed in ARM templates or check if it exists

我有一个生产密钥库,它保留项目可以使用的秘密参考,但只有在使用 ARM 模板部署时,这些秘密才不会被复制粘贴的人处理。

当新项目启动时,作为其部署脚本的一部分,它将创建自己的密钥库。

我希望能够 运行 templates/scripts 作为 CI/CD 的一部分。这将导致相同的秘密在每个 运行 处都有一个新版本,即使值没有改变。

如何让它在主保管库更新时只更新密钥保管库值。

在我的 deployment.sh 脚本中,我使用了以下技术。

SendGridUriWithVersion=$((az group deployment create ... assume that the secret exists ... || az group deployment create ... assume that the secret exists ... ) | jq -r '.properties.outputs.secretUriWithVersion.value')

它之所以有效,是因为在模板中有一个参数,如果设置了参数,它将检索秘密并将其与新值进行比较,只有在不同时才插入。最初的问题是,如果尚未设置秘密,则部署会失败(第一次部署等会发生这种情况)。

但是由于 Unix ||,同样的脚本在没有设置参数的情况下又是 运行,它会使用一个条件来不尝试获取旧值,因此 运行 成功的。

以下是部门的例子:

      SecretName="Sendgrid"
      SourceSecretName="Sendgrid"
      SourceVaultName="io-board"
      SourceResourceGroup="io-board" 
      SendGridUriWithVersion=$((az group deployment create -n ${SecretName}-secret -g $(prefix)-$(projectName)-$(projectEnv) --template-uri https://management.dotnetdevops.org/providers/DotNetDevOps.AzureTemplates/templates/KeyVaults/${keyVaultName}/secrets/${SecretName}?sourced=true --parameters sourceVault=${SourceVaultName} sourceResourceGroup=${SourceResourceGroup} sourceSecretName=${SourceSecretName} update=true || az group deployment create -n ${SecretName}-secret -g $(prefix)-$(projectName)-$(projectEnv) --template-uri https://management.dotnetdevops.org/providers/DotNetDevOps.AzureTemplates/templates/KeyVaults/${keyVaultName}/secrets/${SecretName}?sourced=true --parameters sourceVault=${SourceVaultName} sourceResourceGroup=${SourceResourceGroup} sourceSecretName=${SourceSecretName}) | jq -r '.properties.outputs.secretUriWithVersion.value')

https://management.dotnetdevops.org/providers/DotNetDevOps.AzureTemplates/templates/KeyVaults/{keyvaultName}/secrets/{secretName}?sourced=truereturns一个模板

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "keyVaultName": {
      "type": "string",
      "defaultValue": "io-board-data-ingest-dev"
    },
    "secretName": {
      "type": "string",
      "metadata": {
        "description": "Name of the secret to store in the vault"
      },
      "defaultValue": "DataStorage"
    },
    "sourceVaultSubscription": {
      "type": "string",
      "defaultValue": "[subscription().subscriptionId]"
    },
    "sourceVault": {
      "type": "string",
      "defaultValue": "[subscription().subscriptionId]"
    },
    "sourceResourceGroup": {
      "type": "string",
      "defaultValue": "[resourceGroup().name]"
    },
    "sourceSecretName": {
      "type": "string"
    },
    "update": {
      "type": "bool",
      "defaultValue": false
    }
  },
  "variables": {
    "empty": {
      "value": ""
    },
    "test": {
      "reference": {
        "keyVault": {
          "id": "[resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.KeyVault/vaults', parameters('keyVaultName'))]"
        },
        "secretName": "[parameters('secretName')]"
      }
    }
  },
  "resources": [
    {
      "apiVersion": "2018-05-01",
      "name": "AddLinkedSecret",
      "type": "Microsoft.Resources/deployments",
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "[concat('https://management.dotnetdevops.org/providers/DotNetDevOps.AzureTemplates/templates/KeyVaults/',parameters('keyVaultName'),'/secrets/',parameters('secretName'))]",
          "contentVersion": "1.0.0.0"
        },
        "parameters": {
          "existingValue": "[if(parameters('update'),variables('test'),variables('empty'))]",
          "secretValue": {
            "reference": {
              "keyVault": {
                "id": "[resourceId(parameters('sourceVaultSubscription'), parameters('sourceResourceGroup'), 'Microsoft.KeyVault/vaults', parameters('sourceVault'))]"
              },
              "secretName": "[parameters('sourceSecretName')]"
            }
          }
        }
      }
    }
  ],
  "outputs": {
    "secretUriWithVersion": {
      "type": "string",
      "value": "[reference('AddLinkedSecret').outputs.secretUriWithVersion.value]"
    }
  }
}

并且该模板有一个对 https://management.dotnetdevops.org/providers/DotNetDevOps.AzureTemplates/templates/KeyVaults/{keyvaultName}/secrets/{secretName} 的嵌套调用,它给出了条件

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "keyVaultName": {
      "type": "string",
      "defaultValue": "io-board-data-ingest-dev",
      "metadata": {
        "description": "Name of the existing vault"
      }
    },
    "secretName": {
      "type": "string",
      "metadata": {
        "description": "Name of the secret to store in the vault"
      },
      "defaultValue": "DataStorage"
    },
    "secretValue": {
      "type": "securestring",
      "metadata": {
        "description": "Value of the secret to store in the vault"
      }
    },
    "existingValue": {
      "type": "securestring",
      "defaultValue": ""
    }
  },
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.KeyVault/vaults/secrets",
      "condition": "[not(equals(parameters('existingValue'),parameters('secretValue')))]",
      "apiVersion": "2015-06-01",
      "name": "[concat(parameters('keyVaultName'), '/', parameters('secretName'))]",
      "properties": {
        "value": "[parameters('secretValue')]"
      }
    }
  ],
  "outputs": {
    "secretUriWithVersion": {
      "type": "string",
      "value": "[reference(resourceId(resourceGroup().name, 'Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('secretName')), '2015-06-01').secretUriWithVersion]"
    }
  }
}