I am running into an issue while creating an azure key vault with a default access policy (full access) assigned to the Terraform Service Principal (App running the terraform steps). The key vault and policy are being created successfully but adding a keyvault secret after that is resulting in an access forbidden error. I did verify the presence of access policy from the portal. Also tried adding a depends_on param on the secret resource for default_policy and a time_sleep dependency as well but neither of them helped.
Below are the TF config files
#----------------------------
#providers.tf
#----------------------------
terraform {
backend "local" {
path = "/home/xxx/keyvault/kv-terraform.tfstate"
}
required_providers {
azurerm = {
source = "hashicorp/azurerm"
}
}
}
provider "azurerm" {
features {}
}
#----------------------------
#main.tf
#----------------------------
locals {
tags = {
ApplicationName = "KeyVault"
}
}
resource "azurerm_key_vault" "key-vault" {
name = "test-kv-xxxx"
location = "CentralUS"
resource_group_name = "rg-kv"
sku_name = "standard"
tenant_id = data.azurerm_client_config.current.tenant_id
enabled_for_deployment = "true"
enabled_for_disk_encryption = "true"
enabled_for_template_deployment = "true"
enable_rbac_authorization = false
purge_protection_enabled = false
tags = local.tags
network_acls {
default_action = "Allow"
bypass = "AzureServices"
}
}
#Create a Default Azure Key Vault access policy with Admin permissions for Terraform Service Principal
resource "azurerm_key_vault_access_policy" "default_policy" {
key_vault_id = azurerm_key_vault.key-vault.id
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id
lifecycle {
create_before_destroy = true
}
key_permissions = var.kv-key-permissions-full
secret_permissions = var.kv-secret-permissions-full
certificate_permissions = var.kv-certificate-permissions-full
storage_permissions = var.kv-storage-permissions-full
}
# Create a KeyVault Secret
resource "azurerm_key_vault_secret" "mysecret" {
name = "my-resource-name"
value = "mykeyvault"
key_vault_id = azurerm_key_vault.key-vault.id
depends_on = [azurerm_key_vault_access_policy.default_policy]
}
#-----------------------
#variables.tf
#-----------------------
variable "kv-key-permissions-full" {
type = list(string)
description = "List of full key permissions, must be one or more from the following: backup, create, decrypt, delete, encrypt, get, import, list, purge, recover, restore, sign, unwrapKey, update, verify and wrapKey."
default = ["Backup", "Create", "Decrypt", "Delete", "Encrypt", "Get", "Import", "List", "Purge",
"Recover", "Restore", "Sign", "UnwrapKey", "Update", "Verify", "WrapKey"]
}
variable "kv-secret-permissions-full" {
type = list(string)
description = "List of full secret permissions, must be one or more from the following: backup, delete, get, list, purge, recover, restore and set"
default = ["Backup", "Delete", "Get", "List", "Purge", "Recover", "Restore", "Set"]
}
variable "kv-certificate-permissions-full" {
type = list(string)
description = "List of full certificate permissions, must be one or more from the following: backup, create, delete, deleteissuers, get, getissuers, import, list, listissuers, managecontacts, manageissuers, purge, recover, restore, setissuers and update"
default = ["Create", "Delete", "DeleteIssuers", "Get", "GetIssuers", "Import", "List", "ListIssuers",
"ManageContacts", "ManageIssuers", "Purge", "Recover", "SetIssuers", "Update", "Backup", "Restore"]
}
variable "kv-storage-permissions-full" {
type = list(string)
description = "List of full storage permissions, must be one or more from the following: backup, delete, deletesas, get, getsas, list, listsas, purge, recover, regeneratekey, restore, set, setsas and update"
default = ["Backup", "Delete", "DeleteSAS", "Get", "GetSAS", "List", "ListSAS",
"Purge", "Recover", "RegenerateKey", "Restore", "Set", "SetSAS", "Update"]
}
#----------------------------
#data.tf
#----------------------------
data "azurerm_client_config" "current" {
}
Below is the output of the TF apply step
$ terraform apply
data.azurerm_client_config.current: Reading...
data.azurerm_client_config.current: Read complete after 0s [id=2022-05-30 22:43:22.233950875 +0000 UTC]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# azurerm_key_vault.key-vault will be created
+ resource "azurerm_key_vault" "key-vault" {
+ access_policy = (known after apply)
+ enable_rbac_authorization = false
+ enabled_for_deployment = true
+ enabled_for_disk_encryption = true
+ enabled_for_template_deployment = true
+ id = (known after apply)
+ location = "centralus"
+ name = "test-kv-xxxx"
+ purge_protection_enabled = false
+ resource_group_name = "rg-kv"
+ sku_name = "standard"
+ soft_delete_retention_days = 90
+ tags = {
+ "ApplicationName" = "KeyVault"
}
+ tenant_id = "xxxxxxxx"
+ vault_uri = (known after apply)
+ network_acls {
+ bypass = "AzureServices"
+ default_action = "Allow"
}
}
# azurerm_key_vault_access_policy.default_policy will be created
+ resource "azurerm_key_vault_access_policy" "default_policy" {
+ certificate_permissions = [
+ "Create",
+ "Delete",
+ "DeleteIssuers",
+ "Get",
+ "GetIssuers",
+ "Import",
+ "List",
+ "ListIssuers",
+ "ManageContacts",
+ "ManageIssuers",
+ "Purge",
+ "Recover",
+ "SetIssuers",
+ "Update",
+ "Backup",
+ "Restore",
]
+ id = (known after apply)
+ key_permissions = [
+ "Backup",
+ "Create",
+ "Decrypt",
+ "Delete",
+ "Encrypt",
+ "Get",
+ "Import",
+ "List",
+ "Purge",
+ "Recover",
+ "Restore",
+ "Sign",
+ "UnwrapKey",
+ "Update",
+ "Verify",
+ "WrapKey",
]
+ key_vault_id = (known after apply)
+ object_id = "58ad3551-8b89-4b0e-bb51-534a78b18882"
+ secret_permissions = [
+ "Backup",
+ "Delete",
+ "Get",
+ "List",
+ "Purge",
+ "Recover",
+ "Restore",
+ "Set",
]
+ storage_permissions = [
+ "Backup",
+ "Delete",
+ "DeleteSAS",
+ "Get",
+ "GetSAS",
+ "List",
+ "ListSAS",
+ "Purge",
+ "Recover",
+ "RegenerateKey",
+ "Restore",
+ "Set",
+ "SetSAS",
+ "Update",
]
+ tenant_id = "xxxxxxxxxx"
}
# azurerm_key_vault_secret.mysecret will be created
+ resource "azurerm_key_vault_secret" "mysecret" {
+ id = (known after apply)
+ key_vault_id = (known after apply)
+ name = "my-resource-name"
+ value = (sensitive value)
+ version = (known after apply)
+ versionless_id = (known after apply)
}
Plan: 3 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
azurerm_key_vault.key-vault: Creating...
azurerm_key_vault.key-vault: Still creating... [10s elapsed]
azurerm_key_vault.key-vault: Still creating... [20s elapsed]
azurerm_key_vault.key-vault: Still creating... [30s elapsed]
azurerm_key_vault.key-vault: Still creating... [40s elapsed]
azurerm_key_vault.key-vault: Still creating... [50s elapsed]
azurerm_key_vault.key-vault: Still creating... [1m0s elapsed]
azurerm_key_vault.key-vault: Still creating... [1m10s elapsed]
azurerm_key_vault.key-vault: Still creating... [1m20s elapsed]
azurerm_key_vault.key-vault: Still creating... [1m30s elapsed]
azurerm_key_vault.key-vault: Still creating... [1m40s elapsed]
azurerm_key_vault.key-vault: Still creating... [1m50s elapsed]
azurerm_key_vault.key-vault: Still creating... [2m0s elapsed]
azurerm_key_vault.key-vault: Still creating... [2m10s elapsed]
azurerm_key_vault.key-vault: Still creating... [2m20s elapsed]
azurerm_key_vault.key-vault: Still creating... [2m30s elapsed]
azurerm_key_vault.key-vault: Creation complete after 2m35s [id=/subscriptions/xxxxxx/resourceGroups/rg-kv/providers/Microsoft.KeyVault/vaults/test-kv-xxxx]
azurerm_key_vault_secret.mysecret: Creating...
azurerm_key_vault_access_policy.default_policy: Creating...
azurerm_key_vault_access_policy.default_policy: Creation complete after 6s [id=/subscriptions/xxxxxx/resourceGroups/rg-kv/providers/Microsoft.KeyVault/vaults/test-kv-xxxx/objectId/58ad3551-8b89-4b0e-bb51-534a78b18882]
╷
│ Error: checking for presence of existing Secret "my-resource-name" (Key Vault "https://test-kv-xxxx.vault.azure.net/"): keyvault.BaseClient#GetSecret: Failure responding to request: StatusCode=403 -- Original Error: autorest/azure: Service returned an error. Status=403 Code="Forbidden" Message="The user, group or application 'appid=6554595d-52e6-468d-9562-2ba39425f702;oid=58ad3551-8b89-4b0e-bb51-534a78b18882;numgroups=52;iss=https://sts.windows.net/9b5b8dd2-61cb-4b6f-9664-28fd7b133562/' does not have secrets get permission on key vault 'test-kv-xxxx;location=centralus'. For help resolving this issue, please see https://go.microsoft.com/fwlink/?linkid=2125287" InnerError={"code":"AccessDenied"}
│
│ with azurerm_key_vault_secret.mysecret,
│ on main.tf line 48, in resource "azurerm_key_vault_secret" "mysecret":
│ 48: resource "azurerm_key_vault_secret" "mysecret" {