I am trying to find some way of moving my certificates from a Key Vault in one Azure Subscription to another Azure subscription. Is there anyway of doing this>
Find below an approach to move a self-signed certification created in Azure Key Vault assuming it is already created.
--- Download PFX ---
First, go to the Azure Portal and navigate to the Key Vault that holds the certificate that needs to be moved. Then, select the certificate, the desired version and click Download in PFX/PEM format.
--- Import PFX ---
Now, go to the Key Vault in the destination subscription, Certificates, click +Generate/Import and import the PFX file downloaded in the previous step.
If you need to automate this process, the following article provides good examples related to your question:
https://blogs.technet.microsoft.com/kv/2016/09/26/get-started-with-azure-key-vault-certificates/
I eventually used terraform to achieve this. I referenced the certificates from the azure keyvault secret resource and created new certificates.
the sample code here.
terraform {
required_version = ">= 0.13"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=3.17.0"
}
}
}
provider "azurerm" {
features {}
}
locals {
certificates = [
"certificate_name_1",
"certificate_name_2",
"certificate_name_3",
"certificate_name_4",
"certificate_name_5",
"certificate_name_6"
]
}
data "azurerm_key_vault" "old" {
name = "old_keyvault_name"
resource_group_name = "old_keyvault_resource_group"
}
data "azurerm_key_vault" "new" {
name = "new_keyvault_name"
resource_group_name = "new_keyvault_resource_group"
}
data "azurerm_key_vault_secret" "secrets" {
for_each = toset(local.certificates)
name = each.value
key_vault_id = data.azurerm_key_vault.old.id
}
resource "azurerm_key_vault_certificate" "secrets" {
for_each = data.azurerm_key_vault_secret.secrets
name = each.value.name
key_vault_id = data.azurerm_key_vault.new.id
certificate {
contents = each.value.value
}
}
wrote a post here as well
Related
I have a certificate for an app service in an azure keyvault, I want to import a key vault certificate to my web app in terraform but am not sure where i would refer to the keyvault in the below example?
resource "azurerm_app_service_certificate_binding" "example" {
hostname_binding_id = azurerm_app_service_custom_hostname_binding.example.id
certificate_id = azurerm_app_service_managed_certificate.example.id
ssl_state = "SniEnabled"
}
To bind the existing key vault certificate with your webapp need to use as mentioned below by #json we need to first call key vault certificate using data then bind with webapp .
//First Read the External Key Vault
data "azurerm_key_vault" "production_keyvault" {
name = "testingkeyvault2022"
resource_group_name = "KeyVaultWestEuropeBackend"
}
// Now Read the Certificate
data "azurerm_key_vault_secret" "prod_certificate" {
name = "testcert"
key_vault_id = data.azurerm_key_vault.production_keyvault.id
}
// Now bind the webapp to the domain and look for certificate.
resource "azurerm_app_service_custom_hostname_binding" "website_app_hostname_bind" { //Website App
depends_on = [
azurerm_app_service_certificate.cert,
]
hostname = var.websiteurlbind
app_service_name = data.azurerm_app_service.read_website_app.name
resource_group_name = data.azurerm_resource_group.Terraform.name
ssl_state = "SniEnabled"
thumbprint = azurerm_app_service_certificate.cert.thumbprint
}
// Get Certificate from External KeyVault
resource "azurerm_app_service_certificate" "cert" {
name = "testingcert"
resource_group_name = data.azurerm_resource_group.Terraform.name
location = data.azurerm_resource_group.Terraform.location
pfx_blob = data.azurerm_key_vault_secret.prod_certificate.value
}
Note:- I have not tested due to some access issue from my end,but it should work.
Please find this SO THREAD for more information.
If still the issue persists please re-open at this GitHub issue.
I am trying to deploy application g/w with ssl certificate from key vault. It is prompting error as SecretIdSpecifiedIsInvalid when I run the terraform apply …Even though it is showing correct certificate id and name on error code which I can validate manually on portal.
I am also able to deploy app gateway manually using the same certificate from keyvault.
│ Error: creating Application Gateway: (Name “poc-appgw-iaps” /
Resource Group “poc-rg-appgw”):
network.ApplicationGatewaysClient#CreateOrUpdate: Failure sending
request: StatusCode=400 – Original Error:
Code=“SecretIdSpecifiedIsInvalid” Message=“SecretId
‘https://pockv-iaps.vault.azure.net/certificates/poc-cert-admin/xxxxxxxxxx’
specified in
‘/subscriptions/xxxxxxxxxxxxxxx/resourceGroups/poc-rg-appgw/providers/Microsoft.Network/applicationGateways/poc-appgw-iaps/sslCertificates/poc-cert-admin’
is invalid.” Details=[]
Initially please try solve this problem by upgrading to the latest
azurerm terraform provider. The latest should contain fixes for
the situation if provision is all correct.
The ssl certificate block must contain your PFX certificate. Data
must be used if key vault secret_id is not already set.
Key vault secret id of base-64 encoded unencrypted pfx
certificate/secret must be stored in Azure KeyVault.
Please note that to enable the above feature , azure key vault soft delete must be anabled
Please make sure to have required access policies to get secrets .
provider "azurerm" {
features{}
}
data "azurerm_client_config" "current" {}
resource "azurerm_user_assigned_identity" "base" {
resource_group_name = "resourcegroup"
location = "resgrouplocation"
name = "appgwkeyvault"
}
data "azurerm_key_vault" "example"{
name = "keyvault-name"
resource_group_name = "resourcegroup"
}
resource "azurerm_key_vault_access_policy" "example" {
key_vault_id = data.azurerm_key_vault.example.id
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = azurerm_user_assigned_identity.base.principal_id
key_permissions = [
"Get",
]
certificate_permissions = [
"Get",
]
secret_permissions = [
"Get",
]
}
output "secret_identifier" {
value = azurerm_key_vault_certificate.example.secret_id
}
//TODO required soft delete on the keyvault
ssl_certificate {
name = "app_listener"
key_vault_secret_id = azurerm_key_vault_certificate.example.secret_id
}
Please make sure certificate properties are properly given , secrets must be .pfx format
resource "azurerm_key_vault_certificate" "example" {
name = "imported-cert"
key_vault_id = azurerm_key_vault.kv.id
//make sure certificate is base64 encoded pfx certificate
certificate {
contents = filebase64("C:/appgwlistener.pfx")
password = "password"
}
certificate_policy {
...
}
key_properties {
exportable = true
key_size = 2048
key_type = "RSA"
reuse_key = false
}
secret_properties {
content_type = "application/x-pkcs12"
}
}
}
Below references can guide you:
Terraform - How to attach SSL certificate stored in Azure KeyVault
to an Application Gateway - Stack Overflow
key_vault_secret_id azure_application_gateway| Terraform Registry
I want to update the details of an expired SP through terraform. I can regenerate the SP by changing the expiration date for the SP. but the SP details are been stored in the keyvault. So while updating the keyvault with the same id/secret it errors out. Is there a way to update/delete the key_vault secret through terraform ?
resource "azurerm_key_vault_secret" "sp_arm_client_id"
{
name = "ARM-CLIENT-ID"
value = az_sp.app_id key_vault_id = data.azurerm_key_vault.storable_kvs[each.key].id
}
I tested your scenario in my environment and I was successfully able to do the changes and it got stored in current version and the previous one was in older version using the below code:
provider "azuread" {}
provider "azurerm" {
features{}
}
data "azuread_client_config" "current" {}
data "azuread_application" "appreg" {
display_name="ansumanterraformtest"
}
resource "azuread_application_password" "apppass" {
application_object_id = data.azuread_application.appreg.object_id
end_date_relative = "3h"
}
data "azurerm_key_vault" "kv" {
name = "kvname"
resource_group_name = "ansumantest"
}
resource "azurerm_key_vault_secret" "demo_sp_client_id" {
name = "demo-sp-client-id"
value = data.azuread_application.appreg.application_id
key_vault_id = data.azurerm_key_vault.kv.id
}
resource "azurerm_key_vault_secret" "demo_sp_client_secret" {
name = "demo-sp-client-secret"
value =azuread_application_password.apppass.value
key_vault_id = data.azurerm_key_vault.kv.id
}
Output:
Note: You might be getting the error if that secret in keyvault was not created from terraform . If it was created from portal or any other source then you have to first import that secret to terraform state and then change it so that the terraform can manage it .
Import command:
terraform import azurerm_key_vault_secret.example "https://example-keyvault.vault.azure.net/secrets/example/fdf067c93bbb4b22bff4d8b7a9a56217"
Reference:
azurerm_key_vault_secret | Resources | hashicorp/azurerm | Terraform Registry
I am trying to download a certificate in azure keyvault and save it as a local file by using terraform? Is this operation possible at all with terraform? I have checked it but couldn't find a terraform function doing that.
You may use the azurerm_key_vault_certificate_data data source.
Example from the docs
data "azurerm_key_vault" "example" {
name = "examplekv"
resource_group_name = "some-resource-group"
}
data "azurerm_key_vault_certificate_data" "example" {
name = "secret-sauce"
key_vault_id = data.azurerm_key_vault.example.id
}
output "example_pem" {
value = data.azurerm_key_vault_certificate_data.example.pem
}
i am new to Terraform Scripts i am working on Azure with Terraform i have create a Resource Group and in that resource Group i have created a Key Vault i want to Populate secrets from Central Key vault is there any way ?
Yes, you can import secrets using the data source key_vault_secret https://www.terraform.io/docs/providers/azurerm/d/key_vault_secret.html
data "azurerm_key_vault" "existing" {
name = "Test1-KV"
resource_group_name = "Test1-RG"
}
data "azurerm_key_vault_secret" "existing-sauce" {
name = "secret-sauce"
key_vault_id = data.azurerm_key_vault.existing.id
}
resource "azurerm_key_vault" "new" {
name = "New-KV"
resource_group_name = "New-RG"
...
}
resource "azurerm_key_vault_secret" "new-sauce" {
name = "secret-sauce"
value = data.azurerm_key_vault_secret.existing_sauce.value
key_vault_id = azurerm_key_vault.new.id
}
Of course, the user/service principle that you run Terraform with needs to have an access policy on the KeyVault to allow reading secrets.
//edit: As I understand from the comments, you want to iterate through all the existing secrets in a KeyVault and replicate them in another KV. This not possible with Terraform as of today since there is not TF data source that would list all secrets in a KV. To use the aforementioned data source, you need to specify each secret by its name.
To achieve what you want to do you need something like powershell or az CLI.