0

I’m working on to create Azure Key Vault Managed HSM using terraform. For that I have followed this documentation.

The above documentation contains the code for creating the HSM but not for the activation of managed HSM.

I want to provision and activate a managed HSM using Terraform. Is it possible or not through the terraform?

After Activate a managed HSM, I want to configure encryption with customer-managed keys stored in Azure Key Vault Managed HSM. For that I have followed this documentation, but it contains the Azure CLI code.

Pradeep
  • 5,101
  • 14
  • 68
  • 140

1 Answers1

1

Unfortunately , its not directly possible to activate the Managed HSM from Terraform . Currently , you can only provision it from terraform or ARM template but for activating it has to be done only from PowerShell and Azure CLI. It is also the same while updating the storage account with customer managed key and assigning a key vault role assignment.

If you use azurerm_storage_account_customer_managed_key, then you will get the below error:

enter image description here

Overall all HSM Key vault Operations needs to be performed on CLI or Powershell.

So , For workaround you can use local-exec in terraform to directly run it without performing separate operations.

Code:

provider "azurerm" {
  features {}
}
data "azurerm_client_config" "current" {
}

resource "azurerm_resource_group" "example" {
  name     = "keyvaulthsm-resources"
  location = "West Europe"
}

resource "azurerm_key_vault_managed_hardware_security_module" "example" {
  name                       = "testKVHsm"
  resource_group_name        = azurerm_resource_group.example.name
  location                   = azurerm_resource_group.example.location
  sku_name                   = "Standard_B1"
  purge_protection_enabled   = true
  soft_delete_retention_days = 90
  tenant_id                  = data.azurerm_client_config.current.tenant_id
  admin_object_ids           = [data.azurerm_client_config.current.object_id]

  tags = {
    Env = "Test"
  }
}

variable "KeyName" {
  default=["C:/<Path>/cert_0.key","C:/<Path>/cert_1.key","C:/<Path>/cert_2.key"]
}

variable "CertName" {
  default=["C:/<Path>/cert_0.cer","C:/<Path>/cert_1.cer","C:/<Path>/cert_2.cer"]
}

resource "null_resource" "OPENSSLCERT" {
    count = 3
  provisioner "local-exec" {
    command = <<EOT
     cd  "C:\Program Files\OpenSSL-Win64\bin"
    ./openssl.exe req -newkey rsa:2048 -nodes -keyout ${var.KeyName[count.index]}  -x509 -days 365 -out ${var.CertName[count.index]} -subj "/C=IN/ST=Telangana/L=Hyderabad/O=exy ltd/OU=Stack/CN=domain.onmicrosoft.com"
    EOT
    interpreter = [
      "PowerShell","-Command"
    ]
  }
}

resource "null_resource" "securityDomain" {
  provisioner "local-exec" {
    command = <<EOT
    az keyvault security-domain download --hsm-name ${azurerm_key_vault_managed_hardware_security_module.example.name} --sd-wrapping-keys ./cert_0.cer ./cert_1.cer ./cert_2.cer --sd-quorum 2 --security-domain-file ${azurerm_key_vault_managed_hardware_security_module.example.name}-SD.json
    EOT
    interpreter = [
      "PowerShell","-Command"
    ]
  }
  depends_on = [
    null_resource.OPENSSLCERT
  ]
}

resource "azurerm_storage_account" "example" {
  name                     = "ansumanhsmstor1"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  account_tier             = "Standard"
  account_replication_type = "GRS"

  identity {
    type = "SystemAssigned"
  }
}
resource "null_resource" "roleassignkv" {
  provisioner "local-exec" {
    command = <<EOT
    az keyvault role assignment create --hsm-name ${azurerm_key_vault_managed_hardware_security_module.example.name} --role "Managed HSM Crypto Service Encryption User" --assignee ${azurerm_storage_account.example.identity[0].principal_id} --scope /keys
    az keyvault role assignment create --hsm-name ${azurerm_key_vault_managed_hardware_security_module.example.name} --role "Managed HSM Crypto User" --assignee ${data.azurerm_client_config.current.object_id} --scope /
    az keyvault key create --hsm-name ${azurerm_key_vault_managed_hardware_security_module.example.name} --name storageencryptionkey --ops wrapKey unwrapKey --kty RSA-HSM --size 3072
    EOT
    interpreter = [
      "PowerShell","-Command"
    ]
  }
  depends_on = [
    null_resource.securityDomain,
    azurerm_storage_account.example
  ]
}

resource "null_resource" "storageupdate" {
  provisioner "local-exec" {
    command = <<EOT
    az storage account update --name ${azurerm_storage_account.example.name} --resource-group ${azurerm_resource_group.example.name} --encryption-key-name storageencryptionkey --encryption-key-source Microsoft.Keyvault --encryption-key-vault ${azurerm_key_vault_managed_hardware_security_module.example.hsm_uri}
    EOT
    interpreter = [
      "PowerShell","-Command"
    ]
  }
  depends_on = [
    null_resource.securityDomain,
    azurerm_storage_account.example,
    null_resource.roleassignkv
  ]
}

Output:

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

Note: Please make sure to enable Purge Protection on the HSM Keyvault and have all the required permissions on Management Plane (not added in code) and Control Plane (I have added in the code). To install OpenSSL you can refer this answer by mtotowamkwe on this SO thread.

Ansuman Bal
  • 9,705
  • 2
  • 10
  • 27
  • Thanks @AnsumanBal, I'm unable to find this `C:\Program Files\OpenSSL-Win64\bin" ./openssl.exe` path in my local system. Is possible to store the certs in current terraform working folder? – Pradeep Dec 28 '21 at 16:38
  • I'm trying to generate certificates using openssl from this `C:\Program Files\Git\usr\bin` location. But I'm getting this `req: can't open "cert_0_key" for writing, permission denied error in req` error – Pradeep Dec 28 '21 at 16:40
  • 1
    @Pradeep, For the second permission denied error you have to use elevated terminal to create the certs .. so If you are using VSCode then open it in admin mode. – Ansuman Bal Dec 28 '21 at 17:20
  • Is it possible to use certificates created in Azure Key Vault for activating the HSM, instead of generating certificates in local machine? – Pradeep Dec 28 '21 at 17:25
  • @Pradeep, I have not tried that but I guess we can use as we can create RSA key pairs in keyvault . But for activation again you will have to download it and then reference it as there is no identity in HSM to directly reference it from keyvault. – Ansuman Bal Dec 28 '21 at 18:09
  • AnsumanBal, Getting this `Error: local-exec provisioner error │ │ with null_resource.storageupdate, │ on main.tf line 93, in resource "null_resource" "storageupdate": │ 93: provisioner "local-exec" { │ │ Error running command ' az storage account update --name xxxxx --resource-group xxx-KV-HSM-RG-xx --encryption-key-name storageencryptionkey --encryption-key-source │ Microsoft.Keyvault --encryption-key-vault https://xxxxx.managedhsm.azure.net/ │ ': exit status 1. Output: ERROR: (KeyVaultPolicyError) Keyvault policy recoverable is not set` error. – Pradeep Dec 28 '21 at 18:26
  • 1
    @Pradeep, you have to create a purge enabled HSM keyvault . So keep purge_protection_enabled = true as I have mentioned in note. – Ansuman Bal Dec 28 '21 at 20:19
  • @Pradeep, I am doing the same as mine is a openssl server , that's why I am running cd "C:\Program Files\OpenSSL-Win64\bin" and then calling the openssl to create certs . And then in variables as you can see in answer I am calling paths which are same as my terraform project to save the certs. – Ansuman Bal Dec 28 '21 at 20:23
  • AnsumanBal, I'm getting this `Error: local-exec provisioner error │ │ with null_resource.storageupdate, │ │ Error running command ' az storage account update --name xxxxxx --resource-group xxxx --encryption-key-name storageencryptionkey --encryption-key-source │ Microsoft.Keyvault --encryption-key-vault https://xxxx.managedhsm.azure.net/ │ ': exit status 1. Output: ERROR: (KeyVaultAuthenticationFailure) The operation failed because of authentication issue on the keyvault. For more information, see - │ https://aka.ms/storagekeyvaultaccesspolicy` error. – Pradeep Dec 29 '21 at 03:13