Merge pull request #94 from svc-design/codex/add-azure-terraform-template-with-modules
Add Azure Terraform template aligned with AWS structure
This commit is contained in:
commit
3f318c08a7
33
iac-template/terraform-hcl-standard/azure-cloud/README.md
Normal file
33
iac-template/terraform-hcl-standard/azure-cloud/README.md
Normal file
@ -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 模板。
|
||||
@ -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"
|
||||
}
|
||||
@ -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"
|
||||
}
|
||||
@ -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"
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
terraform {
|
||||
backend "azurerm" {
|
||||
# 请在使用前替换为实际资源组、存储账户、容器和状态文件名
|
||||
resource_group_name = "tfstate-rg"
|
||||
storage_account_name = "tfstateaccount"
|
||||
container_name = "tfstate"
|
||||
key = "terraform.tfstate"
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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"
|
||||
}
|
||||
142
iac-template/terraform-hcl-standard/azure-cloud/envs/dev/main.tf
Normal file
142
iac-template/terraform-hcl-standard/azure-cloud/envs/dev/main.tf
Normal file
@ -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
|
||||
}
|
||||
@ -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"
|
||||
}
|
||||
@ -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"
|
||||
}
|
||||
@ -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"
|
||||
}
|
||||
@ -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"
|
||||
}
|
||||
@ -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"
|
||||
}
|
||||
@ -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"
|
||||
}
|
||||
@ -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"
|
||||
}
|
||||
@ -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"
|
||||
}
|
||||
@ -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"
|
||||
}
|
||||
@ -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"
|
||||
}
|
||||
@ -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"
|
||||
}
|
||||
@ -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"
|
||||
}
|
||||
@ -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"
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user