# Configure the Azure Provider terraform { required_providers { azurerm = { source = "hashicorp/azurerm" version = "~> 3.0" } } } provider "azurerm" { features {} } data "azurerm_client_config" "current" {} # ----------------------------------------------------------------------------- # Naming Conventions # ----------------------------------------------------------------------------- locals { vm_names = ["Quetzalcoatl", "Huitzilopochtli", "Pachamama", "Viracocha", "Inti"] # Native American Deities network_names = ["Aztec", "Inca", "Maya", "Mississippian", "Anasazi"] # Native American Empires resource_group_name_eastus2 = "muscogee-rg" # Muscogee tribe resource_group_name_westus2 = "sioux-rg" # Sioux tribe resource_group_name_centralus = "cherokee-rg" # Cherokee tribe location_default = "eastus2" # Default region for most resources location_quetzalcoatl = "westus2" location_centralus = "centralus" # New region admin_username = "lenape" key_vault_name_prefix = "kv-secure-creds" storage_account_name = "povertypoint" container_name = "tfstate" } # ----------------------------------------------------------------------------- # 1. Resource Groups # ----------------------------------------------------------------------------- resource "azurerm_resource_group" "rg_eastus2" { name = local.resource_group_name_eastus2 location = local.location_default } resource "azurerm_resource_group" "rg_westus2" { name = local.resource_group_name_westus2 location = local.location_quetzalcoatl } resource "azurerm_resource_group" "rg_centralus" { name = local.resource_group_name_centralus location = local.location_centralus } # ----------------------------------------------------------------------------- # 2. Azure Key Vault for Secure Password Management # ----------------------------------------------------------------------------- resource "azurerm_key_vault" "kv" { name = "${local.key_vault_name_prefix}-${random_string.kv_suffix.result}" location = azurerm_resource_group.rg_eastus2.location resource_group_name = azurerm_resource_group.rg_eastus2.name tenant_id = data.azurerm_client_config.current.tenant_id sku_name = "standard" # Standard SKU is usually sufficient access_policy { tenant_id = data.azurerm_client_config.current.tenant_id object_id = data.azurerm_client_config.current.object_id # Your Azure AD User/Service Principal Object ID key_permissions = [ "Get", ] secret_permissions = [ "Get", "Set", # Required for initial password setting (you might remove this later) ] storage_permissions = [ "Get", ] } } resource "random_password" "admin_password" { length = 20 special = true override_special = "!#$%&*()-_=+[]{}<>:?" } resource "azurerm_key_vault_secret" "admin_password_secret" { name = "linux-admin-password" value = random_password.admin_password.result key_vault_id = azurerm_key_vault.kv.id } resource "random_string" "kv_suffix" { length = 8 lower = true numeric = true special = false } # ----------------------------------------------------------------------------- # 3. Virtual Network and Subnet (in the default region, westus2, and centralus) # ----------------------------------------------------------------------------- resource "azurerm_virtual_network" "vnet" { name = "${local.network_names[0]}-vnet" # Using the first empire name for the VNet location = azurerm_resource_group.rg_eastus2.location resource_group_name = azurerm_resource_group.rg_eastus2.name address_space = ["10.0.0.0/16"] } resource "azurerm_subnet" "subnet" { name = "default" resource_group_name = azurerm_resource_group.rg_eastus2.name virtual_network_name = azurerm_virtual_network.vnet.name address_prefixes = ["10.0.1.0/24"] } resource "azurerm_virtual_network" "vnet_westus2" { name = "${local.network_names[0]}-vnet-westus2" location = azurerm_resource_group.rg_westus2.location resource_group_name = azurerm_resource_group.rg_westus2.name address_space = ["10.1.0.0/16"] } resource "azurerm_subnet" "subnet_westus2" { name = "default" resource_group_name = azurerm_resource_group.rg_westus2.name virtual_network_name = azurerm_virtual_network.vnet_westus2.name address_prefixes = ["10.1.1.0/24"] } resource "azurerm_virtual_network" "vnet_centralus" { name = "${local.network_names[0]}-vnet-centralus" location = azurerm_resource_group.rg_centralus.location resource_group_name = azurerm_resource_group.rg_centralus.name address_space = ["10.2.0.0/16"] } resource "azurerm_subnet" "subnet_centralus" { name = "default" resource_group_name = azurerm_resource_group.rg_centralus.name virtual_network_name = azurerm_virtual_network.vnet_centralus.name address_prefixes = ["10.2.1.0/24"] } # ----------------------------------------------------------------------------- # 4. Network Security Group (NSG) - Allowing SSH (in the default region, westus2, and centralus) # ----------------------------------------------------------------------------- resource "azurerm_network_security_group" "nsg" { name = "${local.network_names[0]}-nsg" # Using the first empire name for the NSG location = azurerm_resource_group.rg_eastus2.location resource_group_name = azurerm_resource_group.rg_eastus2.name security_rule { name = "AllowSSH" priority = 100 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_range = "22" source_address_prefix = "*" destination_address_prefix = "*" } } resource "azurerm_network_security_group" "nsg_westus2" { name = "${local.network_names[0]}-nsg-westus2" location = azurerm_resource_group.rg_westus2.location resource_group_name = azurerm_resource_group.rg_westus2.name security_rule { name = "AllowSSH" priority = 100 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_range = "22" source_address_prefix = "*" destination_address_prefix = "*" } } resource "azurerm_network_security_group" "nsg_centralus" { name = "${local.network_names[0]}-nsg-centralus" location = azurerm_resource_group.rg_centralus.location resource_group_name = azurerm_resource_group.rg_centralus.name security_rule { name = "AllowSSH" priority = 100 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_range = "22" source_address_prefix = "*" destination_address_prefix = "*" } } # ----------------------------------------------------------------------------- # 5. Public IP Addresses # ----------------------------------------------------------------------------- resource "azurerm_public_ip" "public_ip_eastus2" { count = 1 name = "${local.vm_names[1]}-pip" # Huitzilopochtli location = azurerm_resource_group.rg_eastus2.location resource_group_name = azurerm_resource_group.rg_eastus2.name allocation_method = "Dynamic" } resource "azurerm_public_ip" "quetzalcoatl_pip" { name = "${local.vm_names[0]}-pip-westus2" # Quetzalcoatl location = local.location_quetzalcoatl resource_group_name = azurerm_resource_group.rg_westus2.name allocation_method = "Dynamic" } resource "azurerm_public_ip" "public_ip_centralus" { count = 2 name = "${local.vm_names[count.index + 3]}-pip" # Viracocha, Inti location = azurerm_resource_group.rg_centralus.location resource_group_name = azurerm_resource_group.rg_centralus.name allocation_method = "Dynamic" } resource "azurerm_public_ip" "pachamama_pip" { name = "${local.vm_names[2]}-pip" # Pachamama location = azurerm_resource_group.rg_eastus2.location resource_group_name = azurerm_resource_group.rg_eastus2.name allocation_method = "Dynamic" } # ----------------------------------------------------------------------------- # 6. Network Interfaces # ----------------------------------------------------------------------------- resource "azurerm_network_interface" "nic_eastus2" { count = 1 name = "${local.vm_names[1]}-nic" # Huitzilopochtli location = local.location_default resource_group_name = azurerm_resource_group.rg_eastus2.name ip_configuration { name = "internal" subnet_id = azurerm_subnet.subnet.id private_ip_address_allocation = "Dynamic" public_ip_address_id = azurerm_public_ip.public_ip_eastus2[count.index].id } } resource "azurerm_network_interface" "quetzalcoatl_nic" { name = "${local.vm_names[0]}-nic-westus2" # Quetzalcoatl location = local.location_quetzalcoatl resource_group_name = azurerm_resource_group.rg_westus2.name ip_configuration { name = "internal" subnet_id = azurerm_subnet.subnet_westus2.id private_ip_address_allocation = "Dynamic" public_ip_address_id = azurerm_public_ip.quetzalcoatl_pip.id } } resource "azurerm_network_interface" "nic_centralus" { count = 2 name = "${local.vm_names[count.index + 3]}-nic" # Viracocha, Inti location = local.location_centralus resource_group_name = azurerm_resource_group.rg_centralus.name ip_configuration { name = "internal" subnet_id = azurerm_subnet.subnet_centralus.id private_ip_address_allocation = "Dynamic" public_ip_address_id = azurerm_public_ip.public_ip_centralus[count.index].id } } resource "azurerm_network_interface" "pachamama_nic" { name = "${local.vm_names[2]}-nic" # Pachamama location = local.location_default resource_group_name = azurerm_resource_group.rg_eastus2.name ip_configuration { name = "internal" subnet_id = azurerm_subnet.subnet.id private_ip_address_allocation = "Dynamic" public_ip_address_id = azurerm_public_ip.pachamama_pip.id } } # ----------------------------------------------------------------------------- # 7. Network Interface Security Group Associations # ----------------------------------------------------------------------------- resource "azurerm_network_interface_security_group_association" "nic_nsg_association_eastus2" { network_interface_id = azurerm_network_interface.nic_eastus2[0].id network_security_group_id = azurerm_network_security_group.nsg.id } resource "azurerm_network_interface_security_group_association" "quetzalcoatl_nic_nsg_association" { network_interface_id = azurerm_network_interface.quetzalcoatl_nic.id network_security_group_id = azurerm_network_security_group.nsg_westus2.id } resource "azurerm_network_interface_security_group_association" "nic_nsg_association_centralus" { count = 2 network_interface_id = azurerm_network_interface.nic_centralus[count.index].id network_security_group_id = azurerm_network_security_group.nsg_centralus.id } resource "azurerm_network_interface_security_group_association" "pachamama_nic_nsg_association" { network_interface_id = azurerm_network_interface.pachamama_nic.id network_security_group_id = azurerm_network_security_group.nsg.id } # ----------------------------------------------------------------------------- # 8. Linux Virtual Machines # ----------------------------------------------------------------------------- resource "azurerm_linux_virtual_machine" "vm_eastus2" { name = local.vm_names[1] # Huitzilopochtli location = local.location_default resource_group_name = azurerm_resource_group.rg_eastus2.name network_interface_ids = [ azurerm_network_interface.nic_eastus2[0].id, ] size = "Standard_B1ls" os_disk { caching = "ReadWrite" storage_account_type = "Standard_LRS" } source_image_reference { publisher = "Canonical" offer = "UbuntuServer" sku = "18.04-LTS" version = "latest" } computer_name = lower(local.vm_names[1]) admin_username = local.admin_username disable_password_authentication = true admin_ssh_key { username = local.admin_username public_key = file("~/.ssh/lenape_key.pub") } } resource "azurerm_linux_virtual_machine" "quetzalcoatl_vm" { name = local.vm_names[0] # Quetzalcoatl location = local.location_quetzalcoatl resource_group_name = azurerm_resource_group.rg_westus2.name network_interface_ids = [ azurerm_network_interface.quetzalcoatl_nic.id, ] size = "Standard_B1ls" os_disk { caching = "ReadWrite" storage_account_type = "Standard_LRS" } source_image_reference { publisher = "Canonical" offer = "UbuntuServer" sku = "18.04-LTS" version = "latest" } computer_name = lower(local.vm_names[0]) admin_username = local.admin_username disable_password_authentication = true admin_ssh_key { username = local.admin_username public_key = file("~/.ssh/lenape_key.pub") } } resource "azurerm_linux_virtual_machine" "vm_centralus" { count = 2 name = local.vm_names[count.index + 3] # Viracocha, Inti location = local.location_centralus resource_group_name = azurerm_resource_group.rg_centralus.name network_interface_ids = [ azurerm_network_interface.nic_centralus[count.index].id, ] size = "Standard_B1ls" os_disk { caching = "ReadWrite" storage_account_type = "Standard_LRS" } source_image_reference { publisher = "Canonical" offer = "UbuntuServer" sku = "18.04-LTS" version = "latest" } computer_name = lower(local.vm_names[count.index + 3]) admin_username = local.admin_username disable_password_authentication = true admin_ssh_key { username = local.admin_username public_key = file("~/.ssh/lenape_key.pub") } } resource "azurerm_linux_virtual_machine" "vm_pachamama" { name = local.vm_names[2] # Pachamama location = local.location_default resource_group_name = azurerm_resource_group.rg_eastus2.name network_interface_ids = [ azurerm_network_interface.pachamama_nic.id, ] size = "Standard_B1ls" os_disk { caching = "ReadWrite" storage_account_type = "Standard_LRS" } source_image_reference { publisher = "Canonical" offer = "UbuntuServer" sku = "18.04-LTS" version = "latest" } computer_name = lower(local.vm_names[2]) admin_username = local.admin_username disable_password_authentication = true admin_ssh_key { username = local.admin_username public_key = file("~/.ssh/lenape_key.pub") } } # ----------------------------------------------------------------------------- # 9. Storage Account and Blob Container for tfstate # ----------------------------------------------------------------------------- resource "azurerm_storage_account" "storage" { name = local.storage_account_name resource_group_name = azurerm_resource_group.rg_eastus2.name location = azurerm_resource_group.rg_eastus2.location account_tier = "Standard" account_replication_type = "LRS" } resource "azurerm_storage_container" "tfstate_container" { name = local.container_name storage_account_name = azurerm_storage_account.storage.name container_access_type = "private" } # ----------------------------------------------------------------------------- # 10. Output the Public IP Addresses and Key Vault Name # ----------------------------------------------------------------------------- output "public_ips_eastus2" { value = azurerm_public_ip.public_ip_eastus2[*].ip_address } output "quetzalcoatl_public_ip" { value = azurerm_public_ip.quetzalcoatl_pip.ip_address } output "public_ips_centralus" { value = azurerm_public_ip.public_ip_centralus[*].ip_address } output "pachamama_public_ip" { value = azurerm_public_ip.pachamama_pip.ip_address } output "key_vault_name" { value = azurerm_key_vault.kv.name } output "storage_account_name" { value = azurerm_storage_account.storage.name } output "storage_container_name" { value = azurerm_storage_container.tfstate_container.name }