Home > Enterprise >  Problems with Azure Key Vault Access Policies when running Terraform Apply
Problems with Azure Key Vault Access Policies when running Terraform Apply

Time:10-13

When Terraform apply runs, in two scenarios the following happens With Key Vault.

When run from a pipeline through the Service Principle, it will apply the service principle only access policies for Key Vault.

When run from the cmd line, it will only apply the Tenant User Ad access policies for Key Vault.

I need it to do both, as I have devs that want to view the secrets generated in Kay Vault when it goes live. When run through the pipeline only the Service Principle has access to do that.

Back ground info on State File:

The State file sits in Azure and can be accessed from the pipeline service principle and the cmd line when running the following command: terraform init -backend-config=/DevOpsProject/Terraform/azure.conf

The code for Key Vault:

data "azurerm_client_config" "current" {}

data "azuread_service_principal" "current" {
  object_id = "VALUE" // This will need changing per tenant used for KeyVault
}

// This gets the Azure AD Tenant ID information to deploy for KeyVault. 
resource "azurerm_key_vault" "nscsecrets" {
  name                       = "${var.key_vault_name}-${random_string.myrandom.id}"
  resource_group_name        = azurerm_resource_group.Classroom_In_The_Cloud_Terraform.name
  location                   = azurerm_resource_group.Classroom_In_The_Cloud_Terraform.location
  sku_name                   = "standard"
  tenant_id                  = data.azurerm_client_config.current.tenant_id
  soft_delete_retention_days = 7
  purge_protection_enabled   = true  

}

resource "azurerm_key_vault_access_policy" "client" { // This is for AD Users Logged into Azure to give them the right access when creating resources. 
  key_vault_id        = azurerm_key_vault.nscsecrets.id
  tenant_id           = data.azurerm_client_config.current.tenant_id
  object_id           = data.azurerm_client_config.current.object_id
  secret_permissions  = ["Backup", "Delete", "Get", "List", "Purge", "Recover", "Restore", "Set", ]
  key_permissions     = ["Backup", "Create", "Decrypt", "Delete", "Encrypt", "Get", "Import", "List", "Purge", "Recover", "Restore", "Sign", "UnwrapKey", "Update", "Verify", "WrapKey", ]
  storage_permissions = ["Backup", "Delete", "DeleteSAS", "Get", "GetSAS", "List", "ListSAS", "Purge", "Recover", "RegenerateKey", "Restore", "Set", "SetSAS", "Update", ]
}

resource "azurerm_key_vault_access_policy" "service_principal" { // This is for the Service Principal in the pipeline to be able to make changes to Key Vault. 
  key_vault_id        = azurerm_key_vault.nscsecrets.id
  tenant_id           = data.azurerm_client_config.current.tenant_id
  object_id           = data.azuread_service_principal.current.object_id
  secret_permissions  = ["Backup", "Delete", "Get", "List", "Purge", "Recover", "Restore", "Set", ]
  key_permissions     = ["Backup", "Create", "Decrypt", "Delete", "Encrypt", "Get", "Import", "List", "Purge", "Recover", "Restore", "Sign", "UnwrapKey", "Update", "Verify", "WrapKey", ]
  storage_permissions = ["Backup", "Delete", "DeleteSAS", "Get", "GetSAS", "List", "ListSAS", "Purge", "Recover", "RegenerateKey", "Restore", "Set", "SetSAS", "Update", ]
}

resource "azurerm_key_vault_access_policy" "website_accesspolicy" {
  key_vault_id       = azurerm_key_vault.nscsecrets.id
  tenant_id          = azurerm_app_service.website_app.identity[0].tenant_id
  object_id          = azurerm_app_service.website_app.identity[0].principal_id
  secret_permissions = ["get"]
}

resource "azurerm_key_vault_access_policy" "website_logs_storage_accesspolicy" { // This is for the Storage Account for Website Logs. 
  key_vault_id       = azurerm_key_vault.nscsecrets.id
  tenant_id          = data.azurerm_client_config.current.tenant_id
  object_id          = azurerm_storage_account.website_log_storage.identity[0].principal_id
  key_permissions    = ["get", "create", "delete", "list", "restore", "recover", "unwrapkey", "wrapkey", "purge", "encrypt", "decrypt", "sign", "verify", ]
  secret_permissions = ["Backup", "Delete", "Get", "List", "Purge", "Recover", "Restore", "Set", ]
}

resource "azurerm_key_vault_key" "website_logs_key" {
  name         = "website-logs-key"
  key_vault_id = azurerm_key_vault.nscsecrets.id

  key_type = "RSA"
  key_size = 2048
  key_opts = ["decrypt", "encrypt", "sign", "unwrapKey", "verify", "wrapKey", ]

  depends_on = [
    azurerm_key_vault_access_policy.client,
    azurerm_key_vault_access_policy.website_logs_storage_accesspolicy
  ]

}

CodePudding user response:

When using the pipeline you must be authenticating to azure using the service principal.

To add the User and Service Principal both to the access policy of the keyvault. Instead of using data source for azuread_service_principal you should use data source for azuread_user as you are authenticating via service principal the data source azurerm_client_config will have the objectId of the service principal. So , your code will be something like below (I tested this by authenticating via service principal from local):

provider "azurerm" {
    subscription_id = "88073b30-xxxx-xxxx-xxx-8442c93573ae"
    tenant_id = "ab078f81-xxxx-xxxx-xxxx-620b694ded30"
    client_id = "7f1a4457-xxxx-xxxx-xxxx-293b51794fb3"
    client_secret = "aGY7Q~0n2iKMOxxxxxxxxxxxxlnNG9Pnt2k"
    features {}
}
provider "azuread"{
    tenant_id = "ab078f81-xxxx-xxxx-xxxx-620b694ded30"
    client_id = "7f1a4457-xxxx-xxxx-xxxx-293b51794fb3"
    client_secret = "aGY7Q~0n2iKMOxxxxxxxxxxxxlnNG9Pnt2k"
}
data "azurerm_client_config" "current" {}
// This gets the Azure AD Tenant ID information to deploy for KeyVault and also contains the service principal objectID.
data "azurerm_resource_group" "Classroom_In_The_Cloud_Terraform"{
    name = "ansuman-resourcegroup"
}
// user which I want to give permissions to be able to access the keyvault.
data "azuread_user" "user"{
user_principal_name = "[email protected]"
}
 
resource "azurerm_key_vault" "nscsecrets" {
  name                       = "Ansumankeyvault0123456"
  resource_group_name        = data.azurerm_resource_group.Classroom_In_The_Cloud_Terraform.name
  location                   = data.azurerm_resource_group.Classroom_In_The_Cloud_Terraform.location
  sku_name                   = "standard"
  tenant_id                  = data.azurerm_client_config.current.tenant_id
  soft_delete_retention_days = 7
  purge_protection_enabled   = true  

}

resource "azurerm_key_vault_access_policy" "client" { // This is for AD Users Logged into Azure to give them the right access when creating resources. 
  key_vault_id        = azurerm_key_vault.nscsecrets.id
  tenant_id           = data.azurerm_client_config.current.tenant_id
  object_id           = data.azuread_user.user.object_id
  secret_permissions  = ["Backup", "Delete", "Get", "List", "Purge", "Recover", "Restore", "Set", ]
  key_permissions     = ["Backup", "Create", "Decrypt", "Delete", "Encrypt", "Get", "Import", "List", "Purge", "Recover", "Restore", "Sign", "UnwrapKey", "Update", "Verify", "WrapKey", ]
  storage_permissions = ["Backup", "Delete", "DeleteSAS", "Get", "GetSAS", "List", "ListSAS", "Purge", "Recover", "RegenerateKey", "Restore", "Set", "SetSAS", "Update", ]
}

resource "azurerm_key_vault_access_policy" "service_principal" { // This is for the Service Principal in the pipeline to be able to make changes to Key Vault. 
  key_vault_id        = azurerm_key_vault.nscsecrets.id
  tenant_id           = data.azurerm_client_config.current.tenant_id
  object_id           = data.azurerm_client_config.current.object_id
  secret_permissions  = ["Backup", "Delete", "Get", "List", "Purge", "Recover", "Restore", "Set", ]
  key_permissions     = ["Backup", "Create", "Decrypt", "Delete", "Encrypt", "Get", "Import", "List", "Purge", "Recover", "Restore", "Sign", "UnwrapKey", "Update", "Verify", "WrapKey", ]
  storage_permissions = ["Backup", "Delete", "DeleteSAS", "Get", "GetSAS", "List", "ListSAS", "Purge", "Recover", "RegenerateKey", "Restore", "Set", "SetSAS", "Update", ]
}

Output:

enter image description here

enter image description here

Note:

Please make sure the Service principal you are using has the below API permissions granted with admin consent for that tenant:

enter image description here

  • Related