459 lines
13 KiB
HCL
459 lines
13 KiB
HCL
# Full Terraform Config for Azure Demo Infra - Fixed for Free Tier
|
|
terraform {
|
|
required_version = ">= 1.3"
|
|
required_providers {
|
|
azurerm = { source = "hashicorp/azurerm", version = ">= 3.50" }
|
|
random = { source = "hashicorp/random" }
|
|
azuread = { source = "hashicorp/azuread" }
|
|
time = { source = "hashicorp/time" }
|
|
}
|
|
}
|
|
|
|
provider "azurerm" {
|
|
features {}
|
|
subscription_id = "1d363cb6-5669-42c2-98d3-5b9a1604b797"
|
|
}
|
|
provider "random" {}
|
|
provider "azuread" {}
|
|
|
|
data "azurerm_client_config" "current" {}
|
|
|
|
locals {
|
|
default_tags = {
|
|
environment = "Demo"
|
|
owner = "Linux Lenape"
|
|
purpose = "Technical-Demo"
|
|
}
|
|
}
|
|
|
|
# Resource Group
|
|
resource "azurerm_resource_group" "core" {
|
|
name = "Prod-Native-American-Empires"
|
|
location = var.location
|
|
tags = local.default_tags
|
|
}
|
|
|
|
# Key Vault
|
|
resource "azurerm_key_vault" "vault" {
|
|
name = var.key_vault_name
|
|
location = var.location
|
|
resource_group_name = azurerm_resource_group.core.name
|
|
tenant_id = data.azurerm_client_config.current.tenant_id
|
|
sku_name = "standard"
|
|
purge_protection_enabled = false
|
|
public_network_access_enabled = true
|
|
soft_delete_retention_days = 7
|
|
tags = local.default_tags
|
|
|
|
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", "Delete", "List"
|
|
]
|
|
|
|
storage_permissions = [
|
|
"Get",
|
|
]
|
|
}
|
|
}
|
|
|
|
# Generate VM admin password
|
|
resource "random_password" "vm_admin" {
|
|
length = 16
|
|
special = true
|
|
}
|
|
|
|
# Store VM admin password in Key Vault
|
|
resource "azurerm_key_vault_secret" "vm_admin_password" {
|
|
name = "vm-admin-password"
|
|
value = random_password.vm_admin.result
|
|
key_vault_id = azurerm_key_vault.vault.id
|
|
depends_on = [azurerm_key_vault.vault]
|
|
}
|
|
|
|
# Networking
|
|
resource "azurerm_virtual_network" "vnet" {
|
|
name = "vnet-prod"
|
|
location = var.location
|
|
resource_group_name = azurerm_resource_group.core.name
|
|
address_space = ["10.0.0.0/16"]
|
|
tags = local.default_tags
|
|
}
|
|
|
|
resource "azurerm_subnet" "subnet" {
|
|
name = "subnet-prod"
|
|
resource_group_name = azurerm_resource_group.core.name
|
|
virtual_network_name = azurerm_virtual_network.vnet.name
|
|
address_prefixes = ["10.0.1.0/24"]
|
|
}
|
|
|
|
resource "azurerm_network_security_group" "nsg" {
|
|
name = "nsg-prod"
|
|
location = var.location
|
|
resource_group_name = azurerm_resource_group.core.name
|
|
tags = local.default_tags
|
|
|
|
security_rule {
|
|
name = "RDP"
|
|
priority = 1001
|
|
direction = "Inbound"
|
|
access = "Allow"
|
|
protocol = "Tcp"
|
|
source_port_range = "*"
|
|
destination_port_range = "3389"
|
|
source_address_prefix = "*"
|
|
destination_address_prefix = "*"
|
|
}
|
|
|
|
security_rule {
|
|
name = "SSH"
|
|
priority = 1002
|
|
direction = "Inbound"
|
|
access = "Allow"
|
|
protocol = "Tcp"
|
|
source_port_range = "*"
|
|
destination_port_range = "22"
|
|
source_address_prefix = "*"
|
|
destination_address_prefix = "*"
|
|
}
|
|
}
|
|
|
|
resource "azurerm_subnet_network_security_group_association" "nsg_assoc" {
|
|
subnet_id = azurerm_subnet.subnet.id
|
|
network_security_group_id = azurerm_network_security_group.nsg.id
|
|
}
|
|
|
|
# Public IPs
|
|
resource "azurerm_public_ip" "win_pip1" {
|
|
name = "pip-okeus"
|
|
resource_group_name = azurerm_resource_group.core.name
|
|
location = var.location
|
|
allocation_method = "Static"
|
|
sku = "Standard"
|
|
tags = local.default_tags
|
|
}
|
|
|
|
resource "azurerm_public_ip" "linux_pip" {
|
|
name = "pip-kokopelli"
|
|
resource_group_name = azurerm_resource_group.core.name
|
|
location = var.location
|
|
allocation_method = "Static"
|
|
sku = "Standard"
|
|
tags = local.default_tags
|
|
}
|
|
|
|
# Network Interfaces
|
|
resource "azurerm_network_interface" "win_nic1" {
|
|
name = "nic-okeus"
|
|
location = var.location
|
|
resource_group_name = azurerm_resource_group.core.name
|
|
ip_configuration {
|
|
name = "ipconfig1"
|
|
subnet_id = azurerm_subnet.subnet.id
|
|
public_ip_address_id = azurerm_public_ip.win_pip1.id
|
|
private_ip_address_allocation = "Dynamic"
|
|
}
|
|
tags = local.default_tags
|
|
}
|
|
|
|
resource "azurerm_network_interface" "linux_nic" {
|
|
name = "nic-kokopelli"
|
|
location = var.location
|
|
resource_group_name = azurerm_resource_group.core.name
|
|
ip_configuration {
|
|
name = "ipconfig1"
|
|
subnet_id = azurerm_subnet.subnet.id
|
|
public_ip_address_id = azurerm_public_ip.linux_pip.id
|
|
private_ip_address_allocation = "Dynamic"
|
|
}
|
|
tags = local.default_tags
|
|
}
|
|
|
|
# Virtual Machines - Reduced to 2 VMs for free tier
|
|
resource "azurerm_windows_virtual_machine" "okeus" {
|
|
name = "okeus"
|
|
resource_group_name = azurerm_resource_group.core.name
|
|
location = var.location
|
|
network_interface_ids = [azurerm_network_interface.win_nic1.id]
|
|
size = "Standard_B1s" # Free tier eligible
|
|
admin_username = var.vm_admin_username
|
|
admin_password = random_password.vm_admin.result
|
|
|
|
os_disk {
|
|
name = "okeus-osdisk"
|
|
caching = "ReadWrite"
|
|
storage_account_type = "Standard_LRS"
|
|
}
|
|
|
|
source_image_reference {
|
|
publisher = "MicrosoftWindowsServer"
|
|
offer = "WindowsServer"
|
|
sku = "2022-Datacenter"
|
|
version = "latest"
|
|
}
|
|
tags = local.default_tags
|
|
}
|
|
|
|
resource "azurerm_linux_virtual_machine" "kokopelli" {
|
|
name = "kokopelli"
|
|
resource_group_name = azurerm_resource_group.core.name
|
|
location = var.location
|
|
network_interface_ids = [azurerm_network_interface.linux_nic.id]
|
|
size = "Standard_B1s" # Free tier eligible
|
|
admin_username = var.vm_admin_username
|
|
admin_password = random_password.vm_admin.result
|
|
disable_password_authentication = false
|
|
|
|
os_disk {
|
|
name = "kokopelli-osdisk"
|
|
caching = "ReadWrite"
|
|
storage_account_type = "Standard_LRS"
|
|
}
|
|
|
|
source_image_reference {
|
|
publisher = "Canonical"
|
|
offer = "0001-com-ubuntu-server-focal"
|
|
sku = "20_04-lts-gen2"
|
|
version = "latest"
|
|
}
|
|
tags = local.default_tags
|
|
}
|
|
|
|
# Azure SQL - Fixed resource names
|
|
resource "random_integer" "sqlsuffix" {
|
|
min = 1000
|
|
max = 9999
|
|
}
|
|
|
|
resource "random_password" "sql_admin" {
|
|
length = 16
|
|
special = true
|
|
}
|
|
|
|
resource "azurerm_mssql_server" "sqlsvr" {
|
|
name = "sqlsrv${random_integer.sqlsuffix.result}"
|
|
resource_group_name = azurerm_resource_group.core.name
|
|
location = var.location
|
|
version = "12.0"
|
|
administrator_login = "sqladmin"
|
|
administrator_login_password = random_password.sql_admin.result
|
|
tags = local.default_tags
|
|
}
|
|
|
|
resource "azurerm_mssql_database" "hoporenkv" {
|
|
name = "Hoporenkv"
|
|
server_id = azurerm_mssql_server.sqlsvr.id
|
|
sku_name = "Basic" # Free tier has 32MB limit, Basic is cheapest paid option
|
|
tags = local.default_tags
|
|
}
|
|
|
|
resource "azurerm_key_vault_secret" "sql_admin_secret" {
|
|
name = "sql-admin-password"
|
|
value = random_password.sql_admin.result
|
|
key_vault_id = azurerm_key_vault.vault.id
|
|
depends_on = [azurerm_key_vault.vault]
|
|
}
|
|
|
|
# AAD Users - 10 users as requested
|
|
resource "random_password" "demo_user_passwords" {
|
|
count = 10
|
|
length = 16
|
|
special = true
|
|
}
|
|
|
|
resource "azuread_user" "demo_users" {
|
|
count = 10
|
|
user_principal_name = "demo-user-${count.index + 1}@${var.tenant_domain}"
|
|
display_name = "Demo User ${count.index + 1}"
|
|
mail_nickname = "demo-user-${count.index + 1}"
|
|
password = random_password.demo_user_passwords[count.index].result
|
|
force_password_change = false
|
|
}
|
|
|
|
resource "azurerm_key_vault_secret" "demo_user_secrets" {
|
|
count = 10
|
|
name = "demo-user-${count.index + 1}-password"
|
|
value = random_password.demo_user_passwords[count.index].result
|
|
key_vault_id = azurerm_key_vault.vault.id
|
|
depends_on = [azurerm_key_vault.vault]
|
|
}
|
|
|
|
resource "azurerm_role_assignment" "demo_user_roles" {
|
|
count = 10
|
|
principal_id = azuread_user.demo_users[count.index].object_id
|
|
role_definition_name = "Reader"
|
|
scope = azurerm_resource_group.core.id
|
|
}
|
|
|
|
# Monitoring - Fixed diagnostic settings
|
|
resource "azurerm_log_analytics_workspace" "law_vm" {
|
|
name = "demo-law-vm"
|
|
location = var.location
|
|
resource_group_name = azurerm_resource_group.core.name
|
|
sku = "PerGB2018"
|
|
retention_in_days = 30
|
|
tags = local.default_tags
|
|
}
|
|
|
|
# Budget
|
|
resource "azurerm_consumption_budget_subscription" "demo_budget" {
|
|
name = "demo-budget"
|
|
amount = 200 # Increased to match your budget
|
|
time_grain = "Monthly"
|
|
subscription_id = "/subscriptions/${data.azurerm_client_config.current.subscription_id}"
|
|
|
|
time_period {
|
|
start_date = formatdate("YYYY-MM-01'T'00:00:00Z", timestamp())
|
|
}
|
|
|
|
notification {
|
|
enabled = true
|
|
operator = "GreaterThan"
|
|
threshold = 80
|
|
contact_emails = [var.admin_email]
|
|
}
|
|
|
|
notification {
|
|
enabled = true
|
|
operator = "GreaterThan"
|
|
threshold = 100
|
|
contact_emails = [var.admin_email]
|
|
}
|
|
}
|
|
|
|
# ACR & Container App - Simplified for free tier
|
|
resource "random_integer" "rand" {
|
|
min = 1000
|
|
max = 9999
|
|
}
|
|
|
|
resource "azurerm_container_registry" "acr" {
|
|
name = "demoacr${random_integer.rand.result}"
|
|
resource_group_name = azurerm_resource_group.core.name
|
|
location = var.location
|
|
sku = "Basic"
|
|
admin_enabled = true
|
|
tags = local.default_tags
|
|
}
|
|
|
|
resource "azurerm_log_analytics_workspace" "law_app" {
|
|
name = "demo-law-app"
|
|
location = var.location
|
|
resource_group_name = azurerm_resource_group.core.name
|
|
sku = "PerGB2018"
|
|
retention_in_days = 30
|
|
tags = local.default_tags
|
|
}
|
|
|
|
resource "azurerm_container_app_environment" "env" {
|
|
name = "demo-env"
|
|
location = var.location
|
|
resource_group_name = azurerm_resource_group.core.name
|
|
log_analytics_workspace_id = azurerm_log_analytics_workspace.law_app.id
|
|
tags = local.default_tags
|
|
}
|
|
|
|
# Add wait time to ensure container environment is fully provisioned
|
|
resource "time_sleep" "wait_for_container_env" {
|
|
depends_on = [azurerm_container_app_environment.env]
|
|
create_duration = "60s"
|
|
}
|
|
|
|
# FIXED: Container App with proper dependencies and public image
|
|
resource "azurerm_container_app" "skennen" {
|
|
name = "skennen"
|
|
container_app_environment_id = azurerm_container_app_environment.env.id
|
|
resource_group_name = azurerm_resource_group.core.name
|
|
revision_mode = "Single"
|
|
|
|
# More explicit dependency management
|
|
depends_on = [
|
|
time_sleep.wait_for_container_env,
|
|
azurerm_container_app_environment.env,
|
|
azurerm_log_analytics_workspace.law_app,
|
|
azurerm_container_registry.acr
|
|
]
|
|
|
|
secret {
|
|
name = "acr-password"
|
|
value = azurerm_container_registry.acr.admin_password
|
|
}
|
|
|
|
registry {
|
|
server = azurerm_container_registry.acr.login_server
|
|
username = azurerm_container_registry.acr.admin_username
|
|
password_secret_name = "acr-password"
|
|
}
|
|
|
|
template {
|
|
container {
|
|
name = "skennen"
|
|
image = "mcr.microsoft.com/azuredocs/containerapps-helloworld:latest" # Use a public image initially
|
|
cpu = 0.25
|
|
memory = "0.5Gi"
|
|
}
|
|
revision_suffix = "initial"
|
|
}
|
|
|
|
ingress {
|
|
external_enabled = true
|
|
target_port = 80
|
|
traffic_weight {
|
|
latest_revision = true
|
|
percentage = 100
|
|
}
|
|
}
|
|
|
|
tags = local.default_tags
|
|
}
|
|
|
|
# Static Web App - Fixed deprecated resource
|
|
resource "azurerm_static_web_app" "landing" {
|
|
name = "plan-jacquesingram"
|
|
resource_group_name = azurerm_resource_group.core.name
|
|
location = var.location
|
|
sku_tier = "Free"
|
|
sku_size = "Free"
|
|
tags = local.default_tags
|
|
}
|
|
|
|
# Outputs
|
|
output "windows_vm_ip" {
|
|
value = azurerm_public_ip.win_pip1.ip_address
|
|
}
|
|
|
|
output "linux_vm_ip" {
|
|
value = azurerm_public_ip.linux_pip.ip_address
|
|
}
|
|
|
|
output "container_registry_url" {
|
|
value = azurerm_container_registry.acr.login_server
|
|
}
|
|
|
|
output "key_vault_uri" {
|
|
value = azurerm_key_vault.vault.vault_uri
|
|
}
|
|
|
|
output "static_site_url" {
|
|
value = azurerm_static_web_app.landing.default_host_name
|
|
}
|
|
|
|
output "sql_server_fqdn" {
|
|
value = azurerm_mssql_server.sqlsvr.fully_qualified_domain_name
|
|
}
|
|
|
|
output "vm_admin_password" {
|
|
value = random_password.vm_admin.result
|
|
sensitive = true
|
|
}
|
|
|
|
output "container_app_url" {
|
|
value = azurerm_container_app.skennen.latest_revision_fqdn
|
|
description = "The URL of the container app"
|
|
} |