diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f8aab111d..d67565861b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ ENHANCEMENTS: * Deny public access to TRE management storage account, and add private endpoint for TRE core [#4353](https://github.com/microsoft/AzureTRE/issues/4353) +* Added backup vault to base workspace & updated Azurerm provider to match core. ([[#4362](https://github.com/microsoft/AzureTRE/issues/4362)]) + BUG FIXES: diff --git a/templates/workspaces/base/parameters.json b/templates/workspaces/base/parameters.json index f95d146600..72f31b874b 100755 --- a/templates/workspaces/base/parameters.json +++ b/templates/workspaces/base/parameters.json @@ -159,6 +159,12 @@ "source": { "env": "KEY_STORE_ID" } + }, + { + "name": "enable_backup", + "source": { + "env": "ENABLE_BACKUP" + } } ] } diff --git a/templates/workspaces/base/porter.yaml b/templates/workspaces/base/porter.yaml index 55976e1b09..c8d907ddf2 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: 2.0.0 +version: 2.0.17 description: "A base Azure TRE workspace" dockerfile: Dockerfile.tmpl registry: azuretre @@ -126,6 +126,10 @@ parameters: type: string default: "GRS" description: "The redundancy option for the storage account in the workspace: GRS (Geo-Redundant Storage) or ZRS (Zone-Redundant Storage)." + - name: enable_backup + type: boolean + default: true + description: "Enable backups for the workspace, including the vm's & shared storage." outputs: - name: app_role_id_workspace_owner @@ -158,6 +162,21 @@ outputs: applyTo: - install - upgrade + - name: backup_vault_name + type: string + applyTo: + - install + - upgrade + - name: backup_vault_vm_backup_policy_name + type: string + applyTo: + - install + - upgrade + - name: backup_vault_fileshare_backup_policy_name + type: string + applyTo: + - install + - upgrade mixins: - exec @@ -196,6 +215,7 @@ install: enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } key_store_id: ${ bundle.parameters.key_store_id } storage_account_redundancy: ${ bundle.parameters.storage_account_redundancy } + enable_backup: ${ bundle.parameters.enable_backup } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -210,6 +230,9 @@ install: - name: client_id - name: scope_id - name: sp_id + - name: backup_vault_name + - name: backup_vault_vm_backup_policy_name + - name: backup_vault_fileshare_backup_policy_name upgrade: - terraform: @@ -241,6 +264,7 @@ upgrade: enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } key_store_id: ${ bundle.parameters.key_store_id } storage_account_redundancy: ${ bundle.parameters.storage_account_redundancy } + enable_backup: ${ bundle.parameters.enable_backup } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -255,6 +279,9 @@ upgrade: - name: client_id - name: scope_id - name: sp_id + - name: backup_vault_name + - name: backup_vault_vm_backup_policy_name + - name: backup_vault_fileshare_backup_policy_name - az: description: "Set Azure Cloud Environment" arguments: @@ -268,17 +295,17 @@ upgrade: - login flags: service-principal: "" - username: '${ bundle.credentials.auth_client_id }' - password: '${ bundle.credentials.auth_client_secret }' - tenant: '${ bundle.credentials.auth_tenant_id }' + username: "${ bundle.credentials.auth_client_id }" + password: "${ bundle.credentials.auth_client_secret }" + tenant: "${ bundle.credentials.auth_tenant_id }" allow-no-subscriptions: "" - exec: description: "Update workspace app redirect urls" command: ./update_redirect_urls.sh flags: - workspace-api-client-id: '${ bundle.parameters.client_id }' - aad-redirect-uris-b64: '${ bundle.parameters.aad_redirect_uris }' - register-aad-application: '${ bundle.parameters.register_aad_application }' + workspace-api-client-id: "${ bundle.parameters.client_id }" + aad-redirect-uris-b64: "${ bundle.parameters.aad_redirect_uris }" + register-aad-application: "${ bundle.parameters.register_aad_application }" uninstall: - terraform: @@ -309,6 +336,7 @@ uninstall: enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } key_store_id: ${ bundle.parameters.key_store_id } storage_account_redundancy: ${ bundle.parameters.storage_account_redundancy } + enable_backup: ${ bundle.parameters.enable_backup } backendConfig: use_azuread_auth: "true" use_oidc: "true" @@ -316,3 +344,13 @@ uninstall: storage_account_name: ${ bundle.parameters.tfstate_storage_account_name } container_name: ${ bundle.parameters.tfstate_container_name } key: ${ bundle.parameters.tre_id }-ws-${ bundle.parameters.id } + outputs: + - name: app_role_id_workspace_owner + - name: app_role_id_workspace_researcher + - name: app_role_id_workspace_airlock_manager + - name: client_id + - name: scope_id + - name: sp_id + - name: backup_vault_name + - name: backup_vault_vm_backup_policy_name + - name: backup_vault_fileshare_backup_policy_name diff --git a/templates/workspaces/base/template_schema.json b/templates/workspaces/base/template_schema.json index 24cec47f34..d1f554207a 100644 --- a/templates/workspaces/base/template_schema.json +++ b/templates/workspaces/base/template_schema.json @@ -73,6 +73,13 @@ "Manual" ], "updateable": true + }, + "enable_backup": { + "type": "boolean", + "title": "Enable Backup", + "description": "Enable backups for the workspace. Workspace services must support this feature.", + "default": true, + "updateable": true } }, "allOf": [ @@ -304,6 +311,7 @@ "create_aad_groups", "client_id", "client_secret", + "enable_backup", "enable_airlock", "configure_review_vms", "airlock_review_config", diff --git a/templates/workspaces/base/terraform/.terraform.lock.hcl b/templates/workspaces/base/terraform/.terraform.lock.hcl index 8a229681d9..e01a2a6b3f 100644 --- a/templates/workspaces/base/terraform/.terraform.lock.hcl +++ b/templates/workspaces/base/terraform/.terraform.lock.hcl @@ -6,7 +6,6 @@ provider "registry.terraform.io/azure/azapi" { constraints = ">= 1.15.0, 1.15.0" hashes = [ "h1:Y7ruMuPh8UJRTRl4rm+cdpGtmURx2taqiuqfYaH3o48=", - "h1:gIOgxVmFSxHrR+XOzgUEA+ybOmp8kxZlZH3eYeB/eFI=", "zh:0627a8bc77254debc25dc0c7b62e055138217c97b03221e593c3c56dc7550671", "zh:2fe045f07070ef75d0bec4b0595a74c14394daa838ddb964e2fd23cc98c40c34", "zh:343009f39c957883b2c06145a5954e524c70f93585f943f1ea3d28ef6995d0d0", @@ -43,28 +42,28 @@ provider "registry.terraform.io/hashicorp/azuread" { } provider "registry.terraform.io/hashicorp/azurerm" { - version = "3.117.0" - constraints = ">= 3.117.0, 3.117.0" + version = "4.14.0" + constraints = "4.14.0" hashes = [ - "h1:Ynfg+Iy7x6K8M6W1AhqXCe3wkoiqIQhROlca7C3KC3w=", - "zh:2e25f47492366821a786762369f0e0921cc9452d64bfd5075f6fdfcf1a9c6d70", - "zh:41eb34f2f7469bf3eb1019dfb0e7fc28256f809824016f4f8b9d691bf473b2ac", - "zh:48bb9c87b3d928da1abc1d3db75453c9725de4674c612daf3800160cc7145d30", - "zh:5d6b0de0bbd78943fcc65c53944ef4496329e247f434c6eab86ed051c5cea67b", - "zh:78c9f6fdb1206a89cf0e6706b4f46178169a93b6c964a4cad8a321058ccbd9b4", - "zh:793b702c352589d4360b580d4a1cf654a7439d2ad6bdb7bfea91de07bc4b0fac", - "zh:7ed687ff0a5509463a592f97431863574fe5cc80a34e395be06766215b8c6285", - "zh:955ba18789bd15592824eb426a8d0f38595bd09fffc6939c1c58933489c1a71e", - "zh:bf5949a55be0714cd9c8815d472eae4baa48ba06d0f6bf2b96775869acda8a54", - "zh:da5d31f635abd2c645ffc76d6176d73f646128e73720cc368247cc424975c127", - "zh:eed5a66d59883c9c56729b0a964a2b60d758ea7489ef3e920a6fbd48518ce5f5", + "h1:FYZ9qh8i3X2gDmUTe1jJ/VzdSyjGjVmhBzv2R8D6CBo=", + "zh:05aaea16fc5f27b14d9fbad81654edf0638949ed3585576b2219c76a2bee095a", + "zh:065ce6ed16ba3fa7efcf77888ea582aead54e6a28f184c6701b73d71edd64bb0", + "zh:3c0cd17c249d18aa2e0120acb5f0c14810725158b379a67fec1331110e7c50df", + "zh:5a3ba3ffb2f1ce519fe3bf84a7296aa5862c437c70c62f0b0a5293bea9f2d01c", + "zh:7a8e9d72fa2714f4d567270b1761d4b4e788de7c15dada7db0cf0e29933185a2", + "zh:a11e190073f31c1238c15af29b9162e0f4564f6b0cd0310a3fa94102738450dc", + "zh:a5c004114410cc6dcb8fed584c9f3b84283b58025b0073a7e88d2bdb27840dfa", + "zh:a674a41db118e244eda7591e455d2ec338626664e0856e4125e909eb038f78db", + "zh:b5139010e4cbb2cb1a27c775610593c1c8063d3a7c82b00a65006509c434df2f", + "zh:cbb031223ccd8b099ac4d19b92641142f330b90f2fc6452843e445bae28f832c", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:f7e7db1b94082a4ac3d4af3dabe7bbd335e1679305bf8e29d011f0ee440724ca", ] } provider "registry.terraform.io/hashicorp/random" { version = "3.3.2" - constraints = "~> 3.3.0" + constraints = ">= 3.1.0, ~> 3.3.0" hashes = [ "h1:H5V+7iXol/EHB2+BUMzGlpIiCOdV74H8YjzCxnSAWcg=", "zh:038293aebfede983e45ee55c328e3fde82ae2e5719c9bd233c324cfacc437f9c", diff --git a/templates/workspaces/base/terraform/aad/providers.tf b/templates/workspaces/base/terraform/aad/providers.tf index 4cf4c2b88a..7a31f12bb1 100644 --- a/templates/workspaces/base/terraform/aad/providers.tf +++ b/templates/workspaces/base/terraform/aad/providers.tf @@ -3,7 +3,7 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" - version = ">= 3.117.0" + version = "=4.14.0" } azuread = { source = "hashicorp/azuread" diff --git a/templates/workspaces/base/terraform/airlock/providers.tf b/templates/workspaces/base/terraform/airlock/providers.tf index 3bc52af981..eaa776f219 100644 --- a/templates/workspaces/base/terraform/airlock/providers.tf +++ b/templates/workspaces/base/terraform/airlock/providers.tf @@ -3,7 +3,7 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" - version = ">= 3.117.0" + version = "=4.14.0" } } } diff --git a/templates/workspaces/base/terraform/api-permissions.tf b/templates/workspaces/base/terraform/api-permissions.tf index ee4f5ee6b8..82b1fb7f98 100644 --- a/templates/workspaces/base/terraform/api-permissions.tf +++ b/templates/workspaces/base/terraform/api-permissions.tf @@ -20,3 +20,5 @@ resource "azurerm_role_assignment" "api_reader" { role_definition_name = "Reader" principal_id = data.azurerm_user_assigned_identity.api_id.principal_id } + + diff --git a/templates/workspaces/base/terraform/azure-monitor/providers.tf b/templates/workspaces/base/terraform/azure-monitor/providers.tf index 073110f2d1..92e7dad7e2 100644 --- a/templates/workspaces/base/terraform/azure-monitor/providers.tf +++ b/templates/workspaces/base/terraform/azure-monitor/providers.tf @@ -3,7 +3,7 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" - version = ">= 3.117.0" + version = "=4.14.0" } azapi = { diff --git a/templates/workspaces/base/terraform/backup/backup.tf b/templates/workspaces/base/terraform/backup/backup.tf new file mode 100644 index 0000000000..22e5231e89 --- /dev/null +++ b/templates/workspaces/base/terraform/backup/backup.tf @@ -0,0 +1,136 @@ + +resource "azurerm_recovery_services_vault" "vault" { + name = local.vault_name + location = var.location + resource_group_name = var.resource_group_name + sku = "Standard" + soft_delete_enabled = false + storage_mode_type = "ZoneRedundant" # Possible values are "GeoRedundant", "LocallyRedundant" and "ZoneRedundant". Defaults to "GeoRedundant". + tags = var.tre_workspace_tags + + dynamic "identity" { + for_each = var.enable_cmk_encryption ? [1] : [] + content { + type = "UserAssigned" + identity_ids = [azurerm_user_assigned_identity.encryption_identity[0].id] + } + } + + dynamic "encryption" { + for_each = var.enable_cmk_encryption ? [1] : [] + content { + key_id = azurerm_key_vault_key.encryption_key[0].versionless_id + infrastructure_encryption_enabled = true + user_assigned_identity_id = azurerm_user_assigned_identity.encryption_identity[0].id + use_system_assigned_identity = false + } + } + + lifecycle { ignore_changes = [encryption, tags] } + +} + +resource "azurerm_backup_policy_vm" "vm_policy" { + name = local.vm_backup_policy_name + resource_group_name = var.resource_group_name + recovery_vault_name = azurerm_recovery_services_vault.vault.name + + + timezone = "UTC" + + backup { + frequency = "Daily" + time = "22:00" + } + + retention_daily { + count = 14 + } + + retention_weekly { + count = 4 + weekdays = ["Sunday"] + } + + retention_monthly { + count = 12 + weekdays = ["Monday"] + weeks = ["First"] + } + + retention_yearly { + count = 2 + months = ["December"] + weekdays = ["Sunday"] + weeks = ["Last"] + } + + depends_on = [ + azurerm_recovery_services_vault.vault + ] + + +} + +resource "azurerm_backup_policy_file_share" "file_share_policy" { + name = local.fs_backup_policy_name + resource_group_name = var.resource_group_name + recovery_vault_name = azurerm_recovery_services_vault.vault.name + + timezone = "UTC" + + backup { + frequency = "Daily" + time = "23:00" + } + + retention_daily { + count = 14 + } + + retention_weekly { + count = 4 + weekdays = ["Sunday"] + } + + retention_monthly { + count = 12 + weekdays = ["Monday"] + weeks = ["First"] + } + + retention_yearly { + count = 2 + months = ["December"] + weekdays = ["Sunday"] + weeks = ["Last"] + } + + depends_on = [ + azurerm_recovery_services_vault.vault + ] + +} + +resource "azurerm_backup_container_storage_account" "storage_account" { + resource_group_name = var.resource_group_name + recovery_vault_name = azurerm_recovery_services_vault.vault.name + storage_account_id = var.azurerm_storage_account_id + + depends_on = [ + azurerm_recovery_services_vault.vault + ] +} + +resource "azurerm_backup_protected_file_share" "file_share" { + resource_group_name = var.resource_group_name + recovery_vault_name = azurerm_recovery_services_vault.vault.name + source_storage_account_id = var.azurerm_storage_account_id + source_file_share_name = var.shared_storage_name + backup_policy_id = azurerm_backup_policy_file_share.file_share_policy.id + + depends_on = [ + azurerm_backup_policy_file_share.file_share_policy, + azurerm_backup_container_storage_account.storage_account + ] +} diff --git a/templates/workspaces/base/terraform/backup/locals.tf b/templates/workspaces/base/terraform/backup/locals.tf new file mode 100644 index 0000000000..54be196867 --- /dev/null +++ b/templates/workspaces/base/terraform/backup/locals.tf @@ -0,0 +1,6 @@ +locals { + short_workspace_id = substr(var.tre_resource_id, -4, -1) + vault_name = "arsv-${var.tre_id}-ws-${local.short_workspace_id}" + vm_backup_policy_name = "abp-vm-${var.tre_id}-ws-${local.short_workspace_id}" + fs_backup_policy_name = "abp-fs-${var.tre_id}-ws-${local.short_workspace_id}" +} \ No newline at end of file diff --git a/templates/workspaces/base/terraform/backup/outputs.tf b/templates/workspaces/base/terraform/backup/outputs.tf new file mode 100644 index 0000000000..d9f78ca882 --- /dev/null +++ b/templates/workspaces/base/terraform/backup/outputs.tf @@ -0,0 +1,11 @@ +output "backup_vault_name" { + value = azurerm_recovery_services_vault.vault.name +} + +output "backup_vault_vm_backup_policy_name" { + value = azurerm_backup_policy_vm.vm_policy.name +} + +output "backup_vault_fileshare_backup_policy_name" { + value = azurerm_backup_policy_file_share.file_share_policy.name +} diff --git a/templates/workspaces/base/terraform/backup/providers.tf b/templates/workspaces/base/terraform/backup/providers.tf new file mode 100644 index 0000000000..c7a0b571d4 --- /dev/null +++ b/templates/workspaces/base/terraform/backup/providers.tf @@ -0,0 +1,13 @@ +terraform { + # In modules we should only specify the min version + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "=4.14.0" + } + random = { + source = "hashicorp/random" + version = ">= 3.1.0" + } + } +} diff --git a/templates/workspaces/base/terraform/backup/variables.tf b/templates/workspaces/base/terraform/backup/variables.tf new file mode 100644 index 0000000000..bd29f28b64 --- /dev/null +++ b/templates/workspaces/base/terraform/backup/variables.tf @@ -0,0 +1,33 @@ +variable "location" { + type = string +} +variable "tre_id" { + type = string +} +variable "resource_group_name" { + type = string +} +variable "resource_group_id" { + type = string +} +variable "enable_local_debugging" { + type = bool +} +variable "tre_workspace_tags" { + type = map(string) +} +variable "arm_environment" { + type = string +} +variable "azurerm_storage_account_id" { + type = string +} +variable "tre_resource_id" { + type = string +} +variable "enable_cmk_encryption" { + type = bool +} +variable "shared_storage_name" { + type = string +} diff --git a/templates/workspaces/base/terraform/locals.tf b/templates/workspaces/base/terraform/locals.tf index bc84d98e4d..cdac8356b5 100644 --- a/templates/workspaces/base/terraform/locals.tf +++ b/templates/workspaces/base/terraform/locals.tf @@ -10,4 +10,5 @@ locals { } kv_encryption_key_name = "tre-encryption-${local.workspace_resource_name_suffix}" encryption_identity_name = "id-encryption-${var.tre_id}-${local.short_workspace_id}" + shared_storage_name = "vm-shared-storage" } diff --git a/templates/workspaces/base/terraform/network/network.tf b/templates/workspaces/base/terraform/network/network.tf index bc9e5fadb3..e311809382 100644 --- a/templates/workspaces/base/terraform/network/network.tf +++ b/templates/workspaces/base/terraform/network/network.tf @@ -14,7 +14,7 @@ resource "azurerm_subnet" "services" { resource_group_name = var.ws_resource_group_name address_prefixes = [local.services_subnet_address_prefix] # notice that private endpoints do not adhere to NSG rules - private_endpoint_network_policies_enabled = false + private_endpoint_network_policies = "Disabled" private_link_service_network_policies_enabled = true } @@ -24,7 +24,7 @@ resource "azurerm_subnet" "webapps" { resource_group_name = var.ws_resource_group_name address_prefixes = [local.webapps_subnet_address_prefix] # notice that private endpoints do not adhere to NSG rules - private_endpoint_network_policies_enabled = false + private_endpoint_network_policies = "Disabled" private_link_service_network_policies_enabled = true delegation { diff --git a/templates/workspaces/base/terraform/network/providers.tf b/templates/workspaces/base/terraform/network/providers.tf index 2817aac3ab..52c3c0eea2 100644 --- a/templates/workspaces/base/terraform/network/providers.tf +++ b/templates/workspaces/base/terraform/network/providers.tf @@ -3,7 +3,16 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" - version = ">=3.117.0" + version = "=4.14.0" + } + } +} + +provider "azurerm" { + features { + recovery_service { + vm_backup_stop_protection_and_retain_data_on_destroy = false + purge_protected_items_from_vault_on_destroy = true } } } diff --git a/templates/workspaces/base/terraform/outputs.tf b/templates/workspaces/base/terraform/outputs.tf index 40fa8dcd69..223f2ea3b0 100644 --- a/templates/workspaces/base/terraform/outputs.tf +++ b/templates/workspaces/base/terraform/outputs.tf @@ -29,3 +29,14 @@ output "scope_id" { value = var.register_aad_application ? module.aad[0].scope_id : var.scope_id } +output "backup_vault_name" { + value = var.enable_backup ? module.backup[0].backup_vault_name : "" +} + +output "backup_vault_vm_backup_policy_name" { + value = var.enable_backup ? module.backup[0].backup_vault_vm_backup_policy_name : "" +} + +output "backup_vault_fileshare_backup_policy_name" { + value = var.enable_backup ? module.backup[0].backup_vault_fileshare_backup_policy_name : "" +} diff --git a/templates/workspaces/base/terraform/providers.tf b/templates/workspaces/base/terraform/providers.tf index e541b4a4c8..59003f4bae 100644 --- a/templates/workspaces/base/terraform/providers.tf +++ b/templates/workspaces/base/terraform/providers.tf @@ -2,7 +2,7 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" - version = "=3.117.0" + version = "=4.14.0" } azuread = { source = "hashicorp/azuread" diff --git a/templates/workspaces/base/terraform/storage.tf b/templates/workspaces/base/terraform/storage.tf index 7fc6f00a2c..35eb471271 100644 --- a/templates/workspaces/base/terraform/storage.tf +++ b/templates/workspaces/base/terraform/storage.tf @@ -36,7 +36,7 @@ resource "azurerm_storage_account" "stg" { # Using AzAPI as AzureRM uses shared account key for Azure files operations resource "azapi_resource" "shared_storage" { type = "Microsoft.Storage/storageAccounts/fileServices/shares@2023-05-01" - name = "vm-shared-storage" + name = local.shared_storage_name parent_id = "${azurerm_storage_account.stg.id}/fileServices/default" body = jsonencode({ properties = { diff --git a/templates/workspaces/base/terraform/variables.tf b/templates/workspaces/base/terraform/variables.tf index b3e2812785..cfb34b2181 100644 --- a/templates/workspaces/base/terraform/variables.tf +++ b/templates/workspaces/base/terraform/variables.tf @@ -75,6 +75,11 @@ variable "auth_client_secret" { type = string description = "Used to authenticate into the AAD Tenant to create the AAD App" } +variable "enable_backup" { + type = bool + default = true + description = "Enable backups for the workspace" +} # These variables are only passed in if you are not registering an AAD # application as they need passing back out diff --git a/templates/workspaces/base/terraform/workspace.tf b/templates/workspaces/base/terraform/workspace.tf index 10fb74c6a7..031b9727ed 100644 --- a/templates/workspaces/base/terraform/workspace.tf +++ b/templates/workspaces/base/terraform/workspace.tf @@ -88,3 +88,28 @@ module "azure_monitor" { module.airlock ] } + + +module "backup" { + count = var.enable_backup ? 1 : 0 + source = "./backup" + tre_id = var.tre_id + tre_resource_id = var.tre_resource_id + location = var.location + resource_group_name = azurerm_resource_group.ws.name + resource_group_id = azurerm_resource_group.ws.id + tre_workspace_tags = local.tre_workspace_tags + arm_environment = var.arm_environment + azurerm_storage_account_id = azurerm_storage_account.stg.id + enable_local_debugging = var.enable_local_debugging + enable_cmk_encryption = var.enable_cmk_encryption + shared_storage_name = local.shared_storage_name + + + depends_on = [ + azurerm_storage_account.stg, + azapi_resource.shared_storage, + module.network, + module.aad + ] +}