From d1bdf6434f3ac7356e50a55ded790e340d8e6b36 Mon Sep 17 00:00:00 2001 From: lovely Date: Wed, 10 Jan 2024 00:36:12 +0530 Subject: [PATCH 01/12] fix: removed one storage resource and added required arguments in the module --- _example/complete/example.tf | 73 +++++++--- _example/complete/outputs.tf | 4 +- _example/storage_with_cmk/example.tf | 127 ---------------- _example/storage_with_cmk/outputs.tf | 11 -- main.tf | 208 +++++++++++++++------------ outputs.tf | 35 ++--- variables.tf | 137 ++++++++++++++++-- 7 files changed, 314 insertions(+), 281 deletions(-) delete mode 100644 _example/storage_with_cmk/example.tf delete mode 100644 _example/storage_with_cmk/outputs.tf diff --git a/_example/complete/example.tf b/_example/complete/example.tf index fc34833..c08b64d 100644 --- a/_example/complete/example.tf +++ b/_example/complete/example.tf @@ -1,9 +1,12 @@ provider "azurerm" { + storage_use_azuread = true features {} } +data "azurerm_client_config" "current_client_config" {} + locals { - name = "app" + name = "storage1" environment = "test" label_order = ["name", "environment"] } @@ -52,7 +55,6 @@ module "subnet" { #subnet subnet_names = ["subnet1"] subnet_prefixes = ["10.0.1.0/24"] - } ##----------------------------------------------------------------------------- @@ -74,37 +76,76 @@ module "log-analytics" { log_analytics_workspace_location = module.resource_group.resource_group_location } +##----------------------------------------------------------------------------- +## Key Vault module call. +##----------------------------------------------------------------------------- +module "vault" { + source = "clouddrove/key-vault/azure" + version = "1.1.0" + + name = "vault27825" + environment = "test" + label_order = ["name", "environment", ] + resource_group_name = module.resource_group.resource_group_name + location = module.resource_group.resource_group_location + # reader_objects_ids = [data.azurerm_client_config.current_client_config.object_id] + admin_objects_ids = [data.azurerm_client_config.current_client_config.object_id] + virtual_network_id = join("", module.vnet.vnet_id) + subnet_id = module.subnet.default_subnet_id[0] + enable_rbac_authorization = false + network_acls = { + bypass = "AzureServices" + default_action = "Deny" + ip_rules = ["0.0.0.0/0"] + } + #private endpoint + enable_private_endpoint = false + ########Following to be uncommnented only when using DNS Zone from different subscription along with existing DNS zone. + + # diff_sub = true + # alias = "" + # alias_sub = "" + + #########Following to be uncommmented when using DNS zone from different resource group or different subscription. + # existing_private_dns_zone = "" + # existing_private_dns_zone_resource_group_name = "" + + #### enable diagnostic setting + diagnostic_setting_enable = false + log_analytics_workspace_id = module.log-analytics.workspace_id ## when diagnostic_setting_enable enable, add log analytics workspace id +} ##----------------------------------------------------------------------------- ## Storage module call. -## Here default storage will be deployed i.e. storage account without cmk encryption. +## Here default storage will be deployed. ##----------------------------------------------------------------------------- module "storage" { source = "../.." name = local.name environment = local.environment - default_enabled = true + label_order = local.label_order resource_group_name = module.resource_group.resource_group_name location = module.resource_group.resource_group_location - storage_account_name = "stordtyrey36" - public_network_access_enabled = false + storage_account_name = "strge36473" + 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" + ###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" }, - { 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 = "file-test", 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 -} +} \ No newline at end of file diff --git a/_example/complete/outputs.tf b/_example/complete/outputs.tf index f0aa19d..9a57e21 100644 --- a/_example/complete/outputs.tf +++ b/_example/complete/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/storage_with_cmk/example.tf b/_example/storage_with_cmk/example.tf deleted file mode 100644 index 79e7124..0000000 --- a/_example/storage_with_cmk/example.tf +++ /dev/null @@ -1,127 +0,0 @@ -provider "azurerm" { - features {} -} - -locals { - name = "app" - environment = "test" - label_order = ["name", "environment"] -} - -##----------------------------------------------------------------------------- -## Resource Group module call -## Resource group in which all resources will be deployed. -##----------------------------------------------------------------------------- -module "resource_group" { - source = "clouddrove/resource-group/azure" - version = "1.0.2" - label_order = local.label_order - name = local.name - environment = local.environment - location = "East US 2" -} - -##----------------------------------------------------------------------------- -## Virtual Network module call. -##----------------------------------------------------------------------------- -module "vnet" { - source = "clouddrove/vnet/azure" - version = "1.0.3" - name = local.name - environment = local.environment - label_order = local.label_order - resource_group_name = module.resource_group.resource_group_name - location = module.resource_group.resource_group_location - address_space = "10.0.0.0/16" -} - -##----------------------------------------------------------------------------- -## Subnet module call. -## Subnet in which storage account and its private endpoint will be created. -##----------------------------------------------------------------------------- -module "subnet" { - source = "clouddrove/subnet/azure" - version = "1.0.2" - name = local.name - environment = local.environment - label_order = local.label_order - resource_group_name = module.resource_group.resource_group_name - location = module.resource_group.resource_group_location - virtual_network_name = join("", module.vnet.vnet_name) - - #subnet - subnet_names = ["subnet1"] - subnet_prefixes = ["10.0.1.0/24"] - -} - -##----------------------------------------------------------------------------- -## Key Vault module call. -## Key Vault in encryption key will be stored. -##----------------------------------------------------------------------------- -module "vault" { - depends_on = [module.resource_group, module.vnet] - source = "clouddrove/key-vault/azure" - version = "1.0.5" - name = "appdvgcyus23654" - environment = local.environment - resource_group_name = module.resource_group.resource_group_name - location = module.resource_group.resource_group_location - virtual_network_id = module.vnet.vnet_id[0] - subnet_id = module.subnet.default_subnet_id[0] - ##RBAC - enable_rbac_authorization = true - principal_id = ["71d1aXXXXXXXXXXXXXXXXX166d7c97", ] - role_definition_name = ["Key Vault Administrator", ] - #### enable diagnostic setting - diagnostic_setting_enable = true - log_analytics_workspace_id = module.log-analytics.workspace_id ## when diagnostic_setting_enable = true, need to add log analytics workspace id -} - -##----------------------------------------------------------------------------- -## Log Analytics module call. -## Log analytics workspace in which storage diagnostic logs will be sent. -##----------------------------------------------------------------------------- -module "log-analytics" { - source = "clouddrove/log-analytics/azure" - version = "1.0.1" - name = local.name - environment = local.environment - label_order = ["name", "environment"] - create_log_analytics_workspace = true - log_analytics_workspace_sku = "PerGB2018" - daily_quota_gb = "-1" - internet_ingestion_enabled = true - internet_query_enabled = true - resource_group_name = module.resource_group.resource_group_name - log_analytics_workspace_location = module.resource_group.resource_group_location -} - - -##----------------------------------------------------------------------------- -## Storage module call. -## Here cmk storage will be deployed i.e. storage account with cmk encryption. -##----------------------------------------------------------------------------- -module "storage" { - source = "../.." - name = local.name - environment = local.environment - label_order = local.label_order - resource_group_name = module.resource_group.resource_group_name - location = module.resource_group.resource_group_location - storage_account_name = "storagkqp0896" - account_kind = "BlockBlobStorage" - account_tier = "Premium" - identity_type = "UserAssigned" - object_id = ["71dXXXXXXXXXXXXXXXXXXXX11c97", ] - account_replication_type = "ZRS" - ###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" }, - ] - 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/storage_with_cmk/outputs.tf b/_example/storage_with_cmk/outputs.tf deleted file mode 100644 index f5c37cf..0000000 --- a/_example/storage_with_cmk/outputs.tf +++ /dev/null @@ -1,11 +0,0 @@ -output "storage_account_id" { - value = module.storage.cmk_storage_account_id - description = "The ID of the storage account." -} - -output "storage_account_name" { - value = module.storage.cmk_storage_account_name - description = "The name of the storage account." -} - - diff --git a/main.tf b/main.tf index 3fd87a1..5368005 100644 --- a/main.tf +++ b/main.tf @@ -18,7 +18,7 @@ module "labels" { ## To create storage account with cmk(customer managed key) encryption set 'var.default_enabled = false'. ##----------------------------------------------------------------------------- resource "azurerm_storage_account" "storage" { - count = var.enabled && var.default_enabled == false ? 1 : 0 + count = var.enabled ? 1 : 0 depends_on = [azurerm_role_assignment.identity_assigned] name = var.storage_account_name resource_group_name = var.resource_group_name @@ -37,7 +37,12 @@ resource "azurerm_storage_account" "storage" { default_to_oauth_authentication = var.default_to_oauth_authentication cross_tenant_replication_enabled = var.cross_tenant_replication_enabled allow_nested_items_to_be_public = var.allow_nested_items_to_be_public + large_file_share_enabled = var.large_file_share_enabled + edge_zone = var.edge_zone + nfsv3_enabled = var.nfsv3_enabled tags = module.labels.tags + table_encryption_key_type = var.table_encryption_key_type + queue_encryption_key_type = var.queue_encryption_key_type blob_properties { delete_retention_policy { days = var.soft_delete_retention @@ -45,56 +50,73 @@ resource "azurerm_storage_account" "storage" { versioning_enabled = var.versioning_enabled last_access_time_enabled = var.last_access_time_enabled } - dynamic "identity" { - for_each = var.identity_type != null ? [1] : [] + dynamic "custom_domain" { + for_each = var.custom_domain_name != null ? [1] : [] content { - type = var.identity_type - identity_ids = var.identity_type == "UserAssigned" ? [join("", azurerm_user_assigned_identity.identity.*.id)] : null + name = var.custom_domain_name + use_subdomain = var.use_subdomain } } - dynamic "customer_managed_key" { - for_each = var.key_vault_id != null ? [1] : [] + dynamic "static_website" { + for_each = var.static_website_config != null ? [1] : [] content { - key_vault_key_id = var.key_vault_id != null ? join("", azurerm_key_vault_key.kvkey.*.id) : null - user_assigned_identity_id = var.key_vault_id != null ? join("", azurerm_user_assigned_identity.identity.*.id) : null + index_document = var.static_website_config.index_document + error_404_document = var.static_website_config.error_404_document } } -} + dynamic "routing" { + for_each = var.enable_routing != null ? [1] : [] + content { + publish_internet_endpoints = var.publish_internet_endpoints + publish_microsoft_endpoints = var.publish_microsoft_endpoints + choice = var.choice + } + } + dynamic "share_properties" { + for_each = var.file_share_cors_rules != null && var.file_share_retention_policy_in_days != null && var.file_share_properties_smb != null ? [1] : [] + content { + dynamic "cors_rule" { + for_each = var.file_share_cors_rules != null ? [1] : [] + content { + allowed_headers = var.file_share_cors_rules.allowed_headers + allowed_methods = var.file_share_cors_rules.allowed_methods + allowed_origins = var.file_share_cors_rules.allowed_origins + exposed_headers = var.file_share_cors_rules.exposed_headers + max_age_in_seconds = var.file_share_cors_rules.max_age_in_seconds + } + } -##----------------------------------------------------------------------------- -## Below resource will create Storage Account resource without custormer managed key encryption and its components. -## To create storage account without cmk(customer managed key) encryption set 'var.default_enabled = true'. -##----------------------------------------------------------------------------- -resource "azurerm_storage_account" "default_storage" { - count = var.enabled && var.default_enabled == true ? 1 : 0 - name = var.storage_account_name - resource_group_name = var.resource_group_name - location = var.location - account_kind = var.account_kind - account_tier = var.account_tier - access_tier = var.access_tier - account_replication_type = var.account_replication_type - enable_https_traffic_only = var.enable_https_traffic_only - min_tls_version = var.min_tls_version - is_hns_enabled = var.is_hns_enabled - sftp_enabled = var.sftp_enabled - infrastructure_encryption_enabled = var.infrastructure_encryption_enabled - public_network_access_enabled = var.public_network_access_enabled - default_to_oauth_authentication = var.default_to_oauth_authentication - cross_tenant_replication_enabled = var.cross_tenant_replication_enabled - allow_nested_items_to_be_public = var.allow_nested_items_to_be_public - tags = module.labels.tags - blob_properties { - delete_retention_policy { - days = var.soft_delete_retention + dynamic "retention_policy" { + for_each = var.file_share_retention_policy_in_days != null ? [1] : [] + content { + days = var.file_share_retention_policy_in_days + } + } + + dynamic "smb" { + for_each = var.file_share_properties_smb != null ? [1] : [] + content { + authentication_types = var.file_share_properties_smb.authentication_types + channel_encryption_type = var.file_share_properties_smb.channel_encryption_type + kerberos_ticket_encryption_type = var.file_share_properties_smb.kerberos_ticket_encryption_type + versions = var.file_share_properties_smb.versions + multichannel_enabled = var.file_share_properties_smb.multichannel_enabled + } + } } - versioning_enabled = var.versioning_enabled - last_access_time_enabled = var.last_access_time_enabled } dynamic "identity" { for_each = var.identity_type != null ? [1] : [] content { - type = var.identity_type + 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] : [] + content { + key_vault_key_id = var.key_vault_id != null ? join("", azurerm_key_vault_key.kvkey.*.id) : null + user_assigned_identity_id = var.key_vault_id != null ? join("", azurerm_user_assigned_identity.identity.*.id) : null } } } @@ -104,7 +126,7 @@ resource "azurerm_storage_account" "default_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.default_enabled == false ? 1 : 0 + count = var.enabled ? 1 : 0 location = var.location name = format("midd-storage-%s", module.labels.id) resource_group_name = var.resource_group_name @@ -115,7 +137,7 @@ resource "azurerm_user_assigned_identity" "identity" { ##----------------------------------------------------------------------------- resource "azurerm_role_assignment" "identity_assigned" { depends_on = [azurerm_user_assigned_identity.identity] - count = var.enabled && var.default_enabled == false && var.key_vault_rbac_auth_enabled ? 1 : 0 + count = var.enabled && var.key_vault_rbac_auth_enabled ? 1 : 0 principal_id = join("", azurerm_user_assigned_identity.identity.*.principal_id) scope = var.key_vault_id role_definition_name = "Key Vault Crypto Service Encryption User" @@ -126,8 +148,8 @@ resource "azurerm_role_assignment" "identity_assigned" { ##----------------------------------------------------------------------------- resource "azurerm_key_vault_key" "kvkey" { depends_on = [azurerm_role_assignment.identity_assigned] - count = var.enabled && var.default_enabled == false ? 1 : 0 - name = format("storage-%s-cmk-key", module.labels.id) + count = var.enabled ? 1 : 0 + name = format("storage-%s-cmk-testing", module.labels.id) expiration_date = var.expiration_date key_vault_id = var.key_vault_id key_type = "RSA" @@ -140,13 +162,17 @@ resource "azurerm_key_vault_key" "kvkey" { "verify", "wrapKey", ] - rotation_policy { - automatic { - time_before_expiry = "P30D" - } - expire_after = "P90D" - notify_before_expiry = "P29D" + dynamic "rotation_policy" { + for_each = var.rotation_policy + content { + automatic { + time_before_expiry = rotation_policy.value.time_before_expiry + } + + expire_after = rotation_policy.value.expire_after + notify_before_expiry = rotation_policy.value.notify_before_expiry + } } } @@ -154,8 +180,8 @@ 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 ? { for rule in var.network_rules : rule.default_action => rule } : {} - storage_account_id = var.default_enabled == false ? join("", azurerm_storage_account.storage.*.id) : join("", azurerm_storage_account.default_storage.*.id) + for_each = var.enabled == false ? { 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) virtual_network_subnet_ids = lookup(each.value, "virtual_network_subnet_ids", null) @@ -167,7 +193,7 @@ resource "azurerm_storage_account_network_rules" "network-rules" { ##----------------------------------------------------------------------------- resource "azurerm_advanced_threat_protection" "atp" { count = var.enabled ? 1 : 0 - target_resource_id = var.default_enabled == false ? join("", azurerm_storage_account.storage.*.id) : join("", azurerm_storage_account.default_storage.*.id) + target_resource_id = join("", azurerm_storage_account.storage.*.id) enabled = var.enable_advanced_threat_protection } @@ -176,10 +202,10 @@ resource "azurerm_advanced_threat_protection" "atp" { ## This resource is not required when key vault has role based authorization(rbac) enabled. ##----------------------------------------------------------------------------- resource "azurerm_key_vault_access_policy" "example" { - count = var.enabled && var.default_enabled == false && var.key_vault_rbac_auth_enabled == false ? length(var.object_id) : 0 + 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 - object_id = element(var.object_id, count.index) + object_id = join("", azurerm_user_assigned_identity.identity.*.principal_id) key_permissions = [ "Create", @@ -198,6 +224,17 @@ resource "azurerm_key_vault_access_policy" "example" { ] secret_permissions = [ "Get", + "List", + "Set", + "Delete", + "Recover", + "Backup", + "Restore", + "Purge", + ] + storage_permissions = [ + "Get", + "List", ] } @@ -207,7 +244,7 @@ resource "azurerm_key_vault_access_policy" "example" { resource "azurerm_storage_container" "container" { count = length(var.containers_list) name = var.containers_list[count.index].name - storage_account_name = var.key_vault_id != null ? join("", azurerm_storage_account.storage.*.name) : join("", azurerm_storage_account.default_storage.*.name) + storage_account_name = azurerm_storage_account.storage[0].name container_access_type = var.containers_list[count.index].access_type } @@ -217,7 +254,7 @@ resource "azurerm_storage_container" "container" { resource "azurerm_storage_share" "fileshare" { count = length(var.file_shares) name = var.file_shares[count.index].name - storage_account_name = var.key_vault_id != null ? join("", azurerm_storage_account.storage.*.name) : join("", azurerm_storage_account.default_storage.*.name) + storage_account_name = azurerm_storage_account.storage[0].name quota = var.file_shares[count.index].quota } @@ -227,7 +264,7 @@ resource "azurerm_storage_share" "fileshare" { resource "azurerm_storage_table" "tables" { count = length(var.tables) name = var.tables[count.index] - storage_account_name = var.key_vault_id != null ? join("", azurerm_storage_account.storage.*.name) : join("", azurerm_storage_account.default_storage.*.name) + storage_account_name = join("", azurerm_storage_account.storage.*.name) } ##----------------------------------------------------------------------------- @@ -236,7 +273,7 @@ resource "azurerm_storage_table" "tables" { resource "azurerm_storage_queue" "queues" { count = length(var.queues) name = var.queues[count.index] - storage_account_name = var.key_vault_id != null ? join("", azurerm_storage_account.storage.*.name) : join("", azurerm_storage_account.default_storage.*.name) + storage_account_name = join("", azurerm_storage_account.storage.*.name) } ##----------------------------------------------------------------------------- @@ -244,7 +281,7 @@ resource "azurerm_storage_queue" "queues" { ##----------------------------------------------------------------------------- resource "azurerm_storage_management_policy" "lifecycle_management" { count = var.enabled && var.management_policy_enable ? length(var.management_policy) : 0 - storage_account_id = var.default_enabled == false ? join("", azurerm_storage_account.storage.*.id) : join("", azurerm_storage_account.default_storage.*.id) + storage_account_id = join("", azurerm_storage_account.storage.*.id) dynamic "rule" { for_each = var.management_policy @@ -293,7 +330,7 @@ resource "azurerm_private_endpoint" "pep" { private_service_connection { name = format("%s-%s-psc", module.labels.id, var.storage_account_name) is_manual_connection = false - private_connection_resource_id = var.default_enabled == false ? join("", azurerm_storage_account.storage.*.id) : join("", azurerm_storage_account.default_storage.*.id) + private_connection_resource_id = join("", azurerm_storage_account.storage.*.id) subresource_names = ["blob"] } @@ -319,23 +356,12 @@ locals { ## Will work when storage account with cmk encryption. ##----------------------------------------------------------------------------- data "azurerm_private_endpoint_connection" "private-ip-0" { - count = var.enabled && var.enable_private_endpoint && var.default_enabled == false ? 1 : 0 + count = var.enabled && var.enable_private_endpoint ? 1 : 0 name = join("", azurerm_private_endpoint.pep.*.name) resource_group_name = local.resource_group_name depends_on = [azurerm_storage_account.storage] } -##----------------------------------------------------------------------------- -## Data block to retreive private ip of private endpoint. -## Will work when storage account without cmk encryption. -##----------------------------------------------------------------------------- -data "azurerm_private_endpoint_connection" "private-ip-1" { - count = var.enabled && var.enable_private_endpoint && var.default_enabled == true ? 1 : 0 - name = join("", azurerm_private_endpoint.pep.*.name) - resource_group_name = local.resource_group_name - depends_on = [azurerm_storage_account.default_storage] -} - ##----------------------------------------------------------------------------- ## Below resource will create private dns zone in your azure subscription. ## Will be created only when there is no existing private dns zone and private endpoint is enabled. @@ -407,11 +433,11 @@ resource "azurerm_private_dns_zone_virtual_network_link" "addon_vent_link" { ##----------------------------------------------------------------------------- resource "azurerm_private_dns_a_record" "arecord" { count = var.enabled && var.enable_private_endpoint && var.diff_sub == false ? 1 : 0 - name = var.key_vault_id != null ? join("", azurerm_storage_account.storage.*.name) : join("", azurerm_storage_account.default_storage.*.name) + name = var.key_vault_id != null ? join("", azurerm_storage_account.storage.*.name) : null zone_name = local.private_dns_zone_name resource_group_name = local.valid_rg_name ttl = 3600 - records = var.default_enabled == false ? [data.azurerm_private_endpoint_connection.private-ip-0.0.private_service_connection.0.private_ip_address] : [data.azurerm_private_endpoint_connection.private-ip-1.0.private_service_connection.0.private_ip_address] + records = [data.azurerm_private_endpoint_connection.private-ip-0.0.private_service_connection.0.private_ip_address] tags = module.labels.tags lifecycle { ignore_changes = [ @@ -427,11 +453,11 @@ resource "azurerm_private_dns_a_record" "arecord" { resource "azurerm_private_dns_a_record" "arecord1" { count = var.enabled && var.enable_private_endpoint && var.diff_sub == true ? 1 : 0 provider = azurerm.peer - name = var.key_vault_id != null ? join("", azurerm_storage_account.storage.*.name) : join("", azurerm_storage_account.default_storage.*.name) + name = var.key_vault_id != null ? join("", azurerm_storage_account.storage.*.name) : null zone_name = local.private_dns_zone_name resource_group_name = local.valid_rg_name ttl = 3600 - records = var.default_enabled == false ? [data.azurerm_private_endpoint_connection.private-ip-0.0.private_service_connection.0.private_ip_address] : [data.azurerm_private_endpoint_connection.private-ip-1.0.private_service_connection.0.private_ip_address] + records = [data.azurerm_private_endpoint_connection.private-ip-0.0.private_service_connection.0.private_ip_address] tags = module.labels.tags lifecycle { ignore_changes = [ @@ -446,7 +472,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 = var.default_enabled == true ? azurerm_storage_account.default_storage[0].id : azurerm_storage_account.storage[0].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) # "${azurerm_storage_account.default_storage[0].id}/blobServices/default/" : "${azurerm_storage_account.storage[0].id}/blobServices/default/" # "${azurerm_storage_account.core.id}/blobServices/default/" storage_account_id = var.storage_account_id eventhub_name = var.eventhub_name eventhub_authorization_rule_id = var.eventhub_authorization_rule_id @@ -457,20 +483,17 @@ resource "azurerm_monitor_diagnostic_setting" "storage" { content { category = metric.value enabled = var.metrics_enabled[count.index] - retention_policy { - days = var.days - enabled = var.retention_policy_enabled - } } } } resource "azurerm_monitor_diagnostic_setting" "datastorage" { + depends_on = [azurerm_storage_account.storage] count = var.enabled && var.enable_diagnostic ? length(var.datastorages) : 0 name = format("%s-diagnostic-log", var.datastorages[count.index]) - target_resource_id = var.default_enabled == true ? "${azurerm_storage_account.default_storage[0].id}/${var.datastorages[count.index]}Services/default" : "${azurerm_storage_account.storage[0].id}/${var.datastorages[count.index]}Services/default" # "${azurerm_storage_account.core.id}/blobServices/default/" storage_account_id = var.storage_account_id + target_resource_id = "${azurerm_storage_account.storage[0].id}/${var.datastorages[count.index]}Services/default" eventhub_name = var.eventhub_name eventhub_authorization_rule_id = var.eventhub_authorization_rule_id log_analytics_workspace_id = var.log_analytics_workspace_id @@ -479,10 +502,6 @@ resource "azurerm_monitor_diagnostic_setting" "datastorage" { for_each = var.logs content { category = enabled_log.value - retention_policy { - days = var.days - enabled = var.retention_policy_enabled - } } } @@ -491,14 +510,11 @@ resource "azurerm_monitor_diagnostic_setting" "datastorage" { content { category = metric.value enabled = true - retention_policy { - days = var.days - enabled = var.retention_policy_enabled - } } } } + resource "azurerm_monitor_diagnostic_setting" "storage-nic" { depends_on = [azurerm_private_endpoint.pep] count = var.enabled && var.enable_diagnostic && var.enable_private_endpoint ? 1 : 0 @@ -512,12 +528,16 @@ resource "azurerm_monitor_diagnostic_setting" "storage-nic" { metric { category = "AllMetrics" enabled = var.Metric_enable - retention_policy { - enabled = var.retention_policy_enabled - days = var.diagnostic_log_days - } } lifecycle { ignore_changes = [log_analytics_destination_type] } } + +resource "azurerm_storage_account_customer_managed_key" "example" { + 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/outputs.tf b/outputs.tf index a153bd0..96b8b6b 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,50 +1,41 @@ -output "default_storage_account_id" { - value = join("", azurerm_storage_account.default_storage.*.id) - description = "The ID of the storage account." -} - -output "default_storage_account_name" { - value = join("", azurerm_storage_account.default_storage.*.name) - description = "The name of the storage account." -} -output "cmk_storage_account_id" { +output "storage_account_id" { value = join("", azurerm_storage_account.storage.*.id) description = "The ID of the storage account." } -output "cmk_storage_account_name" { +output "storage_account_name" { value = join("", azurerm_storage_account.storage.*.name) description = "The name of the storage account." } -output "default_storage_account_primary_location" { - value = join("", azurerm_storage_account.default_storage.*.primary_location) +output "storage_account_primary_location" { + value = join("", azurerm_storage_account.storage.*.primary_location) description = "The primary location of the storage account" } -output "default_storage_account_primary_web_endpoint" { - value = join("", azurerm_storage_account.default_storage.*.primary_web_endpoint) +output "storage_account_primary_web_endpoint" { + value = join("", azurerm_storage_account.storage.*.primary_web_endpoint) description = "The endpoint URL for web storage in the primary location." } -output "default_storage_account_primary_blob_endpoint" { - value = join("", azurerm_storage_account.default_storage.*.primary_blob_endpoint) +output "storage_account_primary_blob_endpoint" { + value = join("", azurerm_storage_account.storage.*.primary_blob_endpoint) description = "The endpoint URL for blob storage in the primary location." } -output "default_storage_account_primary_web_host" { - value = join("", azurerm_storage_account.default_storage.*.primary_web_host) +output "storage_account_primary_web_host" { + value = join("", azurerm_storage_account.storage.*.primary_web_host) description = "The hostname with port if applicable for web storage in the primary location." } -output "default_storage_primary_connection_string" { +output "storage_primary_connection_string" { value = join("", azurerm_storage_account.storage.*.primary_connection_string) sensitive = true description = "The primary connection string for the storage account" } -output "default_storage_primary_access_key" { - value = join("", azurerm_storage_account.default_storage.*.primary_access_key) +output "storage_primary_access_key" { + value = join("", azurerm_storage_account.storage.*.primary_access_key) sensitive = true description = "The primary access key for the storage account" } diff --git a/variables.tf b/variables.tf index e1867c6..0f575c7 100644 --- a/variables.tf +++ b/variables.tf @@ -106,6 +106,36 @@ variable "network_rules" { description = "List of objects that represent the configuration of each network rules." } +variable "table_encryption_key_type" { + default = "Account" + description = "The encryption type of the table service. Possible values are 'Service' and 'Account'." +} + +variable "queue_encryption_key_type" { + default = "Account" + description = "The encryption type of the queue service. Possible values are 'Service' and 'Account'." +} + +variable "large_file_share_enabled" { + type = bool + default = false + description = "Is Large File Share Enabled?" +} + +variable "nfsv3_enabled" { + type = bool + default = false + description = "Is NFSv3 protocol enabled? Changing this forces a new resource to be created." +} + +variable "edge_zone" { + type = string + default = null + description = "Specifies the Edge Zone within the Azure Region where this Storage Account should exist." +} + + + #network_rules = [ # { # default_action = "Deny" @@ -168,11 +198,90 @@ variable "management_policy" { }] } +# Static Website +variable "static_website_config" { + type = object({ + index_document = optional(string) + error_404_document = optional(string) + }) + default = null + description = "Static website configuration. Can only be set when the `account_kind` is set to `StorageV2` or `BlockBlobStorage`." +} + +# Routing +variable "enable_routing" { + type = bool + default = false + description = "Whether or not to enable routing" +} + +variable "publish_internet_endpoints" { + type = bool + default = false + description = "Should internet routing storage endpoints be published?" +} + +variable "publish_microsoft_endpoints" { + type = bool + default = false + description = "Should Microsoft routing storage endpoints be published? " +} + +variable "choice" { + type = string + default = "MicrosoftRouting" + description = "Specifies the kind of network routing opted by the user. Possible values are InternetRouting and MicrosoftRouting. Defaults to MicrosoftRouting." +} + +# Share Properties +variable "file_share_cors_rules" { + type = object({ + allowed_headers = list(string) + allowed_methods = list(string) + allowed_origins = list(string) + exposed_headers = list(string) + max_age_in_seconds = number + }) + default = null + description = "Storage Account file shares CORS rule. Please refer to the [documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#cors_rule) for more information." +} + +variable "file_share_retention_policy_in_days" { + type = number + default = null + description = "Storage Account file shares retention policy in days. Enabling this may require additional directory permissions." +} + +variable "file_share_properties_smb" { + type = object({ + versions = optional(list(string), null) + authentication_types = optional(list(string), null) + kerberos_ticket_encryption_type = optional(list(string), null) + channel_encryption_type = optional(list(string), null) + multichannel_enabled = optional(bool, null) + }) + default = null + description = "Storage Account file shares smb properties." +} + +# Custom Domain +variable "custom_domain_name" { + type = string + default = null + description = "The Custom Domain Name to use for the Storage Account, which will be validated by Azure." +} + +variable "use_subdomain" { + type = bool + default = false + description = "Should the Custom Domain Name be validated by using indirect CNAME validation?" +} + # Identity variable "identity_type" { description = "Specifies the type of Managed Service Identity that should be configured on this Storage Account. Possible values are `SystemAssigned`, `UserAssigned`, `SystemAssigned, UserAssigned` (to enable both)." type = string - default = "SystemAssigned" + default = "UserAssigned" } variable "key_vault_id" { @@ -238,7 +347,7 @@ variable "subnet_id" { variable "enable_private_endpoint" { type = bool - default = true + default = false description = "enable or disable private endpoint to storage account" } @@ -275,7 +384,7 @@ variable "addon_virtual_network_id" { variable "versioning_enabled" { type = bool - default = true + default = false description = "Is versioning enabled? Default to false." } @@ -289,7 +398,7 @@ variable "last_access_time_enabled" { variable "enable_diagnostic" { type = bool - default = true + default = false description = "Set to false to prevent the module from creating the diagnosys setting for the NSG Resource.." } @@ -381,11 +490,6 @@ variable "diagnostic_log_days" { description = " The number of days for which this Retention Policy should apply." } -variable "default_enabled" { - type = bool - default = false -} - variable "multi_sub_vnet_link" { type = bool default = false @@ -396,4 +500,19 @@ variable "key_vault_rbac_auth_enabled" { type = bool default = false description = "Is key vault has role base access enable or not." +} + +variable "cmk_enabled" { + type = bool + default = false + description = "Whether to create CMK or not" +} + +variable "rotation_policy" { + type = map(object({ + time_before_expiry = string + expire_after = string + notify_before_expiry = string + })) + default = {} } \ No newline at end of file From fae3fb8b344450ac5845c7d44901fd597487176b Mon Sep 17 00:00:00 2001 From: lovely Date: Wed, 10 Jan 2024 22:48:14 +0530 Subject: [PATCH 02/12] feat: added required arguments --- _example/complete/example.tf | 6 +- main.tf | 136 +++++++++++++++---- variables.tf | 245 +++++++++++++++++++++++++++++------ 3 files changed, 320 insertions(+), 67 deletions(-) diff --git a/_example/complete/example.tf b/_example/complete/example.tf index c08b64d..84c81ab 100644 --- a/_example/complete/example.tf +++ b/_example/complete/example.tf @@ -6,7 +6,7 @@ provider "azurerm" { data "azurerm_client_config" "current_client_config" {} locals { - name = "storage1" + name = "storage" environment = "test" label_order = ["name", "environment"] } @@ -83,7 +83,7 @@ module "vault" { source = "clouddrove/key-vault/azure" version = "1.1.0" - name = "vault27825" + name = "vault9825" environment = "test" label_order = ["name", "environment", ] resource_group_name = module.resource_group.resource_group_name @@ -126,7 +126,7 @@ 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 = "strge36473" + storage_account_name = "strge56563" public_network_access_enabled = true account_kind = "StorageV2" account_tier = "Standard" diff --git a/main.tf b/main.tf index 5368005..de26192 100644 --- a/main.tf +++ b/main.tf @@ -40,15 +40,54 @@ resource "azurerm_storage_account" "storage" { large_file_share_enabled = var.large_file_share_enabled edge_zone = var.edge_zone nfsv3_enabled = var.nfsv3_enabled - tags = module.labels.tags table_encryption_key_type = var.table_encryption_key_type queue_encryption_key_type = var.queue_encryption_key_type - blob_properties { - delete_retention_policy { - days = var.soft_delete_retention + allowed_copy_scope = var.allowed_copy_scope + tags = module.labels.tags + dynamic "blob_properties" { + for_each = ( + var.account_kind != "FileStorage" && (var.storage_blob_data_protection != null || var.storage_blob_cors_rule != null) ? [1] : [] + ) + content { + change_feed_enabled = var.nfsv3_enabled || var.sftp_enabled ? false : var.storage_blob_data_protection.change_feed_enabled + versioning_enabled = var.nfsv3_enabled || var.sftp_enabled ? false : var.storage_blob_data_protection.versioning_enabled + last_access_time_enabled = var.nfsv3_enabled || var.sftp_enabled ? false : var.storage_blob_data_protection.last_access_time_enabled + dynamic "cors_rule" { + for_each = var.storage_blob_cors_rule != null ? [1] : [] + content { + allowed_headers = var.storage_blob_cors_rule.allowed_headers + allowed_methods = var.storage_blob_cors_rule.allowed_methods + allowed_origins = var.storage_blob_cors_rule.allowed_origins + exposed_headers = var.storage_blob_cors_rule.exposed_headers + max_age_in_seconds = var.storage_blob_cors_rule.max_age_in_seconds + } + } + dynamic "delete_retention_policy" { + for_each = var.storage_blob_data_protection.delete_retention_policy_in_days > 0 ? [1] : [] + content { + days = var.storage_blob_data_protection.delete_retention_policy_in_days + } + } + dynamic "container_delete_retention_policy" { + for_each = var.storage_blob_data_protection.container_delete_retention_policy_in_days > 0 ? [1] : [] + content { + days = var.storage_blob_data_protection.container_delete_retention_policy_in_days + } + } + dynamic "restore_policy" { + for_each = var.restore_policy ? [1] : [] + content { + days = var.storage_blob_data_protection.container_delete_retention_policy_in_days - 1 + } + } + } + } + dynamic "sas_policy" { + for_each = var.enable_sas_policy ? var.sas_policy_settings : [] + content { + expiration_period = sas_policy.value.expiration_period + expiration_action = sas_policy.value.expiration_action } - versioning_enabled = var.versioning_enabled - last_access_time_enabled = var.last_access_time_enabled } dynamic "custom_domain" { for_each = var.custom_domain_name != null ? [1] : [] @@ -64,35 +103,81 @@ resource "azurerm_storage_account" "storage" { error_404_document = var.static_website_config.error_404_document } } + dynamic "azure_files_authentication" { + for_each = var.file_share_authentication != null ? [1] : [] + content { + directory_type = var.file_share_authentication.directory_type + dynamic "active_directory" { + for_each = var.file_share_authentication.directory_type == "AD" ? [var.file_share_authentication.active_directory] : [] + iterator = ad + content { + storage_sid = ad.value.storage_sid + domain_name = ad.value.domain_name + domain_sid = ad.value.domain_sid + domain_guid = ad.value.domain_guid + forest_name = ad.value.forest_name + netbios_domain_name = ad.value.netbios_domain_name + } + } + } + } dynamic "routing" { - for_each = var.enable_routing != null ? [1] : [] + for_each = var.enable_routing ? var.routing : [] content { - publish_internet_endpoints = var.publish_internet_endpoints - publish_microsoft_endpoints = var.publish_microsoft_endpoints - choice = var.choice + publish_internet_endpoints = routing.value.publish_internet_endpoints + publish_microsoft_endpoints = routing.value.publish_microsoft_endpoints + choice = routing.value.choice + } + } + dynamic "queue_properties" { + for_each = var.queue_properties_logging != null && contains(["Storage", "StorageV2"], var.account_kind) ? [1] : [] + content { + logging { + delete = var.queue_properties_logging.delete + read = var.queue_properties_logging.read + write = var.queue_properties_logging.write + version = var.queue_properties_logging.version + retention_policy_days = var.queue_properties_logging.retention_policy_days + } + dynamic "hour_metrics" { + for_each = var.enable_hour_metrics ? var.hour_metrics : {} + content { + enabled = hour_metrics.value.enabled + version = hour_metrics.value.version + include_apis = hour_metrics.value.include_apis + retention_policy_days = hour_metrics.value.retention_policy_days + } + } + dynamic "minute_metrics" { + for_each = var.enable_minute_metrics ? toset(var.minute_metrics) : [] + content { + enabled = minute_metrics.value.enabled + version = minute_metrics.value.version + include_apis = minute_metrics.value.include_apis + retention_policy_days = minute_metrics.value.retention_policy_days + } + } } } dynamic "share_properties" { for_each = var.file_share_cors_rules != null && var.file_share_retention_policy_in_days != null && var.file_share_properties_smb != null ? [1] : [] content { dynamic "cors_rule" { - for_each = var.file_share_cors_rules != null ? [1] : [] + for_each = var.enable_file_share_cors_rules ? var.file_share_cors_rules : [] content { - allowed_headers = var.file_share_cors_rules.allowed_headers - allowed_methods = var.file_share_cors_rules.allowed_methods - allowed_origins = var.file_share_cors_rules.allowed_origins - exposed_headers = var.file_share_cors_rules.exposed_headers - max_age_in_seconds = var.file_share_cors_rules.max_age_in_seconds + allowed_headers = file_share_cors_rules.value.allowed_headers + allowed_methods = file_share_cors_rules.value.allowed_methods + allowed_origins = file_share_cors_rules.value.allowed_origins + exposed_headers = file_share_cors_rules.value.exposed_headers + max_age_in_seconds = file_share_cors_rules.value.max_age_in_seconds } } - dynamic "retention_policy" { for_each = var.file_share_retention_policy_in_days != null ? [1] : [] content { days = var.file_share_retention_policy_in_days } } - dynamic "smb" { for_each = var.file_share_properties_smb != null ? [1] : [] content { @@ -144,11 +229,11 @@ resource "azurerm_role_assignment" "identity_assigned" { } ##----------------------------------------------------------------------------- -## Below resource will will create key vault key that will be used for encryption. +## 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] - count = var.enabled ? 1 : 0 + count = var.enabled && var.cmk_enabled ? 1 : 0 name = format("storage-%s-cmk-testing", module.labels.id) expiration_date = var.expiration_date key_vault_id = var.key_vault_id @@ -162,9 +247,8 @@ resource "azurerm_key_vault_key" "kvkey" { "verify", "wrapKey", ] - dynamic "rotation_policy" { - for_each = var.rotation_policy + for_each = var.enable_rotation_policy ? var.rotation_policy : {} content { automatic { time_before_expiry = rotation_policy.value.time_before_expiry @@ -186,6 +270,13 @@ resource "azurerm_storage_account_network_rules" "network-rules" { ip_rules = lookup(each.value, "ip_rules", null) virtual_network_subnet_ids = lookup(each.value, "virtual_network_subnet_ids", null) bypass = lookup(each.value, "bypass", null) + dynamic "private_link_access" { + for_each = var.enable_private_link_access ? var.private_link_access : [] + content { + endpoint_resource_id = private_link_access.value.endpoint_resource_id + endpoint_tenant_id = coalesce(private_link_access.value.endpoint_tenant_id, data.azuread_tenant.current.tenant_id) + } + } } ##----------------------------------------------------------------------------- @@ -333,7 +424,6 @@ resource "azurerm_private_endpoint" "pep" { private_connection_resource_id = join("", azurerm_storage_account.storage.*.id) subresource_names = ["blob"] } - lifecycle { ignore_changes = [ tags, diff --git a/variables.tf b/variables.tf index 0f575c7..b692f8d 100644 --- a/variables.tf +++ b/variables.tf @@ -134,16 +134,6 @@ variable "edge_zone" { description = "Specifies the Edge Zone within the Azure Region where this Storage Account should exist." } - - -#network_rules = [ -# { -# default_action = "Deny" -# ip_rules = ["0.0.0.0/0"] -# bypass = ["AzureServices"] -# } -#] - variable "is_hns_enabled" { description = "Is Hierarchical Namespace enabled? This can be used with Azure Data Lake Storage Gen 2. Changing this forces a new resource to be created." type = bool @@ -183,10 +173,10 @@ variable "queues" { variable "management_policy" { description = "Configure Azure Storage firewalls and virtual networks" type = list(object({ - prefix_match = set(string), - tier_to_cool_after_days = number, - tier_to_archive_after_days = number, - delete_after_days = number, + prefix_match = set(string) + tier_to_cool_after_days = number + tier_to_archive_after_days = number + delete_after_days = number snapshot_delete_after_days = number })) default = [{ @@ -208,40 +198,62 @@ variable "static_website_config" { description = "Static website configuration. Can only be set when the `account_kind` is set to `StorageV2` or `BlockBlobStorage`." } +# Queue Property Logging +variable "queue_properties_logging" { + description = "Logging queue properties" + type = object({ + delete = optional(bool) + read = optional(bool) + write = optional(bool) + version = optional(string) + retention_policy_days = optional(number) + }) + default = { + delete = true + read = true + write = true + version = "1.0" + retention_policy_days = 7 + } +} + # Routing variable "enable_routing" { type = bool default = false - description = "Whether or not to enable routing" + description = "Enable or disable the creation of the routing block." } -variable "publish_internet_endpoints" { - type = bool - default = false - description = "Should internet routing storage endpoints be published?" +variable "routing" { + type = list(object({ + publish_internet_endpoints = bool + publish_microsoft_endpoints = bool + choice = string + })) + default = [ + { + publish_internet_endpoints = false + publish_microsoft_endpoints = false + choice = "MicrosoftRouting" + } + ] } -variable "publish_microsoft_endpoints" { +# Share Properties +variable "enable_file_share_cors_rules" { type = bool default = false - description = "Should Microsoft routing storage endpoints be published? " -} - -variable "choice" { - type = string - default = "MicrosoftRouting" - description = "Specifies the kind of network routing opted by the user. Possible values are InternetRouting and MicrosoftRouting. Defaults to MicrosoftRouting." + description = "Whether or not enable file share cors rules. " } -# Share Properties variable "file_share_cors_rules" { - type = object({ + type = list(object({ allowed_headers = list(string) allowed_methods = list(string) allowed_origins = list(string) exposed_headers = list(string) max_age_in_seconds = number - }) + })) default = null description = "Storage Account file shares CORS rule. Please refer to the [documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#cors_rule) for more information." } @@ -254,11 +266,11 @@ variable "file_share_retention_policy_in_days" { variable "file_share_properties_smb" { type = object({ - versions = optional(list(string), null) - authentication_types = optional(list(string), null) - kerberos_ticket_encryption_type = optional(list(string), null) - channel_encryption_type = optional(list(string), null) - multichannel_enabled = optional(bool, null) + versions = optional(list(string)) + authentication_types = optional(list(string)) + kerberos_ticket_encryption_type = optional(list(string)) + channel_encryption_type = optional(list(string)) + multichannel_enabled = optional(bool) }) default = null description = "Storage Account file shares smb properties." @@ -331,8 +343,13 @@ variable "object_id" { default = [] } -## Private endpoint +variable "allowed_copy_scope" { + type = string + default = "PrivateLink" + 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." +} +## Private endpoint variable "virtual_network_id" { type = string default = "" @@ -382,20 +399,160 @@ variable "addon_virtual_network_id" { description = "The name of the addon vnet link vnet id" } -variable "versioning_enabled" { +# Data protection +variable "storage_blob_data_protection" { + description = "Storage account blob Data protection parameters." + type = object({ + change_feed_enabled = optional(bool, false) + versioning_enabled = optional(bool, false) + last_access_time_enabled = optional(bool, false) + delete_retention_policy_in_days = optional(number, 0) + container_delete_retention_policy_in_days = optional(number, 0) + container_point_in_time_restore = optional(bool, false) + }) + default = { + change_feed_enabled = false + last_access_time_enabled = false + versioning_enabled = false + delete_retention_policy_in_days = 7 + container_delete_retention_policy_in_days = 7 + } +} + +variable "storage_blob_cors_rule" { + description = "Storage Account blob CORS rule. Please refer to the [documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#cors_rule) for more information." + type = object({ + allowed_headers = list(string) + allowed_methods = list(string) + allowed_origins = list(string) + exposed_headers = list(string) + max_age_in_seconds = number + }) + default = null +} + +variable "restore_policy" { type = bool default = false - description = "Is versioning enabled? Default to false." + description = "Wheteher or not create restore policy" } -variable "last_access_time_enabled" { +# Minute Metrics +variable "enable_minute_metrics" { type = bool default = false - description = "(Optional) Is the last access time based tracking enabled? Default to true." + description = "Enable or disable the creation of the minute_metrics block." } -# Diagnosis Settings Enable +variable "minute_metrics" { + type = list(object({ + enabled = bool + version = string + include_apis = bool + retention_policy_days = number + })) + default = [ + { + enabled = false + version = "" + include_apis = false + retention_policy_days = 7 + } + ] +} + +# Hour Metrics +variable "enable_hour_metrics" { + type = bool + default = false + description = "Enable or disable the creation of the hour_metrics block." +} + +variable "hour_metrics" { + type = object({ + enabled = bool + version = string + include_apis = bool + retention_policy_days = number + }) + default = { + enabled = false + version = "" + include_apis = false + retention_policy_days = 7 + } +} + +# File Share Authentication +variable "file_share_authentication" { + description = "Storage Account file shares authentication configuration." + type = object({ + directory_type = string + active_directory = optional(object({ + storage_sid = string + domain_name = string + domain_sid = string + domain_guid = string + forest_name = string + netbios_domain_name = string + })) + }) + default = null + + validation { + condition = var.file_share_authentication == null || ( + contains(["AADDS", "AD", ""], try(var.file_share_authentication.directory_type, "")) + ) + error_message = "`file_share_authentication.directory_type` can only be `AADDS` or `AD`." + } + validation { + condition = var.file_share_authentication == null || ( + try(var.file_share_authentication.directory_type, null) == "AADDS" || ( + try(var.file_share_authentication.directory_type, null) == "AD" && + try(var.file_share_authentication.active_directory, null) != null + ) + ) + error_message = "`file_share_authentication.active_directory` block is required when `file_share_authentication.directory_type` is set to `AD`." + } +} + +# Private Link Access +variable "enable_private_link_access" { + type = bool + default = false + description = "Enable or disable the creation of the private_link_access." +} +variable "private_link_access" { + description = "List of Privatelink objects to allow access from." + type = list(object({ + endpoint_resource_id = string + endpoint_tenant_id = string + })) + default = [] +} + +# SAS Policy +variable "enable_sas_policy" { + description = "Enable or disable the creation of the sas_policy block." + type = bool + default = false +} + +variable "sas_policy_settings" { + type = list(object({ + expiration_period = string + expiration_action = string + })) + default = [ + { + expiration_period = "7.00:00:00" + expiration_action = "Log" + } + ] +} + +# Diagnosis Settings Enable variable "enable_diagnostic" { type = bool default = false @@ -508,6 +665,12 @@ variable "cmk_enabled" { description = "Whether to create CMK or not" } +variable "enable_rotation_policy" { + type = bool + default = false + description = "Whether or not to enable rotation policy" +} + variable "rotation_policy" { type = map(object({ time_before_expiry = string From 23bbea420efc42ba8e63194586b0951bc3a08dbf Mon Sep 17 00:00:00 2001 From: lovely Date: Wed, 17 Jan 2024 23:41:18 +0530 Subject: [PATCH 03/12] fix: fixed key-vault authentication issue in cmk encryption --- README.yaml | 1 + _example/basic/example.tf | 1 - _example/complete/example.tf | 38 +++++++++++++++++------------------- main.tf | 29 ++++++++++++++------------- variables.tf | 6 +++--- 5 files changed, 37 insertions(+), 38 deletions(-) diff --git a/README.yaml b/README.yaml index d09a446..eb437af 100644 --- a/README.yaml +++ b/README.yaml @@ -94,6 +94,7 @@ usage: |- identity_type = "UserAssigned" object_id = ["71d1a02f-3ae9-4ab9-8fec-d9b1166d7c97", ] account_replication_type = "ZRS" + cmk_enabled = "true" ###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/_example/basic/example.tf b/_example/basic/example.tf index 1187385..d40bdd8 100644 --- a/_example/basic/example.tf +++ b/_example/basic/example.tf @@ -16,7 +16,6 @@ module "storage" { source = "../.." name = local.name environment = local.environment - default_enabled = true resource_group_name = "app-test-rg" location = "Central India" storage_account_name = "stordtyrey36" diff --git a/_example/complete/example.tf b/_example/complete/example.tf index 84c81ab..80eee65 100644 --- a/_example/complete/example.tf +++ b/_example/complete/example.tf @@ -67,7 +67,7 @@ module "log-analytics" { name = local.name environment = local.environment label_order = local.label_order - create_log_analytics_workspace = true + create_log_analytics_workspace = false log_analytics_workspace_sku = "PerGB2018" daily_quota_gb = "-1" internet_ingestion_enabled = true @@ -83,21 +83,17 @@ module "vault" { source = "clouddrove/key-vault/azure" version = "1.1.0" - name = "vault9825" - environment = "test" - label_order = ["name", "environment", ] - resource_group_name = module.resource_group.resource_group_name - location = module.resource_group.resource_group_location - # reader_objects_ids = [data.azurerm_client_config.current_client_config.object_id] - admin_objects_ids = [data.azurerm_client_config.current_client_config.object_id] - virtual_network_id = join("", module.vnet.vnet_id) - subnet_id = module.subnet.default_subnet_id[0] - enable_rbac_authorization = false - network_acls = { - bypass = "AzureServices" - default_action = "Deny" - ip_rules = ["0.0.0.0/0"] - } + name = "vault8767768" + environment = "test" + label_order = ["name", "environment", ] + resource_group_name = module.resource_group.resource_group_name + location = module.resource_group.resource_group_location + admin_objects_ids = [data.azurerm_client_config.current_client_config.object_id] + virtual_network_id = join("", module.vnet.vnet_id) + subnet_id = module.subnet.default_subnet_id[0] + enable_rbac_authorization = true + enabled_for_disk_encryption = false + network_acls = null #private endpoint enable_private_endpoint = false ########Following to be uncommnented only when using DNS Zone from different subscription along with existing DNS zone. @@ -111,13 +107,13 @@ module "vault" { # existing_private_dns_zone_resource_group_name = "" #### enable diagnostic setting - diagnostic_setting_enable = false + diagnostic_setting_enable = true log_analytics_workspace_id = module.log-analytics.workspace_id ## when diagnostic_setting_enable enable, add log analytics workspace id } ##----------------------------------------------------------------------------- ## Storage module call. -## Here default storage will be deployed. +## Here storage account will be deployed with CMK encryption. ##----------------------------------------------------------------------------- module "storage" { source = "../.." @@ -126,13 +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 = "strge56563" + storage_account_name = "storage877656" 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 + ###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 @@ -142,7 +140,7 @@ module "storage" { tables = ["table1"] queues = ["queue1"] file_shares = [ - { name = "file-test", quota = "10" }, + { name = "fileshare", quota = "10" }, ] virtual_network_id = module.vnet.vnet_id[0] diff --git a/main.tf b/main.tf index de26192..945bb5b 100644 --- a/main.tf +++ b/main.tf @@ -200,8 +200,8 @@ resource "azurerm_storage_account" "storage" { dynamic "customer_managed_key" { for_each = var.cmk_enabled ? [1] : [] content { - key_vault_key_id = var.key_vault_id != null ? join("", azurerm_key_vault_key.kvkey.*.id) : null - user_assigned_identity_id = var.key_vault_id != null ? join("", azurerm_user_assigned_identity.identity.*.id) : null + 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,9 +211,9 @@ 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 ? 1 : 0 + count = var.enabled && var.cmk_enabled ? 1 : 0 location = var.location - name = format("midd-storage-%s", module.labels.id) + name = format("%s-storage-mid", module.labels.id) resource_group_name = var.resource_group_name } @@ -223,7 +223,7 @@ 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 - principal_id = join("", azurerm_user_assigned_identity.identity.*.principal_id) + principal_id = azurerm_user_assigned_identity.identity[0].principal_id scope = var.key_vault_id role_definition_name = "Key Vault Crypto Service Encryption User" } @@ -232,9 +232,9 @@ resource "azurerm_role_assignment" "identity_assigned" { ## 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] + depends_on = [azurerm_role_assignment.identity_assigned, azurerm_user_assigned_identity.identity] count = var.enabled && var.cmk_enabled ? 1 : 0 - name = format("storage-%s-cmk-testing", module.labels.id) + name = format("%s-storage-key-vault-key", module.labels.id) expiration_date = var.expiration_date key_vault_id = var.key_vault_id key_type = "RSA" @@ -624,10 +624,11 @@ resource "azurerm_monitor_diagnostic_setting" "storage-nic" { } } -resource "azurerm_storage_account_customer_managed_key" "example" { - 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) -} +# 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 b692f8d..e45096b 100644 --- a/variables.tf +++ b/variables.tf @@ -303,7 +303,7 @@ variable "key_vault_id" { variable "expiration_date" { type = string - default = "2023-12-31T18:29:59Z" + default = null description = "Expiration UTC datetime (Y-m-d'T'H:M:S'Z')" } @@ -655,7 +655,7 @@ variable "multi_sub_vnet_link" { variable "key_vault_rbac_auth_enabled" { type = bool - default = false + default = true description = "Is key vault has role base access enable or not." } @@ -677,5 +677,5 @@ variable "rotation_policy" { expire_after = string notify_before_expiry = string })) - default = {} + default = null } \ No newline at end of file From 0f734cd1e328d64e2740720aae0947ffa8de7530 Mon Sep 17 00:00:00 2001 From: lovely Date: Wed, 17 Jan 2024 23:51:43 +0530 Subject: [PATCH 04/12] updated tfsec workflow --- .github/workflows/tfsec.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tfsec.yml b/.github/workflows/tfsec.yml index 9aaf588..418ce1c 100644 --- a/.github/workflows/tfsec.yml +++ b/.github/workflows/tfsec.yml @@ -5,7 +5,7 @@ on: workflow_dispatch: jobs: tfsec: - uses: clouddrove/github-shared-workflows/.github/workflows/tfsec.yml@master + uses: clouddrove/github-shared-workflows/.github/workflows/tfsec.yml@1.2.1 secrets: inherit with: working_directory: '.' \ No newline at end of file From a2dce2c3b9026e8c81ba893f2681c299afd826b1 Mon Sep 17 00:00:00 2001 From: lovely Date: Thu, 18 Jan 2024 00:18:02 +0530 Subject: [PATCH 05/12] fix: updated all github workflows --- .github/dependabot.yml | 20 +------ .github/workflows/auto_assignee.yml | 14 +++++ .github/workflows/automerge.yml | 12 ++++ .github/workflows/changelog.yml | 4 +- .github/workflows/readme.yml | 3 +- .github/workflows/semantic-releaser.yml | 30 ---------- .github/workflows/static-checks.yml | 74 ------------------------- .github/workflows/tf-checks.yml | 16 ++++++ .github/workflows/tflint.yml | 11 ++++ README.yaml | 37 +++++++------ _test/azure_firewall_test.go | 34 ------------ 11 files changed, 79 insertions(+), 176 deletions(-) create mode 100644 .github/workflows/auto_assignee.yml create mode 100644 .github/workflows/automerge.yml delete mode 100644 .github/workflows/semantic-releaser.yml delete mode 100644 .github/workflows/static-checks.yml create mode 100644 .github/workflows/tf-checks.yml create mode 100644 .github/workflows/tflint.yml delete mode 100644 _test/azure_firewall_test.go diff --git a/.github/dependabot.yml b/.github/dependabot.yml index aa41943..5a49cc6 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -2,7 +2,6 @@ # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates - version: 2 updates: - package-ecosystem: "github-actions" @@ -29,20 +28,7 @@ updates: open-pull-requests-limit: 3 - package-ecosystem: "terraform" # See documentation for possible values - directory: "_example/basic" # Location of package manifests - schedule: - interval: "weekly" - # Add assignees - assignees: - - "clouddrove-ci" - # Add reviewer - reviewers: - - "approvers" - # Allow up to 3 open pull requests for pip dependencies - open-pull-requests-limit: 3 - - - package-ecosystem: "terraform" # See documentation for possible values - directory: "_example/complete" # Location of package manifests + directory: "/_example/complete" # Location of package manifests schedule: interval: "weekly" # Add assignees @@ -55,7 +41,7 @@ updates: open-pull-requests-limit: 3 - package-ecosystem: "terraform" # See documentation for possible values - directory: "_example/storage_with_cmk" # Location of package manifests + directory: "/_example/basic" # Location of package manifests schedule: interval: "weekly" # Add assignees @@ -65,4 +51,4 @@ updates: reviewers: - "approvers" # Allow up to 3 open pull requests for pip dependencies - open-pull-requests-limit: 3 + open-pull-requests-limit: 3 \ No newline at end of file diff --git a/.github/workflows/auto_assignee.yml b/.github/workflows/auto_assignee.yml new file mode 100644 index 0000000..65cd9bb --- /dev/null +++ b/.github/workflows/auto_assignee.yml @@ -0,0 +1,14 @@ +name: Auto Assign PRs + +on: + pull_request: + types: [opened, reopened] + + workflow_dispatch: +jobs: + assignee: + uses: clouddrove/github-shared-workflows/.github/workflows/auto_assignee.yml@1.2.1 + secrets: + GITHUB: ${{ secrets.GITHUB }} + with: + assignees: 'clouddrove-ci' \ No newline at end of file diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml new file mode 100644 index 0000000..cf12aa7 --- /dev/null +++ b/.github/workflows/automerge.yml @@ -0,0 +1,12 @@ +--- +name: Auto merge +on: + pull_request: +jobs: + auto-merge: + uses: clouddrove/github-shared-workflows/.github/workflows/auto_merge.yml@1.2.1 + secrets: + GITHUB: ${{ secrets.GITHUB }} + with: + tfcheck: 'example-basic / Check code format' +... \ No newline at end of file diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 3e88b85..6334714 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -6,8 +6,8 @@ on: - "*" workflow_dispatch: jobs: - call-workflow-changelog: - uses: clouddrove/github-shared-workflows/.github/workflows/changelog.yml@master + changelog: + uses: clouddrove/github-shared-workflows/.github/workflows/changelog.yml@1.2.1 secrets: inherit with: branch: 'master' \ No newline at end of file diff --git a/.github/workflows/readme.yml b/.github/workflows/readme.yml index 03b477f..9513782 100644 --- a/.github/workflows/readme.yml +++ b/.github/workflows/readme.yml @@ -13,7 +13,7 @@ jobs: uses: actions/checkout@master - name: 'Set up Python 3.7' - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' @@ -25,7 +25,6 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: 'pre-commit check errors' uses: pre-commit/action@v3.0.0 continue-on-error: true diff --git a/.github/workflows/semantic-releaser.yml b/.github/workflows/semantic-releaser.yml deleted file mode 100644 index b74a0e4..0000000 --- a/.github/workflows/semantic-releaser.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Release - -on: - push: - branches: - - main - paths: - - '**.tf' - - '!examples/**.tf' - -jobs: - release: - name: Release - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - persist-credentials: false - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 14 - - - name: Release - env: - GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} - run: npx semantic-release diff --git a/.github/workflows/static-checks.yml b/.github/workflows/static-checks.yml deleted file mode 100644 index 645a886..0000000 --- a/.github/workflows/static-checks.yml +++ /dev/null @@ -1,74 +0,0 @@ -name: static-checks - -on: - pull_request: - -jobs: - versionExtract: - name: Get min/max versions - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Terraform min/max versions - id: minMax - uses: clowdhaus/terraform-min-max@main - outputs: - minVersion: ${{ steps.minMax.outputs.minVersion }} - maxVersion: ${{ steps.minMax.outputs.maxVersion }} - - versionEvaluate: - name: Evaluate Terraform versions - runs-on: ubuntu-latest - needs: versionExtract - strategy: - fail-fast: false - matrix: - version: - - ${{ needs.versionExtract.outputs.minVersion }} - - ${{ needs.versionExtract.outputs.maxVersion }} - directory: - - _example/ - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Install Terraform v${{ matrix.version }} - uses: hashicorp/setup-terraform@v3 - with: - terraform_version: ${{ matrix.version }} - - - name: Init & validate v${{ matrix.version }} - run: | - cd ${{ matrix.directory }} - terraform init - terraform validate - - name: tflint - uses: reviewdog/action-tflint@master - with: - tflint_version: v0.29.0 - github_token: ${{ secrets.GITHUB_TOKEN }} - working_directory: ${{ matrix.directory }} - fail_on_error: 'true' - filter_mode: 'nofilter' - flags: '--module' - - format: - name: Check code format - runs-on: ubuntu-latest - needs: versionExtract - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Install Terraform v${{ needs.versionExtract.outputs.maxVersion }} - uses: hashicorp/setup-terraform@v3 - with: - terraform_version: ${{ needs.versionExtract.outputs.maxVersion }} - - - name: Check Terraform format changes - run: terraform fmt --recursive -check=true \ No newline at end of file diff --git a/.github/workflows/tf-checks.yml b/.github/workflows/tf-checks.yml new file mode 100644 index 0000000..af06dd7 --- /dev/null +++ b/.github/workflows/tf-checks.yml @@ -0,0 +1,16 @@ +name: tf-checks +on: + push: + branches: [ master ] + pull_request: + workflow_dispatch: +jobs: + example-basic: + uses: clouddrove/github-shared-workflows/.github/workflows/tf-checks.yml@1.2.1 + with: + working_directory: './_example/basic' + example-complete: + uses: clouddrove/github-shared-workflows/.github/workflows/tf-checks.yml@1.2.1 + with: + working_directory: './_example/complete' + \ No newline at end of file diff --git a/.github/workflows/tflint.yml b/.github/workflows/tflint.yml new file mode 100644 index 0000000..21714e9 --- /dev/null +++ b/.github/workflows/tflint.yml @@ -0,0 +1,11 @@ +name: tf-lint +on: + push: + branches: [ master ] + pull_request: + workflow_dispatch: +jobs: + tf-lint: + uses: clouddrove/github-shared-workflows/.github/workflows/tf-lint.yml@1.2.1 + secrets: + GITHUB: ${{ secrets.GITHUB }} \ No newline at end of file diff --git a/README.yaml b/README.yaml index eb437af..5feff12 100644 --- a/README.yaml +++ b/README.yaml @@ -18,9 +18,12 @@ github_repo: clouddrove/terraform-azure-storage # Badges to display badges: - - name: "Terraform" - image: "https://img.shields.io/badge/Terraform-v1.0.0-green" - url: "https://www.terraform.io" + - name: "Latest Release" + image: "https://img.shields.io/github/release/clouddrove/terraform-azure-storage.svg" + url: "https://github.com/clouddrove/terraform-azure-storage/releases/latest" + - name: "tfsec" + image: "https://github.com/clouddrove/terraform-azure-storage/actions/workflows/tfsec.yml/badge.svg" + url: "https://github.com/clouddrove/terraform-azure-storage/actions/workflows/tfsec.yml" - name: "Licence" image: "https://img.shields.io/badge/License-APACHE-blue.svg" url: "LICENSE.md" @@ -81,20 +84,20 @@ usage: |- #### storage with cmk encryption ```hcl module "storage" { - depends_on = [module.resource_group] - source = "clouddrove/storage/azure" - name = "app" - environment = "test" - label_order = ["name", "environment", ] - resource_group_name = module.resource_group.resource_group_name - location = module.resource_group.resource_group_location - storage_account_name = "storagkqp0896" - account_kind = "BlockBlobStorage" - account_tier = "Premium" - identity_type = "UserAssigned" - object_id = ["71d1a02f-3ae9-4ab9-8fec-d9b1166d7c97", ] - account_replication_type = "ZRS" - cmk_enabled = "true" + source = "../.." + name = local.name + environment = local.environment + 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" + 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 ###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/_test/azure_firewall_test.go b/_test/azure_firewall_test.go deleted file mode 100644 index 3121d5f..0000000 --- a/_test/azure_firewall_test.go +++ /dev/null @@ -1,34 +0,0 @@ -// Managed By : CloudDrove -// Description : This Terratest is used to test the Terraform VPC module. -// Copyright @ CloudDrove. All Right Reserved. -package test - -import ( - "testing" - "github.com/gruntwork-io/terratest/modules/terraform" - "github.com/stretchr/testify/assert" -) - -func Test(t *testing.T) { - t.Parallel() - - terraformOptions := &terraform.Options{ - // Source path of Terraform directory. - TerraformDir: "../_example", - } - - // This will run 'terraform init' and 'terraform application' and will fail the test if any errors occur - terraform.InitAndApply(t, terraformOptions) - - // To clean up any resources that have been created, run 'terraform destroy' towards the end of the test - defer terraform.Destroy(t, terraformOptions) - - // To get the value of an output variable, run 'terraform output' - Id := terraform.Output(t, terraformOptions, "firewall_id") - Tags := terraform.OutputMap(t, terraformOptions, "tags") - - // Check that we get back the outputs that we expect - assert.Equal(t, "test-clouddrove-firewall", Tags["Name"]) - assert.Contains(t, Id, "/subscriptions") -} -} \ No newline at end of file From 3c52c42069f3edae030966d5a32a61f0ed23c6e4 Mon Sep 17 00:00:00 2001 From: lovely Date: Thu, 18 Jan 2024 23:05:07 +0530 Subject: [PATCH 06/12] fix: tf destroy issue fixed --- README.yaml | 67 +++++++++++++++++------------------- _example/basic/example.tf | 26 +++++++------- _example/basic/outputs.tf | 4 +-- _example/complete/example.tf | 9 ++--- main.tf | 43 ++++++++++++----------- variables.tf | 18 ++++++---- 6 files changed, 87 insertions(+), 80 deletions(-) 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" From 2018f6b11ff046986d3bdb372d141dc1aa44aba6 Mon Sep 17 00:00:00 2001 From: lovely Date: Thu, 18 Jan 2024 23:07:18 +0530 Subject: [PATCH 07/12] testing tfsec --- .github/workflows/tfsec.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tfsec.yml b/.github/workflows/tfsec.yml index 418ce1c..fb94fd8 100644 --- a/.github/workflows/tfsec.yml +++ b/.github/workflows/tfsec.yml @@ -8,4 +8,4 @@ jobs: uses: clouddrove/github-shared-workflows/.github/workflows/tfsec.yml@1.2.1 secrets: inherit with: - working_directory: '.' \ No newline at end of file + working_directory: ./ \ No newline at end of file From 9256cb3659b34a402d067c88ca2ab2947e10d0e4 Mon Sep 17 00:00:00 2001 From: lovely Date: Thu, 18 Jan 2024 23:15:55 +0530 Subject: [PATCH 08/12] feat- test tf check --- .github/workflows/tfsec.yml | 2 +- _example/basic/example.tf | 2 +- main.tf | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tfsec.yml b/.github/workflows/tfsec.yml index fb94fd8..9822a67 100644 --- a/.github/workflows/tfsec.yml +++ b/.github/workflows/tfsec.yml @@ -8,4 +8,4 @@ jobs: uses: clouddrove/github-shared-workflows/.github/workflows/tfsec.yml@1.2.1 secrets: inherit with: - working_directory: ./ \ No newline at end of file + working_directory: '_example/basic/' \ No newline at end of file diff --git a/_example/basic/example.tf b/_example/basic/example.tf index 98c75b8..9c3d178 100644 --- a/_example/basic/example.tf +++ b/_example/basic/example.tf @@ -26,7 +26,7 @@ module "storage" { account_replication_type = "GRS" ## Encryption is not enabled for this Storage account - cmk_encryption_enabled = false + cmk_encryption_enabled = false ## Storage Container containers_list = [ diff --git a/main.tf b/main.tf index 099d5e2..2f34225 100644 --- a/main.tf +++ b/main.tf @@ -18,7 +18,7 @@ module "labels" { ## To create storage account with cmk(customer managed key) encryption set 'var.default_enabled = false'. ##----------------------------------------------------------------------------- resource "azurerm_storage_account" "storage" { - count = var.enabled ? 1 : 0 + count = var.enabled ? 1 : 0 # depends_on = [azurerm_role_assignment.identity_assigned] name = var.storage_account_name resource_group_name = var.resource_group_name @@ -574,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) + 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 From 9a183e1ae2c3997d4028464064445a1a0633c3a7 Mon Sep 17 00:00:00 2001 From: lovely Date: Fri, 19 Jan 2024 16:15:21 +0530 Subject: [PATCH 09/12] fix: fixed tfsec --- .github/workflows/tfsec.yml | 2 +- _example/complete/example.tf | 1 - variables.tf | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tfsec.yml b/.github/workflows/tfsec.yml index 9822a67..418ce1c 100644 --- a/.github/workflows/tfsec.yml +++ b/.github/workflows/tfsec.yml @@ -8,4 +8,4 @@ jobs: uses: clouddrove/github-shared-workflows/.github/workflows/tfsec.yml@1.2.1 secrets: inherit with: - working_directory: '_example/basic/' \ No newline at end of file + working_directory: '.' \ No newline at end of file diff --git a/_example/complete/example.tf b/_example/complete/example.tf index e07b509..bdd689d 100644 --- a/_example/complete/example.tf +++ b/_example/complete/example.tf @@ -93,7 +93,6 @@ module "vault" { subnet_id = module.subnet.default_subnet_id[0] enable_rbac_authorization = true enabled_for_disk_encryption = false - network_acls = null #private endpoint enable_private_endpoint = false ########Following to be uncommnented only when using DNS Zone from different subscription along with existing DNS zone. diff --git a/variables.tf b/variables.tf index ff5cc6b..ee3bb68 100644 --- a/variables.tf +++ b/variables.tf @@ -303,7 +303,7 @@ variable "key_vault_id" { variable "expiration_date" { type = string - default = null + default = "2024-05-22T18:29:59Z" description = "Expiration UTC datetime (Y-m-d'T'H:M:S'Z')" } From ea3a2970b5618a2cc132dbe670910171fe902550 Mon Sep 17 00:00:00 2001 From: Deepak Verma Date: Fri, 26 Jan 2024 18:10:44 +0530 Subject: [PATCH 10/12] fix: resource control conditions --- _example/complete/example.tf | 15 +++++++-------- main.tf | 17 ++++++++--------- variables.tf | 7 +------ 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/_example/complete/example.tf b/_example/complete/example.tf index bdd689d..70dec09 100644 --- a/_example/complete/example.tf +++ b/_example/complete/example.tf @@ -6,7 +6,7 @@ provider "azurerm" { data "azurerm_client_config" "current_client_config" {} locals { - name = "storage" + name = "app-storage" environment = "test" label_order = ["name", "environment"] } @@ -83,7 +83,7 @@ module "vault" { source = "clouddrove/key-vault/azure" version = "1.1.0" - name = "vault65960589" + name = "vault6596058" environment = "test" label_order = ["name", "environment", ] resource_group_name = module.resource_group.resource_group_name @@ -95,6 +95,7 @@ module "vault" { enabled_for_disk_encryption = false #private endpoint enable_private_endpoint = false + network_acls = null ########Following to be uncommnented only when using DNS Zone from different subscription along with existing DNS zone. # diff_sub = true @@ -121,18 +122,16 @@ 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 = "storage874682" + storage_account_name = "storage87482" 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_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 + cmk_encryption_enabled = true + key_vault_id = module.vault.id + ## Storage Container containers_list = [ { name = "app-test", access_type = "private" }, diff --git a/main.tf b/main.tf index 2f34225..a5fbdf5 100644 --- a/main.tf +++ b/main.tf @@ -18,8 +18,7 @@ module "labels" { ## To create storage account with cmk(customer managed key) encryption set 'var.default_enabled = false'. ##----------------------------------------------------------------------------- resource "azurerm_storage_account" "storage" { - count = var.enabled ? 1 : 0 - # depends_on = [azurerm_role_assignment.identity_assigned] + count = var.enabled ? 1 : 0 name = var.storage_account_name resource_group_name = var.resource_group_name location = var.location @@ -295,7 +294,7 @@ resource "azurerm_storage_account_network_rules" "network-rules" { ## Below resource will create threat protection for storage account. ##----------------------------------------------------------------------------- resource "azurerm_advanced_threat_protection" "atp" { - count = var.enabled ? 1 : 0 + count = var.enabled && var.enable_advanced_threat_protection ? 1 : 0 target_resource_id = join("", azurerm_storage_account.storage.*.id) enabled = var.enable_advanced_threat_protection } @@ -305,7 +304,7 @@ resource "azurerm_advanced_threat_protection" "atp" { ## This resource is not required when key vault has role based authorization(rbac) enabled. ##----------------------------------------------------------------------------- resource "azurerm_key_vault_access_policy" "keyvault-access-policy" { - count = var.enabled && var.key_vault_rbac_auth_enabled == false ? length(var.object_id) : 0 + count = var.enabled && var.key_vault_rbac_auth_enabled == false ? 1 : 0 key_vault_id = var.key_vault_id tenant_id = data.azurerm_client_config.current.tenant_id object_id = join("", azurerm_user_assigned_identity.identity.*.principal_id) @@ -345,7 +344,7 @@ resource "azurerm_key_vault_access_policy" "keyvault-access-policy" { ## Below resource will create container in storage account. ##----------------------------------------------------------------------------- resource "azurerm_storage_container" "container" { - count = length(var.containers_list) + count = var.enabled ? length(var.containers_list) : 0 name = var.containers_list[count.index].name storage_account_name = azurerm_storage_account.storage[0].name container_access_type = var.containers_list[count.index].access_type @@ -355,7 +354,7 @@ resource "azurerm_storage_container" "container" { ## Below resource will create file share in storage account. ##----------------------------------------------------------------------------- resource "azurerm_storage_share" "fileshare" { - count = length(var.file_shares) + count = var.enabled ? length(var.file_shares) : 0 name = var.file_shares[count.index].name storage_account_name = azurerm_storage_account.storage[0].name quota = var.file_shares[count.index].quota @@ -365,7 +364,7 @@ resource "azurerm_storage_share" "fileshare" { ## Below resource will create tables in storage account. ##----------------------------------------------------------------------------- resource "azurerm_storage_table" "tables" { - count = length(var.tables) + count = var.enabled ? length(var.tables) : 0 name = var.tables[count.index] storage_account_name = join("", azurerm_storage_account.storage.*.name) } @@ -374,7 +373,7 @@ resource "azurerm_storage_table" "tables" { ## Below resource will create queue in storage account. ##----------------------------------------------------------------------------- resource "azurerm_storage_queue" "queues" { - count = length(var.queues) + count = var.enabled ? length(var.queues) : 0 name = var.queues[count.index] storage_account_name = join("", azurerm_storage_account.storage.*.name) } @@ -509,7 +508,7 @@ resource "azurerm_private_dns_zone_virtual_network_link" "vent-link-1" { ##----------------------------------------------------------------------------- resource "azurerm_private_dns_zone_virtual_network_link" "vent-link-diff-subs" { provider = azurerm.peer - count = var.multi_sub_vnet_link && var.existing_private_dns_zone != null ? 1 : 0 + count = var.enabled && var.multi_sub_vnet_link && var.existing_private_dns_zone != null ? 1 : 0 name = format("%s-pdz-vnet-link-storage-1", module.labels.id) resource_group_name = var.existing_private_dns_zone_resource_group_name private_dns_zone_name = var.existing_private_dns_zone diff --git a/variables.tf b/variables.tf index ee3bb68..b48d3c2 100644 --- a/variables.tf +++ b/variables.tf @@ -67,7 +67,7 @@ variable "access_tier" { variable "account_replication_type" { type = string - default = "GRS" + default = "LRS" description = "Defines the type of replication to use for this storage account. Valid options are LRS, GRS, RAGRS, ZRS, GZRS and RAGZRS. Changing this forces a new resource to be created when types LRS, GRS and RAGRS are changed to ZRS, GZRS or RAGZRS and vice versa." } @@ -338,11 +338,6 @@ variable "allow_nested_items_to_be_public" { description = "Allow or disallow nested items within this Account to opt into being public. Defaults to true." } -variable "object_id" { - type = list(string) - default = [] -} - variable "allowed_copy_scope" { type = string default = "PrivateLink" From f8b328f4ca0e9146dfe710d5fea58e912b916f91 Mon Sep 17 00:00:00 2001 From: Deepak Verma Date: Fri, 26 Jan 2024 18:41:56 +0530 Subject: [PATCH 11/12] updated vnet and subnet module version --- _example/complete/example.tf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_example/complete/example.tf b/_example/complete/example.tf index 70dec09..615134c 100644 --- a/_example/complete/example.tf +++ b/_example/complete/example.tf @@ -29,13 +29,13 @@ module "resource_group" { ##----------------------------------------------------------------------------- module "vnet" { source = "clouddrove/vnet/azure" - version = "1.0.3" + version = "1.0.4" name = local.name environment = local.environment label_order = local.label_order resource_group_name = module.resource_group.resource_group_name location = module.resource_group.resource_group_location - address_space = "10.0.0.0/16" + address_spaces = ["10.0.0.0/16"] } ##----------------------------------------------------------------------------- @@ -44,7 +44,7 @@ module "vnet" { ##----------------------------------------------------------------------------- module "subnet" { source = "clouddrove/subnet/azure" - version = "1.0.2" + version = "1.1.0" name = local.name environment = local.environment label_order = local.label_order From e7d67116c554771e99179324d788c237b595b2a1 Mon Sep 17 00:00:00 2001 From: Deepak Verma Date: Fri, 26 Jan 2024 18:44:39 +0530 Subject: [PATCH 12/12] fmt run --- _example/complete/example.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_example/complete/example.tf b/_example/complete/example.tf index 615134c..1b230e0 100644 --- a/_example/complete/example.tf +++ b/_example/complete/example.tf @@ -35,7 +35,7 @@ module "vnet" { label_order = local.label_order resource_group_name = module.resource_group.resource_group_name location = module.resource_group.resource_group_location - address_spaces = ["10.0.0.0/16"] + address_spaces = ["10.0.0.0/16"] } ##-----------------------------------------------------------------------------