From 367069e4ec136d117a7663d3a8d8a00514e18200 Mon Sep 17 00:00:00 2001 From: Mihail Radkov Date: Fri, 17 Nov 2023 10:44:37 +0200 Subject: [PATCH] TES-350: NAT gateway Added NAT gateway for outbound connectivity from GraphDB's VMSS subnet. - Added new nat module that will create single zone NAT gateway - Disabled public IP for GraphDB's VMSS instances - Removed internet connectivity check in the user data script - Added additional output variables in the address module --- main.tf | 14 +++++++++ modules/address/outputs.tf | 7 ++++- modules/nat/README.md | 1 + modules/nat/main.tf | 39 ++++++++++++++++++++++++++ modules/nat/outputs.tf | 9 ++++++ modules/nat/variables.tf | 34 ++++++++++++++++++++++ modules/nat/versions.tf | 10 +++++++ modules/vm/main.tf | 18 ++++++------ modules/vm/templates/entrypoint.sh.tpl | 7 +---- 9 files changed, 122 insertions(+), 17 deletions(-) create mode 100644 modules/nat/README.md create mode 100644 modules/nat/main.tf create mode 100644 modules/nat/outputs.tf create mode 100644 modules/nat/variables.tf create mode 100644 modules/nat/versions.tf diff --git a/main.tf b/main.tf index bc2c669..bfde731 100644 --- a/main.tf +++ b/main.tf @@ -174,6 +174,20 @@ module "bastion" { tags = local.tags } +# Creates a NAT gateway associated with GraphDB's subnet +module "nat" { + source = "./modules/nat" + + resource_name_prefix = var.resource_name_prefix + location = var.location + resource_group_name = azurerm_resource_group.graphdb.name + zones = var.zones + + nat_subnet_id = azurerm_subnet.graphdb-vmss.id + + tags = local.tags +} + # Creates a VM scale set for GraphDB and GraphDB cluster proxies module "vm" { source = "./modules/vm" diff --git a/modules/address/outputs.tf b/modules/address/outputs.tf index 1dc74c0..c05bb8f 100644 --- a/modules/address/outputs.tf +++ b/modules/address/outputs.tf @@ -3,8 +3,13 @@ output "public_ip_address_name" { value = azurerm_public_ip.graphdb-public-ip-address.name } +output "public_ip_address" { + description = "The public IPv4 address" + value = azurerm_public_ip.graphdb-public-ip-address.ip_address +} + output "public_ip_address_id" { - description = "Name of the public IP address" + description = "Identifier of the public IP address" value = azurerm_public_ip.graphdb-public-ip-address.id } diff --git a/modules/nat/README.md b/modules/nat/README.md new file mode 100644 index 0000000..d7ce7fa --- /dev/null +++ b/modules/nat/README.md @@ -0,0 +1 @@ +# GraphDB NAT Module diff --git a/modules/nat/main.tf b/modules/nat/main.tf new file mode 100644 index 0000000..97a5397 --- /dev/null +++ b/modules/nat/main.tf @@ -0,0 +1,39 @@ +locals { + # Choose one of the zones for single zone NAT + # TODO: Is it okay to take the first one ? + nat_zone = var.zones[0] +} + +resource "azurerm_public_ip" "graphdb-nat-ip-address" { + name = "${var.resource_name_prefix}-nat-gateway" + resource_group_name = var.resource_group_name + location = var.location + + sku = "Standard" + allocation_method = "Static" + zones = [local.nat_zone] + + tags = var.tags +} + +resource "azurerm_nat_gateway" "graphdb" { + name = var.resource_name_prefix + resource_group_name = var.resource_group_name + location = var.location + + sku_name = "Standard" + zones = [local.nat_zone] + idle_timeout_in_minutes = 10 # TODO: 120 is the max in the portal, gotta test with long running request + + tags = var.tags +} + +resource "azurerm_nat_gateway_public_ip_association" "graphdb-nat" { + nat_gateway_id = azurerm_nat_gateway.graphdb.id + public_ip_address_id = azurerm_public_ip.graphdb-nat-ip-address.id +} + +resource "azurerm_subnet_nat_gateway_association" "graphdb-nat" { + nat_gateway_id = azurerm_nat_gateway.graphdb.id + subnet_id = var.nat_subnet_id +} diff --git a/modules/nat/outputs.tf b/modules/nat/outputs.tf new file mode 100644 index 0000000..47e43d6 --- /dev/null +++ b/modules/nat/outputs.tf @@ -0,0 +1,9 @@ +output "nat_public_ip_address" { + description = "The public IPv4 address for the NAT gateway" + value = azurerm_public_ip.graphdb-nat-ip-address.ip_address +} + +output "nat_public_ip_address_id" { + description = "Identifier of the public IP address for the NAT gateway" + value = azurerm_public_ip.graphdb-nat-ip-address.id +} diff --git a/modules/nat/variables.tf b/modules/nat/variables.tf new file mode 100644 index 0000000..493b74b --- /dev/null +++ b/modules/nat/variables.tf @@ -0,0 +1,34 @@ +# General configurations + +variable "resource_name_prefix" { + description = "Resource name prefix used for tagging and naming Azure resources" + type = string +} + +variable "location" { + description = "Azure geographical location where resources will be deployed" + type = string +} + +variable "zones" { + description = "Availability zones to use for resource deployment and HA" + type = list(number) +} + +variable "tags" { + description = "Common resource tags." + type = map(string) + default = {} +} + +variable "resource_group_name" { + description = "Name of the resource group where GraphDB will be deployed." + type = string +} + +# Networking + +variable "nat_subnet_id" { + description = "Identifier of the subnet to which the NAT will be associated" + type = string +} diff --git a/modules/nat/versions.tf b/modules/nat/versions.tf new file mode 100644 index 0000000..e9df870 --- /dev/null +++ b/modules/nat/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.5.0" + + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = ">=3.80.0" + } + } +} diff --git a/modules/vm/main.tf b/modules/vm/main.tf index ae62fd4..842c9ba 100644 --- a/modules/vm/main.tf +++ b/modules/vm/main.tf @@ -65,11 +65,12 @@ resource "azurerm_linux_virtual_machine_scale_set" "graphdb" { identity_ids = [var.identity_id] } - sku = var.instance_type - instances = var.node_count - zones = var.zones - zone_balance = true - upgrade_mode = "Manual" + sku = var.instance_type + instances = var.node_count + zones = var.zones + zone_balance = true + upgrade_mode = "Manual" + overprovision = false computer_name_prefix = "${var.resource_name_prefix}-" admin_username = "graphdb" @@ -84,11 +85,6 @@ resource "azurerm_linux_virtual_machine_scale_set" "graphdb" { primary = true subnet_id = var.graphdb_subnet_id application_gateway_backend_address_pool_ids = var.application_gateway_backend_address_pool_ids - - # TODO: Temporary for testing. Remove after configuring the LB - public_ip_address { - name = "first" - } } } @@ -103,6 +99,8 @@ resource "azurerm_linux_virtual_machine_scale_set" "graphdb" { } tags = var.tags + + depends_on = [azurerm_role_assignment.rg-contributor-role] } resource "azurerm_role_definition" "managed_disk_manager" { diff --git a/modules/vm/templates/entrypoint.sh.tpl b/modules/vm/templates/entrypoint.sh.tpl index 17b7064..2c63708 100644 --- a/modules/vm/templates/entrypoint.sh.tpl +++ b/modules/vm/templates/entrypoint.sh.tpl @@ -4,14 +4,9 @@ set -euxo pipefail echo "Configuring GraphDB instance" +# Stop in order to override configurations systemctl stop graphdb -# TODO: If GraphDB is behind closed network, this would break the whole initialization... -until ping -c 1 google.com &> /dev/null; do - echo "waiting for outbound connectivity" - sleep 5 -done - # Login in Azure CLI with managed identity (user or system assigned) az login --identity