From 7732dd6360cd011f2399dddd61e1d0db4d000672 Mon Sep 17 00:00:00 2001 From: shenlan Date: Fri, 21 Nov 2025 07:40:24 +0800 Subject: [PATCH] Add Azure Terraform template aligned with AWS structure --- .../azure-cloud/README.md | 33 ++++ .../azure-cloud/bootstrap-dynamodb/main.tf | 68 +++++++++ .../azure-cloud/bootstrap-iam/main.tf | 50 ++++++ .../azure-cloud/bootstrap-s3/main.tf | 63 ++++++++ .../azure-cloud/config/backend.tf | 9 ++ .../azure-cloud/config/provider.tf | 15 ++ .../azure-cloud/config/variables.tf | 15 ++ .../azure-cloud/envs/dev/main.tf | 142 ++++++++++++++++++ .../azure-cloud/modules/alb/main.tf | 114 ++++++++++++++ .../azure-cloud/modules/ami_lookup/main.tf | 40 +++++ .../azure-cloud/modules/ec2/main.tf | 104 +++++++++++++ .../azure-cloud/modules/iam/main.tf | 31 ++++ .../azure-cloud/modules/keypair/main.tf | 27 ++++ .../azure-cloud/modules/landingzone/main.tf | 45 ++++++ .../azure-cloud/modules/msk/main.tf | 58 +++++++ .../azure-cloud/modules/nlb/main.tf | 101 +++++++++++++ .../azure-cloud/modules/rds/main.tf | 95 ++++++++++++ .../azure-cloud/modules/redis/main.tf | 48 ++++++ .../azure-cloud/modules/s3/main.tf | 46 ++++++ .../azure-cloud/modules/sg/main.tf | 69 +++++++++ .../azure-cloud/modules/vpc/main.tf | 62 ++++++++ 21 files changed, 1235 insertions(+) create mode 100644 iac-template/terraform-hcl-standard/azure-cloud/README.md create mode 100644 iac-template/terraform-hcl-standard/azure-cloud/bootstrap-dynamodb/main.tf create mode 100644 iac-template/terraform-hcl-standard/azure-cloud/bootstrap-iam/main.tf create mode 100644 iac-template/terraform-hcl-standard/azure-cloud/bootstrap-s3/main.tf create mode 100644 iac-template/terraform-hcl-standard/azure-cloud/config/backend.tf create mode 100644 iac-template/terraform-hcl-standard/azure-cloud/config/provider.tf create mode 100644 iac-template/terraform-hcl-standard/azure-cloud/config/variables.tf create mode 100644 iac-template/terraform-hcl-standard/azure-cloud/envs/dev/main.tf create mode 100644 iac-template/terraform-hcl-standard/azure-cloud/modules/alb/main.tf create mode 100644 iac-template/terraform-hcl-standard/azure-cloud/modules/ami_lookup/main.tf create mode 100644 iac-template/terraform-hcl-standard/azure-cloud/modules/ec2/main.tf create mode 100644 iac-template/terraform-hcl-standard/azure-cloud/modules/iam/main.tf create mode 100644 iac-template/terraform-hcl-standard/azure-cloud/modules/keypair/main.tf create mode 100644 iac-template/terraform-hcl-standard/azure-cloud/modules/landingzone/main.tf create mode 100644 iac-template/terraform-hcl-standard/azure-cloud/modules/msk/main.tf create mode 100644 iac-template/terraform-hcl-standard/azure-cloud/modules/nlb/main.tf create mode 100644 iac-template/terraform-hcl-standard/azure-cloud/modules/rds/main.tf create mode 100644 iac-template/terraform-hcl-standard/azure-cloud/modules/redis/main.tf create mode 100644 iac-template/terraform-hcl-standard/azure-cloud/modules/s3/main.tf create mode 100644 iac-template/terraform-hcl-standard/azure-cloud/modules/sg/main.tf create mode 100644 iac-template/terraform-hcl-standard/azure-cloud/modules/vpc/main.tf diff --git a/iac-template/terraform-hcl-standard/azure-cloud/README.md b/iac-template/terraform-hcl-standard/azure-cloud/README.md new file mode 100644 index 0000000..0ec9456 --- /dev/null +++ b/iac-template/terraform-hcl-standard/azure-cloud/README.md @@ -0,0 +1,33 @@ +# Azure Cloud Terraform Standard + +该目录提供与 `aws-cloud` 模板一一对应的 Azure 版本,延续相同的目录与模块命名(bootstrap、config、modules、envs),便于将 AWS 使用习惯映射到 Azure。 + +## 模板映射(AWS → Azure) +- **bootstrap-s3 → Storage Account**:创建存储账户与容器用于 Terraform 远端状态。 +- **bootstrap-dynamodb → Cosmos DB Table API**:提供无服务器键值表存储。 +- **bootstrap-iam → RBAC 角色分配**:为指定主体分配内置角色,替代 AWS IAM 角色/策略。 +- **modules**:保留 AWS 模块命名,内部实现替换为 Azure 服务: + - `vpc`:虚拟网络 + 子网(Virtual Network/Subnet)。 + - `alb`:应用程序网关(Application Gateway)。 + - `nlb`:标准负载均衡器(Standard Load Balancer)。 + - `ec2`:Linux 虚拟机(Virtual Machine)。 + - `s3`:存储账户与容器(Storage Account + Container)。 + - `rds`:PostgreSQL 灵活服务器(Flexible Server)。 + - `redis`:Azure Cache for Redis。 + - `sg`:网络安全组与规则(Network Security Group)。 + - `iam`:基于内置角色的角色分配(Role Assignment)。 + - `ami_lookup`:公共镜像查找(Ubuntu 平台镜像)。 + - `landingzone`:基础资源组与日志工作区。 + - `keypair`:生成 SSH 密钥对。 + - `msk`:事件中心命名空间与 Hub(Event Hubs)。 + +## 使用方式 +1. 在 `config/backend.tf` 中配置 Azure 存储作为 Terraform 远端状态(资源组、存储账户、容器)。 +2. 在 `config/provider.tf` 中设置 `subscription_id`、`tenant_id`、`location` 等参数。 +3. 参考 `envs/dev/main.tf`,按需修改变量后执行: + ```bash + terraform -chdir=envs/dev init + terraform -chdir=envs/dev apply + ``` + +本目录新增 Azure 代码,不改动现有 AWS 模板。 diff --git a/iac-template/terraform-hcl-standard/azure-cloud/bootstrap-dynamodb/main.tf b/iac-template/terraform-hcl-standard/azure-cloud/bootstrap-dynamodb/main.tf new file mode 100644 index 0000000..df2a9be --- /dev/null +++ b/iac-template/terraform-hcl-standard/azure-cloud/bootstrap-dynamodb/main.tf @@ -0,0 +1,68 @@ +variable "resource_group_name" { + description = "Resource group for the Cosmos DB account" + type = string +} + +variable "location" { + description = "Azure region" + type = string + default = "eastus" +} + +variable "account_name" { + description = "Cosmos DB account name" + type = string +} + +variable "table_name" { + description = "Table (Table API) name" + type = string + default = "tfstate-lock" +} + +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "cosmos" { + name = var.resource_group_name + location = var.location +} + +resource "azurerm_cosmosdb_account" "table" { + name = var.account_name + location = azurerm_resource_group.cosmos.location + resource_group_name = azurerm_resource_group.cosmos.name + offer_type = "Standard" + kind = "GlobalDocumentDB" + + consistency_policy { + consistency_level = "Session" + } + + capabilities { + name = "EnableTable" + } + + geo_location { + location = azurerm_resource_group.cosmos.location + failover_priority = 0 + } +} + +resource "azurerm_cosmosdb_table" "state_lock" { + name = var.table_name + resource_group_name = azurerm_resource_group.cosmos.name + account_name = azurerm_cosmosdb_account.table.name + throughput = 400 +} + +output "account" { + value = azurerm_cosmosdb_account.table.name + description = "Cosmos DB account for lock table" +} + +output "table" { + value = azurerm_cosmosdb_table.state_lock.name + description = "Table API collection used for state locking" +} diff --git a/iac-template/terraform-hcl-standard/azure-cloud/bootstrap-iam/main.tf b/iac-template/terraform-hcl-standard/azure-cloud/bootstrap-iam/main.tf new file mode 100644 index 0000000..f72e681 --- /dev/null +++ b/iac-template/terraform-hcl-standard/azure-cloud/bootstrap-iam/main.tf @@ -0,0 +1,50 @@ +variable "resource_group_name" { + description = "Resource group where role assignment is scoped" + type = string +} + +variable "location" { + description = "Azure region" + type = string + default = "eastus" +} + +variable "principal_id" { + description = "Object ID of the user/service principal/group to assign" + type = string +} + +variable "role_definition_name" { + description = "Built-in role to assign" + type = string + default = "Contributor" +} + +provider "azurerm" { + features {} +} + +data "azurerm_role_definition" "selected" { + name = var.role_definition_name +} + +resource "azurerm_resource_group" "iam" { + name = var.resource_group_name + location = var.location +} + +resource "azurerm_role_assignment" "scope_assignment" { + scope = azurerm_resource_group.iam.id + role_definition_id = data.azurerm_role_definition.selected.id + principal_id = var.principal_id +} + +output "role_definition" { + value = data.azurerm_role_definition.selected.name + description = "Role assigned to the principal" +} + +output "scope" { + value = azurerm_resource_group.iam.id + description = "Scope where the role assignment is created" +} diff --git a/iac-template/terraform-hcl-standard/azure-cloud/bootstrap-s3/main.tf b/iac-template/terraform-hcl-standard/azure-cloud/bootstrap-s3/main.tf new file mode 100644 index 0000000..0f8ef64 --- /dev/null +++ b/iac-template/terraform-hcl-standard/azure-cloud/bootstrap-s3/main.tf @@ -0,0 +1,63 @@ +variable "resource_group_name" { + description = "Resource group for state storage" + type = string + default = "tfstate-rg" +} + +variable "location" { + description = "Azure region" + type = string + default = "eastus" +} + +variable "storage_account_name" { + description = "Storage account name for Terraform state" + type = string + default = "tfstateaccount" +} + +variable "container_name" { + description = "Blob container to store state" + type = string + default = "tfstate" +} + +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "state" { + name = var.resource_group_name + location = var.location +} + +resource "azurerm_storage_account" "state" { + name = var.storage_account_name + resource_group_name = azurerm_resource_group.state.name + location = azurerm_resource_group.state.location + account_tier = "Standard" + account_replication_type = "LRS" + min_tls_version = "TLS1_2" + allow_blob_public_access = false +} + +resource "azurerm_storage_container" "state" { + name = var.container_name + storage_account_name = azurerm_storage_account.state.name + container_access_type = "private" +} + +output "resource_group" { + value = azurerm_resource_group.state.name + description = "Resource group created for Terraform state" +} + +output "storage_account" { + value = azurerm_storage_account.state.name + description = "Storage account for Terraform state" +} + +output "container" { + value = azurerm_storage_container.state.name + description = "Blob container used for Terraform state" +} diff --git a/iac-template/terraform-hcl-standard/azure-cloud/config/backend.tf b/iac-template/terraform-hcl-standard/azure-cloud/config/backend.tf new file mode 100644 index 0000000..4c10621 --- /dev/null +++ b/iac-template/terraform-hcl-standard/azure-cloud/config/backend.tf @@ -0,0 +1,9 @@ +terraform { + backend "azurerm" { + # 请在使用前替换为实际资源组、存储账户、容器和状态文件名 + resource_group_name = "tfstate-rg" + storage_account_name = "tfstateaccount" + container_name = "tfstate" + key = "terraform.tfstate" + } +} diff --git a/iac-template/terraform-hcl-standard/azure-cloud/config/provider.tf b/iac-template/terraform-hcl-standard/azure-cloud/config/provider.tf new file mode 100644 index 0000000..190f6f0 --- /dev/null +++ b/iac-template/terraform-hcl-standard/azure-cloud/config/provider.tf @@ -0,0 +1,15 @@ +terraform { + required_version = ">= 1.5.0" + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = ">= 3.90.0" + } + } +} + +provider "azurerm" { + features {} + subscription_id = var.subscription_id + tenant_id = var.tenant_id +} diff --git a/iac-template/terraform-hcl-standard/azure-cloud/config/variables.tf b/iac-template/terraform-hcl-standard/azure-cloud/config/variables.tf new file mode 100644 index 0000000..f72a960 --- /dev/null +++ b/iac-template/terraform-hcl-standard/azure-cloud/config/variables.tf @@ -0,0 +1,15 @@ +variable "subscription_id" { + description = "Azure subscription id" + type = string +} + +variable "tenant_id" { + description = "Azure AD tenant id" + type = string +} + +variable "location" { + description = "Azure region" + type = string + default = "eastus" +} diff --git a/iac-template/terraform-hcl-standard/azure-cloud/envs/dev/main.tf b/iac-template/terraform-hcl-standard/azure-cloud/envs/dev/main.tf new file mode 100644 index 0000000..061cf04 --- /dev/null +++ b/iac-template/terraform-hcl-standard/azure-cloud/envs/dev/main.tf @@ -0,0 +1,142 @@ +terraform { + required_version = ">= 1.5.0" + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = ">= 3.90.0" + } + tls = { + source = "hashicorp/tls" + version = ">= 4.0" + } + } +} + +variable "subscription_id" { + type = string + description = "Target subscription" +} + +variable "tenant_id" { + type = string + description = "AAD tenant id" +} + +variable "location" { + type = string + description = "Azure region" + default = "eastus" +} + +variable "principal_id" { + type = string + description = "Principal to grant Contributor on the landing zone" +} + +provider "azurerm" { + features {} + subscription_id = var.subscription_id + tenant_id = var.tenant_id +} + +locals { + resource_group_name = "demo-rg" + vnet_name = "demo-vnet" +} + +module "landingzone" { + source = "../../modules/landingzone" + resource_group_name = local.resource_group_name + location = var.location +} + +module "iam" { + source = "../../modules/iam" + scope = module.landingzone.resource_group_id + principal_id = var.principal_id + role_definition_name = "Contributor" +} + +module "vpc" { + source = "../../modules/vpc" + resource_group_name = module.landingzone.resource_group_name + location = var.location + vnet_name = local.vnet_name + address_space = ["10.20.0.0/16"] + subnets = [ + { + name = "app" + address_prefix = "10.20.1.0/24" + } + ] +} + +module "nsg" { + source = "../../modules/sg" + resource_group_name = module.landingzone.resource_group_name + location = var.location + name = "demo-nsg" +} + +resource "azurerm_subnet_network_security_group_association" "app" { + subnet_id = module.vpc.subnet_ids["app"] + network_security_group_id = module.nsg.nsg_id +} + +module "keypair" { + source = "../../modules/keypair" +} + +module "vm" { + source = "../../modules/ec2" + resource_group_name = module.landingzone.resource_group_name + location = var.location + vm_name = "demo-vm" + subnet_id = module.vpc.subnet_ids["app"] + admin_username = "azureuser" + ssh_public_key = module.keypair.public_key_openssh +} + +module "storage" { + source = "../../modules/s3" + resource_group_name = module.landingzone.resource_group_name + location = var.location + storage_account_name = "demostorageacct01" + container_name = "artifacts" +} + +module "database" { + source = "../../modules/rds" + resource_group_name = module.landingzone.resource_group_name + location = var.location + server_name = "demo-postgres" + admin_username = "pgadmin" + admin_password = "P@ssword12345!" + db_name = "appdb" + public_network_access_enabled = true +} + +module "cache" { + source = "../../modules/redis" + resource_group_name = module.landingzone.resource_group_name + location = var.location + name = "demorediscache" + sku_name = "Standard" + capacity = 1 +} + +output "resource_group" { + value = module.landingzone.resource_group_name + description = "Resource group provisioned for demo" +} + +output "vm_id" { + value = module.vm.vm_id + description = "Demo VM ID" +} + +output "ssh_private_key" { + value = module.keypair.private_key_pem + description = "Private key to access the VM" + sensitive = true +} diff --git a/iac-template/terraform-hcl-standard/azure-cloud/modules/alb/main.tf b/iac-template/terraform-hcl-standard/azure-cloud/modules/alb/main.tf new file mode 100644 index 0000000..60b7571 --- /dev/null +++ b/iac-template/terraform-hcl-standard/azure-cloud/modules/alb/main.tf @@ -0,0 +1,114 @@ +variable "resource_group_name" { + description = "Resource group for the Application Gateway" + type = string +} + +variable "location" { + description = "Azure region" + type = string +} + +variable "name" { + description = "Application Gateway name" + type = string + default = "app-gateway" +} + +variable "subnet_id" { + description = "Subnet ID used by the Application Gateway" + type = string +} + +variable "backend_port" { + description = "Backend port for the default pool" + type = number + default = 80 +} + +variable "sku_name" { + description = "Application Gateway SKU" + type = string + default = "Standard_v2" +} + +variable "capacity" { + description = "Instance count" + type = number + default = 1 +} + +resource "azurerm_public_ip" "gateway" { + name = "${var.name}-pip" + resource_group_name = var.resource_group_name + location = var.location + allocation_method = "Static" + sku = "Standard" +} + +resource "azurerm_application_gateway" "this" { + name = var.name + resource_group_name = var.resource_group_name + location = var.location + + sku { + name = var.sku_name + tier = "Standard_v2" + } + + autoscale_configuration { + min_capacity = var.capacity + max_capacity = var.capacity + } + + gateway_ip_configuration { + name = "gateway-ipcfg" + subnet_id = var.subnet_id + } + + frontend_port { + name = "frontend-port" + port = 80 + } + + frontend_ip_configuration { + name = "frontend-ip" + public_ip_address_id = azurerm_public_ip.gateway.id + } + + backend_address_pool { + name = "default-backend" + } + + backend_http_settings { + name = "default-http" + cookie_based_affinity = "Disabled" + port = var.backend_port + protocol = "Http" + request_timeout = 30 + } + + http_listener { + name = "http-listener" + frontend_ip_configuration_name = "frontend-ip" + frontend_port_name = "frontend-port" + protocol = "Http" + } + + request_routing_rule { + name = "http-rule" + rule_type = "Basic" + http_listener_name = "http-listener" + backend_address_pool_name = "default-backend" + backend_http_settings_name = "default-http" + } +} + +output "application_gateway_id" { + value = azurerm_application_gateway.this.id + description = "Application Gateway resource ID" +} + +output "public_ip" { + value = azurerm_public_ip.gateway.ip_address + description = "Public IP assigned to the Application Gateway" +} diff --git a/iac-template/terraform-hcl-standard/azure-cloud/modules/ami_lookup/main.tf b/iac-template/terraform-hcl-standard/azure-cloud/modules/ami_lookup/main.tf new file mode 100644 index 0000000..205470a --- /dev/null +++ b/iac-template/terraform-hcl-standard/azure-cloud/modules/ami_lookup/main.tf @@ -0,0 +1,40 @@ +variable "location" { + description = "Azure region" + type = string + default = "eastus" +} + +variable "publisher" { + description = "Image publisher" + type = string + default = "Canonical" +} + +variable "offer" { + description = "Image offer" + type = string + default = "0001-com-ubuntu-server-focal" +} + +variable "sku" { + description = "Image SKU" + type = string + default = "20_04-lts" +} + +data "azurerm_platform_image" "ubuntu" { + location = var.location + publisher = var.publisher + offer = var.offer + sku = var.sku +} + +output "image" { + value = { + publisher = data.azurerm_platform_image.ubuntu.publisher + offer = data.azurerm_platform_image.ubuntu.offer + sku = data.azurerm_platform_image.ubuntu.sku + version = data.azurerm_platform_image.ubuntu.version + } + description = "Latest platform image metadata" +} diff --git a/iac-template/terraform-hcl-standard/azure-cloud/modules/ec2/main.tf b/iac-template/terraform-hcl-standard/azure-cloud/modules/ec2/main.tf new file mode 100644 index 0000000..1ebc5af --- /dev/null +++ b/iac-template/terraform-hcl-standard/azure-cloud/modules/ec2/main.tf @@ -0,0 +1,104 @@ +variable "resource_group_name" { + description = "Resource group for the VM" + type = string +} + +variable "location" { + description = "Azure region" + type = string +} + +variable "vm_name" { + description = "Virtual machine name" + type = string + default = "vm" +} + +variable "subnet_id" { + description = "Subnet ID to attach the VM" + type = string +} + +variable "admin_username" { + description = "Admin username for the VM" + type = string + default = "azureuser" +} + +variable "ssh_public_key" { + description = "Public SSH key for login" + type = string +} + +variable "vm_size" { + description = "Azure VM size" + type = string + default = "Standard_B2s" +} + +variable "source_image" { + description = "Platform image definition" + type = object({ + publisher = string + offer = string + sku = string + version = string + }) + default = { + publisher = "Canonical" + offer = "0001-com-ubuntu-server-focal" + sku = "20_04-lts" + version = "latest" + } +} + +resource "azurerm_network_interface" "vm" { + name = "${var.vm_name}-nic" + location = var.location + resource_group_name = var.resource_group_name + + ip_configuration { + name = "ipconfig1" + subnet_id = var.subnet_id + private_ip_address_allocation = "Dynamic" + } +} + +resource "azurerm_linux_virtual_machine" "vm" { + name = var.vm_name + resource_group_name = var.resource_group_name + location = var.location + size = var.vm_size + admin_username = var.admin_username + network_interface_ids = [ + azurerm_network_interface.vm.id + ] + + admin_ssh_key { + username = var.admin_username + public_key = var.ssh_public_key + } + + os_disk { + name = "${var.vm_name}-osdisk" + caching = "ReadWrite" + storage_account_type = "Standard_LRS" + } + + source_image_reference { + publisher = var.source_image.publisher + offer = var.source_image.offer + sku = var.source_image.sku + version = var.source_image.version + } +} + +output "vm_id" { + value = azurerm_linux_virtual_machine.vm.id + description = "Virtual machine resource ID" +} + +output "nic_id" { + value = azurerm_network_interface.vm.id + description = "Network interface ID" +} diff --git a/iac-template/terraform-hcl-standard/azure-cloud/modules/iam/main.tf b/iac-template/terraform-hcl-standard/azure-cloud/modules/iam/main.tf new file mode 100644 index 0000000..4d3b111 --- /dev/null +++ b/iac-template/terraform-hcl-standard/azure-cloud/modules/iam/main.tf @@ -0,0 +1,31 @@ +variable "scope" { + description = "Scope for the role assignment" + type = string +} + +variable "principal_id" { + description = "Object ID of the principal to assign" + type = string +} + +variable "role_definition_name" { + description = "Built-in role name" + type = string + default = "Contributor" +} + +data "azurerm_role_definition" "selected" { + name = var.role_definition_name + scope = var.scope +} + +resource "azurerm_role_assignment" "assignment" { + scope = var.scope + role_definition_id = data.azurerm_role_definition.selected.id + principal_id = var.principal_id +} + +output "role_definition" { + value = data.azurerm_role_definition.selected.name + description = "Role assigned to the principal" +} diff --git a/iac-template/terraform-hcl-standard/azure-cloud/modules/keypair/main.tf b/iac-template/terraform-hcl-standard/azure-cloud/modules/keypair/main.tf new file mode 100644 index 0000000..83c6d4b --- /dev/null +++ b/iac-template/terraform-hcl-standard/azure-cloud/modules/keypair/main.tf @@ -0,0 +1,27 @@ +variable "algorithm" { + description = "Algorithm for the SSH key" + type = string + default = "RSA" +} + +variable "rsa_bits" { + description = "RSA bits for the key when algorithm is RSA" + type = number + default = 4096 +} + +resource "tls_private_key" "ssh" { + algorithm = var.algorithm + rsa_bits = var.algorithm == "RSA" ? var.rsa_bits : null +} + +output "private_key_pem" { + value = tls_private_key.ssh.private_key_pem + sensitive = true + description = "Generated private key" +} + +output "public_key_openssh" { + value = tls_private_key.ssh.public_key_openssh + description = "Generated public key" +} diff --git a/iac-template/terraform-hcl-standard/azure-cloud/modules/landingzone/main.tf b/iac-template/terraform-hcl-standard/azure-cloud/modules/landingzone/main.tf new file mode 100644 index 0000000..424e8ef --- /dev/null +++ b/iac-template/terraform-hcl-standard/azure-cloud/modules/landingzone/main.tf @@ -0,0 +1,45 @@ +variable "resource_group_name" { + description = "Resource group to bootstrap" + type = string + default = "landingzone-rg" +} + +variable "location" { + description = "Azure region" + type = string + default = "eastus" +} + +variable "log_analytics_workspace_name" { + description = "Log Analytics workspace name" + type = string + default = "landingzone-law" +} + +resource "azurerm_resource_group" "this" { + name = var.resource_group_name + location = var.location +} + +resource "azurerm_log_analytics_workspace" "logs" { + name = var.log_analytics_workspace_name + location = var.location + resource_group_name = azurerm_resource_group.this.name + sku = "PerGB2018" + retention_in_days = 30 +} + +output "resource_group_id" { + value = azurerm_resource_group.this.id + description = "Landing zone resource group ID" +} + +output "log_analytics_workspace_id" { + value = azurerm_log_analytics_workspace.logs.id + description = "Log Analytics workspace ID" +} + +output "resource_group_name" { + value = azurerm_resource_group.this.name + description = "Landing zone resource group name" +} diff --git a/iac-template/terraform-hcl-standard/azure-cloud/modules/msk/main.tf b/iac-template/terraform-hcl-standard/azure-cloud/modules/msk/main.tf new file mode 100644 index 0000000..8496dad --- /dev/null +++ b/iac-template/terraform-hcl-standard/azure-cloud/modules/msk/main.tf @@ -0,0 +1,58 @@ +variable "resource_group_name" { + description = "Resource group for Event Hubs" + type = string +} + +variable "location" { + description = "Azure region" + type = string +} + +variable "namespace_name" { + description = "Event Hubs namespace name" + type = string +} + +variable "eventhub_name" { + description = "Event Hub name" + type = string + default = "events" +} + +variable "partition_count" { + description = "Number of partitions" + type = number + default = 2 +} + +variable "message_retention" { + description = "Message retention in days" + type = number + default = 1 +} + +resource "azurerm_eventhub_namespace" "ns" { + name = var.namespace_name + location = var.location + resource_group_name = var.resource_group_name + sku = "Standard" + capacity = 1 +} + +resource "azurerm_eventhub" "hub" { + name = var.eventhub_name + namespace_name = azurerm_eventhub_namespace.ns.name + resource_group_name = var.resource_group_name + partition_count = var.partition_count + message_retention = var.message_retention +} + +output "namespace_id" { + value = azurerm_eventhub_namespace.ns.id + description = "Event Hubs namespace ID" +} + +output "eventhub_id" { + value = azurerm_eventhub.hub.id + description = "Event Hub ID" +} diff --git a/iac-template/terraform-hcl-standard/azure-cloud/modules/nlb/main.tf b/iac-template/terraform-hcl-standard/azure-cloud/modules/nlb/main.tf new file mode 100644 index 0000000..37dcb23 --- /dev/null +++ b/iac-template/terraform-hcl-standard/azure-cloud/modules/nlb/main.tf @@ -0,0 +1,101 @@ +variable "resource_group_name" { + description = "Resource group for the load balancer" + type = string +} + +variable "location" { + description = "Azure region" + type = string +} + +variable "name" { + description = "Load balancer name" + type = string + default = "nlb" +} + +variable "protocol" { + description = "Frontend protocol" + type = string + default = "Tcp" +} + +variable "frontend_port" { + description = "Frontend port" + type = number + default = 80 +} + +variable "backend_port" { + description = "Backend port" + type = number + default = 80 +} + +variable "backend_pool_backend_ids" { + description = "List of backend NIC IDs or IP configurations" + type = list(string) + default = [] +} + +resource "azurerm_public_ip" "lb" { + name = "${var.name}-pip" + location = var.location + resource_group_name = var.resource_group_name + allocation_method = "Static" + sku = "Standard" +} + +resource "azurerm_lb" "this" { + name = var.name + location = var.location + resource_group_name = var.resource_group_name + sku = "Standard" + + frontend_ip_configuration { + name = "public" + public_ip_address_id = azurerm_public_ip.lb.id + } +} + +resource "azurerm_lb_backend_address_pool" "pool" { + name = "backendpool" + loadbalancer_id = azurerm_lb.this.id +} + +resource "azurerm_lb_probe" "tcp" { + name = "tcp-probe" + resource_group_name = var.resource_group_name + loadbalancer_id = azurerm_lb.this.id + protocol = var.protocol + port = var.backend_port +} + +resource "azurerm_lb_rule" "lb_rule" { + name = "lb-rule" + resource_group_name = var.resource_group_name + loadbalancer_id = azurerm_lb.this.id + protocol = var.protocol + frontend_port = var.frontend_port + backend_port = var.backend_port + frontend_ip_configuration_name = "public" + backend_address_pool_id = azurerm_lb_backend_address_pool.pool.id + probe_id = azurerm_lb_probe.tcp.id +} + +resource "azurerm_network_interface_backend_address_pool_association" "attach" { + for_each = toset(var.backend_pool_backend_ids) + network_interface_id = each.value + ip_configuration_name = "ipconfig1" + backend_address_pool_id = azurerm_lb_backend_address_pool.pool.id +} + +output "lb_public_ip" { + value = azurerm_public_ip.lb.ip_address + description = "Public IP assigned to the load balancer" +} + +output "backend_pool_id" { + value = azurerm_lb_backend_address_pool.pool.id + description = "Backend address pool ID" +} diff --git a/iac-template/terraform-hcl-standard/azure-cloud/modules/rds/main.tf b/iac-template/terraform-hcl-standard/azure-cloud/modules/rds/main.tf new file mode 100644 index 0000000..ca9420d --- /dev/null +++ b/iac-template/terraform-hcl-standard/azure-cloud/modules/rds/main.tf @@ -0,0 +1,95 @@ +variable "resource_group_name" { + description = "Resource group for the database" + type = string +} + +variable "location" { + description = "Azure region" + type = string +} + +variable "server_name" { + description = "PostgreSQL flexible server name" + type = string +} + +variable "admin_username" { + description = "Admin username" + type = string + default = "pgadmin" +} + +variable "admin_password" { + description = "Admin password" + type = string + sensitive = true +} + +variable "version" { + description = "PostgreSQL version" + type = string + default = "14" +} + +variable "sku_name" { + description = "SKU name for flexible server" + type = string + default = "GP_Standard_D2ds_v4" +} + +variable "storage_mb" { + description = "Storage in MB" + type = number + default = 32768 +} + +variable "db_name" { + description = "Default database name" + type = string + default = "app" +} + +variable "public_network_access_enabled" { + description = "Allow public network access" + type = bool + default = true +} + +resource "azurerm_postgresql_flexible_server" "this" { + name = var.server_name + resource_group_name = var.resource_group_name + location = var.location + version = var.version + administrator_login = var.admin_username + administrator_password = var.admin_password + sku_name = var.sku_name + storage_mb = var.storage_mb + zone = 1 + backup_retention_days = 7 + public_network_access_enabled = var.public_network_access_enabled +} + +resource "azurerm_postgresql_flexible_database" "db" { + name = var.db_name + server_id = azurerm_postgresql_flexible_server.this.id + charset = "UTF8" + collation = "en_US.utf8" +} + +resource "azurerm_postgresql_flexible_server_firewall_rule" "allow_all" { + count = var.public_network_access_enabled ? 1 : 0 + name = "allow-all" + server_id = azurerm_postgresql_flexible_server.this.id + start_ip_address = "0.0.0.0" + end_ip_address = "255.255.255.255" +} + +output "server_fqdn" { + value = azurerm_postgresql_flexible_server.this.fqdn + description = "Database server FQDN" +} + +output "database_name" { + value = azurerm_postgresql_flexible_database.db.name + description = "Database name created" +} diff --git a/iac-template/terraform-hcl-standard/azure-cloud/modules/redis/main.tf b/iac-template/terraform-hcl-standard/azure-cloud/modules/redis/main.tf new file mode 100644 index 0000000..e241dd6 --- /dev/null +++ b/iac-template/terraform-hcl-standard/azure-cloud/modules/redis/main.tf @@ -0,0 +1,48 @@ +variable "resource_group_name" { + description = "Resource group for Redis" + type = string +} + +variable "location" { + description = "Azure region" + type = string +} + +variable "name" { + description = "Redis cache name" + type = string +} + +variable "sku_name" { + description = "Redis SKU name" + type = string + default = "Standard" +} + +variable "capacity" { + description = "Redis capacity (size family dependent)" + type = number + default = 1 +} + +resource "azurerm_redis_cache" "this" { + name = var.name + location = var.location + resource_group_name = var.resource_group_name + capacity = var.capacity + family = "C" + sku_name = var.sku_name + enable_non_ssl_port = false + minimum_tls_version = "1.2" +} + +output "hostname" { + value = azurerm_redis_cache.this.hostname + description = "Redis hostname" +} + +output "primary_key" { + value = azurerm_redis_cache.this.primary_access_key + sensitive = true + description = "Redis primary key" +} diff --git a/iac-template/terraform-hcl-standard/azure-cloud/modules/s3/main.tf b/iac-template/terraform-hcl-standard/azure-cloud/modules/s3/main.tf new file mode 100644 index 0000000..0d32e4d --- /dev/null +++ b/iac-template/terraform-hcl-standard/azure-cloud/modules/s3/main.tf @@ -0,0 +1,46 @@ +variable "resource_group_name" { + description = "Resource group for storage" + type = string +} + +variable "location" { + description = "Azure region" + type = string +} + +variable "storage_account_name" { + description = "Storage account name" + type = string +} + +variable "container_name" { + description = "Blob container name" + type = string + default = "app" +} + +resource "azurerm_storage_account" "this" { + name = var.storage_account_name + resource_group_name = var.resource_group_name + location = var.location + account_tier = "Standard" + account_replication_type = "LRS" + min_tls_version = "TLS1_2" + allow_blob_public_access = false +} + +resource "azurerm_storage_container" "this" { + name = var.container_name + storage_account_name = azurerm_storage_account.this.name + container_access_type = "private" +} + +output "storage_account_id" { + value = azurerm_storage_account.this.id + description = "Storage account ID" +} + +output "container_name" { + value = azurerm_storage_container.this.name + description = "Blob container name" +} diff --git a/iac-template/terraform-hcl-standard/azure-cloud/modules/sg/main.tf b/iac-template/terraform-hcl-standard/azure-cloud/modules/sg/main.tf new file mode 100644 index 0000000..f547f6c --- /dev/null +++ b/iac-template/terraform-hcl-standard/azure-cloud/modules/sg/main.tf @@ -0,0 +1,69 @@ +variable "resource_group_name" { + description = "Resource group for NSG" + type = string +} + +variable "location" { + description = "Azure region" + type = string +} + +variable "name" { + description = "Network security group name" + type = string + default = "nsg" +} + +variable "rules" { + description = "List of security rules" + type = list(object({ + name = string + priority = number + direction = string + access = string + protocol = string + source_port_range = string + destination_port_range = string + source_address_prefix = string + destination_address_prefix = string + })) + default = [ + { + name = "ssh" + 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" "this" { + name = var.name + location = var.location + resource_group_name = var.resource_group_name +} + +resource "azurerm_network_security_rule" "rules" { + for_each = { for rule in var.rules : rule.name => rule } + name = each.value.name + priority = each.value.priority + direction = each.value.direction + access = each.value.access + protocol = each.value.protocol + source_port_range = each.value.source_port_range + destination_port_range = each.value.destination_port_range + source_address_prefix = each.value.source_address_prefix + destination_address_prefix = each.value.destination_address_prefix + resource_group_name = var.resource_group_name + network_security_group_name = azurerm_network_security_group.this.name +} + +output "nsg_id" { + value = azurerm_network_security_group.this.id + description = "Network security group ID" +} diff --git a/iac-template/terraform-hcl-standard/azure-cloud/modules/vpc/main.tf b/iac-template/terraform-hcl-standard/azure-cloud/modules/vpc/main.tf new file mode 100644 index 0000000..e5c6def --- /dev/null +++ b/iac-template/terraform-hcl-standard/azure-cloud/modules/vpc/main.tf @@ -0,0 +1,62 @@ +variable "resource_group_name" { + description = "Resource group for the virtual network" + type = string +} + +variable "location" { + description = "Azure region" + type = string +} + +variable "vnet_name" { + description = "Virtual network name" + type = string + default = "main-vnet" +} + +variable "address_space" { + description = "Address space for the virtual network" + type = list(string) + default = ["10.10.0.0/16"] +} + +variable "subnets" { + description = "Subnets to create inside the VNet" + type = list(object({ + name = string + address_prefix = string + service_endpoints = optional(list(string), []) + })) + default = [ + { + name = "default" + address_prefix = "10.10.1.0/24" + } + ] +} + +resource "azurerm_virtual_network" "this" { + name = var.vnet_name + address_space = var.address_space + location = var.location + resource_group_name = var.resource_group_name +} + +resource "azurerm_subnet" "this" { + for_each = { for subnet in var.subnets : subnet.name => subnet } + name = each.value.name + resource_group_name = var.resource_group_name + virtual_network_name = azurerm_virtual_network.this.name + address_prefixes = [each.value.address_prefix] + service_endpoints = lookup(each.value, "service_endpoints", []) +} + +output "vnet_id" { + value = azurerm_virtual_network.this.id + description = "Virtual network resource ID" +} + +output "subnet_ids" { + value = { for name, subnet in azurerm_subnet.this : name => subnet.id } + description = "Map of subnet IDs keyed by name" +}