diff --git a/README.yaml b/README.yaml index 5feff12..e418d32 100644 --- a/README.yaml +++ b/README.yaml @@ -40,48 +40,40 @@ include: usage: |- ### Simple Example Here is an example of how you can use this module in your inventory structure: - #### default storage + #### storage account without cmk encryption ```hcl module "storage" { - depends_on = [module.resource_group] - source = "clouddrove/storage/azure" - name = "app" - environment = "test" - label_order = ["name", "environment"] - default_enabled = true - resource_group_name = module.resource_group.resource_group_name - location = module.resource_group.resource_group_location - storage_account_name = "stordtyre236" + source = "../.." + name = local.name + environment = local.environment + label_order = local.label_order + resource_group_name = "test-rg" + location = "Central India" + storage_account_name = "storage7386" + public_network_access_enabled = true + account_kind = "StorageV2" + account_tier = "Standard" + account_replication_type = "GRS" + ## Encryption is not enabled for this Storage account + cmk_encryption_enabled = false ## Storage Container containers_list = [ { name = "app-test", access_type = "private" }, - { name = "app2", access_type = "private" }, ] - - ## Storage File Share - file_shares = [ - { name = "fileshare1", quota = 5 }, - ] - - ## Storage Tables tables = ["table1"] - - ## Storage Queues queues = ["queue1"] + file_shares = [ + { name = "fileshare", quota = "10" }, + ] - management_policy_enable = true - - #enable private endpoint - virtual_network_id = module.vnet.vnet_id[0] - subnet_id = module.subnet.default_subnet_id[0] - - log_analytics_workspace_id = module.log-analytics.workspace_id - + virtual_network_id = "/subscriptions/-----------------------------" + subnet_id = "/subscriptions/-----------------------------" + log_analytics_workspace_id = "/subscriptions/-----------------------------" } ``` - #### storage with cmk encryption + #### storage account with cmk encryption ```hcl module "storage" { source = "../.." @@ -90,27 +82,30 @@ usage: |- label_order = local.label_order resource_group_name = module.resource_group.resource_group_name location = module.resource_group.resource_group_location - storage_account_name = "storage877656" + storage_account_name = "storage874682" public_network_access_enabled = true account_kind = "StorageV2" account_tier = "Standard" identity_type = "UserAssigned" object_id = [data.azurerm_client_config.current_client_config.object_id] account_replication_type = "ZRS" - cmk_enabled = true + cmk_encryption_enabled = true + admin_objects_ids = [data.azurerm_client_config.current_client_config.object_id] ###customer_managed_key can only be set when the account_kind is set to StorageV2 or account_tier set to Premium, and the identity type is UserAssigned. key_vault_id = module.vault.id - ## Storage Container containers_list = [ { name = "app-test", access_type = "private" }, ] + tables = ["table1"] + queues = ["queue1"] + file_shares = [ + { name = "fileshare", quota = "10" }, + ] - virtual_network_id = module.vnet.vnet_id[0] - subnet_id = module.subnet.default_subnet_id[0] - + virtual_network_id = module.vnet.vnet_id[0] + subnet_id = module.subnet.default_subnet_id[0] log_analytics_workspace_id = module.log-analytics.workspace_id - } ``` diff --git a/_example/basic/example.tf b/_example/basic/example.tf index d40bdd8..98c75b8 100644 --- a/_example/basic/example.tf +++ b/_example/basic/example.tf @@ -16,26 +16,28 @@ module "storage" { source = "../.." name = local.name environment = local.environment - resource_group_name = "app-test-rg" + label_order = local.label_order + resource_group_name = "test-rg" location = "Central India" - storage_account_name = "stordtyrey36" - public_network_access_enabled = false + storage_account_name = "storage7386" + public_network_access_enabled = true + account_kind = "StorageV2" + account_tier = "Standard" + account_replication_type = "GRS" + + ## Encryption is not enabled for this Storage account + cmk_encryption_enabled = false + ## Storage Container containers_list = [ { name = "app-test", access_type = "private" }, - { name = "app2", access_type = "private" }, - ] - ## Storage File Share - file_shares = [ - { name = "fileshare1", quota = 5 }, ] - ## Storage Tables tables = ["table1"] - ## Storage Queues queues = ["queue1"] + file_shares = [ + { name = "fileshare", quota = "10" }, + ] - management_policy_enable = true - #enable private endpoint virtual_network_id = "/subscriptions/-----------------------------" subnet_id = "/subscriptions/-----------------------------" log_analytics_workspace_id = "/subscriptions/-----------------------------" diff --git a/_example/basic/outputs.tf b/_example/basic/outputs.tf index f0aa19d..9a57e21 100644 --- a/_example/basic/outputs.tf +++ b/_example/basic/outputs.tf @@ -1,10 +1,10 @@ output "storage_account_id" { - value = module.storage.default_storage_account_id + value = module.storage.storage_account_id description = "The ID of the storage account." } output "storage_account_name" { - value = module.storage.default_storage_account_name + value = module.storage.storage_account_name description = "The name of the storage account." } diff --git a/_example/complete/example.tf b/_example/complete/example.tf index 80eee65..e07b509 100644 --- a/_example/complete/example.tf +++ b/_example/complete/example.tf @@ -83,7 +83,7 @@ module "vault" { source = "clouddrove/key-vault/azure" version = "1.1.0" - name = "vault8767768" + name = "vault65960589" environment = "test" label_order = ["name", "environment", ] resource_group_name = module.resource_group.resource_group_name @@ -107,7 +107,7 @@ module "vault" { # existing_private_dns_zone_resource_group_name = "" #### enable diagnostic setting - diagnostic_setting_enable = true + diagnostic_setting_enable = false log_analytics_workspace_id = module.log-analytics.workspace_id ## when diagnostic_setting_enable enable, add log analytics workspace id } @@ -122,14 +122,15 @@ module "storage" { label_order = local.label_order resource_group_name = module.resource_group.resource_group_name location = module.resource_group.resource_group_location - storage_account_name = "storage877656" + storage_account_name = "storage874682" public_network_access_enabled = true account_kind = "StorageV2" account_tier = "Standard" identity_type = "UserAssigned" object_id = [data.azurerm_client_config.current_client_config.object_id] account_replication_type = "ZRS" - cmk_enabled = true + cmk_encryption_enabled = true + admin_objects_ids = [data.azurerm_client_config.current_client_config.object_id] ###customer_managed_key can only be set when the account_kind is set to StorageV2 or account_tier set to Premium, and the identity type is UserAssigned. key_vault_id = module.vault.id diff --git a/main.tf b/main.tf index 945bb5b..099d5e2 100644 --- a/main.tf +++ b/main.tf @@ -19,7 +19,7 @@ module "labels" { ##----------------------------------------------------------------------------- resource "azurerm_storage_account" "storage" { count = var.enabled ? 1 : 0 - depends_on = [azurerm_role_assignment.identity_assigned] + # depends_on = [azurerm_role_assignment.identity_assigned] name = var.storage_account_name resource_group_name = var.resource_group_name location = var.location @@ -191,14 +191,14 @@ resource "azurerm_storage_account" "storage" { } } dynamic "identity" { - for_each = var.identity_type != null ? [1] : [] + for_each = var.cmk_encryption_enabled && var.identity_type != null ? [1] : [] content { type = var.identity_type identity_ids = var.identity_type == "UserAssigned" ? [join("", azurerm_user_assigned_identity.identity.*.id)] : null } } dynamic "customer_managed_key" { - for_each = var.cmk_enabled ? [1] : [] + for_each = var.cmk_encryption_enabled ? [1] : [] content { key_vault_key_id = var.key_vault_id != null ? azurerm_key_vault_key.kvkey[0].id : null user_assigned_identity_id = var.key_vault_id != null ? azurerm_user_assigned_identity.identity[0].id : null @@ -211,7 +211,7 @@ resource "azurerm_storage_account" "storage" { ## This user assigned identity will be created when storage account with cmk is created. ##----------------------------------------------------------------------------- resource "azurerm_user_assigned_identity" "identity" { - count = var.enabled && var.cmk_enabled ? 1 : 0 + count = var.enabled && var.cmk_encryption_enabled ? 1 : 0 location = var.location name = format("%s-storage-mid", module.labels.id) resource_group_name = var.resource_group_name @@ -222,18 +222,30 @@ resource "azurerm_user_assigned_identity" "identity" { ##----------------------------------------------------------------------------- resource "azurerm_role_assignment" "identity_assigned" { depends_on = [azurerm_user_assigned_identity.identity] - count = var.enabled && var.key_vault_rbac_auth_enabled ? 1 : 0 + count = var.enabled && var.cmk_encryption_enabled && var.key_vault_rbac_auth_enabled ? 1 : 0 principal_id = azurerm_user_assigned_identity.identity[0].principal_id scope = var.key_vault_id role_definition_name = "Key Vault Crypto Service Encryption User" } +##----------------------------------------------------------------------------- +## Below resource will provide user access on key vault based on role base access in azure environment. +## if rbac is enabled then below resource will create. +##----------------------------------------------------------------------------- +resource "azurerm_role_assignment" "rbac_keyvault_crypto_officer" { + for_each = toset(var.key_vault_rbac_auth_enabled && var.enabled && var.cmk_encryption_enabled ? var.admin_objects_ids : []) + + scope = var.key_vault_id + role_definition_name = "Key Vault Crypto Officer" + principal_id = each.value +} + ##----------------------------------------------------------------------------- ## Below resource will create key vault key that will be used for encryption. ##----------------------------------------------------------------------------- resource "azurerm_key_vault_key" "kvkey" { - depends_on = [azurerm_role_assignment.identity_assigned, azurerm_user_assigned_identity.identity] - count = var.enabled && var.cmk_enabled ? 1 : 0 + depends_on = [azurerm_role_assignment.identity_assigned, azurerm_role_assignment.rbac_keyvault_crypto_officer] + count = var.enabled && var.cmk_encryption_enabled ? 1 : 0 name = format("%s-storage-key-vault-key", module.labels.id) expiration_date = var.expiration_date key_vault_id = var.key_vault_id @@ -248,7 +260,7 @@ resource "azurerm_key_vault_key" "kvkey" { "wrapKey", ] dynamic "rotation_policy" { - for_each = var.enable_rotation_policy ? var.rotation_policy : {} + for_each = var.rotation_policy_enabled ? var.rotation_policy : {} content { automatic { time_before_expiry = rotation_policy.value.time_before_expiry @@ -264,7 +276,7 @@ resource "azurerm_key_vault_key" "kvkey" { ## Below resource will create network rules for storage account. ##----------------------------------------------------------------------------- resource "azurerm_storage_account_network_rules" "network-rules" { - for_each = var.enabled == false ? { for rule in var.network_rules : rule.default_action => rule } : {} + for_each = var.enabled ? { for rule in var.network_rules : rule.default_action => rule } : {} storage_account_id = join("", azurerm_storage_account.storage.*.id) default_action = lookup(each.value, "default_action", "Deny") ip_rules = lookup(each.value, "ip_rules", null) @@ -292,7 +304,7 @@ resource "azurerm_advanced_threat_protection" "atp" { ## Below resource will create access policy for user whose object id will be mentioned. ## This resource is not required when key vault has role based authorization(rbac) enabled. ##----------------------------------------------------------------------------- -resource "azurerm_key_vault_access_policy" "example" { +resource "azurerm_key_vault_access_policy" "keyvault-access-policy" { count = var.enabled && var.key_vault_rbac_auth_enabled == false ? length(var.object_id) : 0 key_vault_id = var.key_vault_id tenant_id = data.azurerm_client_config.current.tenant_id @@ -562,7 +574,7 @@ resource "azurerm_private_dns_a_record" "arecord1" { resource "azurerm_monitor_diagnostic_setting" "storage" { count = var.enabled && var.enable_diagnostic ? 1 : 0 name = format("storage-diagnostic-log") - target_resource_id = join("", azurerm_storage_account.storage.*.id) # "${azurerm_storage_account.default_storage[0].id}/blobServices/default/" : "${azurerm_storage_account.storage[0].id}/blobServices/default/" # "${azurerm_storage_account.core.id}/blobServices/default/" + target_resource_id = join("", azurerm_storage_account.storage.*.id) storage_account_id = var.storage_account_id eventhub_name = var.eventhub_name eventhub_authorization_rule_id = var.eventhub_authorization_rule_id @@ -623,12 +635,3 @@ resource "azurerm_monitor_diagnostic_setting" "storage-nic" { ignore_changes = [log_analytics_destination_type] } } - -# resource "azurerm_storage_account_customer_managed_key" "example" { -# depends_on = [ azurerm_storage_account.storage ] -# count = var.enabled && var.cmk_enabled ? 1 : 0 -# storage_account_id = join("", azurerm_storage_account.storage.*.id) -# key_vault_id = var.key_vault_id -# key_name = join("", azurerm_key_vault_key.kvkey.*.name) -# user_assigned_identity_id = join("", azurerm_user_assigned_identity.identity.*.id) -# } diff --git a/variables.tf b/variables.tf index e45096b..ff5cc6b 100644 --- a/variables.tf +++ b/variables.tf @@ -298,7 +298,7 @@ variable "identity_type" { variable "key_vault_id" { type = string - default = null + default = "" } variable "expiration_date" { @@ -349,6 +349,12 @@ variable "allowed_copy_scope" { description = "Restrict copy to and from Storage Accounts within an AAD tenant or with Private Links to the same VNet. Possible values are AAD and PrivateLink." } +variable "admin_objects_ids" { + description = "IDs of the objects that can do all operations on all keys, secrets and certificates." + type = list(string) + default = [] +} + ## Private endpoint variable "virtual_network_id" { type = string @@ -376,7 +382,7 @@ variable "existing_private_dns_zone" { variable "existing_private_dns_zone_resource_group_name" { type = string - default = "" + default = null description = "The name of the existing resource group" } @@ -389,13 +395,13 @@ variable "addon_vent_link" { variable "addon_resource_group_name" { type = string - default = "" + default = null description = "The name of the addon vnet resource group" } variable "addon_virtual_network_id" { type = string - default = "" + default = null description = "The name of the addon vnet link vnet id" } @@ -659,13 +665,13 @@ variable "key_vault_rbac_auth_enabled" { description = "Is key vault has role base access enable or not." } -variable "cmk_enabled" { +variable "cmk_encryption_enabled" { type = bool default = false description = "Whether to create CMK or not" } -variable "enable_rotation_policy" { +variable "rotation_policy_enabled" { type = bool default = false description = "Whether or not to enable rotation policy"