skip to Main Content

I am trying to create vaults and give get permission to developers.
I am a devops and want to manage this vaults only by me.
Terraform validate command doesn’t give any error. But apply is failed like.

│ Error: checking for presence of existing Secret "ConnectionStrings--DBContext" (Key Vault "https://deneme-beta.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=04b071-811ddb-461a-bbee-02f9e1bf7b46;oid=b78911-511d7b-4968-a654-4389ef10196d;numgroups=1;iss=https://sts.windows.net/d07101-51110d-4151-abf2-d14d0729ada3/' does not have secrets get permission on key vault 'deneme-beta;location=germanywestcentral'. For help resolving this issue, please see https://go.microsoft.com/fwlink/?linkid=2125287" InnerError={"code":"AccessDenied"}
│ 
│   with azurerm_key_vault_secret.vault_secrets["deneme-beta-ConnectionStrings--DBContext"],
│   on main.tf line 59, in resource "azurerm_key_vault_secret" "vault_secrets":
│   59: resource "azurerm_key_vault_secret" "vault_secrets" {

I have 3 tf files as;
My locals.tf file is;

locals {
  contexts = [
    {
      "name" : "deneme-beta",
      "vars" : [
        {
          "variable" : "ConnectionStrings--DBContext",
          "value" : "data source=192.168.10.1:1521/beta;password=deneme-test;user id=PRJ"
        },
        {
          "variable" : "MinioSettings--SecretKey",
          "value" : "flkjdwfkljdkfjdjkfjdkfjkdjf"
        },
        {
          "variable" : "RabbitMQConfiguration--Password",
          "value" : "94j9j9j9j"
        }
      ]
    },
    {
      "name" : "deneme-stage",
      "vars" : [
        {
          "variable" : "ConnectionStrings--DBContext",
          "value" : "data source=192.168.10.1:1521/stage;password=deneme-stage;user id=PRJ"
        },
        {
          "variable" : "MinioSettings--SecretKey",
          "value" : "dkmkdemmdcmdkmckmdkcmddcdcdcdc"
        },
        {
          "variable" : "RabbitMQConfiguration--Password",
          "value" : "223232323"
        }
      ]
    }
  ]

  variables = merge([for context in local.contexts : {
    for vars in context.vars :
    "${context.name}-${vars.variable}" => {
      name     = context.name
      variable = vars.variable
      value    = vars.value
    }
  }]...)

}

My provider.tf file is;

terraform {
  required_version = ">=1.0"
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~>3.0"
    }
    azuread = {
      source  = "hashicorp/azuread"
      version = "~>2.48"
    }
  }

}
provider "azurerm" {
  features {}
}

My main.tf file is;

resource "azurerm_resource_group" "rg" {
  name     = "rg_vault_deneme"
  location = "germanywestcentral"
}

data "azurerm_client_config" "current" {}

resource "azurerm_key_vault" "ygm_vaults" {
  for_each                   = toset([for context in local.contexts : context.name])
  name                       = each.key
  location                   = azurerm_resource_group.rg.location
  resource_group_name        = azurerm_resource_group.rg.name
  tenant_id                  = data.azurerm_client_config.current.tenant_id
  sku_name                   = "standard"
  soft_delete_retention_days = 7
  purge_protection_enabled   = false

}

resource "azurerm_key_vault_access_policy" "ygm_vault_access_policy-devops" {
  for_each     = azurerm_key_vault.ygm_vaults
  key_vault_id = azurerm_key_vault.ygm_vaults[each.value.name].id
  tenant_id    = data.azurerm_client_config.current.tenant_id
  object_id    = data.azurerm_client_config.current.object_id

  key_permissions = [
    "Get", "List", "Update", "Create", "Import", "Delete", "Recover", "Backup", "Restore",
  ]

  secret_permissions = [
    "Get", "List", "Set", "Delete", "Recover", "Backup", "Restore",
  ]

}

data "azuread_client_config" "current" {}

data "azuread_user" "developer" {
  user_principal_name = "[email protected]"
}

resource "azurerm_key_vault_access_policy" "ygm_vault_access_policy-developer" {
  for_each     = azurerm_key_vault.ygm_vaults
  key_vault_id = azurerm_key_vault.ygm_vaults[each.value.name].id
  tenant_id    = data.azurerm_client_config.current.tenant_id
  object_id    = data.azuread_user.developer.object_id

  key_permissions = [
    "Get",
    "List"
  ]

  secret_permissions = [
    "Get",
    "List"
  ]
}

resource "azurerm_key_vault_secret" "vault_secrets" {
  for_each     = local.variables
  key_vault_id = azurerm_key_vault.ygm_vaults[each.value.name].id

  name  = each.value.variable
  value = each.value.value
}

What is the problem in my config files?

Search google and can’t find a good answer.

2

Answers


  1. Chosen as BEST ANSWER

    Thanks for your quick answer. Your help didn't solve my problem but gives the idea of the root problem.

    You said that; developers must have Set and Delete permissions not to get the error. But I want only the owner (devops) have a permission to manage vault. I want developers permissions not exceed Get and List grants.

    By the help of your answer I understandt that terraform also the owner ability to create this resources. But there is a problem in the order. The grant access permissons and vault secret check are done asyncronous. So without the access permission the other part secret creation is giving error.

    I added a depends on to secret creation. By the help of this dependency terraform create a syncronous operation without giving any error.

    My last part main.tf is changed to;

    resource "azurerm_key_vault_secret" "vault_secrets" {
      for_each     = local.variables
      key_vault_id = azurerm_key_vault.ygm_vaults[each.value.name].id
    
      name  = each.value.variable
      value = each.value.value
      depends_on = [
        azurerm_key_vault_access_policy.ygm_vault_access_policy-devops
      ]
    }
    

    And in the destroy process terraform gives purge permisson is not found. I also added "Purge" permission to my grant list.

      key_permissions = [
        "Get", "List", "Update", "Create", "Import", "Delete", "Recover", "Backup", "Restore", "Purge"
      ]
    
      secret_permissions = [
        "Get", "List", "Set", "Delete", "Recover", "Backup", "Restore", "Purge"
      ]
    

    Thanks for your help. By the help of your answer I was able to focus more on the problem.


  2. The user, group or application ‘appid=XYZ’ does not have secrets get permission on key vault

    The error messages suggest that the service principal (or user account) executing the Terraform script lacks the required permissions to retrieve secrets from the designated Azure Key Vaults. The 403 Forbidden error specifically denotes that the account is unauthorized to carry out "Get" operations on the secrets.

    Modify the Key Vault access policies to include the necessary permissions for the account. This includes permissions like "Get" and "List" for secrets.

    Terraform configuration:

    # provider.tf
    terraform {
      required_version = ">=1.0"
      required_providers {
        azurerm = {
          source  = "hashicorp/azurerm"
        }
        azuread = {
          source  = "hashicorp/azuread"
        }
      }
    }
    
    provider "azurerm" {
      features {}
    }
    
    # locals.tf
    locals {
      contexts = [
        {
          "name" : "denemevk-beta",
          "vars" : [
            {
              "variable" : "ConnectionStrings--DBContext",
              "value" : "data source=192.168.10.1:1521/beta;password=deneme-test;user id=PRJ"
            },
            {
              "variable" : "MinioSettings--SecretKey",
              "value" : "flkjdwfkljdkfjdjkfjdkfjkdjf"
            },
            {
              "variable" : "RabbitMQConfiguration--Password",
              "value" : "94j9j9j9j"
            }
          ]
        },
        {
          "name" : "denemevk-stage",
          "vars" : [
            {
              "variable" : "ConnectionStrings--DBContext",
              "value" : "data source=192.168.10.1:1521/stage;password=deneme-stage;user id=PRJ"
            },
            {
              "variable" : "MinioSettings--SecretKey",
              "value" : "dkmkdemmdcmdkmckmdkcmddcdcdcdc"
            },
            {
              "variable" : "RabbitMQConfiguration--Password",
              "value" : "223232323"
            }
          ]
        }
      ]
    
      variables = merge([for context in local.contexts : {
        for vars in context.vars :
        "${context.name}-${vars.variable}" => {
          name     = context.name
          variable = vars.variable
          value    = vars.value
        }
      }]...)
    }
    
    # main.tf
    resource "azurerm_resource_group" "rg" {
      name     = "vkrg_vault_deneme"
      location = "germanywestcentral"
    }
    
    data "azurerm_client_config" "current" {}
    
    resource "azurerm_key_vault" "ygm_vaults" {
      for_each                   = toset([for context in local.contexts : context.name])
      name                       = each.key
      location                   = azurerm_resource_group.rg.location
      resource_group_name        = azurerm_resource_group.rg.name
      tenant_id                  = data.azurerm_client_config.current.tenant_id
      sku_name                   = "standard"
      soft_delete_retention_days = 7
      purge_protection_enabled   = false
    }
    
    data "azuread_client_config" "current" {}
    
    data "azuread_user" "developer" {
      user_principal_name = "[email protected]"
    }
    
    resource "azurerm_key_vault_access_policy" "ygm_vault_access_policy-devops" {
      for_each     = azurerm_key_vault.ygm_vaults
      key_vault_id = each.value.id
      tenant_id    = data.azurerm_client_config.current.tenant_id
      object_id    = data.azurerm_client_config.current.object_id
    
      key_permissions = [
        "Get", "List", "Update", "Create", "Import", "Delete", "Recover", "Backup", "Restore",
      ]
    
      secret_permissions = [
        "Get", "List", "Set", "Delete", "Recover", "Backup", "Restore",
      ]
    }
    
    resource "azurerm_key_vault_access_policy" "ygm_vault_access_policy-developer" {
      for_each     = azurerm_key_vault.ygm_vaults
      key_vault_id = each.value.id
      tenant_id    = data.azurerm_client_config.current.tenant_id
      object_id    = data.azuread_user.developer.object_id
    
      key_permissions = [
        "Get",
        "List"
      ]
    
      secret_permissions = [
        "Get",
        "List",
        "Set",
        "Delete"
      ]
    }
    
    resource "azurerm_key_vault_secret" "vault_secrets" {
      for_each     = local.variables
      key_vault_id = azurerm_key_vault.ygm_vaults[each.value.name].id
    
      name  = each.value.variable
      value = each.value.value
    }
    

    Deployment succeded:

    enter image description here

    enter image description here

    enter image description here

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search