deploy/terraform/terraform-units/modules/sap_landscape/iscsi.tf (385 lines of code) (raw):

# Copyright (c) Microsoft Corporation. # Licensed under the MIT License. #######################################4#######################################8 # # # iSCSI # # # #######################################4#######################################8 /* Only create/import iSCSI subnet and nsg when iSCSI device(s) will be deployed */ // Creates iSCSI subnet of SAP VNET resource "azurerm_subnet" "iscsi" { provider = azurerm.main count = local.enable_sub_iscsi ? (local.sub_iscsi_exists ? 0 : 1) : 0 name = local.sub_iscsi_name resource_group_name = local.SAP_virtualnetwork_exists ? ( data.azurerm_virtual_network.vnet_sap[0].resource_group_name) : ( azurerm_virtual_network.vnet_sap[0].resource_group_name ) virtual_network_name = local.SAP_virtualnetwork_exists ? ( data.azurerm_virtual_network.vnet_sap[0].name) : ( azurerm_virtual_network.vnet_sap[0].name ) address_prefixes = [local.sub_iscsi_prefix] service_endpoints = var.use_service_endpoint ? ( ["Microsoft.Storage", "Microsoft.KeyVault"] ) : ( null ) } // Imports data of existing SAP iSCSI subnet data "azurerm_subnet" "iscsi" { provider = azurerm.main count = local.enable_sub_iscsi ? (local.sub_iscsi_exists ? 1 : 0) : 0 name = split("/", local.sub_iscsi_arm_id)[10] resource_group_name = split("/", local.sub_iscsi_arm_id)[4] virtual_network_name = split("/", local.sub_iscsi_arm_id)[8] } // Creates SAP iSCSI subnet nsg resource "azurerm_network_security_group" "iscsi" { provider = azurerm.main count = local.enable_sub_iscsi ? (local.sub_iscsi_nsg_exists ? 0 : 1) : 0 name = local.sub_iscsi_nsg_name resource_group_name = local.resource_group_exists ? ( data.azurerm_resource_group.resource_group[0].name) : ( azurerm_resource_group.resource_group[0].name ) location = local.resource_group_exists ? ( data.azurerm_resource_group.resource_group[0].location) : ( azurerm_resource_group.resource_group[0].location ) tags = var.tags } // Imports the SAP iSCSI subnet nsg data data "azurerm_network_security_group" "iscsi" { provider = azurerm.main count = local.enable_sub_iscsi ? (local.sub_iscsi_nsg_exists ? 1 : 0) : 0 name = split("/", local.sub_iscsi_nsg_arm_id)[8] resource_group_name = split("/", local.sub_iscsi_nsg_arm_id)[4] } resource "azurerm_subnet_route_table_association" "iscsi" { provider = azurerm.main count = local.enable_iscsi && !local.SAP_virtualnetwork_exists && !local.sub_iscsi_exists ? (local.create_nat_gateway ? 0 : 1) : 0 depends_on = [ azurerm_route_table.rt, azurerm_subnet.iscsi ] subnet_id = local.sub_iscsi_exists ? var.infrastructure.virtual_networks.sap.sub_iscsi.arm_id : azurerm_subnet.iscsi[0].id route_table_id = azurerm_route_table.rt[0].id } // TODO: Add nsr to iSCSI's nsg /* iSCSI device IP address range: .4 - */ // Creates the NIC and IP address for iSCSI device resource "azurerm_network_interface" "iscsi" { provider = azurerm.main count = local.iscsi_count name = format("%s%s%s%s%s", var.naming.resource_prefixes.nic, local.prefix, var.naming.separator, local.virtualmachine_names[count.index], local.resource_suffixes.nic ) resource_group_name = local.resource_group_exists ? ( data.azurerm_resource_group.resource_group[0].name) : ( azurerm_resource_group.resource_group[0].name ) location = local.resource_group_exists ? ( data.azurerm_resource_group.resource_group[0].location) : ( azurerm_resource_group.resource_group[0].location ) tags = var.tags ip_configuration { name = "ipconfig1" subnet_id = local.sub_iscsi_exists ? ( data.azurerm_subnet.iscsi[0].id) : ( azurerm_subnet.iscsi[0].id ) private_ip_address = local.use_DHCP ? ( null) : ( local.sub_iscsi_exists ? ( local.iscsi_nic_ips[count.index]) : ( cidrhost(local.sub_iscsi_prefix, tonumber(count.index) + 4) ) ) private_ip_address_allocation = local.use_DHCP ? "Dynamic" : "Static" } } // Add SSH network security rule resource "azurerm_network_security_rule" "nsr_controlplane_iscsi" { provider = azurerm.main count = local.enable_sub_iscsi ? local.sub_iscsi_nsg_exists ? 0 : 1 : 0 depends_on = [ azurerm_network_security_group.iscsi ] name = "ConnectivityToISCSISubnetFromControlPlane-ssh-rdp-winrm" resource_group_name = local.SAP_virtualnetwork_exists ? ( data.azurerm_virtual_network.vnet_sap[0].resource_group_name ) : ( azurerm_virtual_network.vnet_sap[0].resource_group_name ) network_security_group_name = try(azurerm_network_security_group.iscsi[0].name, azurerm_network_security_group.app[0].name) priority = 100 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_ranges = [22, 443, 3389, 5985, 5986, 2049, 111] source_address_prefixes = compact(concat( var.deployer_tfstate.subnet_mgmt_address_prefixes, var.deployer_tfstate.subnet_bastion_address_prefixes, local.SAP_virtualnetwork_exists ? ( flatten(data.azurerm_virtual_network.vnet_sap[0].address_space)) : ( flatten(azurerm_virtual_network.vnet_sap[0].address_space) ))) destination_address_prefixes = local.sub_iscsi_exists ? data.azurerm_subnet.iscsi[0].address_prefixes : azurerm_subnet.iscsi[0].address_prefixes } // Manages the association between NIC and NSG resource "azurerm_network_interface_security_group_association" "iscsi" { provider = azurerm.main count = local.iscsi_count network_interface_id = azurerm_network_interface.iscsi[count.index].id network_security_group_id = local.sub_iscsi_nsg_exists ? ( data.azurerm_network_security_group.iscsi[0].id) : ( azurerm_network_security_group.iscsi[0].id ) } // Manages Linux Virtual Machine for iSCSI resource "azurerm_linux_virtual_machine" "iscsi" { provider = azurerm.main count = local.iscsi_count name = format("%s%s%s%s%s", var.naming.resource_prefixes.vm, local.prefix, var.naming.separator, local.virtualmachine_names[count.index], local.resource_suffixes.vm ) computer_name = local.virtualmachine_names[count.index] resource_group_name = local.resource_group_exists ? ( data.azurerm_resource_group.resource_group[0].name) : ( azurerm_resource_group.resource_group[0].name ) location = local.resource_group_exists ? ( data.azurerm_resource_group.resource_group[0].location) : ( azurerm_resource_group.resource_group[0].location ) tags = var.tags network_interface_ids = [azurerm_network_interface.iscsi[count.index].id] size = local.iscsi.size admin_username = local.iscsi.authentication.username admin_password = local.iscsi_auth_password disable_password_authentication = local.enable_iscsi_auth_key //If length of zones > 1 distribute servers evenly across zones zone = try(local.iscsi.zones[count.index % max(length(local.iscsi.zones), 1)], null) //custom_data = try(data.template_cloudinit_config.config_growpart.rendered, "Cg==") patch_mode = var.infrastructure.patch_mode patch_assessment_mode = var.infrastructure.patch_assessment_mode bypass_platform_safety_checks_on_user_schedule_enabled = var.infrastructure.patch_mode != "AutomaticByPlatform" ? false : true vm_agent_platform_updates_enabled = true encryption_at_host_enabled = var.infrastructure.encryption_at_host_enabled os_disk { name = format("%s%s%s%s%s", var.naming.resource_prefixes.osdisk, local.prefix, var.naming.separator, local.virtualmachine_names[count.index], local.resource_suffixes.osdisk ) caching = "ReadWrite" storage_account_type = "Premium_LRS" } source_image_reference { publisher = local.iscsi.os.publisher offer = local.iscsi.os.offer sku = local.iscsi.os.sku version = "latest" } dynamic "admin_ssh_key" { for_each = range(local.enable_iscsi_auth_key ? 1 : 0) content { username = local.iscsi_auth_username public_key = local.iscsi_public_key } } boot_diagnostics { storage_account_uri = length(var.diagnostics_storage_account.arm_id) > 0 ? ( data.azurerm_storage_account.storage_bootdiag[0].primary_blob_endpoint) : ( azurerm_storage_account.storage_bootdiag[0].primary_blob_endpoint ) } dynamic "identity" { for_each = range(length(var.infrastructure.iscsi.user_assigned_identity_id) > 0 ? 1 : 0) content { type = "UserAssigned" identity_ids = [var.infrastructure.iscsi.user_assigned_identity_id] } } } // Define a cloud-init config that disables the automatic expansion // of the root partition. data "template_cloudinit_config" "config_growpart" { gzip = true base64_encode = true # Main cloud-config configuration file. part { content_type = "text/cloud-config" content = "growpart: {'mode': 'auto'}" } } resource "azurerm_key_vault_secret" "iscsi_ppk" { provider = azurerm.main count = (local.create_workloadzone_keyvault && local.enable_iscsi_auth_key && !local.iscsi_key_exist) ? 1 : 0 depends_on = [ azurerm_key_vault_access_policy.kv_user, azurerm_role_assignment.role_assignment_spn, azurerm_role_assignment.role_assignment_msi, azurerm_key_vault_access_policy.kv_user_msi, azurerm_private_endpoint.kv_user ] content_type = "secret" name = local.iscsi_ppk_name value = local.iscsi_private_key key_vault_id = local.user_keyvault_exist ? local.user_key_vault_id : azurerm_key_vault.kv_user[0].id expiration_date = var.key_vault.set_secret_expiry ? ( time_offset.secret_expiry_date.rfc3339) : ( null ) } resource "azurerm_key_vault_secret" "iscsi_pk" { provider = azurerm.main count = (local.create_workloadzone_keyvault && local.enable_iscsi_auth_key && !local.iscsi_key_exist) ? 1 : 0 depends_on = [ azurerm_key_vault_access_policy.kv_user, azurerm_role_assignment.role_assignment_spn, azurerm_role_assignment.role_assignment_msi, azurerm_key_vault_access_policy.kv_user_msi, azurerm_private_endpoint.kv_user ] content_type = "secret" name = local.iscsi_pk_name value = local.iscsi_public_key key_vault_id = local.user_keyvault_exist ? local.user_key_vault_id : azurerm_key_vault.kv_user[0].id expiration_date = var.key_vault.set_secret_expiry ? ( time_offset.secret_expiry_date.rfc3339) : ( null ) } resource "azurerm_key_vault_secret" "iscsi_username" { provider = azurerm.main count = (local.create_workloadzone_keyvault && local.enable_iscsi && !local.iscsi_username_exist) ? 1 : 0 depends_on = [ azurerm_key_vault_access_policy.kv_user, azurerm_role_assignment.role_assignment_spn, azurerm_role_assignment.role_assignment_msi, azurerm_key_vault_access_policy.kv_user_msi, azurerm_private_endpoint.kv_user ] content_type = "configuration" name = local.iscsi_username_name value = local.iscsi_auth_username key_vault_id = local.user_keyvault_exist ? local.user_key_vault_id : azurerm_key_vault.kv_user[0].id expiration_date = var.key_vault.set_secret_expiry ? ( time_offset.secret_expiry_date.rfc3339) : ( null ) } resource "azurerm_key_vault_secret" "iscsi_password" { provider = azurerm.main count = (local.create_workloadzone_keyvault && local.enable_iscsi_auth_password && !local.iscsi_pwd_exist) ? 1 : 0 depends_on = [ azurerm_key_vault_access_policy.kv_user, azurerm_role_assignment.role_assignment_spn, azurerm_role_assignment.role_assignment_msi, azurerm_key_vault_access_policy.kv_user_msi, azurerm_private_endpoint.kv_user ] content_type = "secret" name = local.iscsi_pwd_name value = local.iscsi_auth_password key_vault_id = local.user_keyvault_exist ? local.user_key_vault_id : azurerm_key_vault.kv_user[0].id expiration_date = var.key_vault.set_secret_expiry ? ( time_offset.secret_expiry_date.rfc3339) : ( null ) } // Generate random password if password is set as authentication type and user doesn't specify a password, and save in KV resource "random_password" "iscsi_password" { count = (local.create_workloadzone_keyvault && local.enable_iscsi_auth_password && !local.iscsi_pwd_exist && try(var.authentication.password, null) == null) ? 1 : 0 length = 32 min_upper = 2 min_lower = 2 min_numeric = 2 special = true override_special = "_%@" } // Import secrets about iSCSI data "azurerm_key_vault_secret" "iscsi_pk" { provider = azurerm.main count = (local.create_workloadzone_keyvault && local.enable_iscsi_auth_key && local.iscsi_key_exist) ? 1 : 0 name = local.iscsi_pk_name key_vault_id = local.user_key_vault_id } data "azurerm_key_vault_secret" "iscsi_ppk" { provider = azurerm.main count = (local.create_workloadzone_keyvault && local.enable_iscsi_auth_key && local.iscsi_key_exist) ? 1 : 0 name = local.iscsi_ppk_name key_vault_id = local.user_key_vault_id } data "azurerm_key_vault_secret" "iscsi_password" { provider = azurerm.main count = (local.create_workloadzone_keyvault && local.enable_iscsi_auth_password && local.iscsi_pwd_exist) ? 1 : 0 name = local.iscsi_pwd_name key_vault_id = local.user_key_vault_id } data "azurerm_key_vault_secret" "iscsi_username" { provider = azurerm.main count = (local.create_workloadzone_keyvault && local.enable_iscsi && local.iscsi_username_exist) ? 1 : 0 name = local.iscsi_username_name key_vault_id = local.user_key_vault_id } // Using TF tls to generate SSH key pair for iscsi devices and store in user KV resource "tls_private_key" "iscsi" { count = ( local.create_workloadzone_keyvault && local.enable_iscsi_auth_key && !local.iscsi_key_exist && try(file(var.authentication.path_to_public_key), null) == null ) ? 1 : 0 algorithm = "RSA" rsa_bits = 2048 } resource "azurerm_virtual_machine_extension" "monitoring_extension_iscsi_lnx" { provider = azurerm.main count = local.deploy_monitoring_extension ? ( local.iscsi_count) : ( 0 ) virtual_machine_id = azurerm_linux_virtual_machine.iscsi[count.index].id name = "Microsoft.Azure.Monitor.AzureMonitorLinuxAgent" publisher = "Microsoft.Azure.Monitor" type = "AzureMonitorLinuxAgent" type_handler_version = "1.0" auto_upgrade_minor_version = true automatic_upgrade_enabled = true } resource "azurerm_virtual_machine_extension" "monitoring_defender_iscsi_lnx" { provider = azurerm.main count = var.infrastructure.deploy_defender_extension ? ( local.iscsi_count) : ( 0 ) virtual_machine_id = azurerm_linux_virtual_machine.iscsi[count.index].id name = "Microsoft.Azure.Security.Monitoring.AzureSecurityLinuxAgent" publisher = "Microsoft.Azure.Security.Monitoring" type = "AzureSecurityLinuxAgent" type_handler_version = "2.0" auto_upgrade_minor_version = true automatic_upgrade_enabled = true settings = jsonencode( { "authentication" = { "managedIdentity" = { "identifier-name" : "mi_res_id", "identifier-value": var.infrastructure.iscsi.user_assigned_identity_id } } } ) }