Skip to content

Commit 5e186ac

Browse files
committed
chore: add virtual network for private connectivity between containerapps and postgresql
1 parent 10f9de8 commit 5e186ac

8 files changed

Lines changed: 182 additions & 25 deletions

File tree

infra/main.tf

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,34 @@ resource "azurerm_resource_group" "rg" {
1313
tags = local.tags
1414
}
1515

16+
# ------------------------------------------------------------------------------------------------------
17+
# Deploy Virtual Network
18+
# ------------------------------------------------------------------------------------------------------
19+
20+
module "vnet" {
21+
source = "./modules/vnet"
22+
prefix = var.prefix
23+
location = var.location
24+
rg_name = azurerm_resource_group.rg.name
25+
tags = local.tags
26+
}
27+
1628
# ------------------------------------------------------------------------------------------------------
1729
# Deploy PostgresSQL Database
1830
# ------------------------------------------------------------------------------------------------------
1931

2032
module "postgres" {
21-
source = "./modules/postgres"
22-
prefix = var.prefix
23-
location = var.location
24-
tags = local.tags
25-
rg_name = azurerm_resource_group.rg.name
26-
admin_username = var.admin_username
27-
admin_password = var.admin_password
33+
source = "./modules/postgres"
34+
prefix = var.prefix
35+
location = var.location
36+
tags = local.tags
37+
rg_name = azurerm_resource_group.rg.name
38+
admin_username = var.admin_username
39+
admin_password = var.admin_password
40+
postgres_subnet_id = module.vnet.postgres_subnet_id
41+
postgres_dns_zone_id = module.vnet.postgres_dns_zone_id
42+
43+
depends_on = [module.vnet]
2844
}
2945

3046
# ------------------------------------------------------------------------------------------------------
@@ -50,17 +66,18 @@ module "keyvault" {
5066
# Deploy Container App
5167
# ------------------------------------------------------------------------------------------------------
5268
module "containerapp" {
53-
source = "./modules/containerapp"
54-
prefix = var.prefix
55-
location = var.location
56-
rg_name = azurerm_resource_group.rg.name
57-
tags = local.tags
58-
container_image = var.container_image
59-
container_port = var.container_port
60-
container_cpu = var.container_cpu
61-
container_memory = var.container_memory
62-
min_replicas = var.min_replicas
63-
max_replicas = var.max_replicas
69+
source = "./modules/containerapp"
70+
prefix = var.prefix
71+
location = var.location
72+
rg_name = azurerm_resource_group.rg.name
73+
tags = local.tags
74+
container_image = var.container_image
75+
container_port = var.container_port
76+
container_cpu = var.container_cpu
77+
container_memory = var.container_memory
78+
min_replicas = var.min_replicas
79+
max_replicas = var.max_replicas
80+
containerapp_subnet_id = module.vnet.containerapp_subnet_id
6481

6582
# Pass the database connection string as a secret
6683
secrets = [
@@ -79,5 +96,5 @@ module "containerapp" {
7996
}
8097
]
8198

82-
depends_on = [module.postgres, module.keyvault]
99+
depends_on = [module.postgres, module.keyvault, module.vnet]
83100
}

infra/modules/containerapp/containerapp.tf

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@ resource "azurerm_log_analytics_workspace" "logs" {
1414
# DEPLOY CONTAINER APP ENVIRONMENT
1515
# ------------------------------------------------------------------------------------------------------
1616
resource "azurerm_container_app_environment" "env" {
17-
name = "${var.prefix}-env"
18-
location = var.location
19-
resource_group_name = var.rg_name
20-
log_analytics_workspace_id = azurerm_log_analytics_workspace.logs.id
21-
tags = var.tags
17+
name = "${var.prefix}-env"
18+
location = var.location
19+
resource_group_name = var.rg_name
20+
log_analytics_workspace_id = azurerm_log_analytics_workspace.logs.id
21+
infrastructure_subnet_id = var.containerapp_subnet_id
22+
internal_load_balancer_enabled = false
23+
tags = var.tags
2224
}
2325

2426
# ------------------------------------------------------------------------------------------------------

infra/modules/containerapp/containerapp_variables.tf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,8 @@ variable "acr_sku" {
7979
type = string
8080
default = "Basic"
8181
}
82+
83+
variable "containerapp_subnet_id" {
84+
description = "The subnet ID for Container App Environment VNet integration"
85+
type = string
86+
}

infra/modules/postgres/postgres.tf

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# ------------------------------------------------------------------------------------------------------
2-
# DEPLOY POSTGRESQL SERVER
2+
# DEPLOY POSTGRESQL FLEXIBLE SERVER WITH PRIVATE NETWORKING
33
# ------------------------------------------------------------------------------------------------------
44
resource "azurerm_postgresql_flexible_server" "pg" {
55
name = "${var.prefix}-pgflex"
@@ -10,5 +10,14 @@ resource "azurerm_postgresql_flexible_server" "pg" {
1010
administrator_password = var.admin_password
1111
sku_name = var.sku_name
1212
storage_mb = 32768
13+
14+
# Private networking configuration
15+
delegated_subnet_id = var.postgres_subnet_id
16+
private_dns_zone_id = var.postgres_dns_zone_id
17+
18+
# Disable public network access for security
19+
public_network_access_enabled = false
20+
21+
tags = var.tags
1322
}
1423

infra/modules/postgres/postgres_variables.tf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,13 @@ variable "sku_name" {
4141
type = string
4242
default = "B_Standard_B1ms"
4343
}
44+
45+
variable "postgres_subnet_id" {
46+
description = "The subnet ID for PostgreSQL private networking"
47+
type = string
48+
}
49+
50+
variable "postgres_dns_zone_id" {
51+
description = "The private DNS zone ID for PostgreSQL"
52+
type = string
53+
}

infra/modules/vnet/vnet.tf

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# ------------------------------------------------------------------------------------------------------
2+
# DEPLOY VIRTUAL NETWORK
3+
# ------------------------------------------------------------------------------------------------------
4+
resource "azurerm_virtual_network" "vnet" {
5+
name = "${var.prefix}-vnet"
6+
location = var.location
7+
resource_group_name = var.rg_name
8+
address_space = ["10.0.0.0/16"]
9+
tags = var.tags
10+
}
11+
12+
# ------------------------------------------------------------------------------------------------------
13+
# SUBNET FOR CONTAINER APPS ENVIRONMENT
14+
# ------------------------------------------------------------------------------------------------------
15+
resource "azurerm_subnet" "containerapp_subnet" {
16+
name = "${var.prefix}-containerapp-subnet"
17+
resource_group_name = var.rg_name
18+
virtual_network_name = azurerm_virtual_network.vnet.name
19+
address_prefixes = ["10.0.0.0/23"]
20+
21+
# NOTE: Container Apps Environment does NOT require delegation
22+
# The environment itself manages the subnet - no delegation needed
23+
}
24+
25+
# ------------------------------------------------------------------------------------------------------
26+
# SUBNET FOR POSTGRESQL FLEXIBLE SERVER
27+
# ------------------------------------------------------------------------------------------------------
28+
resource "azurerm_subnet" "postgres_subnet" {
29+
name = "${var.prefix}-postgres-subnet"
30+
resource_group_name = var.rg_name
31+
virtual_network_name = azurerm_virtual_network.vnet.name
32+
address_prefixes = ["10.0.2.0/24"]
33+
34+
# Delegation required for PostgreSQL Flexible Server
35+
delegation {
36+
name = "Microsoft.DBforPostgreSQL.flexibleServers"
37+
38+
service_delegation {
39+
name = "Microsoft.DBforPostgreSQL/flexibleServers"
40+
actions = [
41+
"Microsoft.Network/virtualNetworks/subnets/join/action",
42+
]
43+
}
44+
}
45+
46+
# Service endpoints for PostgreSQL
47+
service_endpoints = ["Microsoft.Storage"]
48+
}
49+
50+
# ------------------------------------------------------------------------------------------------------
51+
# PRIVATE DNS ZONE FOR POSTGRESQL
52+
# ------------------------------------------------------------------------------------------------------
53+
resource "azurerm_private_dns_zone" "postgres_dns" {
54+
name = "${var.prefix}.postgres.database.azure.com"
55+
resource_group_name = var.rg_name
56+
tags = var.tags
57+
}
58+
59+
resource "azurerm_private_dns_zone_virtual_network_link" "postgres_dns_link" {
60+
name = "${var.prefix}-postgres-dns-link"
61+
resource_group_name = var.rg_name
62+
private_dns_zone_name = azurerm_private_dns_zone.postgres_dns.name
63+
virtual_network_id = azurerm_virtual_network.vnet.id
64+
tags = var.tags
65+
}

infra/modules/vnet/vnet_output.tf

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
output "vnet_id" {
2+
description = "Virtual Network ID"
3+
value = azurerm_virtual_network.vnet.id
4+
}
5+
6+
output "vnet_name" {
7+
description = "Virtual Network name"
8+
value = azurerm_virtual_network.vnet.name
9+
}
10+
11+
output "containerapp_subnet_id" {
12+
description = "Container App subnet ID"
13+
value = azurerm_subnet.containerapp_subnet.id
14+
}
15+
16+
output "postgres_subnet_id" {
17+
description = "PostgreSQL subnet ID"
18+
value = azurerm_subnet.postgres_subnet.id
19+
}
20+
21+
output "postgres_dns_zone_id" {
22+
description = "PostgreSQL Private DNS Zone ID"
23+
value = azurerm_private_dns_zone.postgres_dns.id
24+
}
25+
26+
output "postgres_dns_zone_name" {
27+
description = "PostgreSQL Private DNS Zone name"
28+
value = azurerm_private_dns_zone.postgres_dns.name
29+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
variable "prefix" {
2+
description = "Resource naming prefix"
3+
type = string
4+
}
5+
6+
variable "location" {
7+
description = "Azure region"
8+
type = string
9+
}
10+
11+
variable "rg_name" {
12+
description = "Resource group name"
13+
type = string
14+
}
15+
16+
variable "tags" {
17+
description = "Resource tags"
18+
type = map(string)
19+
default = {}
20+
}

0 commit comments

Comments
 (0)