Facing Terraform KeyVault Certificates creation issue - terraform

hello everyone I am facing issue I have a script in which I am creating resource group and key vault and I copied the credentials from central KV into new one when I create RG and Key vault alone and then add Credentials copy portion into the script everything gets created but when I combine the code where 1 RG and 1 KV along with the credentials copy happens it says the Error Key vault in RG is does not exist. I am asking that is there any sequence in terraform do I need to follow ?
Resource.tf
resource "azurerm_resource_group" "main" {
name = "${var.prefix}-resourceGB"
location = var.location
}
# --- Get reference to logged on Azure subscription ---
data "azurerm_client_config" "current" {}
resource "azurerm_key_vault" "New" {
name = "KV1"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
enabled_for_disk_encryption = true
tenant_id = data.azurerm_client_config.current.tenant_id
soft_delete_enabled = true
purge_protection_enabled = false
sku_name = "standard"
access_policy {
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id
certificate_permissions = [
"create",
"delete",
"deleteissuers",
"get",
"getissuers",
"import",
"purge",
"list",
"listissuers",
"managecontacts",
"manageissuers",
"setissuers",
"update",
]
key_permissions = [
"backup",
"create",
"decrypt",
"delete",
"encrypt",
"get",
"import",
"list",
"purge",
"recover",
"restore",
"sign",
"unwrapKey",
"update",
"verify",
"wrapKey",
]
secret_permissions = [
"backup",
"delete",
"get",
"list",
"purge",
"recover",
"restore",
"set",
]
}
}
data "azurerm_key_vault" "existing" {
name = "Old-KV"
resource_group_name = "Old-RG"
}
data "azurerm_key_vault" "New" {
name = "KV1"
resource_group_name = "${var.prefix}-resourceGB"
}
module "Cert1" {
source = "../module/copy_cert"
source_key_vault_id = data.azurerm_key_vault.existing.id
source_key_vault_cert_name = "Cert1"
destination_key_vault_id = data.azurerm_key_vault.New.id
destination_key_vault_cert_name = "Cert1"
}
module "Cert2" {
source = "../module/copy_cert"
source_key_vault_id = data.azurerm_key_vault.existing.id
source_key_vault_cert_name = "Cert2"
destination_key_vault_id = data.azurerm_key_vault.New.id
destination_key_vault_cert_name = "Cert2"
}
Copy Cert main.tf
data "azurerm_key_vault_secret" "source_KV_cert" {
name = var.source_key_vault_cert_name
key_vault_id = var.source_key_vault_id
}
data "azurerm_key_vault_certificate" "source_cert" {
name = var.source_key_vault_cert_name
key_vault_id = var.source_key_vault_id
}
resource "azurerm_key_vault_certificate" "dest_cert" {
name = var.destination_key_vault_cert_name
key_vault_id = var.destination_key_vault_id
certificate {
contents = data.azurerm_key_vault_secret.source_KV_cert.value
}
certificate_policy {
issuer_parameters {
name = "self"
}
key_properties {
exportable = true
key_size = 2048
key_type = "RSA"
reuse_key = true
}
secret_properties {
content_type = "application/x-pkcs12"
}
}
}
Copy Cert Variable.tf
variable "source_key_vault_id" {
type = string
}
variable "source_key_vault_cert_name" {
type = string
}
variable "destination_key_vault_id" {
type = string
}
variable "destination_key_vault_cert_name" {
type = string
}

Since you are creating a new key vault with resource "azurerm_key_vault", you can't use the data source to query for a new resource that is creating at that time in your modules module "Cert1" and module "Cert2" in the same .tf file. The data "azurerm_key_vault" is used to access information about an existing Key Vault.
So change the related code in the file Resource.tf like this:
# data "azurerm_key_vault" "New" {
# name = "KV1"
# resource_group_name = "${var.prefix}-resourceGB"
# }
module "Cert1" {
source = "../module/copy_cert"
source_key_vault_id = data.azurerm_key_vault.existing.id
source_key_vault_cert_name = "Cert1"
destination_key_vault_id = azurerm_key_vault.New.id # changed
destination_key_vault_cert_name = "Cert1"
}
module "Cert2" {
source = "../module/copy_cert"
source_key_vault_id = data.azurerm_key_vault.existing.id
source_key_vault_cert_name = "Cert2"
destination_key_vault_id = azurerm_key_vault.New.id # changed
destination_key_vault_cert_name = "Cert2"
}

Related

Certificate access error during Terraform plan

I think I'm in a bit of a chicken and egg situation, where I need to declare a certificate resource for our application gateway, but our app principal that runs Terraform in our pipeline doesn't have permissions until after applying is complete. Basically, the service principal cannot access certificates during planning, so planning never completes, and apply can't run because there is no plan file output.
Is there any way around this besides manually configuring permissions in the UI?
The access policy does include "Get" permissions for the certificate
Key Vault
resource "azurerm_key_vault" "web" {
name = lower(format("az-kv-web-%s-%s-%s", var.instance.environment, var.instance.az-region, var.instance.serial))
location = azurerm_resource_group.web.location
resource_group_name = azurerm_resource_group.web.name
sku_name = var.instance.key-vault.sku-name
# Azure AD tenant
tenant_id = var.instance.aad-tenant-id
dynamic "access_policy" {
for_each = var.instance.key-vault.access
content {
tenant_id = var.instance.aad-tenant-id
object_id = access_policy.value.object-id
certificate_permissions = access_policy.value.cert-permissions
key_permissions = access_policy.value.key-permissions
secret_permissions = access_policy.value.secret-permissions
storage_permissions = access_policy.value.storage-permissions
}
}
}
Certificate
data "azurerm_key_vault_certificate" "gateway" {
name = var.gateway.certificate-name
key_vault_id = var.key-vault.id
}
Error
╷
│ Error: reading Key Vault Certificate: keyvault.BaseClient#GetCertificate: 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=***;oid=***;numgroups=3;iss=https://sts.windows.net/***/' does not have certificates get permission on key vault 'az-kv-web-dev-eastus-001;location=eastus'. For help resolving this issue, please see https://go.microsoft.com/fwlink/?linkid=2125287" InnerError={"code":"ForbiddenByPolicy"}
│
│ with module.web["001"].module.app-gateway.data.azurerm_key_vault_certificate.gateway,
│ on modules\app-gateway\main.tf line 123, in data "azurerm_key_vault_certificate" "gateway":
│ 123: data "azurerm_key_vault_certificate" "gateway" {
│
╵
To create certificate and access it , I used below code:
gave terraform plan and terraform apply
code:
data "azurerm_subscription" "current" {}
resource "azuread_application" "example" {
display_name = "newexample"
// identifier_uris = ["https://kavyaexample.com"]
owners = [data.azuread_client_config.current.object_id]
sign_in_audience = "AzureADMultipleOrgs"
api {
mapped_claims_enabled = true
requested_access_token_version = 2
oauth2_permission_scope {
admin_consent_description = "Allow the application to access example on behalf of the signed-in user."
admin_consent_display_name = "Access example"
enabled = true
id = "96183846-204b-4b43-82e1-5d2222eb4b9b"
type = "User"
user_consent_description = "Allow the application to access example on your behalf."
user_consent_display_name = "Access example"
value = "user_impersonation"
}
oauth2_permission_scope {
admin_consent_description = "Administer the example application"
admin_consent_display_name = "Administer"
enabled = true
id = "be98fa3e-ab5b-4b11-83d9-04ba2b7946bc"
type = "Admin"
value = "administer"
}
}
app_role {
allowed_member_types = ["User", "Application"]
description = "Admins can manage roles and perform all task actions"
display_name = "Admin"
enabled = true
id = "1b19509b-32b1-4e9f-b71d-4992aa991967"
value = "admin"
}
app_role {
allowed_member_types = ["User"]
description = "ReadOnly roles have limited query access"
display_name = "ReadOnly"
enabled = true
id = "497406e4-012a-4267-bf18-45a1cb148a01"
value = "User"
}
feature_tags {
enterprise = true
gallery = true
}
optional_claims {
access_token {
name = "myclaim"
}
access_token {
name = "otherclaim"
}
id_token {
name = "userclaim"
source = "user"
essential = true
additional_properties = ["emit_as_roles"]
}
saml2_token {
name = "samlexample"
}
}
required_resource_access {
resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
resource_access {
id = "df021288-bdef-4463-88db-98f22de89214" # User.Read.All
type = "Role"
}
resource_access {
id = "b4e74841-8e56-480b-be8b-910348b18b4c" # User.ReadWrite
type = "Scope"
}
}
required_resource_access {
resource_app_id = "c5393580-f805-4401-95e8-94b7a6ef2fc2" # Office 365 Management
resource_access {
id = "594c1fb6-4f81-4475-ae41-0c394909246c" # ActivityFeed.Read
type = "Role"
}
}
web {
homepage_url = "https://app.example.net"
logout_url = "https://app.example.net/logout"
redirect_uris = ["https://app.example.net/account"]
implicit_grant {
access_token_issuance_enabled = true
id_token_issuance_enabled = true
}
}
}
resource "azuread_service_principal" "example" {
application_id = azuread_application.example.application_id
app_role_assignment_required = false
owners = [data.azuread_client_config.current.object_id]
}
/*
resource "azurerm_role_assignment" "example" {
scope = "/subscriptions/f10a5570-53f3-473f-9c2f-bd0ee87ca71c/resourceGroups/v-sakavya-Mindtree"
role_definition_id = "b24988ac-6180-42a0-ab88-20f7382dd24c"
principal_id = azuread_service_principal.example.object_id
}
*/
resource "azurerm_key_vault" "example" {
name = "kavyaexmplkeyvault"
location = data.azurerm_resource_group.example.location
resource_group_name = data.azurerm_resource_group.example.name
enabled_for_disk_encryption = true
tenant_id = data.azurerm_client_config.current.tenant_id
soft_delete_retention_days = 7
purge_protection_enabled = false
sku_name = "standard"
access_policy {
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id
//object_id= azuread_service_principal.example.object_id
certificate_permissions = [
"Create",
"Delete",
"DeleteIssuers",
"Get",
"GetIssuers",
"Import",
"List",
"ListIssuers",
"ManageContacts",
"ManageIssuers",
"Purge",
"SetIssuers",
"Update",
]
key_permissions = [
"Backup",
"Create",
"Decrypt",
"Delete",
"Encrypt",
"Get",
"Import",
"List",
"Purge",
"Recover",
"Restore",
"Sign",
"UnwrapKey",
"Update",
"Verify",
"WrapKey",
]
secret_permissions = [
"Backup",
"Delete",
"Get",
"List",
"Purge",
"Recover",
"Restore",
"Set",
]
storage_permissions = [
"Get","Set"
]
}
}
resource "tls_private_key" "example" {
algorithm = "RSA"
rsa_bits = 4096
}
resource "azurerm_key_vault_certificate" "example" {
name = "kavya-cert"
key_vault_id = azurerm_key_vault.example.id
certificate_policy {
issuer_parameters {
name = "Self"
}
key_properties {
exportable = true
key_size = 2048
key_type = "RSA"
reuse_key = true
}
lifetime_action {
action {
action_type = "AutoRenew"
}
trigger {
days_before_expiry = 30
}
}
secret_properties {
content_type = "application/x-pkcs12"
}
x509_certificate_properties {
# Server Authentication = 1.3.6.1.5.5.7.3.1
# Client Authentication = 1.3.6.1.5.5.7.3.2
extended_key_usage = ["1.3.6.1.5.5.7.3.1"]
key_usage = [
"cRLSign",
"dataEncipherment",
"digitalSignature",
"keyAgreement",
"keyCertSign",
"keyEncipherment",
]
subject_alternative_names {
dns_names = ["internal.contoso.com", "domain.hello.world"]
}
subject = "CN=hello-world"
validity_in_months = 12
}
}
}
resource "azuread_application_certificate" "example" {
application_object_id = azuread_application.example.id
type = "AsymmetricX509Cert"
encoding = "hex"
value = azurerm_key_vault_certificate.example.certificate_data
//end_date = azurerm_key_vault_certificate.example.certificate_attribute[0].expires
//start_date = azurerm_key_vault_certificate.example.certificate_attribute[0].not_before
}
As the service principal got the certificate get, list , create and delete access privileges.
But when I tried removing this access policy to the service principal , I got similar error
resource "azurerm_key_vault" "example" {
name = "kavyaexmplkeyvault"
location = data.azurerm_resource_group.example.location
resource_group_name = data.azurerm_resource_group.example.name
enabled_for_disk_encryption = true
tenant_id = data.azurerm_client_config.current.tenant_id
soft_delete_retention_days = 7
purge_protection_enabled = false
sku_name = "standard"
access_policy {
tenant_id = data.azurerm_client_config.current.tenant_id
// object_id = data.azurerm_client_config.current.object_id
object_id= azuread_service_principal.example.object_id
certificate_permissions = [
"Create",
"Delete",
"DeleteIssuers",
"Get",
"GetIssuers",
"Import",
"List",
"ListIssuers",
"ManageContacts",
"ManageIssuers",
"Purge",
"SetIssuers",
"Update",
]
key_permissions = [
"Backup",
"Create",
"Decrypt",
"Delete",
"Encrypt",
"Get",
"Import",
"List",
"Purge",
"Recover",
"Restore",
"Sign",
"UnwrapKey",
"Update",
"Verify",
"WrapKey",
]
secret_permissions = [
"Backup",
"Delete",
"Get",
"List",
"Purge",
"Recover",
"Restore",
"Set",
]
storage_permissions = [
"Get","Set"
]
}
}
Error:
Status=403 Code="Forbidden" Message="The user, group or application 'appid=***;oid=***;numgroups=3;iss=https://sts.windows.net/***/' does not have certificates get permission on key vault
Then I tried to create it again with the servicepricipal giving access policies .
But still faced same error .
Then I destroyed the files but no change as it is stored in the backend and the certificate privileges cant be changes unless we have access.
Instead I have changed the keyvault name and certificate name in terraform.
Deleted the existing certificate in azure ad app.
And then created and run terraform plan and terraform apply .
Direct terraform apply also worked with the above starting code.
And it created the service principal access policies.
Certificate retrieved in azure ad application.

Error when appending multiple key_vault_access_policy in a key_vault resource - resource needs to be imported into the State - Terraform / Azure

I'm trying to deploy a key_vault resource that contains two key_vault_access_policy using this code:
data "azurerm_client_config" "current" {}
module "agw_user_assigned_identity" {
source = "../modules/resources-blocks/user_assigned_identity"
user_assigned_identity_name = "agw-user-signed-id"
resource_group_name = module.resource_group.name
resource_group_location = module.resource_group.location
}
module "key_vault" {
source = "../modules/resources-hub/key_vault"
key_vault_name = local.key_vault_name
resource_group_location = module.resource_group.location
resource_group_name = module.resource_group.name
tenant_id = data.azurerm_client_config.current.tenant_id
soft_delete_retention_days = 90
}
module "key_vault_private_certificate" {
source = "../modules/resources-blocks/key_vault_certificate"
key_vault_id = module.key_vault.id
certificate_name = local.agw_certificate_name
certificate_path = var.SSL_CERTIFICATE_PATH
certificate_password = var.SSL_CERTIFICATE_PASSWORD
depends_on = [module.key_vault_access_policy_agw]
}
module "key_vault_access_policy_users" {
source = "../modules/resources-blocks/key_vault_access_policy"
key_vault_id = module.key_vault.id
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id
certificate_permissions = ["Backup", "Create", "Delete", "DeleteIssuers", "Get", "GetIssuers", "Import", "List", "ListIssuers", "ManageContacts", "ManageIssuers", "Purge", "Recover", "Restore", "SetIssuers", "Update"]
key_permissions = ["Backup", "Create", "Decrypt", "Delete", "Encrypt", "Get", "Import", "List", "Purge", "Recover", "Restore", "Sign", "UnwrapKey", "Update", "Verify", "WrapKey"]
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"]
depends_on = [module.key_vault]
}
module "key_vault_access_policy_agw" {
source = "../modules/resources-blocks/key_vault_access_policy"
key_vault_id = module.key_vault.id
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = module.agw_user_assigned_identity.principal_id
secret_permissions = ["Get"]
depends_on = [module.key_vault_access_policy_users]
}
With the resources created in another file:
resource "azurerm_key_vault" "kv" {
name = var.key_vault_name
location = var.resource_group_location
resource_group_name = var.resource_group_name
enabled_for_disk_encryption = true
tenant_id = var.tenant_id
soft_delete_retention_days = var.soft_delete_retention_days
purge_protection_enabled = false
sku_name = "standard"
}
locals {
get_only_access = ["Get", "List"]
}
resource "azurerm_key_vault_access_policy" "acess_policy" {
key_vault_id = var.key_vault_id
tenant_id = var.tenant_id
object_id = var.object_id
key_permissions = var.get_only_access ? local.get_only_access : var.key_permissions
secret_permissions = var.get_only_access ? local.get_only_access : var.secret_permissions
storage_permissions = var.get_only_access ? local.get_only_access : var.storage_permissions
certificate_permissions = var.get_only_access ? local.get_only_access : var.certificate_permissions
}
The error that I get with the command "terraform apply -var-file="variables.tfvars"" is the following:
Error: A resource with the ID "/subscriptions/xxxxxxxxxxx/resourceGroups/xxxxxxxxxx/providers/Microsoft.KeyVault/vaults/xxxxxxxx/objectId/xxxxxxxxxxxx" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for "azurerm_key_vault_access_policy" for more information.
│
│ with module.key_vault_access_policy_users.azurerm_key_vault_access_policy.acess_policy,
│ on ..\modules\resources-blocks\key_vault_access_policy\main.tf line 5, in resource "azurerm_key_vault_access_policy" "acess_policy":
│ 5: resource "azurerm_key_vault_access_policy" "acess_policy" {
Could you please help me to solve this issue?
Just to give you a more general overview, the reason I'm trying to deploy this resources is because I'm creating an Application Gateway and I need to store the SSL certificate in the key_vault resource.
Error: A resource with the ID "/subscriptions/xxxxxxxxxxx/resourceGroups/xxxxxxxxxx/providers/Microsoft.KeyVault/vaults/xxxxxxxx/objectId/xxxxxxxxxxxx" already exists - to be managed via Terraform this resource needs to be imported into the State.
It commonly happens when the terraform state file (running locally) does not match the resources in the Portal terraform state file.
As #Marcin said, you should import the resource with the resourceID and add the respective objectID of keyvault.
Goto keyvault in the portal & get the "resourceID, objectID" as shown here:
Use
terraform import azurerm_key_vault_access_policy.xxxxx ResourceID
to fix this issue.
terraform import azurerm_key_vault_access_policy.example /subscriptions/<suscriptionID>/resourceGroups/<resourcegroupName>/providers/Microsoft.KeyVault/vaults/examples-keyvault/objectId/<ObjectID of Keyvault>
Refer terraform registry & SO worked by me for more information- regarding it.
Output:

How to get key vault certificate value correctly in terraform module to create VPN gateway

Objective: Trying to create VPN gateway in Azure via Terraform
Problem Statement: I am not able to get value of Certificate.
Reference documentation : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/key_vault_certificate_data
Code that I used:
In Main.tf:
resource "azurerm_key_vault" "kv-ab-vgw" {
name = "kv-ab-vgw"
location = azurerm_resource_group.rg[0].location
resource_group_name = azurerm_resource_group.rg[0].name
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "standard"
soft_delete_retention_days = 7
access_policy {
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id
certificate_permissions = [
"Create",
"Delete",
"DeleteIssuers",
"Get",
"GetIssuers",
"Import",
"List",
"ListIssuers",
"ManageContacts",
"ManageIssuers",
"Purge",
"SetIssuers",
"Update",
]
key_permissions = [
"Backup",
"Create",
"Decrypt",
"Delete",
"Encrypt",
"Get",
"Import",
"List",
"Purge",
"Recover",
"Restore",
"Sign",
"UnwrapKey",
"Update",
"Verify",
"WrapKey",
]
secret_permissions = [
"Backup",
"Delete",
"Get",
"List",
"Purge",
"Recover",
"Restore",
"Set",
]
}
}
resource "azurerm_key_vault_certificate" "kvc" {
name = "ab-generated-cert"
key_vault_id = azurerm_key_vault.kv-ab-vgw.id
certificate_policy {
issuer_parameters {
name = "Self"
}
key_properties {
exportable = true
key_size = 2048
key_type = "RSA"
reuse_key = true
}
lifetime_action {
action {
action_type = "AutoRenew"
}
trigger {
days_before_expiry = 30
}
}
secret_properties {
content_type = "application/x-pkcs12"
}
x509_certificate_properties {
extended_key_usage = ["1.3.6.1.5.5.7.3.1"]
key_usage = [
"cRLSign",
"dataEncipherment",
"digitalSignature",
"keyAgreement",
"keyCertSign",
"keyEncipherment",
]
subject = "CN=VGWCreation"
validity_in_months = 12
}
}
}
data "azurerm_key_vault_certificate_data" "kvcdata" {
name = "ab-generated-cert"
key_vault_id = azurerm_key_vault.kv-ab-vgw.id
}
# VPN
resource "azurerm_virtual_network_gateway" "vpn-gw" {
name = "vng-ab-hub-dev-we"
location = azurerm_resource_group.rg[0].location
resource_group_name = azurerm_resource_group.rg[0].name
type = "Vpn"
vpn_type = "RouteBased"
active_active = true
enable_bgp = false
sku = "VpnGw1AZ"
ip_configuration {
name = "vnet"
public_ip_address_id = azurerm_public_ip.vpn-gateway-ip.id
private_ip_address_allocation = "Static"
# using gateway subnet for configuring vpn correct ?
subnet_id = azurerm_subnet.gw_snet[0].id
}
vpn_client_configuration {
address_space = ["10.xxx.xx.xx/24"]
root_certificate {
name = "ab-generated-cert"
public_cert_data = data.azurerm_key_vault_certificate_data.kvcdata.key
}
}
}
Error I get is:
Error: Creating/Updating Virtual Network Gateway: (Name "vng-ab-hub-dev-we" / Resource Group "xx-xx-vnet"): network.VirtualNetworkGatewaysClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="VpnClientRootCertificateDataInvalid" Message="Data for certificate /subscriptions/xxxxxxx--xxxxx---xxxxxx--xxxxx/resourceGroups/rg-ab-vnet/providers/Microsoft.Network/virtualNetworkGateways/vng-ab-hub-dev-we/vpnClientRootCertificates/ab-generated-cert is invalid." Details=[]
│
│ with azurerm_virtual_network_gateway.vpn-gw,
│ on main.tf line 1275, in resource "azurerm_virtual_network_gateway" "vpn-gw":
│ 1275: resource "azurerm_virtual_network_gateway" "vpn-gw" {
Key Vault is successfully created, and I see certificate also there but while using in creating VPN gives invalid data.
Can someone suggest, how to get this fixed..
As mentioned in the comment, you are providing a certificate key, where in fact you need to provide the certificate itself [1]:
public_cert_data - (Required) The public certificate of the root certificate authority. The certificate must be provided in Base-64 encoded X.509 format (PEM). In particular, this argument must not include the -----BEGIN CERTIFICATE----- or -----END CERTIFICATE----- markers.
In order for the error to be fixed, you first need to get the value from the data source using the terraform console:
terraform console
> data.azurerm_key_vault_certificate_data.kvcdata.pem
After you get the value, you should omit the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- markers and add it as a value for the public_cert_data argument:
public_cert_data = <<EOF
MIIDKDCCAhCgAwIBAgIQPVBXb+qPT/mxZXY0HDo9djANBgkqhkiG9w0BAQsFADAW
...
EOF
Note that it does not matter if EOF or EOT is used [2] as long as rules are followed.
[1] https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_gateway#public_cert_data
[2] https://www.terraform.io/language/expressions/strings#heredoc-strings

Azure terraform application gateway does not have secrets get permission on key vault

I am trying to provision an azure application gateway with terraform. And I have a key vault which has a self signed certificate referenced by the application gateway, but I am getting the below error:
Error: waiting for create/update of Application Gateway: (Name "ssi-test-public-appgateway" / Resource Group "ssi-test"): Code="ApplicationGatewayKeyVaultSecretException" Message="Problem occured while accessing and validating KeyVault Secrets associated with Application Gateway '/subscriptions/XXX/resourceGroups/ssi-test/providers/Microsoft.Network/applicationGateways/ssi-test-public-appgateway'. See details below:" Details=[{"code":"0","message":"The user, group or application 'name=Microsoft.Network/applicationGateways;appid=XXX;oid=XXX;iss=https://sts.windows.net/XXX/' does not have secrets get permission on key vault 'ssi-app-gw-kv;location=westeurope'. For help resolving this issue, please see https://go.microsoft.com/fwlink/?linkid=2125287"}]
And here's my terraform code:
identity.tf
data "azurerm_client_config" "current" {}
resource "azurerm_key_vault" "front_end_key_vault_cert" {
name = var.key_vault_name
location = var.location
resource_group_name = var.resource_group_name
enabled_for_disk_encryption = true
tenant_id = data.azurerm_client_config.current.tenant_id
soft_delete_retention_days = 7
purge_protection_enabled = false
sku_name = "standard"
access_policy {
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id
certificate_permissions = [
"Backup",
"Create",
"Delete",
"DeleteIssuers",
"Get",
"Import",
"List",
"ListIssuers",
"ManageContacts",
"ManageIssuers",
"Purge",
"Recover",
"Restore",
"SetIssuers",
"Update"
]
key_permissions = [
"Backup",
"Create",
"Decrypt",
"Delete",
"Encrypt",
"Get",
"Import",
"List",
"Purge",
"Recover",
"Restore",
"Sign",
"UnwrapKey",
"Update",
"Verify",
"WrapKey",
]
secret_permissions = [
"Backup",
"Delete",
"Get",
"List",
"Purge",
"Recover",
"Restore",
"Set",
]
}
}
resource "azurerm_key_vault_certificate" "https_cert" {
name = "ssi-self-signed-cert"
key_vault_id = azurerm_key_vault.front_end_key_vault_cert.id
certificate_policy {
issuer_parameters {
name = "Self"
}
key_properties {
exportable = true
key_size = 2048
key_type = "RSA"
reuse_key = true
}
lifetime_action {
action {
action_type = "AutoRenew"
}
trigger {
days_before_expiry = 30
}
}
secret_properties {
content_type = "application/x-pkcs12"
}
x509_certificate_properties {
# Server Authentication = 1.3.6.1.5.5.7.3.1
# Client Authentication = 1.3.6.1.5.5.7.3.2
extended_key_usage = ["1.3.6.1.5.5.7.3.1"]
key_usage = [
"cRLSign",
"dataEncipherment",
"digitalSignature",
"keyAgreement",
"keyCertSign",
"keyEncipherment",
]
subject_alternative_names {
dns_names = ["*.ssi.com"]
}
subject = "CN=*.ssi.com"
validity_in_months = 12
}
}
depends_on = [
azurerm_key_vault.front_end_key_vault_cert
]
}
resource "azurerm_user_assigned_identity" "key_vault_read" {
resource_group_name = var.resource_group_name
location = var.location
name = join("-", [var.project, var.environment, "key_vault_read_permission"])
}
resource "azurerm_role_assignment" "key_vault_role" {
scope = azurerm_key_vault.front_end_key_vault_cert.id
role_definition_name = "Reader"
principal_id = azurerm_user_assigned_identity.key_vault_read.principal_id
depends_on = [
azurerm_key_vault.front_end_key_vault_cert,
azurerm_user_assigned_identity.key_vault_read,
azurerm_key_vault_certificate.https_cert
]
app-gateway.tf
resource "azurerm_application_gateway" "public_app_gateway" {
name = join("-", [var.project, var.environment, "public-appgateway"])
location = var.location
resource_group_name = var.resource_group_name
sku {
name = "Standard_V2"
tier = "Standard_v2"
}
.
.
.
dynamic "ssl_certificate" {
for_each = var.ssl_certificates_configs
content {
name = lookup(ssl_certificate.value, "name")
key_vault_secret_id = azurerm_key_vault_certificate.https_cert.secret_id
}
}
identity {
type = "UserAssigned"
identity_ids = [azurerm_user_assigned_identity.key_vault_read.id]
}
dynamic "request_routing_rule" {
for_each = var.appgw_routings
content {
name = lookup(request_routing_rule.value, "name", local.pb_request_routing_rule_name)
rule_type = lookup(request_routing_rule.value, "rule_type", "Basic")
http_listener_name = lookup(request_routing_rule.value, "http_listener_name", local.pb_listener_name)
backend_address_pool_name = lookup(request_routing_rule.value, "backend_address_pool_name", null)
backend_http_settings_name = lookup(request_routing_rule.value, "backend_http_settings_name", null)
url_path_map_name = lookup(request_routing_rule.value, "url_path_map_name", null)
# redirect_configuration_name = lookup(request_routing_rule.value, "redirect_configuration_name", null)
# rewrite_rule_set_name = lookup(request_routing_rule.value, "rewrite_rule_set_name", null)
}
}
depends_on = [azurerm_role_assignment.key_vault_role]
}
Can someone help me on this?
This role assignment is wrong (i.e. not doing what you want to do): resource "azurerm_role_assignment" "key_vault_role"
What you want do add is a Key Vault access policy: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_access_policy
Beware: You need to remove the one access policy that you already have defined in your Key Vault resource and make this a distinct key_vault_access_policy resource, too. You can't mix those two ways to create access policies.
See for instance here for a complete example. Make sure to add an explicit dependency on our resource "azurerm_key_vault_certificate" "https_cert" for the first access policy (example).

Terraform Azure data factory creation

I'm trying to deploy Azure data factory along with customer managed key and identity but after terraform apply customer managed key is not showing in the data factory.
When I try to add the customer managed key manually in data factory it is giving below error.
Operation failed. Managed identity used in CMK not found.
data "azurerm_client_config" "main" {}
resource "azurerm_resource_group" "main" {
name = "rgsupports01"
location = "East US 2"
}
resource "azurerm_user_assigned_identity" "main" {
depends_on = [azurerm_resource_group.main]
name = "supports01-mid"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
}
resource "azurerm_key_vault" "main" {
name = "supportskv01"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
enabled_for_disk_encryption = true
tenant_id = data.azurerm_client_config.main.tenant_id
soft_delete_retention_days = 7
purge_protection_enabled = false
sku_name = "standard"
access_policy {
tenant_id = data.azurerm_client_config.main.tenant_id
object_id = data.azurerm_client_config.main.object_id
key_permissions = [
"Get",
"Unwrapkey",
"Wrapkey",
"Create",
"Delete",
]
secret_permissions = [
"Get",
]
storage_permissions = [
"Get",
]
}
}
resource "azurerm_key_vault_access_policy" "main" {
key_vault_id = azurerm_key_vault.main.id
tenant_id = data.azurerm_client_config.main.tenant_id
object_id = azurerm_user_assigned_identity.main.client_id
key_permissions = [
"Get","List","Unwrapkey","Wrapkey"
]
secret_permissions = [
"Get","List",
]
}
resource "azurerm_key_vault_key" "main" {
depends_on = [azurerm_key_vault_access_policy.main]
name = "supportrsakeys01"
key_vault_id = azurerm_key_vault.main.id
key_type = "RSA"
key_size = 2048
key_opts = [
"decrypt",
"encrypt",
"sign",
"unwrapKey",
"verify",
"wrapKey",
]
}
resource "azurerm_data_factory" "adf" {
#depends_on = [azurerm_key_vault_key.main]
name = "supportdfs01"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
public_network_enabled = false
customer_managed_key_id = resource.azurerm_key_vault_key.main.id
identity {
type = "UserAssigned"
identity_ids = [resource.azurerm_user_assigned_identity.main.id]
}
}
resource "azurerm_key_vault_access_policy" "new" {
depends_on = [azurerm_data_factory.adf]
key_vault_id = azurerm_key_vault.main.id
tenant_id = data.azurerm_client_config.main.tenant_id
object_id = azurerm_user_assigned_identity.main.principal_id
key_permissions = [
"Get","List","Unwrapkey","Wrapkey"
]
secret_permissions = [
"Get","List",
]
}
Do not specific access_policy within the Key Vault resource, only use azurerm_key_vault_access_policy resources. The way you have specified it, will bring conflicts and probably mess up access policies. See here.

Resources