From 2b9b074b9cc7c6b4bfd8e68fd18bebb0db825abb Mon Sep 17 00:00:00 2001 From: ryhud Date: Mon, 25 Oct 2021 10:45:29 -0400 Subject: [PATCH] adding Azure Bastion and DSVM --- .../bastion.tf | 125 ++++++++++++++++++ .../dsvm.tf | 52 ++++++++ .../network.tf | 15 +++ .../variables.tf | 29 ++++ 4 files changed, 221 insertions(+) create mode 100644 quickstart/201-machine-learning-moderately-secure/bastion.tf create mode 100644 quickstart/201-machine-learning-moderately-secure/dsvm.tf diff --git a/quickstart/201-machine-learning-moderately-secure/bastion.tf b/quickstart/201-machine-learning-moderately-secure/bastion.tf new file mode 100644 index 00000000..d8cae3d8 --- /dev/null +++ b/quickstart/201-machine-learning-moderately-secure/bastion.tf @@ -0,0 +1,125 @@ +resource "azurerm_public_ip" "azure_bastion" { + name = "pip-azure-bastion" + location = azurerm_resource_group.default.location + resource_group_name = azurerm_resource_group.default.name + allocation_method = "Static" + sku = "Standard" +} + +resource "azurerm_network_security_group" "bastion_nsg" { + name = "nsg-bastion" + location = azurerm_resource_group.default.location + resource_group_name = azurerm_resource_group.default.name + + security_rule { + name = "AllowHTTPSInbound" + priority = 100 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "443" + source_address_prefix = "Internet" + destination_address_prefix = "*" + } + security_rule { + name = "AllowGatewayManagerInbound" + priority = 200 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "443" + source_address_prefix = "GatewayManager" + destination_address_prefix = "*" + } + security_rule { + name = "AllowAzureLBInbound" + priority = 300 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "443" + source_address_prefix = "AzureLoadBalancer" + destination_address_prefix = "*" + } + security_rule { + name = "AllowBastionHostCommunication" + priority = 400 + direction = "Inbound" + access = "Allow" + protocol = "*" + source_port_range = "*" + destination_port_ranges = ["5701","8080"] + source_address_prefix = "VirtualNetwork" + destination_address_prefix = "VirtualNetwork" + } + security_rule { + name = "AllowRdpSshOutbound" + priority = 100 + direction = "Outbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_ranges = ["22", "3389"] + source_address_prefix = "*" + destination_address_prefix = "VirtualNetwork" + } + security_rule { + name = "AllowBastionHostCommunicationOutbound" + priority = 110 + direction = "Outbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_ranges = ["5701", "8080"] + source_address_prefix = "VirtualNetwork" + destination_address_prefix = "VirtualNetwork" + } + security_rule { + name = "AllowAzureCloudOutbound" + priority = 120 + direction = "Outbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_ranges = ["443"] + source_address_prefix = "*" + destination_address_prefix = "AzureCloud" + } + security_rule { + name = "AllowGetSessionInformation" + priority = 130 + direction = "Outbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_ranges = ["80"] + source_address_prefix = "*" + destination_address_prefix = "Internet" +} + +} + +resource "azurerm_subnet_network_security_group_association" "bastion_nsg_assoc" { + subnet_id = azurerm_subnet.azure_bastion.id + network_security_group_id = azurerm_network_security_group.bastion_nsg.id + depends_on = [ + azurerm_bastion_host.azure_bastion_instance + ] +} + + +resource "azurerm_bastion_host" "azure_bastion_instance" { + name = "bas-${var.name}-${var.environment}" + location = azurerm_resource_group.default.location + resource_group_name = azurerm_resource_group.default.name + + ip_configuration { + name = "configuration" + subnet_id = azurerm_subnet.azure_bastion.id + public_ip_address_id = azurerm_public_ip.azure_bastion.id + } +} + diff --git a/quickstart/201-machine-learning-moderately-secure/dsvm.tf b/quickstart/201-machine-learning-moderately-secure/dsvm.tf new file mode 100644 index 00000000..0ad12aa8 --- /dev/null +++ b/quickstart/201-machine-learning-moderately-secure/dsvm.tf @@ -0,0 +1,52 @@ +resource "azurerm_network_interface" "dsvm" { + name = "nic-${var.dsvm_name}" + location = azurerm_resource_group.default.location + resource_group_name = azurerm_resource_group.default.name + + ip_configuration { + name = "configuration" + subnet_id = azurerm_subnet.snet-dsvm.id + private_ip_address_allocation = "Dynamic" + } + /*depends_on = [ + azurerm_route_table.jumphost_rt + ] + */ +} + +resource "azurerm_windows_virtual_machine" "dsvm" { + name = var.dsvm_name + location = azurerm_resource_group.default.location + resource_group_name = azurerm_resource_group.default.name + network_interface_ids = [ + azurerm_network_interface.dsvm.id + ] + size = "Standard_DS3_v2" + + source_image_reference { + publisher = "microsoft-dsvm" + offer = "dsvm-win-2019" + sku = "server-2019" + version = "latest" + } + + os_disk { + name = "osdisk-${var.dsvm_name}" + caching = "ReadWrite" + storage_account_type = "Premium_LRS" + } + + identity { + type = "SystemAssigned" + } + computer_name = var.dsvm_name + admin_username = var.dsvm_admin_username + admin_password = var.dsvm_host_password + + provision_vm_agent = true + + timeouts { + create = "60m" + delete = "2h" + } +} diff --git a/quickstart/201-machine-learning-moderately-secure/network.tf b/quickstart/201-machine-learning-moderately-secure/network.tf index 0e56d74d..11bf0c28 100644 --- a/quickstart/201-machine-learning-moderately-secure/network.tf +++ b/quickstart/201-machine-learning-moderately-secure/network.tf @@ -30,6 +30,21 @@ resource "azurerm_subnet" "snet-workspace" { enforce_private_link_endpoint_network_policies = true } +resource "azurerm_subnet" "snet-dsvm" { + name = "snet-dsvm" + resource_group_name = azurerm_resource_group.default.name + virtual_network_name = azurerm_virtual_network.default.name + address_prefixes = var.dsvm_subnet_address_space + enforce_private_link_endpoint_network_policies = true +} + +resource "azurerm_subnet" "azure_bastion" { + name = "AzureBastionSubnet" + resource_group_name = azurerm_resource_group.default.name + virtual_network_name = azurerm_virtual_network.default.name + address_prefixes = var.bastion_subnet_address_space +} + # Private DNS Zones resource "azurerm_private_dns_zone" "dnsvault" { name = "privatelink.vaultcore.azure.net" diff --git a/quickstart/201-machine-learning-moderately-secure/variables.tf b/quickstart/201-machine-learning-moderately-secure/variables.tf index 6a67c802..fb8299d2 100644 --- a/quickstart/201-machine-learning-moderately-secure/variables.tf +++ b/quickstart/201-machine-learning-moderately-secure/variables.tf @@ -38,9 +38,38 @@ variable "ml_subnet_address_space" { description = "Address space of the ML workspace subnet" default = ["10.0.0.0/24"] } +variable "dsvm_subnet_address_space" { + type = list(string) + description = "Address space of the DSVM subnet" + default = ["10.0.4.0/24"] +} + +variable "bastion_subnet_address_space" { + type = list(string) + description = "Address space of the bastion subnet" + default = ["10.0.5.0/24"] +} variable "image_build_compute_name" { type = string description = "Name of the compute cluster to be created and set to build docker images" default = "image-builder" +} + +# DSVM Variables +variable "dsvm_name" { + type = string + description = "Name of the Data Science VM" + default = "vmdsvm01" +} +variable "dsvm_admin_username" { + type = string + description = "Admin username of the Data Science VM" + default = "azureadmin" +} + +variable "dsvm_host_password" { + type = string + description = "Password for the admin username of the Data Science VM" + sensitive = true } \ No newline at end of file