Skip to content

Commit 3bb0bca

Browse files
feat: workload IaC
1 parent ff94194 commit 3bb0bca

File tree

14 files changed

+504
-38
lines changed

14 files changed

+504
-38
lines changed

infrastructure/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ override.tf.json
2828
# Ignore CLI configuration files
2929
.terraformrc
3030
terraform.rc
31+
.terraform.lock.hcl

infrastructure/environments/poc/variables.tfvars

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
features = {
1+
features = {
22
front_door = false
33
hub_and_spoke = false
44
private_networking = false

infrastructure/environments/poc/variables.yml

Whitespace-only changes.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
data "azurerm_client_config" "current" {}
2+
3+
data "azuread_group" "postgres_sql_admin_group" {
4+
display_name = var.postgres_sql_admin_group
5+
}
6+
7+
data "azurerm_private_dns_zone" "storage" {
8+
count = var.features.private_networking ? 1 : 0
9+
10+
provider = azurerm.hub
11+
12+
name = "privatelink.blob.core.windows.net"
13+
resource_group_name = "rg-hub-${var.hub}-uks-private-dns-zones"
14+
}
15+
16+
data "azurerm_private_dns_zone" "storage-account-blob" {
17+
count = var.features.private_networking ? 1 : 0
18+
19+
provider = azurerm.hub
20+
21+
name = "privatelink.blob.core.windows.net"
22+
resource_group_name = "rg-hub-${var.hub}-uks-private-dns-zones"
23+
}
24+
25+
data "azurerm_private_dns_zone" "storage-account-queue" {
26+
count = var.features.private_networking ? 1 : 0
27+
28+
provider = azurerm.hub
29+
30+
name = "privatelink.queue.core.windows.net"
31+
resource_group_name = "rg-hub-${var.hub}-uks-private-dns-zones"
32+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
data "azurerm_cdn_frontdoor_profile" "this" {
2+
count = var.features.front_door ? 1 : 0
3+
4+
provider = azurerm.hub
5+
6+
name = var.front_door_profile
7+
resource_group_name = "rg-hub-${var.hub}-uks-${var.app_short_name}"
8+
}
9+
10+
module "frontdoor_endpoint" {
11+
count = var.features.front_door ? 1 : 0
12+
13+
source = "../dtos-devops-templates/infrastructure/modules/cdn-frontdoor-endpoint"
14+
15+
providers = {
16+
azurerm = azurerm.hub # Each project's Front Door profile (with secrets) resides in Hub since it's shared infra with a Non-live/Live deployment pattern
17+
azurerm.dns = azurerm.hub
18+
}
19+
20+
cdn_frontdoor_profile_id = data.azurerm_cdn_frontdoor_profile.this[0].id
21+
custom_domains = {
22+
"${var.environment}-domain" = {
23+
host_name = local.hostname # For prod it must be equal to the dns_zone_name to use apex
24+
dns_zone_name = var.dns_zone_name
25+
dns_zone_rg_name = "rg-hub-${var.hub}-uks-public-dns-zones"
26+
}
27+
}
28+
name = var.environment # environment-specific to avoid naming collisions within a Front Door Profile
29+
30+
origins = {
31+
"${var.environment}-origin" = {
32+
hostname = module.webapp.fqdn
33+
origin_host_header = module.webapp.fqdn
34+
private_link = {
35+
target_type = "managedEnvironments"
36+
location = var.region
37+
private_link_target_id = var.container_app_environment_id
38+
}
39+
}
40+
}
41+
route = {
42+
https_redirect_enabled = true
43+
supported_protocols = ["Http", "Https"]
44+
}
45+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
resource "azurerm_resource_group" "main" {
2+
name = local.resource_group_name
3+
location = var.region
4+
}
5+
6+
module "webapp" {
7+
source = "../dtos-devops-templates/infrastructure/modules/container-app"
8+
9+
providers = {
10+
azurerm = azurerm
11+
azurerm.hub = azurerm.hub
12+
}
13+
14+
name = "${var.app_short_name}-web-${var.environment}"
15+
container_app_environment_id = var.container_app_environment_id
16+
resource_group_name = azurerm_resource_group.main.name
17+
fetch_secrets_from_app_key_vault = var.fetch_secrets_from_app_key_vault
18+
infra_key_vault_name = "kv-${var.app_short_name}-${var.env_config}-inf"
19+
infra_key_vault_rg = "rg-${var.app_short_name}-${var.env_config}-infra"
20+
enable_auth = var.enable_auth
21+
app_key_vault_id = var.app_key_vault_id
22+
docker_image = var.docker_image
23+
user_assigned_identity_ids = var.deploy_database_as_container ? [] : [module.db_connect_identity[0].id]
24+
environment_variables = merge(
25+
local.common_env,
26+
{
27+
ALLOWED_HOSTS = "${var.app_short_name}-web-${var.environment}.${var.default_domain}"
28+
},
29+
var.deploy_database_as_container ? local.container_db_env : local.azure_db_env
30+
)
31+
secret_variables = var.deploy_database_as_container ? { DATABASE_PASSWORD = resource.random_password.admin_password[0].result } : {}
32+
is_web_app = true
33+
port = 8000
34+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
output "internal_url" {
2+
value = module.webapp.url
3+
}
4+
5+
output "external_url" {
6+
value = var.features.front_door ? "https://${module.frontdoor_endpoint.custom_domains["${var.environment}-domain"].host_name}/" : null
7+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
data "azurerm_private_dns_zone" "postgres" {
2+
count = var.features.private_networking ? 1 : 0
3+
4+
provider = azurerm.hub
5+
6+
name = "privatelink.postgres.database.azure.com"
7+
resource_group_name = "rg-hub-${var.hub}-uks-private-dns-zones"
8+
}
9+
10+
# Don't deploy if deploy_database_as_container is true
11+
module "postgres" {
12+
count = var.deploy_database_as_container ? 0 : 1
13+
14+
source = "../dtos-devops-templates/infrastructure/modules/postgresql-flexible"
15+
16+
# postgresql Server
17+
name = "postgres-${var.app_short_name}-${var.environment}-uks"
18+
resource_group_name = azurerm_resource_group.main.name
19+
location = var.region
20+
21+
backup_retention_days = var.postgres_backup_retention_days
22+
geo_redundant_backup_enabled = var.postgres_geo_redundant_backup_enabled
23+
postgresql_admin_object_id = data.azuread_group.postgres_sql_admin_group.object_id
24+
postgresql_admin_principal_name = var.postgres_sql_admin_group
25+
postgresql_admin_principal_type = "Group"
26+
administrator_login = local.database_user
27+
admin_identities = [module.db_connect_identity[0]]
28+
29+
# Diagnostic Settings
30+
log_analytics_workspace_id = var.log_analytics_workspace_audit_id
31+
monitor_diagnostic_setting_postgresql_server_enabled_logs = ["PostgreSQLLogs", "PostgreSQLFlexSessions", "PostgreSQLFlexQueryStoreRuntime", "PostgreSQLFlexQueryStoreWaitStats", "PostgreSQLFlexTableStats", "PostgreSQLFlexDatabaseXacts"]
32+
monitor_diagnostic_setting_postgresql_server_metrics = ["AllMetrics"]
33+
34+
sku_name = var.postgres_sku_name
35+
storage_mb = var.postgres_storage_mb
36+
storage_tier = var.postgres_storage_tier
37+
38+
server_version = "16"
39+
tenant_id = data.azurerm_client_config.current.tenant_id
40+
41+
private_endpoint_properties = var.features.private_networking ? {
42+
private_dns_zone_ids_postgresql = [data.azurerm_private_dns_zone.postgres[0].id]
43+
private_endpoint_enabled = true
44+
private_endpoint_subnet_id = var.postgres_subnet_id
45+
private_endpoint_resource_group_name = azurerm_resource_group.main.name
46+
private_service_connection_is_manual = false
47+
} : null
48+
49+
databases = {
50+
db1 = {
51+
collation = "en_US.utf8"
52+
charset = "UTF8"
53+
max_size_gb = 10
54+
name = local.database_name
55+
}
56+
}
57+
58+
tags = {}
59+
}
60+
61+
module "db_connect_identity" {
62+
count = var.deploy_database_as_container ? 0 : 1
63+
64+
source = "../dtos-devops-templates/infrastructure/modules/managed-identity"
65+
resource_group_name = azurerm_resource_group.main.name
66+
location = var.region
67+
uai_name = "mi-${var.app_short_name}-${var.environment}-db-connect"
68+
}
69+
70+
resource "random_password" "admin_password" {
71+
count = var.deploy_database_as_container ? 1 : 0
72+
73+
length = 30
74+
special = true
75+
override_special = "!@#$%^&*()-_=+"
76+
}
77+
78+
module "database_container" {
79+
count = var.deploy_database_as_container ? 1 : 0
80+
81+
providers = {
82+
azurerm = azurerm
83+
azurerm.hub = azurerm.hub
84+
}
85+
86+
source = "../dtos-devops-templates/infrastructure/modules/container-app"
87+
name = "${var.app_short_name}-db-${var.environment}"
88+
container_app_environment_id = var.container_app_environment_id
89+
docker_image = "postgres:16"
90+
secret_variables = var.deploy_database_as_container ? { POSTGRES_PASSWORD = resource.random_password.admin_password[0].result } : {}
91+
environment_variables = {
92+
POSTGRES_USER = local.database_user
93+
POSTGRES_DB = local.database_name
94+
}
95+
resource_group_name = azurerm_resource_group.main.name
96+
is_tcp_app = true
97+
# postgres has a port of 5432
98+
port = 5432
99+
exposed_port = local.database_port
100+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
terraform {
2+
required_providers {
3+
azurerm = {
4+
source = "hashicorp/azurerm"
5+
configuration_aliases = [azurerm.hub]
6+
}
7+
}
8+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
module "azure_blob_storage_identity" {
2+
source = "../dtos-devops-templates/infrastructure/modules/managed-identity"
3+
resource_group_name = azurerm_resource_group.main.name
4+
location = var.region
5+
uai_name = "mi-${var.app_short_name}-${var.environment}-blob-storage"
6+
}
7+
8+
module "azure_queue_storage_identity" {
9+
source = "../dtos-devops-templates/infrastructure/modules/managed-identity"
10+
resource_group_name = azurerm_resource_group.main.name
11+
location = var.region
12+
uai_name = "mi-${var.app_short_name}-${var.environment}-queue-storage"
13+
}
14+
15+
module "storage" {
16+
source = "../dtos-devops-templates/infrastructure/modules/storage"
17+
18+
containers = local.storage_containers
19+
location = var.region
20+
log_analytics_workspace_id = var.log_analytics_workspace_audit_id
21+
22+
monitor_diagnostic_setting_storage_account_enabled_logs = ["StorageWrite", "StorageRead", "StorageDelete"]
23+
monitor_diagnostic_setting_storage_account_metrics = ["AllMetrics"]
24+
25+
name = replace(lower(local.storage_account_name), "-", "")
26+
27+
private_endpoint_properties = features.private_networking ? {
28+
private_dns_zone_ids_blob = [data.azurerm_private_dns_zone.storage-account-blob[0].id]
29+
private_dns_zone_ids_queue = [data.azurerm_private_dns_zone.storage-account-queue[0].id]
30+
private_endpoint_enabled = true
31+
private_endpoint_subnet_id = var.main_subnet_id
32+
private_endpoint_resource_group_name = azurerm_resource_group.main.name
33+
private_service_connection_is_manual = false
34+
} : null
35+
queues = local.storage_queues
36+
resource_group_name = azurerm_resource_group.main.name
37+
}
38+
39+
module "blob_storage_role_assignment" {
40+
source = "../dtos-devops-templates/infrastructure/modules/rbac-assignment"
41+
principal_id = module.azure_blob_storage_identity.principal_id
42+
role_definition_name = "Storage Blob Data Contributor"
43+
scope = module.storage.storage_account_id
44+
depends_on = [module.storage, module.azure_blob_storage_identity]
45+
}
46+
47+
module "queue_storage_role_assignment" {
48+
source = "../dtos-devops-templates/infrastructure/modules/rbac-assignment"
49+
principal_id = module.azure_queue_storage_identity.principal_id
50+
role_definition_name = "Storage Queue Data Contributor"
51+
scope = module.storage.storage_account_id
52+
depends_on = [module.storage, module.azure_queue_storage_identity]
53+
}

0 commit comments

Comments
 (0)