From 8baad00e07e42ca6d52652d6a6d953f2656bc96e Mon Sep 17 00:00:00 2001 From: Yuval Yaron <43217306+yuvalyaron@users.noreply.github.com> Date: Mon, 23 Dec 2024 11:58:43 +0200 Subject: [PATCH] CMK Encryption support for resources in templates (#4195) * change cmk name to include tre-id + add dependency to one of the stg accounts * add cmk for ACR and service bus * add null default for acr_sku * bump core version to 0.11.8 * set 'Enable support for customer-managed keys' for tables and queues in storage accounts (core/mgmt only) * add key type encryption to state store * add support for customer-managed key (CMK) encryption in templates * fix terraform issues found by linter * raise minor instead of major version * fix terraform issues found by linter * fix terraform issues found by linter * fix: update identity_client_id reference in azureml * remove the 'vmss' from disks encryption set names * move all data resources to a data.tf file --- CHANGELOG.md | 1 + core/terraform/cmk_encryption.tf | 2 +- core/terraform/locals.tf | 3 +- core/version.txt | 2 +- docs/tre-admins/customer-managed-keys.md | 5 --- .../shared_services/admin-vm/parameters.json | 12 +++++ .../shared_services/admin-vm/porter.yaml | 14 +++++- .../admin-vm/terraform/admin-jumpbox.tf | 22 +++++++-- .../admin-vm/terraform/data.tf | 12 +++++ .../admin-vm/terraform/locals.tf | 2 + .../admin-vm/terraform/variables.tf | 9 ++++ .../shared_services/certs/parameters.json | 12 +++++ templates/shared_services/certs/porter.yaml | 13 +++++- .../shared_services/certs/terraform/data.tf | 8 +++- .../shared_services/certs/terraform/locals.tf | 3 ++ .../certs/terraform/staticweb.tf | 18 ++++++++ .../certs/terraform/variables.tf | 9 ++++ .../cyclecloud/parameters.json | 12 +++++ .../shared_services/cyclecloud/porter.yaml | 14 +++++- .../cyclecloud/terraform/data.tf | 5 +++ .../cyclecloud/terraform/locals.tf | 2 + .../cyclecloud/terraform/storage.tf | 18 ++++++++ .../cyclecloud/terraform/variables.tf | 9 +++- .../sonatype-nexus-vm/parameters.json | 12 +++++ .../sonatype-nexus-vm/porter.yaml | 14 +++++- .../sonatype-nexus-vm/terraform/data.tf | 11 +++++ .../sonatype-nexus-vm/terraform/locals.tf | 2 + .../sonatype-nexus-vm/terraform/variables.tf | 9 ++++ .../sonatype-nexus-vm/terraform/vm.tf | 24 ++++++++-- .../azureml/parameters.json | 12 +++++ .../workspace_services/azureml/porter.yaml | 14 +++++- .../azureml/terraform/.terraform.lock.hcl | 1 + .../azureml/terraform/acr.tf | 18 ++++++++ .../azureml/terraform/data.tf | 12 +++++ .../azureml/terraform/locals.tf | 2 + .../azureml/terraform/storage.tf | 19 +++++++- .../azureml/terraform/variables.tf | 9 +++- .../workspace_services/gitea/parameters.json | 12 +++++ .../workspace_services/gitea/porter.yaml | 14 +++++- .../gitea/terraform/data.tf | 6 +++ .../gitea/terraform/locals.tf | 4 +- .../gitea/terraform/storage.tf | 18 ++++++++ .../gitea/terraform/variables.tf | 7 +++ .../parameters.json | 12 +++++ .../porter.yaml | 14 +++++- .../terraform/data.tf | 12 +++++ .../terraform/locals.tf | 3 ++ .../terraform/variables.tf | 7 +++ .../terraform/windowsvm.tf | 22 +++++++-- .../parameters.json | 12 +++++ .../porter.yaml | 14 +++++- .../terraform/data.tf | 12 +++++ .../terraform/locals.tf | 3 ++ .../terraform/variables.tf | 9 +++- .../terraform/windowsvm.tf | 22 +++++++-- .../guacamole-azure-linuxvm/parameters.json | 12 +++++ .../guacamole-azure-linuxvm/porter.yaml | 14 +++++- .../guacamole-azure-linuxvm/terraform/data.tf | 45 +++++++++++++++++++ .../terraform/linuxvm.tf | 22 +++++++-- .../terraform/locals.tf | 3 ++ .../guacamole-azure-linuxvm/terraform/main.tf | 33 -------------- .../terraform/variables.tf | 7 +++ .../guacamole-azure-windowsvm/parameters.json | 12 +++++ .../guacamole-azure-windowsvm/porter.yaml | 14 +++++- .../terraform/data.tf | 12 +++++ .../terraform/locals.tf | 3 ++ .../terraform/variables.tf | 7 +++ .../terraform/windowsvm.tf | 23 ++++++++-- .../airlock-import-review/parameters.json | 12 +++++ .../airlock-import-review/porter.yaml | 14 +++++- templates/workspaces/base/parameters.json | 4 +- templates/workspaces/base/porter.yaml | 2 +- .../terraform/airlock/storage_accounts.tf | 10 +++++ .../terraform/azure-monitor/azure-monitor.tf | 2 + .../base/terraform/cmk-encryption.tf | 2 +- templates/workspaces/base/terraform/locals.tf | 3 +- .../workspaces/base/terraform/storage.tf | 2 + .../workspaces/base/terraform/variables.tf | 1 - .../workspaces/unrestricted/parameters.json | 12 +++++ templates/workspaces/unrestricted/porter.yaml | 14 +++++- 80 files changed, 767 insertions(+), 87 deletions(-) create mode 100644 templates/shared_services/cyclecloud/terraform/data.tf create mode 100644 templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/data.tf diff --git a/CHANGELOG.md b/CHANGELOG.md index ef1e8ebc36..09e4a73244 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ ENHANCEMENTS: * Add ability to download VSCode Extensions ([[#4187](https://github.com/microsoft/AzureTRE/issues/4187)]) * Update Windows VM Images ([#4198](https://github.com/microsoft/AzureTRE/pull/4198)) * Enhance DPI of Linux display ([[#4200](https://github.com/microsoft/AzureTRE/issues/4200)]) +* Add support for customer-managed keys encryption in templates ([#4145](https://github.com/microsoft/AzureTRE/issues/4145)) BUG FIXES: * Update KeyVault references in API to use the version so Terraform cascades the update ([#4112](https://github.com/microsoft/AzureTRE/pull/4112)) diff --git a/core/terraform/cmk_encryption.tf b/core/terraform/cmk_encryption.tf index 4c0b5a1b1c..056a471478 100644 --- a/core/terraform/cmk_encryption.tf +++ b/core/terraform/cmk_encryption.tf @@ -4,7 +4,7 @@ resource "azurerm_user_assigned_identity" "encryption" { location = azurerm_resource_group.core.location tags = local.tre_core_tags - name = "id-encryption-${var.tre_id}" + name = local.encryption_identity_name lifecycle { ignore_changes = [tags] } } diff --git a/core/terraform/locals.tf b/core/terraform/locals.tf index bac02640e6..22d327f96f 100644 --- a/core/terraform/locals.tf +++ b/core/terraform/locals.tf @@ -44,5 +44,6 @@ locals { # The key store for encryption keys could either be external or created by terraform key_store_id = var.enable_cmk_encryption ? (var.external_key_store_id != null ? var.external_key_store_id : data.azurerm_key_vault.encryption_kv[0].id) : "" - cmk_name = "tre-encryption-${var.tre_id}" + cmk_name = "tre-encryption-${var.tre_id}" + encryption_identity_name = "id-encryption-${var.tre_id}" } diff --git a/core/version.txt b/core/version.txt index 20cc868f1e..c9f772e183 100644 --- a/core/version.txt +++ b/core/version.txt @@ -1 +1 @@ -__version__ = "0.11.9" +__version__ = "0.11.10" diff --git a/docs/tre-admins/customer-managed-keys.md b/docs/tre-admins/customer-managed-keys.md index e97bc61655..252d16e87b 100644 --- a/docs/tre-admins/customer-managed-keys.md +++ b/docs/tre-admins/customer-managed-keys.md @@ -2,11 +2,6 @@ You can enable customer-managed keys (CMK) for supporting resources in Azure TRE. -!!! warning - Currently Azure TRE only supports CMK encryption for resources in the TRE core and Base Workspace. - CMK encryption is not supported for the rest of the resources such as those deployed by a TRE workspace. - - !!! caution Currently, it is not possible to redeploy TRE with CMK enabled if it has previously been deployed without it. This is due to limitations of resources such as Azure Container Registry (ACR) that only allow enabling the CMK encryption at the time of resource creation. diff --git a/templates/shared_services/admin-vm/parameters.json b/templates/shared_services/admin-vm/parameters.json index ac546acffc..f133067bf8 100755 --- a/templates/shared_services/admin-vm/parameters.json +++ b/templates/shared_services/admin-vm/parameters.json @@ -45,6 +45,18 @@ "source": { "env": "ARM_ENVIRONMENT" } + }, + { + "name": "enable_cmk_encryption", + "source": { + "env": "ENABLE_CMK_ENCRYPTION" + } + }, + { + "name": "key_store_id", + "source": { + "env": "KEY_STORE_ID" + } } ] } diff --git a/templates/shared_services/admin-vm/porter.yaml b/templates/shared_services/admin-vm/porter.yaml index 4f9977a8b6..b91375f0ce 100644 --- a/templates/shared_services/admin-vm/porter.yaml +++ b/templates/shared_services/admin-vm/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-shared-service-admin-vm -version: 0.4.8 +version: 0.5.0 description: "An admin vm shared service" dockerfile: Dockerfile.tmpl registry: azuretre @@ -44,6 +44,12 @@ parameters: env: ADMIN_JUMPBOX_VM_SKU type: string default: Standard_B2s + - name: enable_cmk_encryption + type: boolean + default: false + - name: key_store_id + type: string + default: "" mixins: - terraform: @@ -56,6 +62,8 @@ install: tre_id: ${ bundle.parameters.tre_id } tre_resource_id: ${ bundle.parameters.id } admin_jumpbox_vm_sku: ${ bundle.parameters.admin_jumpbox_vm_sku } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -71,6 +79,8 @@ upgrade: tre_id: ${ bundle.parameters.tre_id } tre_resource_id: ${ bundle.parameters.id } admin_jumpbox_vm_sku: ${ bundle.parameters.admin_jumpbox_vm_sku } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -86,6 +96,8 @@ uninstall: tre_id: ${ bundle.parameters.tre_id } tre_resource_id: ${ bundle.parameters.id } admin_jumpbox_vm_sku: ${ bundle.parameters.admin_jumpbox_vm_sku } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" diff --git a/templates/shared_services/admin-vm/terraform/admin-jumpbox.tf b/templates/shared_services/admin-vm/terraform/admin-jumpbox.tf index 3ef4b8734b..5160524505 100644 --- a/templates/shared_services/admin-vm/terraform/admin-jumpbox.tf +++ b/templates/shared_services/admin-vm/terraform/admin-jumpbox.tf @@ -45,14 +45,30 @@ resource "azurerm_windows_virtual_machine" "jumpbox" { } os_disk { - name = "vm-dsk-${var.tre_id}" - caching = "ReadWrite" - storage_account_type = "Standard_LRS" + name = "vm-dsk-${var.tre_id}" + caching = "ReadWrite" + storage_account_type = "Standard_LRS" + disk_encryption_set_id = var.enable_cmk_encryption ? azurerm_disk_encryption_set.jumpbox_disk_encryption[0].id : null } lifecycle { ignore_changes = [tags] } } +resource "azurerm_disk_encryption_set" "jumpbox_disk_encryption" { + count = var.enable_cmk_encryption ? 1 : 0 + name = "disk-encryption-jumpbox-${var.tre_id}-${var.tre_resource_id}" + location = data.azurerm_resource_group.rg.location + resource_group_name = data.azurerm_resource_group.rg.name + key_vault_key_id = data.azurerm_key_vault_key.tre_encryption_key[0].versionless_id + encryption_type = "EncryptionAtRestWithPlatformAndCustomerKeys" + auto_key_rotation_enabled = true + + identity { + type = "UserAssigned" + identity_ids = [data.azurerm_user_assigned_identity.tre_encryption_identity[0].id] + } +} + resource "azurerm_key_vault_secret" "jumpbox_credentials" { name = "${azurerm_windows_virtual_machine.jumpbox.name}-jumpbox-password" value = random_password.password.result diff --git a/templates/shared_services/admin-vm/terraform/data.tf b/templates/shared_services/admin-vm/terraform/data.tf index 69c133b06e..b6ad53211c 100644 --- a/templates/shared_services/admin-vm/terraform/data.tf +++ b/templates/shared_services/admin-vm/terraform/data.tf @@ -11,3 +11,15 @@ data "azurerm_key_vault" "keyvault" { data "azurerm_resource_group" "rg" { name = local.core_resource_group_name } + +data "azurerm_key_vault_key" "tre_encryption_key" { + count = var.enable_cmk_encryption ? 1 : 0 + name = local.cmk_name + key_vault_id = var.key_store_id +} + +data "azurerm_user_assigned_identity" "tre_encryption_identity" { + count = var.enable_cmk_encryption ? 1 : 0 + name = local.encryption_identity_name + resource_group_name = local.core_resource_group_name +} diff --git a/templates/shared_services/admin-vm/terraform/locals.tf b/templates/shared_services/admin-vm/terraform/locals.tf index f9ad84b852..84c7fb8dfb 100644 --- a/templates/shared_services/admin-vm/terraform/locals.tf +++ b/templates/shared_services/admin-vm/terraform/locals.tf @@ -6,4 +6,6 @@ locals { tre_id = var.tre_id tre_shared_service_id = var.tre_resource_id } + cmk_name = "tre-encryption-${var.tre_id}" + encryption_identity_name = "id-encryption-${var.tre_id}" } diff --git a/templates/shared_services/admin-vm/terraform/variables.tf b/templates/shared_services/admin-vm/terraform/variables.tf index b52d21ea1e..69ba1e51b3 100644 --- a/templates/shared_services/admin-vm/terraform/variables.tf +++ b/templates/shared_services/admin-vm/terraform/variables.tf @@ -11,3 +11,12 @@ variable "tre_resource_id" { variable "admin_jumpbox_vm_sku" { type = string } + +variable "enable_cmk_encryption" { + type = bool + default = false +} + +variable "key_store_id" { + type = string +} diff --git a/templates/shared_services/certs/parameters.json b/templates/shared_services/certs/parameters.json index 53dd18791e..ba8512e794 100755 --- a/templates/shared_services/certs/parameters.json +++ b/templates/shared_services/certs/parameters.json @@ -57,6 +57,18 @@ "source": { "env": "ARM_ENVIRONMENT" } + }, + { + "name": "enable_cmk_encryption", + "source": { + "env": "ENABLE_CMK_ENCRYPTION" + } + }, + { + "name": "key_store_id", + "source": { + "env": "KEY_STORE_ID" + } } ] } diff --git a/templates/shared_services/certs/porter.yaml b/templates/shared_services/certs/porter.yaml index 6c4fee6453..cb0ae604d0 100755 --- a/templates/shared_services/certs/porter.yaml +++ b/templates/shared_services/certs/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-shared-service-certs -version: 0.6.1 +version: 0.7.0 description: "An Azure TRE shared service to generate certificates for a specified internal domain using Letsencrypt" registry: azuretre dockerfile: Dockerfile.tmpl @@ -51,6 +51,12 @@ parameters: - name: id type: string description: "Resource ID" + - name: enable_cmk_encryption + type: boolean + default: false + - name: key_store_id + type: string + default: "" mixins: - exec @@ -67,6 +73,8 @@ install: domain_prefix: ${ bundle.parameters.domain_prefix } cert_name: ${ bundle.parameters.cert_name } tre_resource_id: ${ bundle.parameters.id } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -116,7 +124,6 @@ install: resource-group: ${ bundle.outputs.resource_group_name } name: ${ bundle.outputs.application_gateway_name } - upgrade: - exec: description: "Upgrade shared service" @@ -132,6 +139,8 @@ uninstall: domain_prefix: ${ bundle.parameters.domain_prefix } cert_name: ${ bundle.parameters.cert_name } tre_resource_id: ${ bundle.parameters.id } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" diff --git a/templates/shared_services/certs/terraform/data.tf b/templates/shared_services/certs/terraform/data.tf index bb577f11ae..359ae36f43 100644 --- a/templates/shared_services/certs/terraform/data.tf +++ b/templates/shared_services/certs/terraform/data.tf @@ -1,5 +1,3 @@ -data "azurerm_client_config" "current" {} - data "azurerm_resource_group" "rg" { name = "rg-${var.tre_id}" } @@ -19,3 +17,9 @@ data "azurerm_user_assigned_identity" "resource_processor_vmss_id" { name = "id-vmss-${var.tre_id}" resource_group_name = "rg-${var.tre_id}" } + +data "azurerm_user_assigned_identity" "tre_encryption_identity" { + count = var.enable_cmk_encryption ? 1 : 0 + name = local.encryption_identity_name + resource_group_name = data.azurerm_resource_group.rg.name +} diff --git a/templates/shared_services/certs/terraform/locals.tf b/templates/shared_services/certs/terraform/locals.tf index 47cb8f6843..eb6e2bc676 100644 --- a/templates/shared_services/certs/terraform/locals.tf +++ b/templates/shared_services/certs/terraform/locals.tf @@ -23,4 +23,7 @@ locals { tre_id = var.tre_id tre_shared_service_id = var.tre_resource_id } + + cmk_name = "tre-encryption-${var.tre_id}" + encryption_identity_name = "id-encryption-${var.tre_id}" } diff --git a/templates/shared_services/certs/terraform/staticweb.tf b/templates/shared_services/certs/terraform/staticweb.tf index 49f20fd03c..5de49e6065 100644 --- a/templates/shared_services/certs/terraform/staticweb.tf +++ b/templates/shared_services/certs/terraform/staticweb.tf @@ -6,6 +6,8 @@ resource "azurerm_storage_account" "staticweb" { account_kind = "StorageV2" account_tier = "Standard" account_replication_type = "LRS" + table_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" + queue_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" enable_https_traffic_only = true allow_nested_items_to_be_public = false cross_tenant_replication_enabled = false @@ -19,9 +21,25 @@ resource "azurerm_storage_account" "staticweb" { error_404_document = "404.html" } + dynamic "identity" { + for_each = var.enable_cmk_encryption ? [1] : [] + content { + type = "UserAssigned" + identity_ids = [data.azurerm_user_assigned_identity.tre_encryption_identity[0].id] + } + } + lifecycle { ignore_changes = [infrastructure_encryption_enabled, tags] } } +resource "azurerm_storage_account_customer_managed_key" "staticweb_stg_encryption" { + count = var.enable_cmk_encryption ? 1 : 0 + storage_account_id = azurerm_storage_account.staticweb.id + key_vault_id = var.key_store_id + key_name = local.cmk_name + user_assigned_identity_id = data.azurerm_user_assigned_identity.tre_encryption_identity[0].id +} + resource "azurerm_role_assignment" "stgwriter" { scope = azurerm_storage_account.staticweb.id role_definition_name = "Storage Blob Data Contributor" diff --git a/templates/shared_services/certs/terraform/variables.tf b/templates/shared_services/certs/terraform/variables.tf index 4aff0698f5..228654d989 100644 --- a/templates/shared_services/certs/terraform/variables.tf +++ b/templates/shared_services/certs/terraform/variables.tf @@ -14,3 +14,12 @@ variable "tre_resource_id" { type = string description = "Resource ID" } + +variable "enable_cmk_encryption" { + type = bool + default = false +} + +variable "key_store_id" { + type = string +} diff --git a/templates/shared_services/cyclecloud/parameters.json b/templates/shared_services/cyclecloud/parameters.json index fe722bc241..c39909257d 100755 --- a/templates/shared_services/cyclecloud/parameters.json +++ b/templates/shared_services/cyclecloud/parameters.json @@ -45,6 +45,18 @@ "source": { "env": "ARM_ENVIRONMENT" } + }, + { + "name": "enable_cmk_encryption", + "source": { + "env": "ENABLE_CMK_ENCRYPTION" + } + }, + { + "name": "key_store_id", + "source": { + "env": "KEY_STORE_ID" + } } ] } diff --git a/templates/shared_services/cyclecloud/porter.yaml b/templates/shared_services/cyclecloud/porter.yaml index f8a2ae9272..732b59447f 100644 --- a/templates/shared_services/cyclecloud/porter.yaml +++ b/templates/shared_services/cyclecloud/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-shared-service-cyclecloud -version: 0.6.7 +version: 0.7.0 description: "An Azure TRE Shared Service Template for Azure Cyclecloud" registry: azuretre dockerfile: Dockerfile.tmpl @@ -46,6 +46,12 @@ parameters: env: ARM_ENVIRONMENT type: string default: "public" + - name: enable_cmk_encryption + type: boolean + default: false + - name: key_store_id + type: string + default: "" outputs: - name: connection_uri @@ -74,6 +80,8 @@ install: tre_id: ${ bundle.parameters.tre_id } tre_resource_id: ${ bundle.parameters.id } arm_environment: ${ bundle.parameters.arm_environment } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -92,6 +100,8 @@ upgrade: tre_id: ${ bundle.parameters.tre_id } tre_resource_id: ${ bundle.parameters.id } arm_environment: ${ bundle.parameters.arm_environment } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -110,6 +120,8 @@ uninstall: tre_id: ${ bundle.parameters.tre_id } tre_resource_id: ${ bundle.parameters.id } arm_environment: ${ bundle.parameters.arm_environment } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" diff --git a/templates/shared_services/cyclecloud/terraform/data.tf b/templates/shared_services/cyclecloud/terraform/data.tf new file mode 100644 index 0000000000..b3ab49aa77 --- /dev/null +++ b/templates/shared_services/cyclecloud/terraform/data.tf @@ -0,0 +1,5 @@ +data "azurerm_user_assigned_identity" "tre_encryption_identity" { + count = var.enable_cmk_encryption ? 1 : 0 + name = local.encryption_identity_name + resource_group_name = local.core_resource_group_name +} diff --git a/templates/shared_services/cyclecloud/terraform/locals.tf b/templates/shared_services/cyclecloud/terraform/locals.tf index 5c3777bc06..9d75e9f53b 100644 --- a/templates/shared_services/cyclecloud/terraform/locals.tf +++ b/templates/shared_services/cyclecloud/terraform/locals.tf @@ -8,4 +8,6 @@ locals { tre_id = var.tre_id tre_shared_service_id = var.tre_resource_id } + cmk_name = "tre-encryption-${var.tre_id}" + encryption_identity_name = "id-encryption-${var.tre_id}" } diff --git a/templates/shared_services/cyclecloud/terraform/storage.tf b/templates/shared_services/cyclecloud/terraform/storage.tf index 4803993332..ed669ac609 100644 --- a/templates/shared_services/cyclecloud/terraform/storage.tf +++ b/templates/shared_services/cyclecloud/terraform/storage.tf @@ -4,15 +4,33 @@ resource "azurerm_storage_account" "cyclecloud" { resource_group_name = data.azurerm_resource_group.rg.name account_tier = "Standard" account_replication_type = "GRS" + table_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" + queue_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" cross_tenant_replication_enabled = false tags = local.tre_shared_service_tags # changing this value is destructive, hence attribute is in lifecycle.ignore_changes block below infrastructure_encryption_enabled = true + dynamic "identity" { + for_each = var.enable_cmk_encryption ? [1] : [] + content { + type = "UserAssigned" + identity_ids = [data.azurerm_user_assigned_identity.tre_encryption_identity[0].id] + } + } + lifecycle { ignore_changes = [infrastructure_encryption_enabled, tags] } } +resource "azurerm_storage_account_customer_managed_key" "cyclecloud_stg_encryption" { + count = var.enable_cmk_encryption ? 1 : 0 + storage_account_id = azurerm_storage_account.cyclecloud.id + key_vault_id = var.key_store_id + key_name = local.cmk_name + user_assigned_identity_id = data.azurerm_user_assigned_identity.tre_encryption_identity[0].id +} + data "azurerm_private_dns_zone" "blobcore" { name = module.terraform_azurerm_environment_configuration.private_links["privatelink.blob.core.windows.net"] resource_group_name = local.core_resource_group_name diff --git a/templates/shared_services/cyclecloud/terraform/variables.tf b/templates/shared_services/cyclecloud/terraform/variables.tf index 1c064dbb76..48a64a1945 100644 --- a/templates/shared_services/cyclecloud/terraform/variables.tf +++ b/templates/shared_services/cyclecloud/terraform/variables.tf @@ -6,4 +6,11 @@ variable "tre_resource_id" { } variable "arm_environment" { type = string -} \ No newline at end of file +} +variable "enable_cmk_encryption" { + type = bool + default = false +} +variable "key_store_id" { + type = string +} diff --git a/templates/shared_services/sonatype-nexus-vm/parameters.json b/templates/shared_services/sonatype-nexus-vm/parameters.json index 0e7c0c4e58..26712c312d 100755 --- a/templates/shared_services/sonatype-nexus-vm/parameters.json +++ b/templates/shared_services/sonatype-nexus-vm/parameters.json @@ -51,6 +51,18 @@ "source": { "env": "ARM_ENVIRONMENT" } + }, + { + "name": "enable_cmk_encryption", + "source": { + "env": "ENABLE_CMK_ENCRYPTION" + } + }, + { + "name": "key_store_id", + "source": { + "env": "KEY_STORE_ID" + } } ] } diff --git a/templates/shared_services/sonatype-nexus-vm/porter.yaml b/templates/shared_services/sonatype-nexus-vm/porter.yaml index 5f62ec6321..b89fbbf673 100644 --- a/templates/shared_services/sonatype-nexus-vm/porter.yaml +++ b/templates/shared_services/sonatype-nexus-vm/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-shared-service-sonatype-nexus -version: 3.2.2 +version: 3.3.0 description: "A Sonatype Nexus shared service" dockerfile: Dockerfile.tmpl registry: azuretre @@ -47,6 +47,12 @@ parameters: type: string default: "nexus-ssl" description: "Name of the certificate for configuring Nexus SSL with (stored in the core KeyVault)" + - name: enable_cmk_encryption + type: boolean + default: false + - name: key_store_id + type: string + default: "" outputs: - name: workspace_vm_allowed_fqdns_list type: string @@ -85,6 +91,8 @@ install: tre_id: ${ bundle.parameters.tre_id } tre_resource_id: ${ bundle.parameters.id } ssl_cert_name: ${ bundle.parameters.ssl_cert_name } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -106,6 +114,8 @@ upgrade: tre_id: ${ bundle.parameters.tre_id } tre_resource_id: ${ bundle.parameters.id } ssl_cert_name: ${ bundle.parameters.ssl_cert_name } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -127,6 +137,8 @@ uninstall: tre_id: ${ bundle.parameters.tre_id } tre_resource_id: ${ bundle.parameters.id } ssl_cert_name: ${ bundle.parameters.ssl_cert_name } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" diff --git a/templates/shared_services/sonatype-nexus-vm/terraform/data.tf b/templates/shared_services/sonatype-nexus-vm/terraform/data.tf index ad0ed71585..37ccf7d9b6 100644 --- a/templates/shared_services/sonatype-nexus-vm/terraform/data.tf +++ b/templates/shared_services/sonatype-nexus-vm/terraform/data.tf @@ -38,3 +38,14 @@ data "azurerm_private_dns_zone" "nexus" { resource_group_name = local.core_resource_group_name } +data "azurerm_key_vault_key" "tre_encryption_key" { + count = var.enable_cmk_encryption ? 1 : 0 + name = local.cmk_name + key_vault_id = var.key_store_id +} + +data "azurerm_user_assigned_identity" "tre_encryption_identity" { + count = var.enable_cmk_encryption ? 1 : 0 + name = local.encryption_identity_name + resource_group_name = local.core_resource_group_name +} diff --git a/templates/shared_services/sonatype-nexus-vm/terraform/locals.tf b/templates/shared_services/sonatype-nexus-vm/terraform/locals.tf index 85bb6d34f6..be9698931f 100644 --- a/templates/shared_services/sonatype-nexus-vm/terraform/locals.tf +++ b/templates/shared_services/sonatype-nexus-vm/terraform/locals.tf @@ -10,4 +10,6 @@ locals { tre_id = var.tre_id tre_shared_service_id = var.tre_resource_id } + cmk_name = "tre-encryption-${var.tre_id}" + encryption_identity_name = "id-encryption-${var.tre_id}" } diff --git a/templates/shared_services/sonatype-nexus-vm/terraform/variables.tf b/templates/shared_services/sonatype-nexus-vm/terraform/variables.tf index 23c2fa3826..b0ff6e794a 100644 --- a/templates/shared_services/sonatype-nexus-vm/terraform/variables.tf +++ b/templates/shared_services/sonatype-nexus-vm/terraform/variables.tf @@ -10,3 +10,12 @@ variable "tre_resource_id" { variable "ssl_cert_name" { type = string } + +variable "enable_cmk_encryption" { + type = bool + default = false +} + +variable "key_store_id" { + type = string +} diff --git a/templates/shared_services/sonatype-nexus-vm/terraform/vm.tf b/templates/shared_services/sonatype-nexus-vm/terraform/vm.tf index cd27bd2c80..91216ca219 100644 --- a/templates/shared_services/sonatype-nexus-vm/terraform/vm.tf +++ b/templates/shared_services/sonatype-nexus-vm/terraform/vm.tf @@ -116,10 +116,11 @@ resource "azurerm_linux_virtual_machine" "nexus" { } os_disk { - name = "osdisk-nexus-${var.tre_id}" - caching = "ReadWrite" - storage_account_type = "Standard_LRS" - disk_size_gb = 64 + name = "osdisk-nexus-${var.tre_id}" + caching = "ReadWrite" + storage_account_type = "Standard_LRS" + disk_size_gb = 64 + disk_encryption_set_id = var.enable_cmk_encryption ? azurerm_disk_encryption_set.nexus_disk_encryption[0].id : null } identity { @@ -145,6 +146,21 @@ resource "azurerm_linux_virtual_machine" "nexus" { } } +resource "azurerm_disk_encryption_set" "nexus_disk_encryption" { + count = var.enable_cmk_encryption ? 1 : 0 + name = "disk-encryption-nexus-${var.tre_id}-${var.tre_resource_id}" + location = data.azurerm_resource_group.rg.location + resource_group_name = data.azurerm_resource_group.rg.name + key_vault_key_id = data.azurerm_key_vault_key.tre_encryption_key[0].versionless_id + encryption_type = "EncryptionAtRestWithPlatformAndCustomerKeys" + auto_key_rotation_enabled = true + + identity { + type = "UserAssigned" + identity_ids = [data.azurerm_user_assigned_identity.tre_encryption_identity[0].id] + } +} + data "template_cloudinit_config" "nexus_config" { gzip = true base64_encode = true diff --git a/templates/workspace_services/azureml/parameters.json b/templates/workspace_services/azureml/parameters.json index e538071afc..db593f4b28 100755 --- a/templates/workspace_services/azureml/parameters.json +++ b/templates/workspace_services/azureml/parameters.json @@ -69,6 +69,18 @@ "source": { "env": "ARM_ENVIRONMENT" } + }, + { + "name": "enable_cmk_encryption", + "source": { + "env": "ENABLE_CMK_ENCRYPTION" + } + }, + { + "name": "key_store_id", + "source": { + "env": "KEY_STORE_ID" + } } ] } diff --git a/templates/workspace_services/azureml/porter.yaml b/templates/workspace_services/azureml/porter.yaml index ca607547b3..75f659cc55 100644 --- a/templates/workspace_services/azureml/porter.yaml +++ b/templates/workspace_services/azureml/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-azureml -version: 0.8.16 +version: 0.9.0 description: "An Azure TRE service for Azure Machine Learning" registry: azuretre dockerfile: Dockerfile.tmpl @@ -63,6 +63,12 @@ parameters: env: ARM_ENVIRONMENT - name: azure_environment env: AZURE_ENVIRONMENT + - name: enable_cmk_encryption + type: boolean + default: false + - name: key_store_id + type: string + default: "" outputs: - name: azureml_workspace_name @@ -139,6 +145,8 @@ install: auth_tenant_id: ${ bundle.credentials.auth_tenant_id } arm_environment: ${ bundle.parameters.arm_environment } azure_environment: ${ bundle.parameters.azure_environment } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -175,6 +183,8 @@ upgrade: auth_tenant_id: ${ bundle.credentials.auth_tenant_id } arm_environment: ${ bundle.parameters.arm_environment } azure_environment: ${ bundle.parameters.azure_environment } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -211,6 +221,8 @@ uninstall: auth_tenant_id: ${ bundle.credentials.auth_tenant_id } arm_environment: ${ bundle.parameters.arm_environment } azure_environment: ${ bundle.parameters.azure_environment } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" diff --git a/templates/workspace_services/azureml/terraform/.terraform.lock.hcl b/templates/workspace_services/azureml/terraform/.terraform.lock.hcl index 973c2cf117..d052c17d11 100644 --- a/templates/workspace_services/azureml/terraform/.terraform.lock.hcl +++ b/templates/workspace_services/azureml/terraform/.terraform.lock.hcl @@ -5,6 +5,7 @@ provider "registry.terraform.io/azure/azapi" { version = "1.15.0" constraints = "1.15.0" hashes = [ + "h1:Y7ruMuPh8UJRTRl4rm+cdpGtmURx2taqiuqfYaH3o48=", "h1:gIOgxVmFSxHrR+XOzgUEA+ybOmp8kxZlZH3eYeB/eFI=", "zh:0627a8bc77254debc25dc0c7b62e055138217c97b03221e593c3c56dc7550671", "zh:2fe045f07070ef75d0bec4b0595a74c14394daa838ddb964e2fd23cc98c40c34", diff --git a/templates/workspace_services/azureml/terraform/acr.tf b/templates/workspace_services/azureml/terraform/acr.tf index a0de2fca71..7fc9295e9a 100644 --- a/templates/workspace_services/azureml/terraform/acr.tf +++ b/templates/workspace_services/azureml/terraform/acr.tf @@ -9,6 +9,24 @@ resource "azurerm_container_registry" "acr" { public_network_access_enabled = false tags = local.tre_workspace_service_tags + dynamic "identity" { + for_each = var.enable_cmk_encryption ? [1] : [] + content { + type = "UserAssigned" + identity_ids = [data.azurerm_user_assigned_identity.ws_encryption_identity[0].id] + } + } + + dynamic "encryption" { + for_each = var.enable_cmk_encryption ? [1] : [] + content { + enabled = true + key_vault_key_id = data.azurerm_key_vault_key.ws_encryption_key[0].id + identity_client_id = data.azurerm_user_assigned_identity.ws_encryption_identity[0].client_id + } + + } + lifecycle { ignore_changes = [tags] } } diff --git a/templates/workspace_services/azureml/terraform/data.tf b/templates/workspace_services/azureml/terraform/data.tf index 0612a9d634..d9db7e09b9 100644 --- a/templates/workspace_services/azureml/terraform/data.tf +++ b/templates/workspace_services/azureml/terraform/data.tf @@ -47,3 +47,15 @@ data "azurerm_private_dns_zone" "notebooks" { name = module.terraform_azurerm_environment_configuration.private_links["privatelink.notebooks.azure.net"] resource_group_name = local.core_resource_group_name } + +data "azurerm_key_vault_key" "ws_encryption_key" { + count = var.enable_cmk_encryption ? 1 : 0 + name = local.cmk_name + key_vault_id = var.key_store_id +} + +data "azurerm_user_assigned_identity" "ws_encryption_identity" { + count = var.enable_cmk_encryption ? 1 : 0 + name = local.encryption_identity_name + resource_group_name = data.azurerm_resource_group.ws.name +} diff --git a/templates/workspace_services/azureml/terraform/locals.tf b/templates/workspace_services/azureml/terraform/locals.tf index ac11d6c921..2ed4ce0787 100644 --- a/templates/workspace_services/azureml/terraform/locals.tf +++ b/templates/workspace_services/azureml/terraform/locals.tf @@ -14,4 +14,6 @@ locals { tre_workspace_id = var.workspace_id tre_workspace_service_id = var.tre_resource_id } + cmk_name = "tre-encryption-${local.workspace_resource_name_suffix}" + encryption_identity_name = "id-encryption-${var.tre_id}-${local.short_workspace_id}" } diff --git a/templates/workspace_services/azureml/terraform/storage.tf b/templates/workspace_services/azureml/terraform/storage.tf index 2a5966beb8..94925a85eb 100644 --- a/templates/workspace_services/azureml/terraform/storage.tf +++ b/templates/workspace_services/azureml/terraform/storage.tf @@ -4,18 +4,36 @@ resource "azurerm_storage_account" "aml" { resource_group_name = data.azurerm_resource_group.ws.name account_tier = "Standard" account_replication_type = "GRS" + table_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" + queue_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" cross_tenant_replication_enabled = false tags = local.tre_workspace_service_tags network_rules { default_action = "Deny" } + dynamic "identity" { + for_each = var.enable_cmk_encryption ? [1] : [] + content { + type = "UserAssigned" + identity_ids = [data.azurerm_user_assigned_identity.ws_encryption_identity[0].id] + } + } + # changing this value is destructive, hence attribute is in lifecycle.ignore_changes block below infrastructure_encryption_enabled = true lifecycle { ignore_changes = [infrastructure_encryption_enabled, tags] } } +resource "azurerm_storage_account_customer_managed_key" "aml_stg_encryption" { + count = var.enable_cmk_encryption ? 1 : 0 + storage_account_id = azurerm_storage_account.aml.id + key_vault_id = var.key_store_id + key_name = local.cmk_name + user_assigned_identity_id = data.azurerm_user_assigned_identity.ws_encryption_identity[0].id +} + data "azurerm_private_dns_zone" "blobcore" { name = module.terraform_azurerm_environment_configuration.private_links["privatelink.blob.core.windows.net"] resource_group_name = local.core_resource_group_name @@ -49,7 +67,6 @@ resource "azurerm_private_endpoint" "blobpe" { } - resource "azurerm_private_endpoint" "filepe" { name = "pe-file-${local.storage_name}" location = data.azurerm_resource_group.ws.location diff --git a/templates/workspace_services/azureml/terraform/variables.tf b/templates/workspace_services/azureml/terraform/variables.tf index a47b5588ff..ef994567b2 100644 --- a/templates/workspace_services/azureml/terraform/variables.tf +++ b/templates/workspace_services/azureml/terraform/variables.tf @@ -35,11 +35,16 @@ variable "auth_client_secret" { sensitive = true description = "Used to authenticate into the AAD Tenant to get app role members" } - variable "arm_environment" { type = string } - variable "azure_environment" { type = string } +variable "enable_cmk_encryption" { + type = bool + default = false +} +variable "key_store_id" { + type = string +} diff --git a/templates/workspace_services/gitea/parameters.json b/templates/workspace_services/gitea/parameters.json index 811e0a5f3b..b35183879d 100755 --- a/templates/workspace_services/gitea/parameters.json +++ b/templates/workspace_services/gitea/parameters.json @@ -69,6 +69,18 @@ "source": { "env": "SQL_SKU" } + }, + { + "name": "enable_cmk_encryption", + "source": { + "env": "ENABLE_CMK_ENCRYPTION" + } + }, + { + "name": "key_store_id", + "source": { + "env": "KEY_STORE_ID" + } } ] } diff --git a/templates/workspace_services/gitea/porter.yaml b/templates/workspace_services/gitea/porter.yaml index 6f756cb438..b8aff0fa35 100644 --- a/templates/workspace_services/gitea/porter.yaml +++ b/templates/workspace_services/gitea/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-workspace-service-gitea -version: 1.1.1 +version: 1.2.0 description: "A Gitea workspace service" dockerfile: Dockerfile.tmpl registry: azuretre @@ -66,6 +66,12 @@ parameters: - name: aad_authority_url type: string default: "https://login.microsoftonline.com" + - name: enable_cmk_encryption + type: boolean + default: false + - name: key_store_id + type: string + default: "" mixins: - exec @@ -106,6 +112,8 @@ install: aad_authority_url: ${ bundle.parameters.aad_authority_url } arm_environment: ${ bundle.parameters.arm_environment } sql_sku: ${ bundle.parameters.sql_sku } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -131,6 +139,8 @@ upgrade: aad_authority_url: ${ bundle.parameters.aad_authority_url } arm_environment: ${ bundle.parameters.arm_environment } sql_sku: ${ bundle.parameters.sql_sku } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -156,6 +166,8 @@ uninstall: aad_authority_url: ${ bundle.parameters.aad_authority_url } arm_environment: ${ bundle.parameters.arm_environment } sql_sku: ${ bundle.parameters.sql_sku } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" diff --git a/templates/workspace_services/gitea/terraform/data.tf b/templates/workspace_services/gitea/terraform/data.tf index 883091089d..4447529bb0 100644 --- a/templates/workspace_services/gitea/terraform/data.tf +++ b/templates/workspace_services/gitea/terraform/data.tf @@ -74,3 +74,9 @@ data "azurerm_monitor_diagnostic_categories" "gitea" { azurerm_linux_web_app.gitea, ] } + +data "azurerm_user_assigned_identity" "ws_encryption_identity" { + count = var.enable_cmk_encryption ? 1 : 0 + name = local.encryption_identity_name + resource_group_name = data.azurerm_resource_group.ws.name +} diff --git a/templates/workspace_services/gitea/terraform/locals.tf b/templates/workspace_services/gitea/terraform/locals.tf index 665181c21e..69f7c9f0df 100644 --- a/templates/workspace_services/gitea/terraform/locals.tf +++ b/templates/workspace_services/gitea/terraform/locals.tf @@ -22,5 +22,7 @@ locals { "AppServiceHTTPLogs", "AppServiceConsoleLogs", "AppServiceAppLogs", "AppServiceAuditLogs", "AppServiceIPSecAuditLogs", "AppServicePlatformLogs", "AppServiceAntivirusScanAuditLogs" ] - gitea_openid_auth = "${var.aad_authority_url}/${data.azurerm_key_vault_secret.aad_tenant_id.value}/v2.0" + gitea_openid_auth = "${var.aad_authority_url}/${data.azurerm_key_vault_secret.aad_tenant_id.value}/v2.0" + cmk_name = "tre-encryption-${local.workspace_resource_name_suffix}" + encryption_identity_name = "id-encryption-${var.tre_id}-${local.short_workspace_id}" } diff --git a/templates/workspace_services/gitea/terraform/storage.tf b/templates/workspace_services/gitea/terraform/storage.tf index 649ee11092..c042a18ff7 100644 --- a/templates/workspace_services/gitea/terraform/storage.tf +++ b/templates/workspace_services/gitea/terraform/storage.tf @@ -4,15 +4,33 @@ resource "azurerm_storage_account" "gitea" { location = data.azurerm_resource_group.ws.location account_tier = "Standard" account_replication_type = "GRS" + table_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" + queue_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" cross_tenant_replication_enabled = false tags = local.workspace_service_tags # changing this value is destructive, hence attribute is in lifecycle.ignore_changes block below infrastructure_encryption_enabled = true + dynamic "identity" { + for_each = var.enable_cmk_encryption ? [1] : [] + content { + type = "UserAssigned" + identity_ids = [data.azurerm_user_assigned_identity.ws_encryption_identity[0].id] + } + } + lifecycle { ignore_changes = [infrastructure_encryption_enabled, tags] } } +resource "azurerm_storage_account_customer_managed_key" "gitea_stg_encryption" { + count = var.enable_cmk_encryption ? 1 : 0 + storage_account_id = azurerm_storage_account.gitea.id + key_vault_id = var.key_store_id + key_name = local.cmk_name + user_assigned_identity_id = data.azurerm_user_assigned_identity.ws_encryption_identity[0].id +} + resource "azurerm_storage_account_network_rules" "stgrules" { storage_account_id = azurerm_storage_account.gitea.id diff --git a/templates/workspace_services/gitea/terraform/variables.tf b/templates/workspace_services/gitea/terraform/variables.tf index 181a27045e..267c41fcc6 100644 --- a/templates/workspace_services/gitea/terraform/variables.tf +++ b/templates/workspace_services/gitea/terraform/variables.tf @@ -27,3 +27,10 @@ variable "arm_environment" { variable "sql_sku" { type = string } +variable "enable_cmk_encryption" { + type = bool + default = false +} +variable "key_store_id" { + type = string +} diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/parameters.json b/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/parameters.json index 9c6ec9b9f3..e6b0e091fe 100755 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/parameters.json +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/parameters.json @@ -75,6 +75,18 @@ "source": { "env": "ARM_ENVIRONMENT" } + }, + { + "name": "enable_cmk_encryption", + "source": { + "env": "ENABLE_CMK_ENCRYPTION" + } + }, + { + "name": "key_store_id", + "source": { + "env": "KEY_STORE_ID" + } } ] } diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/porter.yaml index 03e283dd57..0151929595 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole-export-reviewvm -version: 0.1.13 +version: 0.2.0 description: "An Azure TRE User Resource Template for reviewing Airlock export requests" dockerfile: Dockerfile.tmpl registry: azuretre @@ -75,6 +75,12 @@ parameters: type: string description: "A SAS token to access storage resource in workspace under review" env: airlock_request_sas_url + - name: enable_cmk_encryption + type: boolean + default: false + - name: key_store_id + type: string + default: "" outputs: - name: ip @@ -118,6 +124,8 @@ install: image: ${ bundle.parameters.os_image } vm_size: ${ bundle.parameters.vm_size } airlock_request_sas_url: ${ bundle.parameters.airlock_request_sas_url } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -142,6 +150,8 @@ upgrade: image: ${ bundle.parameters.os_image } vm_size: ${ bundle.parameters.vm_size } airlock_request_sas_url: "unused" + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -178,6 +188,8 @@ uninstall: image: ${ bundle.parameters.os_image } vm_size: ${ bundle.parameters.vm_size } airlock_request_sas_url: "unused" + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/terraform/data.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/terraform/data.tf index 2c6512997b..5379f1a599 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/terraform/data.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/terraform/data.tf @@ -33,3 +33,15 @@ data "azurerm_private_endpoint_connection" "airlock_export_inprogress_pe" { name = "pe-sa-export-ip-blob-${local.short_workspace_id}" resource_group_name = data.azurerm_resource_group.ws.name } + +data "azurerm_key_vault_key" "ws_encryption_key" { + count = var.enable_cmk_encryption ? 1 : 0 + name = local.cmk_name + key_vault_id = var.key_store_id +} + +data "azurerm_user_assigned_identity" "ws_encryption_identity" { + count = var.enable_cmk_encryption ? 1 : 0 + name = local.encryption_identity_name + resource_group_name = data.azurerm_resource_group.ws.name +} diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/terraform/locals.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/terraform/locals.tf index 508f1083c2..1f3ac946bd 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/terraform/locals.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/terraform/locals.tf @@ -24,4 +24,7 @@ locals { # selected_image_source_refs is an array to enable easy use of a dynamic block selected_image_source_refs = lookup(local.selected_image, "source_image_reference", null) == null ? [] : [local.selected_image.source_image_reference] selected_image_source_id = lookup(local.selected_image, "source_image_name", null) == null ? null : "${var.image_gallery_id}/images/${local.selected_image.source_image_name}" + + cmk_name = "tre-encryption-${local.workspace_resource_name_suffix}" + encryption_identity_name = "id-encryption-${var.tre_id}-${local.short_workspace_id}" } diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/terraform/variables.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/terraform/variables.tf index 36cdb77b3c..b557c708cb 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/terraform/variables.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/terraform/variables.tf @@ -23,3 +23,10 @@ variable "image_gallery_id" { variable "airlock_request_sas_url" { type = string } +variable "enable_cmk_encryption" { + type = bool + default = false +} +variable "key_store_id" { + type = string +} diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/terraform/windowsvm.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/terraform/windowsvm.tf index 9efc1661f2..318ff29761 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/terraform/windowsvm.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-export-reviewvm/terraform/windowsvm.tf @@ -140,9 +140,10 @@ resource "azurerm_windows_virtual_machine" "windowsvm" { } os_disk { - name = "osdisk-${local.vm_name}" - caching = "ReadWrite" - storage_account_type = "Standard_LRS" + name = "osdisk-${local.vm_name}" + caching = "ReadWrite" + storage_account_type = "Standard_LRS" + disk_encryption_set_id = var.enable_cmk_encryption ? azurerm_disk_encryption_set.windowsvm_disk_encryption[0].id : null } identity { @@ -154,6 +155,21 @@ resource "azurerm_windows_virtual_machine" "windowsvm" { lifecycle { ignore_changes = [tags] } } +resource "azurerm_disk_encryption_set" "windowsvm_disk_encryption" { + count = var.enable_cmk_encryption ? 1 : 0 + name = "disk-encryption-windowsvm-${var.tre_id}-${var.tre_resource_id}" + location = data.azurerm_resource_group.ws.location + resource_group_name = data.azurerm_resource_group.ws.name + key_vault_key_id = data.azurerm_key_vault_key.ws_encryption_key[0].versionless_id + encryption_type = "EncryptionAtRestWithPlatformAndCustomerKeys" + auto_key_rotation_enabled = true + + identity { + type = "UserAssigned" + identity_ids = [data.azurerm_user_assigned_identity.ws_encryption_identity[0].id] + } +} + resource "azurerm_virtual_machine_extension" "config_script" { name = "${azurerm_windows_virtual_machine.windowsvm.name}-vmextension" virtual_machine_id = azurerm_windows_virtual_machine.windowsvm.id diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/parameters.json b/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/parameters.json index 5e12488c7e..07be376ae5 100755 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/parameters.json +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/parameters.json @@ -81,6 +81,18 @@ "source": { "env": "ARM_ENVIRONMENT" } + }, + { + "name": "enable_cmk_encryption", + "source": { + "env": "ENABLE_CMK_ENCRYPTION" + } + }, + { + "name": "key_store_id", + "source": { + "env": "KEY_STORE_ID" + } } ] } diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/porter.yaml index a70cea2d47..a5f1bb2812 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole-import-reviewvm -version: 0.2.13 +version: 0.3.0 description: "An Azure TRE User Resource Template for reviewing Airlock import requests" dockerfile: Dockerfile.tmpl registry: azuretre @@ -84,6 +84,12 @@ parameters: type: string description: "A SAS token to access storage resource in workspace under review" env: airlock_request_sas_url + - name: enable_cmk_encryption + type: boolean + default: false + - name: key_store_id + type: string + default: "" outputs: - name: ip @@ -128,6 +134,8 @@ install: vm_size: ${ bundle.parameters.vm_size } image_gallery_id: ${ bundle.parameters.image_gallery_id } airlock_request_sas_url: ${ bundle.parameters.airlock_request_sas_url } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -153,6 +161,8 @@ upgrade: vm_size: ${ bundle.parameters.vm_size } image_gallery_id: ${ bundle.parameters.image_gallery_id } airlock_request_sas_url: "unused" + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -190,6 +200,8 @@ uninstall: vm_size: ${ bundle.parameters.vm_size } image_gallery_id: ${ bundle.parameters.image_gallery_id } airlock_request_sas_url: "unused" + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/terraform/data.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/terraform/data.tf index 04675964b9..d3ce0f2eb3 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/terraform/data.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/terraform/data.tf @@ -22,3 +22,15 @@ data "azurerm_linux_web_app" "guacamole" { name = "guacamole-${var.tre_id}-ws-${local.short_workspace_id}-svc-${local.short_parent_id}" resource_group_name = data.azurerm_resource_group.ws.name } + +data "azurerm_key_vault_key" "ws_encryption_key" { + count = var.enable_cmk_encryption ? 1 : 0 + name = local.cmk_name + key_vault_id = var.key_store_id +} + +data "azurerm_user_assigned_identity" "ws_encryption_identity" { + count = var.enable_cmk_encryption ? 1 : 0 + name = local.encryption_identity_name + resource_group_name = data.azurerm_resource_group.ws.name +} diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/terraform/locals.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/terraform/locals.tf index 508f1083c2..1f3ac946bd 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/terraform/locals.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/terraform/locals.tf @@ -24,4 +24,7 @@ locals { # selected_image_source_refs is an array to enable easy use of a dynamic block selected_image_source_refs = lookup(local.selected_image, "source_image_reference", null) == null ? [] : [local.selected_image.source_image_reference] selected_image_source_id = lookup(local.selected_image, "source_image_name", null) == null ? null : "${var.image_gallery_id}/images/${local.selected_image.source_image_name}" + + cmk_name = "tre-encryption-${local.workspace_resource_name_suffix}" + encryption_identity_name = "id-encryption-${var.tre_id}-${local.short_workspace_id}" } diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/terraform/variables.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/terraform/variables.tf index c6847da884..b557c708cb 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/terraform/variables.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/terraform/variables.tf @@ -22,4 +22,11 @@ variable "image_gallery_id" { } variable "airlock_request_sas_url" { type = string -} \ No newline at end of file +} +variable "enable_cmk_encryption" { + type = bool + default = false +} +variable "key_store_id" { + type = string +} diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/terraform/windowsvm.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/terraform/windowsvm.tf index 75891d5018..a4d250b7f4 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/terraform/windowsvm.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/terraform/windowsvm.tf @@ -61,9 +61,10 @@ resource "azurerm_windows_virtual_machine" "windowsvm" { } os_disk { - name = "osdisk-${local.vm_name}" - caching = "ReadWrite" - storage_account_type = "Standard_LRS" + name = "osdisk-${local.vm_name}" + caching = "ReadWrite" + storage_account_type = "Standard_LRS" + disk_encryption_set_id = var.enable_cmk_encryption ? azurerm_disk_encryption_set.windowsvm_disk_encryption[0].id : null } identity { @@ -75,6 +76,21 @@ resource "azurerm_windows_virtual_machine" "windowsvm" { lifecycle { ignore_changes = [tags] } } +resource "azurerm_disk_encryption_set" "windowsvm_disk_encryption" { + count = var.enable_cmk_encryption ? 1 : 0 + name = "disk-encryption-windowsvm-${var.tre_id}-${var.tre_resource_id}" + location = data.azurerm_resource_group.ws.location + resource_group_name = data.azurerm_resource_group.ws.name + key_vault_key_id = data.azurerm_key_vault_key.ws_encryption_key[0].versionless_id + encryption_type = "EncryptionAtRestWithPlatformAndCustomerKeys" + auto_key_rotation_enabled = true + + identity { + type = "UserAssigned" + identity_ids = [data.azurerm_user_assigned_identity.ws_encryption_identity[0].id] + } +} + resource "azurerm_virtual_machine_extension" "config_script" { name = "${azurerm_windows_virtual_machine.windowsvm.name}-vmextension" virtual_machine_id = azurerm_windows_virtual_machine.windowsvm.id diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/parameters.json b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/parameters.json index 0c4dc1a484..6ff93df11d 100755 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/parameters.json +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/parameters.json @@ -87,6 +87,18 @@ "source": { "env": "ARM_ENVIRONMENT" } + }, + { + "name": "enable_cmk_encryption", + "source": { + "env": "ENABLE_CMK_ENCRYPTION" + } + }, + { + "name": "key_store_id", + "source": { + "env": "KEY_STORE_ID" + } } ] } diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/porter.yaml index 98b827932f..412d509713 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole-linuxvm -version: 1.1.0 +version: 1.2.0 description: "An Azure TRE User Resource Template for Guacamole (Linux)" dockerfile: Dockerfile.tmpl registry: azuretre @@ -106,6 +106,12 @@ parameters: - name: shared_storage_name type: string default: "vm-shared-storage" + - name: enable_cmk_encryption + type: boolean + default: false + - name: key_store_id + type: string + default: "" outputs: - name: ip @@ -154,6 +160,8 @@ install: enable_shutdown_schedule: ${ bundle.parameters.enable_shutdown_schedule } shutdown_time: ${ bundle.parameters.shutdown_time } shutdown_timezone: ${ bundle.parameters.shutdown_timezone } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -183,6 +191,8 @@ upgrade: enable_shutdown_schedule: ${ bundle.parameters.enable_shutdown_schedule } shutdown_time: ${ bundle.parameters.shutdown_time } shutdown_timezone: ${ bundle.parameters.shutdown_timezone } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -224,6 +234,8 @@ uninstall: enable_shutdown_schedule: ${ bundle.parameters.enable_shutdown_schedule } shutdown_time: ${ bundle.parameters.shutdown_time } shutdown_timezone: ${ bundle.parameters.shutdown_timezone } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/data.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/data.tf new file mode 100644 index 0000000000..c4edbbf029 --- /dev/null +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/data.tf @@ -0,0 +1,45 @@ +data "azurerm_resource_group" "ws" { + name = "rg-${var.tre_id}-ws-${local.short_workspace_id}" +} + +data "azurerm_resource_group" "core" { + name = "rg-${var.tre_id}" +} + +data "azurerm_virtual_network" "ws" { + name = "vnet-${var.tre_id}-ws-${local.short_workspace_id}" + resource_group_name = data.azurerm_resource_group.ws.name +} + +data "azurerm_subnet" "services" { + name = "ServicesSubnet" + virtual_network_name = data.azurerm_virtual_network.ws.name + resource_group_name = data.azurerm_resource_group.ws.name +} + +data "azurerm_key_vault" "ws" { + name = local.keyvault_name + resource_group_name = data.azurerm_resource_group.ws.name +} + +data "azurerm_linux_web_app" "guacamole" { + name = "guacamole-${var.tre_id}-ws-${local.short_workspace_id}-svc-${local.short_parent_id}" + resource_group_name = data.azurerm_resource_group.ws.name +} + +data "azurerm_public_ip" "app_gateway_ip" { + name = "pip-agw-${var.tre_id}" + resource_group_name = data.azurerm_resource_group.core.name +} + +data "azurerm_key_vault_key" "ws_encryption_key" { + count = var.enable_cmk_encryption ? 1 : 0 + name = local.cmk_name + key_vault_id = var.key_store_id +} + +data "azurerm_user_assigned_identity" "ws_encryption_identity" { + count = var.enable_cmk_encryption ? 1 : 0 + name = local.encryption_identity_name + resource_group_name = data.azurerm_resource_group.ws.name +} diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/linuxvm.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/linuxvm.tf index 68b9d36773..83dd0c0072 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/linuxvm.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/linuxvm.tf @@ -60,9 +60,10 @@ resource "azurerm_linux_virtual_machine" "linuxvm" { } os_disk { - name = "osdisk-${local.vm_name}" - caching = "ReadWrite" - storage_account_type = "Standard_LRS" + name = "osdisk-${local.vm_name}" + caching = "ReadWrite" + storage_account_type = "Standard_LRS" + disk_encryption_set_id = var.enable_cmk_encryption ? azurerm_disk_encryption_set.linuxvm_disk_encryption[0].id : null } identity { @@ -74,6 +75,21 @@ resource "azurerm_linux_virtual_machine" "linuxvm" { lifecycle { ignore_changes = [tags] } } +resource "azurerm_disk_encryption_set" "linuxvm_disk_encryption" { + count = var.enable_cmk_encryption ? 1 : 0 + name = "disk-encryption-linuxvm-${var.tre_id}-${var.tre_resource_id}" + location = data.azurerm_resource_group.ws.location + resource_group_name = data.azurerm_resource_group.ws.name + key_vault_key_id = data.azurerm_key_vault_key.ws_encryption_key[0].versionless_id + encryption_type = "EncryptionAtRestWithPlatformAndCustomerKeys" + auto_key_rotation_enabled = true + + identity { + type = "UserAssigned" + identity_ids = [data.azurerm_user_assigned_identity.ws_encryption_identity[0].id] + } +} + data "template_cloudinit_config" "config" { gzip = true base64_encode = true diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/locals.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/locals.tf index e0281269fd..a7f326efcf 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/locals.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/locals.tf @@ -26,4 +26,7 @@ locals { selected_image_source_refs = lookup(local.selected_image, "source_image_reference", null) == null ? [] : [local.selected_image.source_image_reference] selected_image_source_id = lookup(local.selected_image, "source_image_name", null) == null ? null : "${var.image_gallery_id}/images/${local.selected_image.source_image_name}" apt_sku = local.selected_image_source_refs[0]["apt_sku"] + + cmk_name = "tre-encryption-${local.workspace_resource_name_suffix}" + encryption_identity_name = "id-encryption-${var.tre_id}-${local.short_workspace_id}" } diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/main.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/main.tf index 5231913385..856d97f0ec 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/main.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/main.tf @@ -40,36 +40,3 @@ provider "azurerm" { storage_use_azuread = true } -data "azurerm_resource_group" "ws" { - name = "rg-${var.tre_id}-ws-${local.short_workspace_id}" -} - -data "azurerm_resource_group" "core" { - name = "rg-${var.tre_id}" -} - -data "azurerm_virtual_network" "ws" { - name = "vnet-${var.tre_id}-ws-${local.short_workspace_id}" - resource_group_name = data.azurerm_resource_group.ws.name -} - -data "azurerm_subnet" "services" { - name = "ServicesSubnet" - virtual_network_name = data.azurerm_virtual_network.ws.name - resource_group_name = data.azurerm_resource_group.ws.name -} - -data "azurerm_key_vault" "ws" { - name = local.keyvault_name - resource_group_name = data.azurerm_resource_group.ws.name -} - -data "azurerm_linux_web_app" "guacamole" { - name = "guacamole-${var.tre_id}-ws-${local.short_workspace_id}-svc-${local.short_parent_id}" - resource_group_name = data.azurerm_resource_group.ws.name -} - -data "azurerm_public_ip" "app_gateway_ip" { - name = "pip-agw-${var.tre_id}" - resource_group_name = data.azurerm_resource_group.core.name -} diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/variables.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/variables.tf index a515e46e30..91bff4de77 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/variables.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/variables.tf @@ -37,3 +37,10 @@ variable "shutdown_timezone" { type = string default = "UTC" } +variable "enable_cmk_encryption" { + type = bool + default = false +} +variable "key_store_id" { + type = string +} diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/parameters.json b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/parameters.json index 23e54b669b..d9becce90e 100755 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/parameters.json +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/parameters.json @@ -87,6 +87,18 @@ "source": { "env": "ARM_ENVIRONMENT" } + }, + { + "name": "enable_cmk_encryption", + "source": { + "env": "ENABLE_CMK_ENCRYPTION" + } + }, + { + "name": "key_store_id", + "source": { + "env": "KEY_STORE_ID" + } } ] } diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/porter.yaml index f490a5c089..49462c45fe 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole-windowsvm -version: 1.0.8 +version: 1.2.0 description: "An Azure TRE User Resource Template for Guacamole (Windows 10)" dockerfile: Dockerfile.tmpl registry: azuretre @@ -100,6 +100,12 @@ parameters: default: "vm-shared-storage" - name: arm_environment type: string + - name: enable_cmk_encryption + type: boolean + default: false + - name: key_store_id + type: string + default: "" outputs: - name: ip @@ -145,6 +151,8 @@ install: shared_storage_access: ${ bundle.parameters.shared_storage_access } shared_storage_name: ${ bundle.parameters.shared_storage_name } image_gallery_id: ${ bundle.parameters.image_gallery_id } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -171,6 +179,8 @@ upgrade: shared_storage_access: ${ bundle.parameters.shared_storage_access } shared_storage_name: ${ bundle.parameters.shared_storage_name } image_gallery_id: ${ bundle.parameters.image_gallery_id } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -209,6 +219,8 @@ uninstall: shared_storage_access: ${ bundle.parameters.shared_storage_access } shared_storage_name: ${ bundle.parameters.shared_storage_name } image_gallery_id: ${ bundle.parameters.image_gallery_id } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/data.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/data.tf index b8f4239143..4f670db1fb 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/data.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/data.tf @@ -42,3 +42,15 @@ data "azurerm_storage_share" "shared_storage" { name = var.shared_storage_name storage_account_name = data.azurerm_storage_account.stg.name } + +data "azurerm_key_vault_key" "ws_encryption_key" { + count = var.enable_cmk_encryption ? 1 : 0 + name = local.cmk_name + key_vault_id = var.key_store_id +} + +data "azurerm_user_assigned_identity" "ws_encryption_identity" { + count = var.enable_cmk_encryption ? 1 : 0 + name = local.encryption_identity_name + resource_group_name = data.azurerm_resource_group.ws.name +} diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/locals.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/locals.tf index e5137d1967..239e304772 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/locals.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/locals.tf @@ -26,4 +26,7 @@ locals { # selected_image_source_refs is an array to enable easy use of a dynamic block selected_image_source_refs = lookup(local.selected_image, "source_image_reference", null) == null ? [] : [local.selected_image.source_image_reference] selected_image_source_id = lookup(local.selected_image, "source_image_name", null) == null ? null : "${var.image_gallery_id}/images/${local.selected_image.source_image_name}" + + cmk_name = "tre-encryption-${local.workspace_resource_name_suffix}" + encryption_identity_name = "id-encryption-${var.tre_id}-${local.short_workspace_id}" } diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/variables.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/variables.tf index 4908ae52a2..2e3f95b33d 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/variables.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/variables.tf @@ -26,3 +26,10 @@ variable "image_gallery_id" { type = string default = "" } +variable "enable_cmk_encryption" { + type = bool + default = false +} +variable "key_store_id" { + type = string +} diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/windowsvm.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/windowsvm.tf index 575f8a7efd..40e6601f4b 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/windowsvm.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/windowsvm.tf @@ -71,9 +71,10 @@ resource "azurerm_windows_virtual_machine" "windowsvm" { } os_disk { - name = "osdisk-${local.vm_name}" - caching = "ReadWrite" - storage_account_type = "Standard_LRS" + name = "osdisk-${local.vm_name}" + caching = "ReadWrite" + storage_account_type = "Standard_LRS" + disk_encryption_set_id = var.enable_cmk_encryption ? azurerm_disk_encryption_set.windowsvm_disk_encryption[0].id : null } identity { @@ -85,6 +86,22 @@ resource "azurerm_windows_virtual_machine" "windowsvm" { lifecycle { ignore_changes = [tags] } } +resource "azurerm_disk_encryption_set" "windowsvm_disk_encryption" { + count = var.enable_cmk_encryption ? 1 : 0 + name = "disk-encryption-windowsvm-${var.tre_id}-${var.tre_resource_id}" + location = data.azurerm_resource_group.ws.location + resource_group_name = data.azurerm_resource_group.ws.name + key_vault_key_id = data.azurerm_key_vault_key.ws_encryption_key[0].versionless_id + encryption_type = "EncryptionAtRestWithPlatformAndCustomerKeys" + auto_key_rotation_enabled = true + + identity { + type = "UserAssigned" + identity_ids = [data.azurerm_user_assigned_identity.ws_encryption_identity[0].id] + } +} + + resource "azurerm_virtual_machine_extension" "config_script" { name = "${azurerm_windows_virtual_machine.windowsvm.name}-vmextension" virtual_machine_id = azurerm_windows_virtual_machine.windowsvm.id diff --git a/templates/workspaces/airlock-import-review/parameters.json b/templates/workspaces/airlock-import-review/parameters.json index 3af43908f2..56dd8ec0de 100755 --- a/templates/workspaces/airlock-import-review/parameters.json +++ b/templates/workspaces/airlock-import-review/parameters.json @@ -135,6 +135,18 @@ "source": { "env": "AZURE_ENVIRONMENT" } + }, + { + "name": "enable_cmk_encryption", + "source": { + "env": "ENABLE_CMK_ENCRYPTION" + } + }, + { + "name": "key_store_id", + "source": { + "env": "KEY_STORE_ID" + } } ] } diff --git a/templates/workspaces/airlock-import-review/porter.yaml b/templates/workspaces/airlock-import-review/porter.yaml index 3cd8e7c3d2..55c90896f6 100644 --- a/templates/workspaces/airlock-import-review/porter.yaml +++ b/templates/workspaces/airlock-import-review/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-workspace-airlock-import-review -version: 0.13.5 +version: 0.14.0 description: "A workspace to do Airlock Data Import Reviews for Azure TRE" dockerfile: Dockerfile.tmpl registry: azuretre @@ -112,6 +112,12 @@ parameters: type: string description: "The SKU used when deploying an Azure App Service Plan" default: "P1v3" + - name: enable_cmk_encryption + type: boolean + default: false + - name: key_store_id + type: string + default: "" outputs: - name: app_role_id_workspace_owner @@ -178,6 +184,8 @@ install: app_service_plan_sku: ${ bundle.parameters.app_service_plan_sku } enable_airlock: false arm_environment: ${ bundle.parameters.arm_environment } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -219,6 +227,8 @@ upgrade: app_service_plan_sku: ${ bundle.parameters.app_service_plan_sku } enable_airlock: false arm_environment: ${ bundle.parameters.arm_environment } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -283,6 +293,8 @@ uninstall: app_service_plan_sku: ${ bundle.parameters.app_service_plan_sku } enable_airlock: false arm_environment: ${ bundle.parameters.arm_environment } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" diff --git a/templates/workspaces/base/parameters.json b/templates/workspaces/base/parameters.json index fa261465ca..f95d146600 100755 --- a/templates/workspaces/base/parameters.json +++ b/templates/workspaces/base/parameters.json @@ -151,13 +151,13 @@ { "name": "enable_cmk_encryption", "source": { - "env": "enable_cmk_encryption" + "env": "ENABLE_CMK_ENCRYPTION" } }, { "name": "key_store_id", "source": { - "env": "key_store_id" + "env": "KEY_STORE_ID" } } ] diff --git a/templates/workspaces/base/porter.yaml b/templates/workspaces/base/porter.yaml index 1cdc6d24a6..901ae0541b 100644 --- a/templates/workspaces/base/porter.yaml +++ b/templates/workspaces/base/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-workspace-base -version: 1.7.1 +version: 1.8.0 description: "A base Azure TRE workspace" dockerfile: Dockerfile.tmpl registry: azuretre diff --git a/templates/workspaces/base/terraform/airlock/storage_accounts.tf b/templates/workspaces/base/terraform/airlock/storage_accounts.tf index 0bcea7c812..88b35883a7 100644 --- a/templates/workspaces/base/terraform/airlock/storage_accounts.tf +++ b/templates/workspaces/base/terraform/airlock/storage_accounts.tf @@ -5,6 +5,8 @@ resource "azurerm_storage_account" "sa_import_approved" { resource_group_name = var.ws_resource_group_name account_tier = "Standard" account_replication_type = "LRS" + table_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" + queue_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" allow_nested_items_to_be_public = false cross_tenant_replication_enabled = false @@ -68,6 +70,8 @@ resource "azurerm_storage_account" "sa_export_internal" { resource_group_name = var.ws_resource_group_name account_tier = "Standard" account_replication_type = "LRS" + table_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" + queue_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" allow_nested_items_to_be_public = false cross_tenant_replication_enabled = false @@ -131,6 +135,8 @@ resource "azurerm_storage_account" "sa_export_inprogress" { resource_group_name = var.ws_resource_group_name account_tier = "Standard" account_replication_type = "LRS" + table_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" + queue_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" allow_nested_items_to_be_public = false cross_tenant_replication_enabled = false @@ -201,6 +207,8 @@ resource "azurerm_storage_account" "sa_export_rejected" { resource_group_name = var.ws_resource_group_name account_tier = "Standard" account_replication_type = "LRS" + table_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" + queue_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" allow_nested_items_to_be_public = false cross_tenant_replication_enabled = false @@ -264,6 +272,8 @@ resource "azurerm_storage_account" "sa_export_blocked" { resource_group_name = var.ws_resource_group_name account_tier = "Standard" account_replication_type = "LRS" + table_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" + queue_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" allow_nested_items_to_be_public = false cross_tenant_replication_enabled = false diff --git a/templates/workspaces/base/terraform/azure-monitor/azure-monitor.tf b/templates/workspaces/base/terraform/azure-monitor/azure-monitor.tf index 89c44962d6..b1f00d2a15 100644 --- a/templates/workspaces/base/terraform/azure-monitor/azure-monitor.tf +++ b/templates/workspaces/base/terraform/azure-monitor/azure-monitor.tf @@ -19,6 +19,8 @@ resource "azurerm_storage_account" "app_insights" { account_kind = "StorageV2" account_tier = "Standard" account_replication_type = "LRS" + table_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" + queue_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" allow_nested_items_to_be_public = false cross_tenant_replication_enabled = false tags = var.tre_workspace_tags diff --git a/templates/workspaces/base/terraform/cmk-encryption.tf b/templates/workspaces/base/terraform/cmk-encryption.tf index 954bfd2361..9776a62d7e 100644 --- a/templates/workspaces/base/terraform/cmk-encryption.tf +++ b/templates/workspaces/base/terraform/cmk-encryption.tf @@ -4,7 +4,7 @@ resource "azurerm_user_assigned_identity" "encryption_identity" { location = azurerm_resource_group.ws.location tags = local.tre_workspace_tags - name = "id-encryption-${var.tre_id}-${local.short_workspace_id}" + name = local.encryption_identity_name lifecycle { ignore_changes = [tags] } } diff --git a/templates/workspaces/base/terraform/locals.tf b/templates/workspaces/base/terraform/locals.tf index 37a8263266..bc84d98e4d 100644 --- a/templates/workspaces/base/terraform/locals.tf +++ b/templates/workspaces/base/terraform/locals.tf @@ -8,5 +8,6 @@ locals { tre_id = var.tre_id tre_workspace_id = var.tre_resource_id } - kv_encryption_key_name = "tre-encryption-${local.workspace_resource_name_suffix}" + kv_encryption_key_name = "tre-encryption-${local.workspace_resource_name_suffix}" + encryption_identity_name = "id-encryption-${var.tre_id}-${local.short_workspace_id}" } diff --git a/templates/workspaces/base/terraform/storage.tf b/templates/workspaces/base/terraform/storage.tf index 5992d88d7c..626af7b63e 100644 --- a/templates/workspaces/base/terraform/storage.tf +++ b/templates/workspaces/base/terraform/storage.tf @@ -4,6 +4,8 @@ resource "azurerm_storage_account" "stg" { location = azurerm_resource_group.ws.location account_tier = "Standard" account_replication_type = "GRS" + table_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" + queue_encryption_key_type = var.enable_cmk_encryption ? "Account" : "Service" allow_nested_items_to_be_public = false is_hns_enabled = true cross_tenant_replication_enabled = false // not technically needed as cross tenant replication not supported when is_hns_enabled = true diff --git a/templates/workspaces/base/terraform/variables.tf b/templates/workspaces/base/terraform/variables.tf index 42eecbad69..a9b398e9fd 100644 --- a/templates/workspaces/base/terraform/variables.tf +++ b/templates/workspaces/base/terraform/variables.tf @@ -132,6 +132,5 @@ variable "enable_cmk_encryption" { variable "key_store_id" { type = string description = "ID of the Key Vault to store CMKs in (only used if enable_cmk_encryption is true)" - default = null } diff --git a/templates/workspaces/unrestricted/parameters.json b/templates/workspaces/unrestricted/parameters.json index 77e5faf93c..00ce33d3ba 100755 --- a/templates/workspaces/unrestricted/parameters.json +++ b/templates/workspaces/unrestricted/parameters.json @@ -147,6 +147,18 @@ "source": { "env": "ARM_ENVIRONMENT" } + }, + { + "name": "enable_cmk_encryption", + "source": { + "env": "ENABLE_CMK_ENCRYPTION" + } + }, + { + "name": "key_store_id", + "source": { + "env": "KEY_STORE_ID" + } } ] } diff --git a/templates/workspaces/unrestricted/porter.yaml b/templates/workspaces/unrestricted/porter.yaml index 97f1531997..2a72c33b2c 100644 --- a/templates/workspaces/unrestricted/porter.yaml +++ b/templates/workspaces/unrestricted/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-workspace-unrestricted -version: 0.12.5 +version: 0.13.0 description: "A base Azure TRE workspace" dockerfile: Dockerfile.tmpl registry: azuretre @@ -118,6 +118,12 @@ parameters: - name: enable_airlock type: boolean default: false + - name: enable_cmk_encryption + type: boolean + default: false + - name: key_store_id + type: string + default: "" outputs: - name: app_role_id_workspace_owner @@ -185,6 +191,8 @@ install: app_service_plan_sku: ${ bundle.parameters.app_service_plan_sku } enable_airlock: ${ bundle.parameters.enable_airlock } arm_environment: ${ bundle.parameters.arm_environment } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -227,6 +235,8 @@ upgrade: app_service_plan_sku: ${ bundle.parameters.app_service_plan_sku } enable_airlock: ${ bundle.parameters.enable_airlock } arm_environment: ${ bundle.parameters.arm_environment } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -292,6 +302,8 @@ uninstall: app_service_plan_sku: ${ bundle.parameters.app_service_plan_sku } enable_airlock: ${ bundle.parameters.enable_airlock } arm_environment: ${ bundle.parameters.arm_environment } + enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } + key_store_id: ${ bundle.parameters.key_store_id } backendConfig: use_azuread_auth: "true" use_oidc: "true"