Hi @apparentlymart
Thanks for the answer.
I’m creating a terraform module for Storage Account, blob Storage, monitoring, alert and alert group.
To create the storage account I am using type a variable map(object).
The code below is woking now.
variables.tf
variable "storage_accounts" {
type = map(object({
storage_account_name = string
resource_group_name = string
location = string
account_kind = string
account_tier = string
access_tier = string
account_replication_type = string
cross_tenant_replication_enabled = bool
enable_https_traffic_only = bool
min_tls_version = string
allow_nested_items_to_be_public = any
shared_access_key_enabled = bool
public_network_access_enabled = any
default_to_oauth_authentication = bool
is_hns_enabled = bool
nfsv3_enabled = bool
large_file_share_enabled = any
queue_encryption_key_type = string
table_encryption_key_type = string
infrastructure_encryption_enabled = bool
soft_delete_enabled = bool
network_rules = list(object({
default_action = string
bypass = list(string)
ip_rules = list(string)
virtual_network_subnet_ids = list(string)
private_link_access = list(string)
}))
blob_properties = list(object({
versioning_enabled = bool
change_feed_enabled = bool
change_feed_retention_in_days = number
default_service_version = string
last_access_time_enabled = bool
cors_rule = list(any)
delete_retention_policy = list(any)
container_delete_retention_policy = list(any)
}))
queue_properties = list(object({
cors_rule = list(any)
logging = list(any)
minute_metrics = list(any)
hour_metrics = list(any)
}))
share_properties = list(object({
cors_rule = list(any)
retention_policy = list(any)
smb = list(any)
}))
static_website = list(object({
index_document = string
error_404_document = string
}))
routing = list(any)
immutability_policy = list(object({
allow_protected_append_writes = bool
state = string
period_since_creation_in_days = number
}))
tags = map(any)
}))
default = {}
description = "(Required) Map of key/value to configure `Storage Accoounts`."
}
/* CONTAINER STORAGE */
variable "storage_container" {
type = map(any)
description = "(Required) Map of key/value to configure `Storage Containers`."
default = {}
}
/* BLOB STORAGE */
variable "blob_storage" {
type = map(any)
description = "(Optional) Map of key/value to configure `Blob Storage`."
default = {}
}
main.tf:
resource "azurerm_storage_account" "default" {
for_each = var.storage_accounts
name = each.value["storage_account_name"]
resource_group_name = each.value["resource_group_name"]
location = each.value["location"]
account_kind = lookup(each.value, "account_kind", "StorageV2")
account_tier = each.value["account_tier"]
access_tier = lookup(each.value, "access_tier", "Hot")
account_replication_type = each.value["account_replication_type"]
cross_tenant_replication_enabled = lookup(each.value, "cross_tenant_replication_enabled", false)
enable_https_traffic_only = lookup(each.value, "enable_https_traffic_only", true)
min_tls_version = lookup(each.value, "min_tls_version", "TLS1_2")
allow_nested_items_to_be_public = lookup(each.value, "allow_nested_items_to_be_public", false)
public_network_access_enabled = lookup(each.value, "public_network_access_enabled", false)
shared_access_key_enabled = lookup(each.value, "shared_access_key_enabled", true)
default_to_oauth_authentication = lookup(each.value, "default_to_oauth_authentication", false)
is_hns_enabled = lookup(each.value, "is_hns_enabled", false)
nfsv3_enabled = lookup(each.value, "nfsv3_enabled", false)
large_file_share_enabled = lookup(each.value, "large_file_share_enabled", true)
queue_encryption_key_type = lookup(each.value, "queue_encryption_key_type", "Service")
table_encryption_key_type = lookup(each.value, "table_encryption_key_type", "Service")
infrastructure_encryption_enabled = lookup(each.value, "infrastructure_encryption_enabled", false)
dynamic "custom_domain" {
for_each = try(each.value["custom_domain"], [])
content {
name = lookup(custom_domain.value, "name", null)
use_subdomain = lookup(custom_domain.value, "use_subdomain", null)
}
}
dynamic "customer_managed_key" {
for_each = try(each.value["customer_managed_key"], [])
content {
key_vault_key_id = lookup(customer_managed_key.value, "key_vault_key_id", null)
user_assigned_identity_id = lookup(customer_managed_key.value, "user_assigned_identity_id", null)
}
}
dynamic "identity" {
for_each = try(each.value["identity"], [])
content {
type = lookup(identity.value, "key_vault_key_id", null)
identity_ids = lookup(identity.value, "user_assigned_identity_id", null)
}
}
dynamic "blob_properties" {
for_each = each.value["blob_properties"]
content {
versioning_enabled = lookup(blob_properties.value, "versioning_enabled", null)
change_feed_enabled = lookup(blob_properties.value, "change_feed_enabled", null)
change_feed_retention_in_days = lookup(blob_properties.value, "change_feed_retention_in_days", null)
default_service_version = lookup(blob_properties.value, "default_service_version", null)
last_access_time_enabled = lookup(blob_properties.value, "last_access_time_enabled", null)
dynamic "cors_rule" {
for_each = try(blob_properties.value["cors_rule"], [])
content {
allowed_headers = lookup(cors_rule.value, "allowed_headers", ["x-ms-blob-content-type"])
allowed_methods = lookup(cors_rule.value, "allowed_methods", ["GET"])
allowed_origins = lookup(cors_rule.value, "allowed_origins", [http://www.contoso.com])
exposed_headers = lookup(cors_rule.value, "exposed_headers", ["x-ms-*"])
max_age_in_seconds = lookup(cors_rule.value, "max_age_in_seconds", "5")
}
}
dynamic "delete_retention_policy" {
for_each = try(blob_properties.value["delete_retention_policy"], [])
content {
days = lookup(delete_retention_policy.value, "days", "7")
}
}
dynamic "container_delete_retention_policy" {
for_each = try(blob_properties.value["container_delete_retention_policy"], [])
content {
days = lookup(container_delete_retention_policy.value, "days", "7")
}
}
}
}
dynamic "queue_properties" {
for_each = each.value["queue_properties"]
content {
dynamic "cors_rule" {
for_each = try(queue_properties.value["cors_rule"], [])
content {
allowed_headers = lookup(cors_rule.value, "allowed_headers", ["x-ms-blob-content-type"])
allowed_methods = lookup(cors_rule.value, "allowed_methods", ["GET"])
allowed_origins = lookup(cors_rule.value, "allowed_origins", [http://www.contoso.com])
exposed_headers = lookup(cors_rule.value, "exposed_headers", ["x-ms-*"])
max_age_in_seconds = lookup(cors_rule.value, "max_age_in_seconds", "5")
}
}
dynamic "logging" {
for_each = try(queue_properties.value["logging"], [])
content {
delete = lookup(logging.value, "delete", false)
read = lookup(logging.value, "read", false)
version = lookup(logging.value, "version", "1.0")
write = lookup(logging.value, "write", false)
retention_policy_days = lookup(logging.value, "retention_policy_days", "1")
}
}
dynamic "minute_metrics" {
for_each = try(queue_properties.value["minute_metrics"], [])
content {
enabled = lookup(minute_metrics.value, "enabled", false)
version = lookup(minute_metrics.value, "version", "1.0")
include_apis = lookup(minute_metrics.value, "include_apis", false)
retention_policy_days = lookup(minute_metrics.value, "retention_policy_days", "1")
}
}
dynamic "hour_metrics" {
for_each = try(queue_properties.value["hour_metrics"], [])
content {
enabled = lookup(hour_metrics.value, "enabled", false)
version = lookup(hour_metrics.value, "version", "1.0")
include_apis = lookup(hour_metrics.value, "include_apis", false)
retention_policy_days = lookup(hour_metrics.value, "retention_policy_days", "1")
}
}
}
}
dynamic "share_properties" {
for_each = each.value["share_properties"]
content {
dynamic "cors_rule" {
for_each = try(share_properties.value["cors_rule"], [])
content {
allowed_headers = lookup(cors_rule.value, "allowed_headers", ["x-ms-blob-content-type"])
allowed_methods = lookup(cors_rule.value, "allowed_methods", ["GET"])
allowed_origins = lookup(cors_rule.value, "allowed_origins", [http://www.contoso.com])
exposed_headers = lookup(cors_rule.value, "exposed_headers", ["x-ms-*"])
max_age_in_seconds = lookup(cors_rule.value, "max_age_in_seconds", "5")
}
}
dynamic "retention_policy" {
for_each = try(share_properties.value["retention_policy"], [])
content {
days = lookup(retention_policy.value, "days", "7")
}
}
dynamic "smb" {
for_each = try(share_properties.value["smb"], {})
content {
versions = lookup(smb.value, "versions", [])
authentication_types = lookup(smb.value, "authentication_types", [])
kerberos_ticket_encryption_type = lookup(smb.value, "kerberos_ticket_encryption_type", [])
channel_encryption_type = lookup(smb.value, "channel_encryption_type", [])
multichannel_enabled = lookup(smb.value, "multichannel_enabled", false)
}
}
}
}
dynamic "network_rules" {
for_each = each.value["network_rules"]
content {
default_action = network_rules.value["default_action"]
bypass = network_rules.value["bypass"]
ip_rules = network_rules.value["ip_rules"]
virtual_network_subnet_ids = network_rules.value["virtual_network_subnet_ids"]
dynamic "private_link_access" {
for_each = try(each.value.network_rules.private_link_access, {})
content {
endpoint_resource_id = lookup(private_link_access.value, "endpoint_resource_id", "")
endpoint_tenant_id = lookup(private_link_access.value, "endpoint_tenant_id", "")
}
}
}
}
dynamic "azure_files_authentication" {
for_each = try(each.value["azure_files_authentication"], [])
content {
directory_type = lookup(azure_files_authentication.value, "directory_type", "AD")
dynamic "active_directory" {
for_each = try(azure_files_authentication.value["active_directory"], {})
content {
storage_sid = lookup(active_directory.value, "storage_sid", null)
domain_name = lookup(active_directory.value, "domain_name", null
domain_sid = lookup(active_directory.value, "domain_sid", null)
domain_guid = lookup(active_directory.value, "domain_guid", null)
forest_name = lookup(active_directory.value, "forest_name", null)
netbios_domain_name = lookup(active_directory.value, "netbios_domain_name", null)
}
}
}
}
dynamic "static_website" {
for_each = try(each.value["static_website"], [])
content {
index_document = lookup(static_website.value, "index_document", "index.html")
error_404_document = lookup(static_website.value, "error_404_document", "erro_404.html")
}
}
dynamic "routing" {
for_each = try(each.value["routing"], [])
content {
publish_internet_endpoints = lookup(routing.value, "publish_internet_endpoints", false)
publish_microsoft_endpoints = lookup(routing.value, "publish_microsoft_endpoints", false)
choice = lookup(routing.value, "choice", "MicrosoftRouting")
}
}
dynamic "immutability_policy" {
for_each = try(each.value["immutability_policy"], [])
content {
allow_protected_append_writes = lookup(immutability_policy.value, "allow_protected_append_writes", false)
state = lookup(immutability_policy.value, "state", "Disabled")
period_since_creation_in_days = lookup(immutability_policy.value, "period_since_creation_in_days", "0")
}
}
tags = each.value["tags"]
lifecycle {
create_before_destroy = true
}
}
monitoring.tf
resource "azurerm_monitor_action_group" "default" {
for_each = try(var.blob_storage, {})
name = ${each.value["blob_name"]-group}
resource_group_name = each.value["resource_group_name"]
short_name = lookup(each.value, "short_name", "shortgrpexpl")
tags = each.value["tags"]
depends_on = [
azurerm_storage_account.default,
azurerm_storage_blob.default
]
}
resource "azurerm_monitor_diagnostic_setting" "default" {
for_each = try(var.blob_storage, {})
name = "${lookup(each.value, "storage_account_name")}-diags"
target_resource_id = "${element(values(azurerm_storage_account.default)[*].id, length(var.storage_accounts))}/blobServices/default"
storage_account_id = element(values(azurerm_storage_account.default)[*].id, length(var.storage_accounts))
dynamic "metric" {
for_each = try(each.value["metric"], [])
content {
category = lookup(metric.value, "category", "Transaction")
enabled = lookup(metric.value, "enabled", true)
dynamic "retention_policy" {
for_each = metric.value["retention_policy"]
content {
enabled = lookup(retention_policy.value, "enabled", true)
days = lookup(retention_policy.value, "days", "5")
}
}
}
}
dynamic "log" {
for_each = try(each.value["log"], [])
content {
category = lookup(log.value, "category", "StorageRead")
category_group = lookup(log.value, "category_group", "null")
enabled = lookup(log.value, "enabled", true)
dynamic "retention_policy" {
for_each = log.value["retention_policy"]
content {
enabled = lookup(retention_policy.value, "enabled", true)
days = lookup(retention_policy.value, "days", "5")
}
}
}
}
depends_on = [
azurerm_storage_blob.default
]
}
resource "azurerm_monitor_metric_alert" "default" {
for_each = try(var.blob_storage, {})
name = each.value["storage_account_name"]
resource_group_name = each.value["resource_group_name"]
scopes = [(element(values(azurerm_storage_account.default)[*].id, length(var.storage_accounts)))]
description = "Action will be triggered when Transactions count is greater than 50."
dynamic "criteria" {
for_each = each.value["criteria"]
content {
metric_namespace = lookup(criteria.value, "metric_namespace", "Microsoft.Storage/storageAccounts")
metric_name = lookup(criteria.value, "metric_name", "Transactions")
aggregation = lookup(criteria.value, "aggregation", "Total")
operator = lookup(criteria.value, "operator", "GreaterThan")
threshold = lookup(criteria.value, "threshold", "50")
dynamic "dimension" {
for_each = criteria.value["dimension"]
content {
name = lookup(dimension.value, "name", "ApiName")
operator = lookup(dimension.value, "operator", "Include")
values = lookup(dimension.value, "values", ["*"])
}
}
}
}
action {
action_group_id = (element(values(azurerm_monitor_action_group.default)[*].id, length(var.storage_accounts)))
}
tags = each.value["tags"]
depends_on = [
azurerm_storage_account.default,
azurerm_storage_blob.default,
azurerm_monitor_action_group.default,
azurerm_data_protection_backup_policy_blob_storage.default
]
}
container.tf
resource "azurerm_storage_container" "example" {
for_each = var.storage_container
name = each.value["name"]
storage_account_name = element(values(azurerm_storage_account.default)[*].name, length(var.storage_accounts))
container_access_type = lookup(each.value, "container_access_type", "private")
metadata = lookup(each.value, "container_access_type", {})
}
For to configure monitoring I used variable blob_storage, map(object), where I provided parameters as, name, resource_group and others need to configure resource.
By default all features are implemented when run.
My idea for code improvement is to configurer in the monitoring resources, a trigger to disable services but to continue using all parameters sent to the blob_storage variable.
Is This possible?
In case it not possible, could you suggest another way.
I hope I was clear in my idea, but if I wasn’t please let me know and I will try explain again.