diff --git a/README.md b/README.md
index 7c0c086..0a65813 100644
--- a/README.md
+++ b/README.md
@@ -70,7 +70,7 @@ resources that lack official modules.
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
-| [allowed\_ip\_ranges](#input\_allowed\_ip\_ranges) | allowed public IP addresses or CIDR ranges. | `list(string)` | `[]` | no |
+| [allowed\_ip\_ranges](#input\_allowed\_ip\_ranges) | Allowed public IP addresses or CIDR ranges. | `list(string)` | `[]` | no |
| [allowed\_subscriptions](#input\_allowed\_subscriptions) | List of allowed customer subscriptions coma seperated values | `string` | `""` | no |
| [app\_wandb\_env](#input\_app\_wandb\_env) | Extra environment variables for W&B | `map(string)` | `{}` | no |
| [azuremonitor](#input\_azuremonitor) | # To support otel azure monitor sql and redis metrics need operator-wandb chart minimum version 0.14.0 | `bool` | `false` | no |
@@ -78,11 +78,16 @@ resources that lack official modules.
| [cluster\_sku\_tier](#input\_cluster\_sku\_tier) | The Azure AKS SKU Tier to use for this cluster (https://learn.microsoft.com/en-us/azure/aks/free-standard-pricing-tiers) | `string` | `"Free"` | no |
| [create\_private\_link](#input\_create\_private\_link) | Use for the azure private link. | `bool` | `false` | no |
| [create\_redis](#input\_create\_redis) | Boolean indicating whether to provision an redis instance (true) or not (false). | `bool` | `false` | no |
+| [customer\_storage\_vault\_key\_id](#input\_customer\_storage\_vault\_key\_id) | The Azure Key Vault key ID for customer-provided storage encryption keys. Must match the pattern 'https://.vault.azure.net/keys//', or be null. | `string` | `null` | no |
| [database\_availability\_mode](#input\_database\_availability\_mode) | n/a | `string` | `"SameZone"` | no |
| [database\_sku\_name](#input\_database\_sku\_name) | Specifies the SKU Name for this MySQL Server | `string` | `"GP_Standard_D4ds_v4"` | no |
| [database\_version](#input\_database\_version) | Version for MySQL | `string` | `"5.7"` | no |
| [deletion\_protection](#input\_deletion\_protection) | If the instance should have deletion protection enabled. The database / Bucket can't be deleted when this value is set to `true`. | `bool` | `true` | no |
+| [disable\_storage\_vault\_key\_id](#input\_disable\_storage\_vault\_key\_id) | Flag to disable the `customer_managed_key` block, the properties 'encryption.identity, encryption.keyvaultproperties' cannot be updated in a single operation. | `bool` | `false` | no |
| [domain\_name](#input\_domain\_name) | Domain for accessing the Weights & Biases UI. | `string` | `null` | no |
+| [enable\_database\_vault\_key](#input\_enable\_database\_vault\_key) | Flag to enable managed key encryption for the database. Once enabled, cannot be disabled. | `bool` | `false` | no |
+| [enable\_purge\_protection](#input\_enable\_purge\_protection) | Flag to enable purge protection for the Azure Key Vault. Once enabled, cannot be disabled. | `bool` | `false` | no |
+| [enable\_storage\_vault\_key](#input\_enable\_storage\_vault\_key) | Flag to enable managed key encryption for the storage account. | `bool` | `false` | no |
| [external\_bucket](#input\_external\_bucket) | config an external bucket | `any` | `null` | no |
| [kubernetes\_instance\_type](#input\_kubernetes\_instance\_type) | Use for the Kubernetes cluster. | `string` | `"Standard_D4a_v4"` | no |
| [kubernetes\_node\_count](#input\_kubernetes\_node\_count) | n/a | `number` | `2` | no |
@@ -116,6 +121,7 @@ resources that lack official modules.
| [address](#output\_address) | n/a |
| [aks\_node\_count](#output\_aks\_node\_count) | n/a |
| [aks\_node\_instance\_type](#output\_aks\_node\_instance\_type) | n/a |
+| [client\_id](#output\_client\_id) | n/a |
| [cluster\_ca\_certificate](#output\_cluster\_ca\_certificate) | n/a |
| [cluster\_client\_certificate](#output\_cluster\_client\_certificate) | n/a |
| [cluster\_client\_key](#output\_cluster\_client\_key) | n/a |
@@ -128,5 +134,6 @@ resources that lack official modules.
| [standardized\_size](#output\_standardized\_size) | n/a |
| [storage\_account](#output\_storage\_account) | n/a |
| [storage\_container](#output\_storage\_container) | n/a |
+| [tenant\_id](#output\_tenant\_id) | n/a |
| [url](#output\_url) | The URL to the W&B application |
diff --git a/examples/byob/README.md b/examples/byob/README.md
index 2cb5de2..b4fcc0e 100644
--- a/examples/byob/README.md
+++ b/examples/byob/README.md
@@ -23,13 +23,53 @@ storage_key =
To retrieve the storage key, you can use the Azure CLI installed previously like the example below.
-```basb
-az storage account keys list --account-name rgnamestorage --query '[].{key: value}' --output tsv
+```bash
+az storage account keys list --account-name --resource-group --query '[0].value' -o tsv
1111111111111122222222222333333333334444444555555555
-5555555554444444333333333332222222222211111111111111
```
-You only need to provide one key.
+This command will return the storage key, which you can then use for your deployment needs. Ensure you handle the storage key securely as it contains sensitive information.
+
+# Customer Managed Key Encryption
+
+The following section provides details on enabling Customer Managed Key (CMK) encryption for the Azure Blob Storage container which is disabled by default.
+
+To configure Customer Managed Key encryption, ensure you are using the latest version of out terraform which has the following added to the `variables.tf` file:
+
+- create_cmk
+- disable_storage_vault_key_id
+- enable_purge_protection
+- tenant_id
+- client_id
+
+You need to obtain the `tenant_id` and `client_id` from a Solutions Architect at W&B for an already instantiated instance of a Weights & Biases managed deployment.
+
+Set the follwoing new variabels to enable the CMK:
+
+```ini terraform.tfvars
+create_cmk = true
+
+enable_purge_protection = true
+disable_storage_vault_key_id = false
+
+tenant_id = ""
+client_id = ""
+```
+
+After updating your `terraform.tfvars` configuration, run the Terraform commands to apply the changes:
+
+```bash
+terraform init -upgrade
+terraform apply -var-file=terraform.tfvars
+```
+
+Upon successful execution, you will receive the following output which needs to the shared with the SA at Weights & Biases.
-* Note that all information about Storage Account and keys are mere examples, they are not valid.
+```bash
+blob_container = "/wandb"
+command_to_get_storage_key = "az storage account keys list --account-name --resource-group --query '[0].value' -o tsv"
+storage_key =
+storage_vault_key_id = "https://.vault.azure.net/keys//"
+```
+Retrieve the storage key as shown above and also share that with the SA at Weights & Biases.
diff --git a/examples/byob/main.tf b/examples/byob/main.tf
index 66fab24..f62f9ce 100644
--- a/examples/byob/main.tf
+++ b/examples/byob/main.tf
@@ -3,14 +3,19 @@ provider "azurerm" {
}
module "byob" {
- source = "../../modules/byob"
- resource_group_name = var.resource_group_name
- location = var.location
- prefix = var.prefix
- deletion_protection = var.deletion_protection
+ source = "../../modules/byob"
+ resource_group_name = var.resource_group_name
+ location = var.location
+ prefix = var.prefix
+ deletion_protection = var.deletion_protection
+ create_cmk = var.create_cmk
+ enable_purge_protection = var.enable_purge_protection
+ client_id = var.client_id
+ tenant_id = var.tenant_id
+ tags = var.tags
+ disable_storage_vault_key_id = var.disable_storage_vault_key_id
}
-
output "blob_container" {
value = module.byob.blob_container
}
@@ -19,3 +24,11 @@ output "storage_key" {
value = module.byob.azure_storage_key
sensitive = true
}
+
+output "storage_vault_key_id" {
+ value = module.byob.vault_key_id
+}
+
+output "command_to_get_storage_key" {
+ value = "az storage account keys list --account-name ${module.byob.storage_account_name} --resource-group ${module.byob.resource_group_name.name} --query '[0].value' -o tsv"
+}
diff --git a/examples/byob/terraform.tfvars b/examples/byob/terraform.tfvars
index ed42c15..62e6b1d 100644
--- a/examples/byob/terraform.tfvars
+++ b/examples/byob/terraform.tfvars
@@ -1,3 +1,16 @@
-resource_group_name = "rg-name"
-location = "westeurope"
-prefix = "byob-wandb"
+resource_group_name = ""
+
+location = ""
+prefix = ""
+tags = {
+ "name" = "wandb"
+}
+
+#To enable Azure Key Vault encryption uncomment the below lines
+# create_cmk = true
+
+# enable_purge_protection = true
+# disable_storage_vault_key_id = false
+
+# tenant_id = ""
+# client_id = ""
\ No newline at end of file
diff --git a/examples/byob/variables.tf b/examples/byob/variables.tf
index fafa958..7b265e5 100644
--- a/examples/byob/variables.tf
+++ b/examples/byob/variables.tf
@@ -1,6 +1,6 @@
variable "resource_group_name" {
- description = "Resource Group name"
type = string
+ description = "Resource Group"
}
variable "location" {
@@ -18,3 +18,37 @@ variable "deletion_protection" {
type = bool
default = false
}
+
+variable "create_cmk" {
+ type = bool
+ default = false
+ description = "Flag to create a Customer Managed Key for the Key Vault to encrypt the storage account."
+}
+
+variable "disable_storage_vault_key_id" {
+ type = bool
+ default = false
+ description = "Flag to disable the `customer_managed_key` block, the properties 'encryption.identity, encryption.keyvaultproperties' cannot be updated in a single operation."
+}
+
+variable "enable_purge_protection" {
+ type = bool
+ default = false
+ description = "Flag to enable purge protection for the Azure Key Vault. Once enabled, cannot be disabled."
+}
+
+variable "tenant_id" {
+ type = string
+ description = "The tenant ID for the Key Vault Access Policy. Get from W&B SA"
+}
+
+variable "client_id" {
+ type = string
+ description = "The client ID (object id) for the Key Vault Access Policy. Get from W&B SA"
+}
+
+variable "tags" {
+ type = map(string)
+ description = "Map of tags for resource"
+ default = {}
+}
diff --git a/main.tf b/main.tf
index eadd9ec..53c2349 100644
--- a/main.tf
+++ b/main.tf
@@ -2,6 +2,8 @@ locals {
fqdn = var.subdomain == null ? var.domain_name : "${var.subdomain}.${var.domain_name}"
url_prefix = var.ssl ? "https" : "http"
url = "${local.url_prefix}://${local.fqdn}"
+
+ enable_internal_storage = var.blob_container == "" && var.external_bucket == null
}
resource "azurerm_resource_group" "default" {
@@ -27,12 +29,12 @@ module "networking" {
private_link = var.create_private_link
allowed_ip_ranges = var.allowed_ip_ranges
tags = var.tags
-
}
module "database" {
- source = "./modules/database"
- namespace = var.namespace
+ source = "./modules/database"
+ namespace = var.namespace
+
resource_group_name = azurerm_resource_group.default.name
location = azurerm_resource_group.default.location
@@ -40,10 +42,11 @@ module "database" {
database_version = var.database_version
database_private_dns_zone_id = module.networking.database_private_dns_zone.id
database_subnet_id = module.networking.database_subnet.id
+ sku_name = try(local.deployment_size[var.size].db, var.database_sku_name)
+ deletion_protection = var.deletion_protection
- sku_name = try(local.deployment_size[var.size].db, var.database_sku_name)
- deletion_protection = var.deletion_protection
-
+ database_key_id = try(module.vault.vault_internal_keys[module.vault.vault_key_map.database].id, null)
+ identity_ids = module.identity.identity.id
tags = {
"customer-ns" = var.namespace,
"env" = "managed-install"
@@ -64,23 +67,33 @@ module "redis" {
module "vault" {
source = "./modules/vault"
- identity_object_id = module.identity.identity.principal_id
- location = azurerm_resource_group.default.location
- namespace = var.namespace
- resource_group = azurerm_resource_group.default
+ identity_object_id = module.identity.identity.principal_id
+ location = azurerm_resource_group.default.location
+ namespace = var.namespace
+ resource_group = azurerm_resource_group.default
+ enable_purge_protection = var.enable_purge_protection
+
+ enable_database_vault_key = var.enable_database_vault_key
+ enable_storage_vault_key = var.enable_storage_vault_key && local.enable_internal_storage
tags = var.tags
}
module "storage" {
- count = (var.blob_container == "" && var.external_bucket == null) ? 1 : 0
- source = "./modules/storage"
+ source = "./modules/storage"
+
+ count = local.enable_internal_storage ? 1 : 0
namespace = var.namespace
resource_group_name = azurerm_resource_group.default.name
location = azurerm_resource_group.default.location
create_queue = !var.use_internal_queue
+ identity_ids = module.identity.identity.id
deletion_protection = var.deletion_protection
- tags = var.tags
+
+ storage_key_id = var.customer_storage_vault_key_id == null ? try(module.vault.vault_internal_keys[module.vault.vault_key_map.storage].id, null) : var.customer_storage_vault_key_id
+ disable_storage_vault_key_id = var.disable_storage_vault_key_id
+
+ tags = var.tags
}
module "app_lb" {
@@ -176,8 +189,9 @@ resource "azurerm_role_assignment" "gateway_role" {
}
module "cron_job" {
- count = length(var.allowed_subscriptions) > 0 ? 1 : 0 # private endpoint approval application deployed as a cronjob in default namespace
- source = "./modules/cron_job"
+ count = length(var.allowed_subscriptions) > 0 ? 1 : 0 # private endpoint approval application deployed as a cronjob in default namespace
+ source = "./modules/cron_job"
+
namespace = "default"
client_id = module.pod_identity[0].identity.client_id
serviceaccountName = local.private_endpoint_approval_sa
@@ -186,7 +200,6 @@ module "cron_job" {
applicationGatewayName = module.app_lb.gateway.name
allowedSubscriptions = var.allowed_subscriptions
depends_on = [module.app_lb, module.pod_identity]
-
}
resource "azurerm_role_assignment" "otel_role" {
@@ -194,7 +207,6 @@ resource "azurerm_role_assignment" "otel_role" {
scope = azurerm_resource_group.default.id
role_definition_name = "Contributor"
principal_id = module.identity.otel_identity.principal_id
-
}
resource "azurerm_federated_identity_credential" "otel_app" {
@@ -235,8 +247,8 @@ module "wandb" {
spec = {
values = {
global = {
- host = local.url
- license = var.license
+ host = local.url
+ license = var.license
cloudProvider = "azure"
bucket = var.external_bucket == null ? {
provider = "az"
diff --git a/modules/byob/main.tf b/modules/byob/main.tf
index 72ba9b4..f16edb1 100644
--- a/modules/byob/main.tf
+++ b/modules/byob/main.tf
@@ -1,10 +1,47 @@
-module "storage" {
- source = "../storage"
+module "identity" {
+ count = var.create_cmk ? 1 : 0
+ source = "../identity"
+
+ namespace = var.prefix
+ resource_group = { name = "${var.resource_group_name}", id = "byob" }
+ location = var.location
+}
+
+module "vault" {
+ count = var.create_cmk ? 1 : 0
+ source = "../vault"
+ namespace = var.prefix
+ resource_group = { name = "${var.resource_group_name}", id = "byob" }
+ location = var.location
+
+ identity_object_id = module.identity[0].identity.principal_id
+ depends_on = [module.identity]
+ tags = var.tags
+ enable_purge_protection = var.enable_purge_protection
+ enable_storage_vault_key = var.create_cmk
+}
+
+resource "azurerm_key_vault_access_policy" "wandb" {
+ count = var.create_cmk ? 1 : 0
+ key_vault_id = module.vault[0].vault.id
+ tenant_id = var.tenant_id
+ object_id = var.client_id
+ key_permissions = ["Get", "List", "Update", "Create", "Import", "Delete", "Recover", "Backup", "Restore"]
+ certificate_permissions = ["Get", "List", "Update", "Create", "Import", "Delete", "Recover", "Backup", "Restore"]
+ secret_permissions = ["Get", "List", "Set", "Delete", "Recover", "Backup", "Restore"]
+}
+
+module "storage" {
+ source = "../storage"
create_queue = false
namespace = var.prefix
resource_group_name = var.resource_group_name
location = var.location
-
deletion_protection = var.deletion_protection
+ storage_key_id = try(module.vault[0].vault_internal_keys[module.vault[0].vault_key_map.storage].id, null)
+ identity_ids = try(module.identity[0].identity.id, null)
+
+ disable_storage_vault_key_id = var.disable_storage_vault_key_id
}
+
diff --git a/modules/byob/outputs.tf b/modules/byob/outputs.tf
index 3c3e8ac..4177455 100644
--- a/modules/byob/outputs.tf
+++ b/modules/byob/outputs.tf
@@ -2,6 +2,14 @@ output "azure_storage_key" {
value = module.storage.account.primary_access_key
}
+output "storage_key_id" {
+ value = try(module.vault[0].vault_internal_keys[module.vault[0].vault_key_map.storage].id, null)
+}
+
output "blob_container" {
value = "${module.storage.account.name}/${module.storage.container.name}"
-}
\ No newline at end of file
+}
+
+output "storage_account_name" {
+ value = module.storage.account.name
+}
diff --git a/modules/byob/variables.tf b/modules/byob/variables.tf
index 57c9157..75e0888 100644
--- a/modules/byob/variables.tf
+++ b/modules/byob/variables.tf
@@ -1,6 +1,5 @@
variable "resource_group_name" {
- description = "Resource Group name"
- type = string
+ type = string
}
variable "location" {
@@ -18,3 +17,37 @@ variable "deletion_protection" {
type = bool
default = true
}
+
+variable "create_cmk" {
+ type = bool
+ default = false
+ description = "Flag to create a Customer Managed Key for the Key Vault to encrypt the storage account."
+}
+
+variable "tags" {
+ type = map(string)
+ description = "Map of tags for resource"
+ default = {}
+}
+
+variable "enable_purge_protection" {
+ type = bool
+ default = false
+ description = "Flag to enable purge protection for the Azure Key Vault. Once enabled, cannot be disabled."
+}
+
+variable "disable_storage_vault_key_id" {
+ type = bool
+ default = false
+ description = "Flag to disable the `customer_managed_key` block, the properties 'encryption.identity, encryption.keyvaultproperties' cannot be updated in a single operation."
+}
+
+variable "tenant_id" {
+ type = string
+ description = "The tenant ID for the Key Vault Access Policy. Get from W&B SA"
+}
+
+variable "client_id" {
+ type = string
+ description = "The client ID (object id) for the Key Vault Access Policy. Get from W&B SA"
+}
diff --git a/modules/database/main.tf b/modules/database/main.tf
index d5f5d12..4c4b9ae 100644
--- a/modules/database/main.tf
+++ b/modules/database/main.tf
@@ -52,6 +52,20 @@ resource "azurerm_mysql_flexible_server" "default" {
]
}
+ dynamic "identity" {
+ for_each = var.database_key_id != null ? [1] : []
+ content {
+ type = "UserAssigned"
+ identity_ids = [var.identity_ids]
+ }
+ }
+ dynamic "customer_managed_key" {
+ for_each = var.database_key_id != null ? [1] : []
+ content {
+ primary_user_assigned_identity_id = var.identity_ids
+ key_vault_key_id = var.database_key_id
+ }
+ }
tags = var.tags
}
diff --git a/modules/database/variables.tf b/modules/database/variables.tf
index a75ab3e..d01456f 100644
--- a/modules/database/variables.tf
+++ b/modules/database/variables.tf
@@ -53,6 +53,16 @@ variable "tags" {
}
variable "deletion_protection" {
- description = "If the instance should have deletion protection enabled. The database can't be deleted when this value is set to `true`."
type = bool
-}
\ No newline at end of file
+ description = "If the instance should have deletion protection enabled. The database can't be deleted when this value is set to `true`."
+}
+
+variable "database_key_id" {
+ type = string
+ description = "The Azure Key Vault key identifier for the database encryption key."
+}
+
+variable "identity_ids" {
+ type = string
+ description = "The identity ids to assign to the database when database_key_id is passed."
+}
diff --git a/modules/identity/main.tf b/modules/identity/main.tf
index 6880b99..6a4b825 100644
--- a/modules/identity/main.tf
+++ b/modules/identity/main.tf
@@ -9,4 +9,4 @@ resource "azurerm_user_assigned_identity" "otel" {
name = "${var.namespace}-identity-otel"
location = var.location
resource_group_name = var.resource_group.name
-}
\ No newline at end of file
+}
diff --git a/modules/identity/outputs.tf b/modules/identity/outputs.tf
index 453d5a4..fa7c529 100644
--- a/modules/identity/outputs.tf
+++ b/modules/identity/outputs.tf
@@ -1,6 +1,7 @@
output "identity" {
value = azurerm_user_assigned_identity.default
}
+
output "otel_identity" {
value = var.otel_identity ? azurerm_user_assigned_identity.otel[0] : null
-}
\ No newline at end of file
+}
diff --git a/modules/identity/variables.tf b/modules/identity/variables.tf
index 54cb0e4..1522c50 100644
--- a/modules/identity/variables.tf
+++ b/modules/identity/variables.tf
@@ -14,6 +14,6 @@ variable "location" {
}
variable "otel_identity" {
- type = bool
+ type = bool
default = false
-}
\ No newline at end of file
+}
diff --git a/modules/storage/main.tf b/modules/storage/main.tf
index b077e4d..0c55022 100644
--- a/modules/storage/main.tf
+++ b/modules/storage/main.tf
@@ -26,6 +26,20 @@ resource "azurerm_storage_account" "default" {
}
}
+ dynamic "identity" {
+ for_each = var.storage_key_id != null ? [1] : []
+ content {
+ type = "UserAssigned"
+ identity_ids = [var.identity_ids]
+ }
+ }
+ dynamic "customer_managed_key" {
+ for_each = var.storage_key_id != null && var.disable_storage_vault_key_id == false ? [1] : []
+ content {
+ user_assigned_identity_id = var.identity_ids
+ key_vault_key_id = var.storage_key_id
+ }
+ }
tags = var.tags
}
diff --git a/modules/storage/variables.tf b/modules/storage/variables.tf
index 774306a..dab57e6 100644
--- a/modules/storage/variables.tf
+++ b/modules/storage/variables.tf
@@ -29,8 +29,22 @@ variable "deletion_protection" {
type = bool
}
+variable "storage_key_id" {
+ type = string
+}
+
+variable "disable_storage_vault_key_id" {
+ type = bool
+ default = false
+ description = "Flag to disable the `customer_managed_key` block, the properties 'encryption.identity, encryption.keyvaultproperties' cannot be updated in a single operation."
+}
+
+variable "identity_ids" {
+ type = string
+}
+
variable "blob_container_name" {
description = "Name of azure storage account container for storing blobs"
type = string
default = "wandb"
-}
\ No newline at end of file
+}
diff --git a/modules/vault/main.tf b/modules/vault/main.tf
index e43290c..477c779 100644
--- a/modules/vault/main.tf
+++ b/modules/vault/main.tf
@@ -4,14 +4,21 @@ data "azurerm_client_config" "current" {}
locals {
vault_name = "${var.namespace}-vault"
vault_truncated_name = substr(local.vault_name, 0, min(length(local.vault_name), 24))
+ max_key_length = 127
+ vault_key_map = {
+ database = var.enable_database_vault_key ? substr("database-key-${var.namespace}", 0, local.max_key_length) : null
+ storage = var.enable_storage_vault_key ? substr("storage-key-${var.namespace}", 0, local.max_key_length) : null
+ }
}
resource "azurerm_key_vault" "default" {
- name = trim(local.vault_truncated_name, "-")
- location = var.location
- resource_group_name = var.resource_group.name
- tenant_id = data.azurerm_client_config.current.tenant_id
-
+ name = trim(local.vault_truncated_name, "-")
+ location = var.location
+ resource_group_name = var.resource_group.name
+ tenant_id = data.azurerm_client_config.current.tenant_id
+ purge_protection_enabled = var.enable_purge_protection
+ # https://learn.microsoft.com/en-us/azure/mysql/flexible-server/concepts-customer-managed-key#requirements-for-configuring-data-encryption-for-azure-database-for-mysql-flexible-server
+ soft_delete_retention_days = 90 # This must be 90 for azure msyql flex server encryption.
enabled_for_disk_encryption = true
sku_name = "standard"
@@ -41,21 +48,32 @@ resource "azurerm_key_vault_access_policy" "identity" {
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = var.identity_object_id
- key_permissions = ["Create", "Decrypt", "Encrypt", "Get", "List"]
+ key_permissions = ["Create", "Decrypt", "Encrypt", "Get", "List", "UnwrapKey", "WrapKey"]
secret_permissions = ["Delete", "Get", "List", "Purge", "Recover", "Restore", "Set"]
storage_permissions = ["Get", "List"]
-
depends_on = [azurerm_key_vault.default]
}
resource "azurerm_key_vault_key" "etcd" {
- depends_on = [azurerm_key_vault_access_policy.parent, azurerm_key_vault_access_policy.identity]
-
name = "generated-etcd-key"
key_vault_id = azurerm_key_vault.default.id
key_type = "RSA"
key_size = 2048
key_opts = ["decrypt", "encrypt", "sign", "unwrapKey", "verify", "wrapKey", ]
+
+ depends_on = [azurerm_key_vault_access_policy.parent, azurerm_key_vault_access_policy.identity]
+}
+
+resource "azurerm_key_vault_key" "intenral_encryption_keys" {
+ for_each = { for v in local.vault_key_map : v => v if v != null }
+ name = each.value
+ key_vault_id = azurerm_key_vault.default.id
+ key_type = "RSA"
+ key_size = 2048
+
+ key_opts = ["decrypt", "encrypt", "sign", "unwrapKey", "verify", "wrapKey"]
+
+ depends_on = [azurerm_key_vault_access_policy.parent, azurerm_key_vault_access_policy.identity]
}
diff --git a/modules/vault/outputs.tf b/modules/vault/outputs.tf
index 9ec675d..0402867 100644
--- a/modules/vault/outputs.tf
+++ b/modules/vault/outputs.tf
@@ -4,4 +4,16 @@ output "etcd_key_id" {
output "vault" {
value = azurerm_key_vault.default
-}
\ No newline at end of file
+}
+
+output "vault_id" {
+ value = azurerm_key_vault.default.id
+}
+
+output "vault_internal_keys" {
+ value = azurerm_key_vault_key.intenral_encryption_keys
+}
+
+output "vault_key_map" {
+ value = local.vault_key_map
+}
diff --git a/modules/vault/variables.tf b/modules/vault/variables.tf
index f061a9a..693b9ca 100644
--- a/modules/vault/variables.tf
+++ b/modules/vault/variables.tf
@@ -20,4 +20,22 @@ variable "resource_group" {
variable "tags" {
type = map(string)
description = "Map of tags for resource"
-}
\ No newline at end of file
+}
+
+variable "enable_storage_vault_key" {
+ type = bool
+ default = false
+ description = "Flag to enable managed key encryption for the storage account."
+}
+
+variable "enable_database_vault_key" {
+ type = bool
+ default = false
+ description = "Flag to enable managed key encryption for the database. Once enabled, cannot be disabled or you will loose access to the database."
+}
+
+variable "enable_purge_protection" {
+ type = bool
+ default = false
+ description = "Flag to enable purge protection for the Azure Key Vault. Once enabled, cannot be disabled."
+}
diff --git a/outputs.tf b/outputs.tf
index 4a43945..40870ec 100644
--- a/outputs.tf
+++ b/outputs.tf
@@ -48,7 +48,7 @@ output "private_link_resource_id" {
output "private_link_sub_resource_name" {
value = module.app_lb.frontend_ip_configuration_names
}
-
+
output "standardized_size" {
value = var.size
}
@@ -63,4 +63,12 @@ output "aks_node_instance_type" {
output "database_instance_type" {
value = try(local.deployment_size[var.size].db, var.database_sku_name)
-}
\ No newline at end of file
+}
+
+output "client_id" {
+ value = module.identity.identity.client_id
+}
+
+output "tenant_id" {
+ value = module.identity.identity.tenant_id
+}
diff --git a/variables.tf b/variables.tf
index cdddcc2..4cfa373 100644
--- a/variables.tf
+++ b/variables.tf
@@ -145,9 +145,9 @@ variable "create_redis" {
}
variable "redis_capacity" {
- type = number
+ type = number
description = "Number indicating size of an redis instance"
- default = 2
+ default = 2
}
##########################################
@@ -210,7 +210,7 @@ variable "node_pool_zones" {
variable "node_max_pods" {
type = number
description = "Maximum number of pods per node"
- default = 30
+ default = 30
}
###########################################
@@ -225,14 +225,14 @@ variable "create_private_link" {
variable "allowed_subscriptions" {
type = string
description = "List of allowed customer subscriptions coma seperated values"
- default = ""
+ default = ""
}
##########################################
# Network #
##########################################
variable "allowed_ip_ranges" {
- description = "allowed public IP addresses or CIDR ranges."
+ description = "Allowed public IP addresses or CIDR ranges."
type = list(string)
default = []
}
@@ -255,6 +255,45 @@ variable "parquet_wandb_env" {
default = {}
}
+##########################################
+# vault key #
+##########################################
+
+variable "enable_storage_vault_key" {
+ type = bool
+ default = false
+ description = "Flag to enable managed key encryption for the storage account."
+}
+
+variable "disable_storage_vault_key_id" {
+ type = bool
+ default = false
+ description = "Flag to disable the `customer_managed_key` block, the properties 'encryption.identity, encryption.keyvaultproperties' cannot be updated in a single operation."
+}
+
+variable "customer_storage_vault_key_id" {
+ type = string
+ default = null
+ description = "The Azure Key Vault key ID for customer-provided storage encryption keys. Must match the pattern 'https://.vault.azure.net/keys//', or be null."
+
+ validation {
+ condition = var.customer_storage_vault_key_id == null || can(regex("^https://[a-zA-Z0-9-]+.vault.azure.net/keys/[a-zA-Z0-9-]+/[a-f0-9]+$", var.customer_storage_vault_key_id))
+ error_message = "The customer_storage_vault_key_id must be null or a valid Azure Key Vault key ID in the format 'https://.vault.azure.net/keys//'."
+ }
+}
+
+variable "enable_database_vault_key" {
+ type = bool
+ default = false
+ description = "Flag to enable managed key encryption for the database. Once enabled, cannot be disabled."
+}
+
+variable "enable_purge_protection" {
+ type = bool
+ default = false
+ description = "Flag to enable purge protection for the Azure Key Vault. Once enabled, cannot be disabled."
+}
+
## To support otel azure monitor sql and redis metrics need operator-wandb chart minimum version 0.14.0
variable "azuremonitor" {
type = bool
diff --git a/versions.tf b/versions.tf
index d740277..79b7958 100644
--- a/versions.tf
+++ b/versions.tf
@@ -14,5 +14,4 @@ terraform {
version = "~> 2.6"
}
}
-}
-
+}
\ No newline at end of file