main.tf (193 lines of code) (raw):

resource "azurerm_mssql_managed_instance" "this" { administrator_login = var.administrator_login administrator_login_password = var.administrator_login_password license_type = var.license_type location = var.location name = var.name resource_group_name = var.resource_group_name sku_name = var.sku_name storage_size_in_gb = var.storage_size_in_gb subnet_id = var.subnet_id vcores = var.vcores collation = var.collation dns_zone_partner_id = var.dns_zone_partner_id maintenance_configuration_name = var.maintenance_configuration_name minimum_tls_version = var.minimum_tls_version proxy_override = var.proxy_override public_data_endpoint_enabled = var.public_data_endpoint_enabled storage_account_type = var.storage_account_type tags = var.tags timezone_id = var.timezone_id zone_redundant_enabled = var.zone_redundant_enabled dynamic "timeouts" { for_each = var.timeouts == null ? [] : [var.timeouts] content { create = timeouts.value.create delete = timeouts.value.delete read = timeouts.value.read update = timeouts.value.update } } # identity is done via an azapi_resource_action further on, because of this bug that # prevents system & user assigned identities being set at the same time. # https://github.com/hashicorp/terraform-provider-azurerm/issues/19802 lifecycle { ignore_changes = [ identity ] } } resource "azurerm_mssql_managed_instance_active_directory_administrator" "this" { count = try(var.active_directory_administrator.object_id, null) == null ? 0 : 1 login_username = var.active_directory_administrator.login_username managed_instance_id = azurerm_mssql_managed_instance.this.id object_id = var.active_directory_administrator.object_id tenant_id = var.active_directory_administrator.tenant_id azuread_authentication_only = var.active_directory_administrator.azuread_authentication_only dynamic "timeouts" { for_each = var.active_directory_administrator.timeouts == null ? [] : [var.active_directory_administrator.timeouts] content { create = timeouts.value.create delete = timeouts.value.delete read = timeouts.value.read update = timeouts.value.update } } } # https://learn.microsoft.com/en-us/rest/api/sql/managed-server-security-alert-policies/create-or-update?view=rest-sql-2023-08-01-preview&tabs=HTTP resource "azapi_resource_action" "mssql_managed_instance_security_alert_policy" { count = var.security_alert_policy == {} ? 0 : 1 resource_id = "${azurerm_mssql_managed_instance.this.id}/securityAlertPolicies/Default" type = "Microsoft.Sql/managedInstances/securityAlertPolicies@2023-08-01-preview" body = { properties = { disabledAlerts = try(var.security_alert_policy.disabled_alerts, []) emailAccountAdmins = try(var.security_alert_policy.email_account_admins_enabled, false) emailAddresses = try(var.security_alert_policy.email_addresses, []) retentionDays = try(var.security_alert_policy.retention_days, 0) state = try(var.security_alert_policy.enabled ? "Enabled" : "Disabled", "Enabled") storageAccountAccessKey = try(var.security_alert_policy.storage_account_access_key, null) storageEndpoint = try(var.security_alert_policy.storage_endpoint, null) } } method = "PUT" } resource "azurerm_mssql_managed_instance_transparent_data_encryption" "this" { count = var.transparent_data_encryption == {} ? 0 : 1 managed_instance_id = azurerm_mssql_managed_instance.this.id auto_rotation_enabled = var.transparent_data_encryption.auto_rotation_enabled key_vault_key_id = var.transparent_data_encryption.key_vault_key_id dynamic "timeouts" { for_each = var.transparent_data_encryption.timeouts == null ? [] : [var.transparent_data_encryption.timeouts] content { create = timeouts.value.create delete = timeouts.value.delete read = timeouts.value.read update = timeouts.value.update } } } # API: # https://learn.microsoft.com/en-us/rest/api/sql/managed-instance-vulnerability-assessments/create-or-update?view=rest-sql-2023-08-01-preview&tabs=HTTP # # Note that user assigned identities are not support for vulnerability assessments, so must use user assigned & system assigned, or just system assigned. # https://learn.microsoft.com/en-us/azure/azure-sql/database/sql-database-vulnerability-assessment-storage?view=azuresql#store-va-scan-results-for-azure-sql-managed-instance-in-a-storage-account-that-can-be-accessed-behind-a-firewall-or-vnet resource "azapi_resource_action" "mssql_managed_instance_vulnerability_assessment" { count = var.vulnerability_assessment == null ? 0 : 1 resource_id = "${azurerm_mssql_managed_instance.this.id}/vulnerabilityAssessments/default" type = "Microsoft.Sql/managedInstances/vulnerabilityAssessments@2023-08-01-preview" body = { properties = { storageAccountAccessKey = try(var.vulnerability_assessment.storage_account_access_key, null) storageContainerPath = try(var.vulnerability_assessment.storage_container_path, null) storageContainerSasKey = try(var.vulnerability_assessment.storage_container_sas_key, null) recurringScans = var.vulnerability_assessment.recurring_scans != {} ? { isEnabled = try(var.vulnerability_assessment.recurring_scans.enabled, true) emailSubscriptionAdmins = try(var.vulnerability_assessment.recurring_scans.email_subscription_admins, true), emails = try(var.vulnerability_assessment.recurring_scans.emails, []) } : null } } method = "PUT" } # this is required for vulnerability assessments to function - user assigned identities are not supported # https://learn.microsoft.com/en-us/azure/azure-sql/database/sql-database-vulnerability-assessment-storage?view=azuresql resource "azurerm_role_assignment" "sqlmi_system_assigned" { count = var.storage_account_resource_id != null ? 1 : 0 principal_id = jsondecode(data.azapi_resource.identity.output).identity.principal_id scope = var.storage_account_resource_id role_definition_name = "Storage Blob Data Contributor" } # required AVM resources interfaces resource "azurerm_management_lock" "this" { count = var.lock != null ? 1 : 0 lock_level = var.lock.kind name = coalesce(var.lock.name, "lock-${var.lock.kind}") scope = azurerm_mssql_managed_instance.this.id notes = var.lock.kind == "CanNotDelete" ? "Cannot delete the resource or its child resources." : "Cannot delete or modify the resource or its child resources." } resource "azurerm_role_assignment" "this" { for_each = var.role_assignments principal_id = each.value.principal_id scope = azurerm_mssql_managed_instance.this.id condition = each.value.condition condition_version = each.value.condition_version delegated_managed_identity_resource_id = each.value.delegated_managed_identity_resource_id role_definition_id = strcontains(lower(each.value.role_definition_id_or_name), lower(local.role_definition_resource_substring)) ? each.value.role_definition_id_or_name : null role_definition_name = strcontains(lower(each.value.role_definition_id_or_name), lower(local.role_definition_resource_substring)) ? null : each.value.role_definition_id_or_name skip_service_principal_aad_check = each.value.skip_service_principal_aad_check } # identity is done via an azapi_resource_action further on, because of this bug that # prevents system & user assigned identities being set at the same time. # https://github.com/hashicorp/terraform-provider-azurerm/issues/19802 resource "azapi_resource_action" "sql_managed_instance_patch_identities" { count = local.managed_identities.system_assigned_user_assigned == {} ? 0 : 1 resource_id = azurerm_mssql_managed_instance.this.id type = "Microsoft.Sql/managedInstances@2023-05-01-preview" body = { identity = { type = local.managed_identities.system_assigned_user_assigned.this.type userAssignedIdentities = { for id in tolist(local.managed_identities.system_assigned_user_assigned.this.user_assigned_resource_ids) : id => {} } }, properties = { primaryUserAssignedIdentityId = length(local.managed_identities.system_assigned_user_assigned.this.user_assigned_resource_ids) > 0 ? tolist(local.managed_identities.system_assigned_user_assigned.this.user_assigned_resource_ids)[0] : null } } method = "PATCH" } data "azurerm_resource_group" "parent" { name = azurerm_mssql_managed_instance.this.resource_group_name } data "azapi_resource" "identity" { type = "Microsoft.Sql/managedInstances@2023-05-01-preview" name = azurerm_mssql_managed_instance.this.name parent_id = data.azurerm_resource_group.parent.id response_export_values = ["identity"] depends_on = [azapi_resource_action.sql_managed_instance_patch_identities] } resource "azapi_resource_action" "sql_advanced_threat_protection" { resource_id = "${azurerm_mssql_managed_instance.this.id}/advancedThreatProtectionSettings/Default" type = "Microsoft.Sql/managedInstances/advancedThreatProtectionSettings@2023-08-01-preview" body = { properties = { state = var.enable_advanced_threat_protection ? "Enabled" : "Disabled" } } method = "PUT" } resource "azurerm_monitor_diagnostic_setting" "this" { for_each = var.diagnostic_settings name = each.value.name != null ? each.value.name : "diag-${var.name}" target_resource_id = azurerm_mssql_managed_instance.this.id eventhub_authorization_rule_id = each.value.event_hub_authorization_rule_resource_id eventhub_name = each.value.event_hub_name log_analytics_destination_type = each.value.log_analytics_destination_type log_analytics_workspace_id = each.value.workspace_resource_id partner_solution_id = each.value.marketplace_partner_resource_id storage_account_id = each.value.storage_account_resource_id dynamic "enabled_log" { for_each = each.value.log_categories content { category = enabled_log.value } } dynamic "enabled_log" { for_each = each.value.log_groups content { category_group = enabled_log.value } } dynamic "metric" { for_each = each.value.metric_categories content { category = metric.value } } }