diff --git a/ops/terraform/locals.tf b/ops/terraform/locals.tf index 3ac01c81..b25d9249 100644 --- a/ops/terraform/locals.tf +++ b/ops/terraform/locals.tf @@ -10,6 +10,7 @@ locals { appsubnetcidr = "10.0.1.0/24" websubnetcidr = "10.0.2.0/24" lbsubnetcidr = "10.0.3.0/24" + dbsubnetcidr = "10.0.4.0/24" } } demo = { @@ -18,6 +19,7 @@ locals { appsubnetcidr = "10.1.1.0/24" websubnetcidr = "10.1.2.0/24" lbsubnetcidr = "10.1.3.0/24" + dbsubnetcidr = "10.1.4.0/24" } } -} \ No newline at end of file +} diff --git a/ops/terraform/main.tf b/ops/terraform/main.tf index 8b192d17..89f159e5 100644 --- a/ops/terraform/main.tf +++ b/ops/terraform/main.tf @@ -8,9 +8,6 @@ locals { } } -########## -## 02-network -########## module "networking" { source = "./modules/network" name = var.name @@ -20,22 +17,19 @@ module "networking" { websubnetcidr = local.workspace["websubnetcidr"] lbsubnetcidr = local.workspace["lbsubnetcidr"] appsubnetcidr = local.workspace["appsubnetcidr"] + dbsubnetcidr = local.workspace["dbsubnetcidr"] env = local.environment } -########## -## 02-security -########## - module "securitygroup" { source = "./modules/security" name = var.name location = data.azurerm_resource_group.rg.location resource_group = data.azurerm_resource_group.rg.name web_subnet_id = module.networking.websubnet_id - # db_subnet_id = module.networking.dbsubnet_id - lb_subnet_id = module.networking.lbsubnet_id - env = local.environment + db_subnet_id = module.networking.dbsubnet_id + lb_subnet_id = module.networking.lbsubnet_id + env = local.environment } module "app_gateway" { @@ -53,10 +47,6 @@ module "app_gateway" { depends_on = [module.networking, module.ocr_api] } -########## -## 05-Persistent -########## - module "storage" { source = "./modules/storage" name = var.name @@ -68,10 +58,6 @@ module "storage" { web_subnet_id = module.networking.websubnet_id } -########## -## 06-App -########## - module "ocr_api" { source = "./modules/app_service" name = var.name @@ -98,26 +84,9 @@ module "ocr_autoscale" { weekend_capacity_instances = 1 } -# module "compute" { -# source = "./modules/container_instances" -# location = data.azurerm_resource_group.rg.location -# resource_group = data.azurerm_resource_group.rg.name -# environment = local.environment -# app_subnet = module.networking.appsubnet_id -# # web_subnet_id = module.networking.websubnet_id -# # app_subnet_id = module.networking.appsubnet_id -# # web_host_name = local.app.web_host_name -# # web_username = local.app.web_username -# # web_os_password = local.app.web_os_password -# # app_host_name = local.app.app_host_name -# # app_username = local.app.app_username -# # app_os_password = local.app.app_os_password -# } - -########## -## 04-config -########## - -########## -## 07-Monitor -########## \ No newline at end of file +module "database" { + source = "./modules/database" + resource_group_name = data.azurerm_resource_group.rg.name + subnet = module.networking.dbsubnet_id + private_dns_zone_id = module.networking.private_dns_zone_id +} diff --git a/ops/terraform/modules/database/main.tf b/ops/terraform/modules/database/main.tf new file mode 100644 index 00000000..4bb30a53 --- /dev/null +++ b/ops/terraform/modules/database/main.tf @@ -0,0 +1,37 @@ +# Azure Postgres Single Service (azurerm_postgresql_server) retires in March 2025. +# As a result we are using Azure Database for PostgreSQL Flexible Server +# with granular control, flexibility and better cost optimization. +resource "azurerm_postgresql_flexible_server" "postgres_flexible_server" { + name = "reportvisionpostgresql-flexible-server" + location = var.location + resource_group_name = var.resource_group_name + sku_name = var.postgres_sku_name + version = var.engine_version + storage_mb = 32768 # 32 GB, the lowest of the valid options + backup_retention_days = 7 + + administrator_login = var.db_username + administrator_password = random_string.setup_rds_password.result + delegated_subnet_id = var.subnet + private_dns_zone_id = var.private_dns_zone_id + + # Disable Public Network Access + public_network_access_enabled = false + + lifecycle { + prevent_destroy = true + } +} + +resource "azurerm_postgresql_flexible_server_database" "postgres_db" { + name = "${azurerm_postgresql_flexible_server.postgres_flexible_server.name}-db" + server_id = azurerm_postgresql_flexible_server.postgres_flexible_server.id +} + +# Random string resource for the postgres password +resource "random_string" "setup_rds_password" { + length = 16 # Length of the password + + # Character set that excludes problematic characters like quotes, backslashes, etc. + override_special = "_!@#-$%^&*()[]{}" +} diff --git a/ops/terraform/modules/database/outputs.tf b/ops/terraform/modules/database/outputs.tf new file mode 100644 index 00000000..1afbb7db --- /dev/null +++ b/ops/terraform/modules/database/outputs.tf @@ -0,0 +1,3 @@ +output "postgres_db_password" { + value = azurerm_postgresql_flexible_server.postgres_flexible_server.administrator_login +} diff --git a/ops/terraform/modules/database/variables.tf b/ops/terraform/modules/database/variables.tf new file mode 100644 index 00000000..ef91bef5 --- /dev/null +++ b/ops/terraform/modules/database/variables.tf @@ -0,0 +1,37 @@ +variable "db_username" { + type = string + description = "Username of RDS Instance." + default = "reportVisionDbUser" +} + +variable "engine_version" { + description = "Postgres DB engine version." + default = "11" +} + +variable "location" { + type = string + description = "Location of the resource." + default = "eastus2" +} + +variable "resource_group_name" { + type = string + description = "The Azure Resource Group to deploy to" +} + +variable "postgres_sku_name" { + type = string + description = "value" + default = "Standard_B1ms" +} + +variable "subnet" { + type = string + description = "The subnet ID to associate with the PostgreSQL Flexible Server" +} + +variable "private_dns_zone_id" { + type = string + description = "Private DNS Zone for PostgreSQL Flexible Server" +} diff --git a/ops/terraform/modules/network/main.tf b/ops/terraform/modules/network/main.tf index 7b2dc6a3..15419ab0 100644 --- a/ops/terraform/modules/network/main.tf +++ b/ops/terraform/modules/network/main.tf @@ -10,11 +10,11 @@ resource "azurerm_subnet" "web-subnet" { virtual_network_name = azurerm_virtual_network.vnet.name resource_group_name = var.resource_group address_prefixes = [var.websubnetcidr] - service_endpoints = [ + service_endpoints = [ "Microsoft.Storage", "Microsoft.Web" ] - depends_on = [azurerm_virtual_network.vnet] + depends_on = [azurerm_virtual_network.vnet] } resource "azurerm_subnet" "app-subnet" { @@ -45,9 +45,30 @@ resource "azurerm_subnet" "lb-subnet" { depends_on = [azurerm_virtual_network.vnet] } -# resource "azurerm_subnet" "db-subnet" { -# name = "${var.name}-db-subnet-${var.env}" -# virtual_network_name = azurerm_virtual_network.vnet.name -# resource_group_name = var.resource_group -# address_prefixes = [var.dbsubnetcidr] -# } \ No newline at end of file + +resource "azurerm_subnet" "db-subnet" { + name = "${var.name}-db-subnet-${var.env}" + virtual_network_name = azurerm_virtual_network.vnet.name + resource_group_name = var.resource_group + address_prefixes = [var.dbsubnetcidr] + + delegation { + name = "postgresql-delegation" + service_delegation { + name = "Microsoft.DBforPostgreSQL/flexibleServers" + } + } +} + +resource "azurerm_private_dns_zone" "postgresql_dns_zone" { + name = "privatelink.postgres.database.azure.com" + resource_group_name = var.resource_group +} + +# Link Private DNS Zone to Virtual Network +resource "azurerm_private_dns_zone_virtual_network_link" "dns_link" { + name = "postgresql-vnet-link" + resource_group_name = var.resource_group + private_dns_zone_name = azurerm_private_dns_zone.postgresql_dns_zone.name + virtual_network_id = azurerm_virtual_network.vnet.id +} diff --git a/ops/terraform/modules/network/outputs.tf b/ops/terraform/modules/network/outputs.tf index ec9709b6..db0980eb 100644 --- a/ops/terraform/modules/network/outputs.tf +++ b/ops/terraform/modules/network/outputs.tf @@ -8,10 +8,10 @@ output "websubnet_id" { description = "Id of websubnet in the network" } -# output "dbsubnet_id" { -# value = azurerm_subnet.db-subnet.id -# description = "Id of dbsubnet in the network" -# } +output "dbsubnet_id" { + value = azurerm_subnet.db-subnet.id + description = "Id of dbsubnet in the network" +} output "lbsubnet_id" { value = azurerm_subnet.lb-subnet.id @@ -21,4 +21,9 @@ output "lbsubnet_id" { output "appsubnet_id" { value = azurerm_subnet.app-subnet.id description = "Id of lbsubnet in the network" -} \ No newline at end of file +} + +output "private_dns_zone_id" { + value = azurerm_private_dns_zone.postgresql_dns_zone.id + description = "Private DNS Zone for PostgreSQL Flexible Server" +} diff --git a/ops/terraform/modules/network/variables.tf b/ops/terraform/modules/network/variables.tf index affded85..2a506fc9 100644 --- a/ops/terraform/modules/network/variables.tf +++ b/ops/terraform/modules/network/variables.tf @@ -1,9 +1,12 @@ variable "resource_group" {} variable "name" {} -variable "location" {} variable "vnetcidr" {} variable "websubnetcidr" {} variable "lbsubnetcidr" {} -# variable "dbsubnetcidr" {} +variable "dbsubnetcidr" {} variable "appsubnetcidr" {} -variable "env" {} \ No newline at end of file +variable "env" {} + +variable "location" { + default = "eastus2" +} diff --git a/ops/terraform/modules/security/variables.tf b/ops/terraform/modules/security/variables.tf index 9c62eaba..0a1186e7 100644 --- a/ops/terraform/modules/security/variables.tf +++ b/ops/terraform/modules/security/variables.tf @@ -3,5 +3,5 @@ variable "name" {} variable "env" {} variable "resource_group" {} variable "web_subnet_id" {} -# variable "db_subnet_id" {} -variable "lb_subnet_id" {} \ No newline at end of file +variable "db_subnet_id" {} +variable "lb_subnet_id" {} diff --git a/ops/terraform/providers.tf b/ops/terraform/providers.tf index 3f578cdf..345c788e 100644 --- a/ops/terraform/providers.tf +++ b/ops/terraform/providers.tf @@ -6,14 +6,26 @@ terraform { azurerm = { source = "hashicorp/azurerm" version = "~>3.0" + } random = { source = "hashicorp/random" version = "~>3.0" } + # azuread = { + # source = "hashicorp/azuread" + # } } } provider "azurerm" { features {} -} \ No newline at end of file +} + +# # Provider for Azure Active Directory resources (e.g., service principals) +# provider "azuread" { + +# client_id = var.client_id +# tenant_id = var.tenant_id + +# } diff --git a/ops/terraform/variables.tf b/ops/terraform/variables.tf index a7006bc4..ed8f0976 100644 --- a/ops/terraform/variables.tf +++ b/ops/terraform/variables.tf @@ -1,7 +1,10 @@ +variable "name" {} + +variable "sku_name" { + type = string + description = "The Azure Stock Keep Unit (SKU) version" +} + variable "resource_group_name" { description = "value of the Azure resource group to deploy to" } - -variable "name" {} - -variable "sku_name" {} \ No newline at end of file