3 changed files with 470 additions and 2097 deletions
@ -0,0 +1,241 @@
|
||||
# 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"] |
||||
network_names = ["Aztec", "Inca", "Maya", "Mississippian", "Anasazi"] |
||||
resource_groups = { |
||||
eastus2 = "muscogee-rg" |
||||
westus2 = "sioux-rg" |
||||
centralus = "cherokee-rg" |
||||
} |
||||
location_default = "eastus2" |
||||
location_quetzalcoatl = "westus2" |
||||
location_centralus = "centralus" |
||||
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" { |
||||
for_each = local.resource_groups |
||||
name = each.value |
||||
location = local.location_default |
||||
} |
||||
|
||||
# ----------------------------------------------------------------------------- |
||||
# 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" |
||||
|
||||
access_policy { |
||||
tenant_id = data.azurerm_client_config.current.tenant_id |
||||
object_id = data.azurerm_client_config.current.object_id |
||||
key_permissions = ["Get"] |
||||
secret_permissions = ["Get", "Set"] |
||||
storage_permissions = ["Get"] |
||||
} |
||||
} |
||||
|
||||
resource "random_string" "kv_suffix" { |
||||
length = 8 |
||||
lower = true |
||||
numeric = true |
||||
special = false |
||||
} |
||||
|
||||
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 |
||||
} |
||||
|
||||
# ----------------------------------------------------------------------------- |
||||
# 3. Virtual Networks, Subnets, and Network Security Groups |
||||
# ----------------------------------------------------------------------------- |
||||
resource "azurerm_virtual_network" "vnet" { |
||||
for_each = toset([local.location_default, local.location_quetzalcoatl, local.location_centralus]) |
||||
name = "${local.network_names[0]}-vnet-${each.key}" |
||||
location = each.key |
||||
resource_group_name = azurerm_resource_group.rg[each.key].name |
||||
address_space = ["10.0.0.0/16"] |
||||
} |
||||
|
||||
resource "azurerm_subnet" "subnet" { |
||||
for_each = azurerm_virtual_network.vnet |
||||
name = "default" |
||||
resource_group_name = azurerm_resource_group.rg[each.key].name |
||||
virtual_network_name = each.value.name |
||||
address_prefixes = ["10.0.1.0/24"] |
||||
} |
||||
|
||||
resource "azurerm_network_security_group" "nsg" { |
||||
for_each = azurerm_virtual_network.vnet |
||||
name = "${local.network_names[0]}-nsg-${each.key}" |
||||
location = each.key |
||||
resource_group_name = azurerm_resource_group.rg[each.key].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 = "*" |
||||
} |
||||
} |
||||
|
||||
# ----------------------------------------------------------------------------- |
||||
# 4. Public IPs for VMs |
||||
# ----------------------------------------------------------------------------- |
||||
resource "azurerm_public_ip" "public_ip" { |
||||
for_each = toset(local.vm_names) |
||||
name = "${each.value}-pip" |
||||
location = azurerm_resource_group.rg[local.location_default].location |
||||
resource_group_name = azurerm_resource_group.rg[local.location_default].name |
||||
allocation_method = "Dynamic" |
||||
} |
||||
|
||||
# ----------------------------------------------------------------------------- |
||||
# 5. Load Balancer Setup (Blue-Green with Frontend IPs and Backend Pools) |
||||
# ----------------------------------------------------------------------------- |
||||
resource "azurerm_lb" "load_balancer" { |
||||
for_each = toset([local.location_default, local.location_centralus]) |
||||
name = "lb-${each.key}" |
||||
location = each.key |
||||
resource_group_name = azurerm_resource_group.rg[each.key].name |
||||
sku = "Basic" |
||||
} |
||||
|
||||
resource "azurerm_lb_frontend_ip_configuration" "frontend_ip" { |
||||
for_each = azurerm_lb.load_balancer |
||||
name = "frontend-${each.key}" |
||||
resource_group_name = each.value.resource_group_name |
||||
loadbalancer_id = each.value.id |
||||
private_ip_address = "10.0.0.4" |
||||
private_ip_address_allocation = "Dynamic" |
||||
} |
||||
|
||||
resource "azurerm_lb_backend_address_pool" "backend_pool" { |
||||
for_each = azurerm_lb.load_balancer |
||||
name = "backend-${each.key}" |
||||
resource_group_name = each.value.resource_group_name |
||||
loadbalancer_id = each.value.id |
||||
} |
||||
|
||||
# ----------------------------------------------------------------------------- |
||||
# 6. Network Interface and VM Configurations (Blue-Green) |
||||
# ----------------------------------------------------------------------------- |
||||
resource "azurerm_network_interface" "nic" { |
||||
for_each = toset(local.vm_names) |
||||
name = "${each.value}-nic" |
||||
location = azurerm_resource_group.rg[local.location_default].location |
||||
resource_group_name = azurerm_resource_group.rg[local.location_default].name |
||||
ip_configuration { |
||||
name = "internal" |
||||
subnet_id = azurerm_subnet.subnet["eastus2"].id |
||||
private_ip_address_allocation = "Dynamic" |
||||
public_ip_address_id = azurerm_public_ip.public_ip[each.value].id |
||||
} |
||||
} |
||||
|
||||
resource "azurerm_linux_virtual_machine" "vm" { |
||||
for_each = toset(local.vm_names) |
||||
name = each.value |
||||
location = azurerm_resource_group.rg[local.location_default].location |
||||
resource_group_name = azurerm_resource_group.rg[local.location_default].name |
||||
network_interface_ids = [azurerm_network_interface.nic[each.value].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(each.value) |
||||
admin_username = local.admin_username |
||||
disable_password_authentication = false |
||||
admin_password = azurerm_key_vault_secret.admin_password_secret.value |
||||
} |
||||
|
||||
# ----------------------------------------------------------------------------- |
||||
# 7. Load Balancer Backend Pool Associations (VMs to Backend) |
||||
# ----------------------------------------------------------------------------- |
||||
resource "azurerm_lb_backend_address_pool_association" "backend_pool_association" { |
||||
for_each = toset(local.vm_names) |
||||
network_interface_id = azurerm_network_interface.nic[each.value].id |
||||
backend_address_pool_id = azurerm_lb_backend_address_pool.backend_pool["eastus2"].id |
||||
} |
||||
|
||||
# ----------------------------------------------------------------------------- |
||||
# 8. 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" |
||||
} |
||||
|
||||
# ----------------------------------------------------------------------------- |
||||
# 9. Output the Public IP Addresses and Key Vault Name |
||||
# ----------------------------------------------------------------------------- |
||||
output "public_ips" { |
||||
value = azurerm_public_ip.public_ip[*].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 |
||||
} |
@ -0,0 +1,226 @@
|
||||
{ |
||||
"version": 4, |
||||
"terraform_version": "1.11.3", |
||||
"serial": 80, |
||||
"lineage": "22565f98-f6c8-a960-466f-9dfb72683787", |
||||
"outputs": {}, |
||||
"resources": [ |
||||
{ |
||||
"mode": "data", |
||||
"type": "azurerm_client_config", |
||||
"name": "current", |
||||
"provider": "provider[\"registry.terraform.io/hashicorp/azurerm\"]", |
||||
"instances": [ |
||||
{ |
||||
"schema_version": 0, |
||||
"attributes": { |
||||
"client_id": "04b07795-8ddb-461a-bbee-02f9e1bf7b46", |
||||
"id": "Y2xpZW50Q29uZmlncy9jbGllbnRJZD0wNGIwNzc5NS04ZGRiLTQ2MWEtYmJlZS0wMmY5ZTFiZjdiNDY7b2JqZWN0SWQ9MTNkOWE2OGYtYTlmZi00ZjllLWJiYWMtNWMzNDE2NDQyOWQ2O3N1YnNjcmlwdGlvbklkPWUzZjY2M2U4LTk5YjEtNGUwYS1iMjM2LWEyYTZlNGRjZWNhYTt0ZW5hbnRJZD1lMmMwNWQ3Ni1hNTMwLTQxZTUtYWUwNC1lNjBmN2VmYTFmNzg=", |
||||
"object_id": "13d9a68f-a9ff-4f9e-bbac-5c34164429d6", |
||||
"subscription_id": "e3f663e8-99b1-4e0a-b236-a2a6e4dcecaa", |
||||
"tenant_id": "e2c05d76-a530-41e5-ae04-e60f7efa1f78", |
||||
"timeouts": null |
||||
}, |
||||
"sensitive_attributes": [] |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
"mode": "managed", |
||||
"type": "azurerm_key_vault", |
||||
"name": "kv", |
||||
"provider": "provider[\"registry.terraform.io/hashicorp/azurerm\"]", |
||||
"instances": [ |
||||
{ |
||||
"schema_version": 2, |
||||
"attributes": { |
||||
"access_policy": [ |
||||
{ |
||||
"application_id": "", |
||||
"certificate_permissions": [], |
||||
"key_permissions": [ |
||||
"Get" |
||||
], |
||||
"object_id": "13d9a68f-a9ff-4f9e-bbac-5c34164429d6", |
||||
"secret_permissions": [ |
||||
"Get", |
||||
"Set" |
||||
], |
||||
"storage_permissions": [ |
||||
"Get" |
||||
], |
||||
"tenant_id": "e2c05d76-a530-41e5-ae04-e60f7efa1f78" |
||||
} |
||||
], |
||||
"contact": [], |
||||
"enable_rbac_authorization": false, |
||||
"enabled_for_deployment": false, |
||||
"enabled_for_disk_encryption": false, |
||||
"enabled_for_template_deployment": false, |
||||
"id": "/subscriptions/e3f663e8-99b1-4e0a-b236-a2a6e4dcecaa/resourceGroups/muscogee-rg/providers/Microsoft.KeyVault/vaults/kv-secure-creds-tlr5sYFS", |
||||
"location": "eastus2", |
||||
"name": "kv-secure-creds-tlr5sYFS", |
||||
"network_acls": [ |
||||
{ |
||||
"bypass": "AzureServices", |
||||
"default_action": "Allow", |
||||
"ip_rules": [], |
||||
"virtual_network_subnet_ids": [] |
||||
} |
||||
], |
||||
"public_network_access_enabled": true, |
||||
"purge_protection_enabled": false, |
||||
"resource_group_name": "muscogee-rg", |
||||
"sku_name": "standard", |
||||
"soft_delete_retention_days": 90, |
||||
"tags": {}, |
||||
"tenant_id": "e2c05d76-a530-41e5-ae04-e60f7efa1f78", |
||||
"timeouts": null, |
||||
"vault_uri": "https://kv-secure-creds-tlr5syfs.vault.azure.net/" |
||||
}, |
||||
"sensitive_attributes": [], |
||||
"private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxODAwMDAwMDAwMDAwLCJkZWxldGUiOjE4MDAwMDAwMDAwMDAsInJlYWQiOjMwMDAwMDAwMDAwMCwidXBkYXRlIjoxODAwMDAwMDAwMDAwfSwic2NoZW1hX3ZlcnNpb24iOiIyIn0=", |
||||
"dependencies": [ |
||||
"azurerm_resource_group.rg_eastus2", |
||||
"data.azurerm_client_config.current", |
||||
"random_string.kv_suffix" |
||||
] |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
"mode": "managed", |
||||
"type": "azurerm_key_vault_secret", |
||||
"name": "admin_password_secret", |
||||
"provider": "provider[\"registry.terraform.io/hashicorp/azurerm\"]", |
||||
"instances": [ |
||||
{ |
||||
"schema_version": 0, |
||||
"attributes": { |
||||
"content_type": "", |
||||
"expiration_date": null, |
||||
"id": "https://kv-secure-creds-tlr5syfs.vault.azure.net/secrets/linux-admin-password/0762d4e91c3d49e89f9c0b7ed2d6c02e", |
||||
"key_vault_id": "/subscriptions/e3f663e8-99b1-4e0a-b236-a2a6e4dcecaa/resourceGroups/muscogee-rg/providers/Microsoft.KeyVault/vaults/kv-secure-creds-tlr5sYFS", |
||||
"name": "linux-admin-password", |
||||
"not_before_date": null, |
||||
"resource_id": "/subscriptions/e3f663e8-99b1-4e0a-b236-a2a6e4dcecaa/resourceGroups/muscogee-rg/providers/Microsoft.KeyVault/vaults/kv-secure-creds-tlr5sYFS/secrets/linux-admin-password/versions/0762d4e91c3d49e89f9c0b7ed2d6c02e", |
||||
"resource_versionless_id": "/subscriptions/e3f663e8-99b1-4e0a-b236-a2a6e4dcecaa/resourceGroups/muscogee-rg/providers/Microsoft.KeyVault/vaults/kv-secure-creds-tlr5sYFS/secrets/linux-admin-password", |
||||
"tags": {}, |
||||
"timeouts": null, |
||||
"value": "-tv1k#:*pqQK7Sw1\u0026E\u003eS", |
||||
"version": "0762d4e91c3d49e89f9c0b7ed2d6c02e", |
||||
"versionless_id": "https://kv-secure-creds-tlr5syfs.vault.azure.net/secrets/linux-admin-password" |
||||
}, |
||||
"sensitive_attributes": [ |
||||
[ |
||||
{ |
||||
"type": "get_attr", |
||||
"value": "value" |
||||
} |
||||
] |
||||
], |
||||
"private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxODAwMDAwMDAwMDAwLCJkZWxldGUiOjE4MDAwMDAwMDAwMDAsInJlYWQiOjE4MDAwMDAwMDAwMDAsInVwZGF0ZSI6MTgwMDAwMDAwMDAwMH19", |
||||
"dependencies": [ |
||||
"azurerm_key_vault.kv", |
||||
"azurerm_resource_group.rg_eastus2", |
||||
"data.azurerm_client_config.current", |
||||
"random_password.admin_password", |
||||
"random_string.kv_suffix" |
||||
] |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
"mode": "managed", |
||||
"type": "azurerm_resource_group", |
||||
"name": "rg_eastus2", |
||||
"provider": "provider[\"registry.terraform.io/hashicorp/azurerm\"]", |
||||
"instances": [ |
||||
{ |
||||
"schema_version": 0, |
||||
"attributes": { |
||||
"id": "/subscriptions/e3f663e8-99b1-4e0a-b236-a2a6e4dcecaa/resourceGroups/muscogee-rg", |
||||
"location": "eastus2", |
||||
"managed_by": "", |
||||
"name": "muscogee-rg", |
||||
"tags": {}, |
||||
"timeouts": null |
||||
}, |
||||
"sensitive_attributes": [], |
||||
"private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo1NDAwMDAwMDAwMDAwLCJkZWxldGUiOjU0MDAwMDAwMDAwMDAsInJlYWQiOjMwMDAwMDAwMDAwMCwidXBkYXRlIjo1NDAwMDAwMDAwMDAwfX0=" |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
"mode": "managed", |
||||
"type": "random_password", |
||||
"name": "admin_password", |
||||
"provider": "provider[\"registry.terraform.io/hashicorp/random\"]", |
||||
"instances": [ |
||||
{ |
||||
"schema_version": 3, |
||||
"attributes": { |
||||
"bcrypt_hash": "$2a$10$MuY.C09fQYh0IF.aEhLD.uUJbfv9JM1zpDq1f6aF2nXTs6oFBb/YS", |
||||
"id": "none", |
||||
"keepers": null, |
||||
"length": 20, |
||||
"lower": true, |
||||
"min_lower": 0, |
||||
"min_numeric": 0, |
||||
"min_special": 0, |
||||
"min_upper": 0, |
||||
"number": true, |
||||
"numeric": true, |
||||
"override_special": "!#$%\u0026*()-_=+[]{}\u003c\u003e:?", |
||||
"result": "-tv1k#:*pqQK7Sw1\u0026E\u003eS", |
||||
"special": true, |
||||
"upper": true |
||||
}, |
||||
"sensitive_attributes": [ |
||||
[ |
||||
{ |
||||
"type": "get_attr", |
||||
"value": "bcrypt_hash" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"type": "get_attr", |
||||
"value": "result" |
||||
} |
||||
] |
||||
] |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
"mode": "managed", |
||||
"type": "random_string", |
||||
"name": "kv_suffix", |
||||
"provider": "provider[\"registry.terraform.io/hashicorp/random\"]", |
||||
"instances": [ |
||||
{ |
||||
"schema_version": 2, |
||||
"attributes": { |
||||
"id": "tlr5sYFS", |
||||
"keepers": null, |
||||
"length": 8, |
||||
"lower": true, |
||||
"min_lower": 0, |
||||
"min_numeric": 0, |
||||
"min_special": 0, |
||||
"min_upper": 0, |
||||
"number": true, |
||||
"numeric": true, |
||||
"override_special": null, |
||||
"result": "tlr5sYFS", |
||||
"special": false, |
||||
"upper": true |
||||
}, |
||||
"sensitive_attributes": [] |
||||
} |
||||
] |
||||
} |
||||
], |
||||
"check_results": null |
||||
} |
Loading…
Reference in new issue