Skip to content

Commit

Permalink
Managed identity support for Azure Database for PostgreSQL (#215)
Browse files Browse the repository at this point in the history
* Add Azure CLI serviceconnector-passwordless extension to the devcontainer

* Remove Terraform deprecated retention_policy from azurerm_monitor_diagnostic_setting

* Terraform infrastructure for the app service connector

* script to set up service connector

* devcontainer changes to ensure az service connector extension is installed

* pom.xml changes to support passwordless

* Terraform for dev infra

* prod deployment

* fix terraform outputs.tf

* private dns zone for postgresql

* Set the user's principal name for the database admin

* update comments for dns zones

* Remove commented Terraform code
  • Loading branch information
nickdala authored Sep 20, 2024
1 parent 7f08e1d commit 856caaa
Show file tree
Hide file tree
Showing 18 changed files with 184 additions and 103 deletions.
1 change: 1 addition & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"VARIANT": "jammy"
}
},
"postStartCommand": "./.devcontainer/scripts/onCreateCommand.sh",
"remoteUser": "vscode",
"containerEnv": {
"M2": "/home/vscode" // required because the java feature is not setting this correctly
Expand Down
3 changes: 3 additions & 0 deletions .devcontainer/scripts/onCreateCommand.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
set -x

az extension add --name serviceconnector-passwordless --upgrade
9 changes: 9 additions & 0 deletions infra/scripts/setup-service-connector.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

source_id=$1
target_id=$2

random_string=$RANDOM
connection_name=postgresql_${RANDOM}

az webapp connection create postgres-flexible --connection ${connection_name} --source-id ${source_id} --target-id ${target_id} --client-type springBoot --system-identity
4 changes: 0 additions & 4 deletions infra/shared/terraform/modules/app-service/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,6 @@ resource "azurerm_linux_web_app" "application" {
APPLICATIONINSIGHTS_CONNECTION_STRING = var.app_insights_connection_string
ApplicationInsightsAgent_EXTENSION_VERSION = "~3"

SPRING_DATASOURCE_URL = var.contoso_webapp_options.postgresql_database_url
SPRING_DATASOURCE_USERNAME = var.contoso_webapp_options.postgresql_database_user
SPRING_DATASOURCE_PASSWORD = var.contoso_webapp_options.postgresql_database_password

SPRING_CLOUD_AZURE_ACTIVE_DIRECTORY_CREDENTIAL_CLIENT_ID = var.contoso_webapp_options.contoso_active_directory_client_id
SPRING_CLOUD_AZURE_ACTIVE_DIRECTORY_CREDENTIAL_CLIENT_SECRET = var.contoso_webapp_options.contoso_active_directory_client_secret
SPRING_CLOUD_AZURE_ACTIVE_DIRECTORY_PROFILE_TENANT_ID = var.contoso_webapp_options.contoso_active_directory_tenant_id
Expand Down
4 changes: 0 additions & 4 deletions infra/shared/terraform/modules/app-service/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,6 @@ variable "contoso_webapp_options" {
contoso_active_directory_client_id = string
contoso_active_directory_client_secret = string

postgresql_database_url = string
postgresql_database_user = string
postgresql_database_password = string

redis_host_name = string
redis_port = number
redis_password = string
Expand Down
14 changes: 0 additions & 14 deletions infra/shared/terraform/modules/cache/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -75,28 +75,14 @@ resource "azurerm_monitor_diagnostic_setting" "redis_diagnostic" {

enabled_log {
category_group = "audit"

retention_policy {
days = 0
enabled = false
}
}

enabled_log {
category_group = "allLogs"

retention_policy {
days = 0
enabled = false
}
}

metric {
category = "AllMetrics"
enabled = true
retention_policy {
enabled = false
days = 0
}
}
}
14 changes: 0 additions & 14 deletions infra/shared/terraform/modules/key-vault/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -87,28 +87,14 @@ resource "azurerm_monitor_diagnostic_setting" "key_vault_diagnostic" {

enabled_log {
category_group = "audit"

retention_policy {
days = 0
enabled = false
}
}

enabled_log {
category_group = "allLogs"

retention_policy {
days = 0
enabled = false
}
}

metric {
category = "AllMetrics"
enabled = true
retention_policy {
enabled = false
days = 0
}
}
}
41 changes: 1 addition & 40 deletions infra/shared/terraform/modules/postresql/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,6 @@ terraform {
}
}

# Quickstart: Use Terraform to create an Azure Database for MySQL - Flexible Server
# https://docs.microsoft.com/azure/mysql/flexible-server/quickstart-create-terraform?tabs=azure-cli


# Azure Private DNS provides a reliable, secure DNS service to manage and
# resolve domain names in a virtual network without the need to add a custom DNS solution
# https://docs.microsoft.com/azure/dns/private-dns-privatednszone
resource "azurerm_private_dns_zone" "postgresql_database" {
count = var.environment == "prod" ? 1 : 0
name = "privatelink.${var.location}.postgres.database.azure.com"
resource_group_name = var.resource_group
}

# After you create a private DNS zone in Azure, you'll need to link a virtual network to it.
# https://docs.microsoft.com/azure/dns/private-dns-virtual-network-links
resource "azurerm_private_dns_zone_virtual_network_link" "postgresql_database" {
count = var.environment == "prod" ? 1 : 0
name = azurerm_private_dns_zone.postgresql_database[0].name
private_dns_zone_name = azurerm_private_dns_zone.postgresql_database[0].name
virtual_network_id = var.virtual_network_id
resource_group_name = var.resource_group
}

resource "azurecaf_name" "postgresql_server" {
count = var.environment == "prod" ? 1 : 0
name = var.application_name
Expand All @@ -54,7 +31,7 @@ resource "azurerm_postgresql_flexible_server" "postgresql_database" {

public_network_access_enabled = false
delegated_subnet_id = var.subnet_network_id
private_dns_zone_id = azurerm_private_dns_zone.postgresql_database[0].id
private_dns_zone_id = var.private_dns_zone_id #azurerm_private_dns_zone.postgresql_database[0].id

geo_redundant_backup_enabled = false

Expand Down Expand Up @@ -85,8 +62,6 @@ resource "azurerm_postgresql_flexible_server" "postgresql_database" {
"environment" = var.environment
"application-name" = var.application_name
}

depends_on = [azurerm_private_dns_zone_virtual_network_link.postgresql_database]
}

# Configure Diagnostic Settings for PostgreSQL
Expand All @@ -98,29 +73,15 @@ resource "azurerm_monitor_diagnostic_setting" "postgresql_diagnostic" {

enabled_log {
category_group = "audit"

retention_policy {
days = 0
enabled = false
}
}

enabled_log {
category_group = "allLogs"

retention_policy {
days = 0
enabled = false
}
}

metric {
category = "AllMetrics"
enabled = true
retention_policy {
enabled = false
days = 0
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions infra/shared/terraform/modules/postresql/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,8 @@ output "dev_database_fqdn" {
value = length(azurerm_postgresql_flexible_server.dev_postresql_database) > 0 ? azurerm_postgresql_flexible_server.dev_postresql_database[0].fqdn : ""
description = "The FQDN of the database"
}

output "dev_database_name" {
value = length(azurerm_postgresql_flexible_server.dev_postresql_database) > 0 ? azurerm_postgresql_flexible_server.dev_postresql_database[0].name : ""
description = "The name of the database server"
}
5 changes: 5 additions & 0 deletions infra/shared/terraform/modules/postresql/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,9 @@ variable "log_analytics_workspace_id" {
variable "sku_name" {
type = string
default = "B_Standard_B1ms"
}

variable "private_dns_zone_id" {
type = string
description = "The id of the private dns zone"
}
27 changes: 18 additions & 9 deletions infra/terraform/application.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ module "application" {
contoso_active_directory_tenant_id = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.contoso_application_tenant_id[0].id})"
contoso_active_directory_client_id = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.contoso_application_client_id[0].id})"
contoso_active_directory_client_secret = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.contoso_application_client_secret[0].id})"
postgresql_database_url = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.contoso_database_url[0].id})"
postgresql_database_user = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.contoso_database_admin[0].id})"
postgresql_database_password = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.contoso_database_admin_password[0].id})"
redis_host_name = module.cache[0].cache_hostname
redis_port = module.cache[0].cache_ssl_port
redis_password = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.contoso_cache_secret[0].id})"
Expand Down Expand Up @@ -59,9 +56,6 @@ module "secondary_application" {
contoso_active_directory_tenant_id = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.contoso_application_tenant_id[0].id})"
contoso_active_directory_client_id = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.contoso_application_client_id[0].id})"
contoso_active_directory_client_secret = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.contoso_application_client_secret[0].id})"
postgresql_database_url = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.secondary_contoso_database_url[0].id})"
postgresql_database_user = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.contoso_database_admin[0].id})"
postgresql_database_password = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.contoso_database_admin_password[0].id})"
redis_host_name = module.secondary_cache[0].cache_hostname
redis_port = module.secondary_cache[0].cache_ssl_port
redis_password = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.contoso_cache_secret[0].id})"
Expand Down Expand Up @@ -96,11 +90,26 @@ module "dev_application" {
contoso_active_directory_tenant_id = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.dev_contoso_application_tenant_id[0].id})"
contoso_active_directory_client_id = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.dev_contoso_application_client_id[0].id})"
contoso_active_directory_client_secret = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.dev_contoso_application_client_secret[0].id})"
postgresql_database_url = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.dev_contoso_database_url[0].id})"
postgresql_database_user = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.dev_contoso_database_admin[0].id})"
postgresql_database_password = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.dev_contoso_database_admin_password[0].id})"
redis_host_name = module.dev-cache[0].cache_hostname
redis_port = module.dev-cache[0].cache_ssl_port
redis_password = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.dev_contoso_cache_secret[0].id})"
}
}

resource "null_resource" "dev_service_connector" {
count = var.environment == "dev" ? 1 : 0

triggers = {
always_run = "${timestamp()}"
}

provisioner "local-exec" {
command = "bash ../scripts/setup-service-connector.sh ${module.dev_application[0].web_app_id} ${azurerm_postgresql_flexible_server_database.dev_postresql_database_db[0].id}"
}

depends_on = [
module.dev_application,
azurerm_postgresql_flexible_server_database.dev_postresql_database_db,
azurerm_postgresql_flexible_server_active_directory_administrator.dev-contoso-ad-admin
]
}
27 changes: 24 additions & 3 deletions infra/terraform/database.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ module "postresql_database" {
administrator_password = local.database_administrator_password
log_analytics_workspace_id = module.hub_app_insights[0].log_analytics_workspace_id
sku_name = local.postgresql_sku_name
private_dns_zone_id = azurerm_private_dns_zone.postgres_dns_zone[0].id
}

resource "azurerm_postgresql_flexible_server_database" "postresql_database" {
Expand All @@ -34,15 +35,14 @@ resource "azurerm_postgresql_flexible_server_database" "postresql_database" {
server_id = module.postresql_database[0].database_server_id
}


# Demo purposes only: assign current user as admin to the created DB
# Demo purposes only: assign current user as admin for the primary DB
resource "azurerm_postgresql_flexible_server_active_directory_administrator" "contoso-ad-admin" {
count = var.environment == "prod" ? 1 : 0
server_name = module.postresql_database[0].database_name
resource_group_name = azurerm_resource_group.spoke[0].name
tenant_id = data.azuread_client_config.current.tenant_id
object_id = data.azuread_client_config.current.object_id
principal_name = data.azuread_client_config.current.object_id
principal_name = data.azuread_user.current.user_principal_name
principal_type = "User"
}

Expand All @@ -64,6 +64,7 @@ module "secondary_postresql_database" {
administrator_password = local.database_administrator_password
log_analytics_workspace_id = module.hub_app_insights[0].log_analytics_workspace_id
sku_name = local.postgresql_sku_name
private_dns_zone_id = azurerm_private_dns_zone.postgres_dns_zone[0].id

depends_on = [
module.spoke_vnet[0],
Expand Down Expand Up @@ -91,6 +92,26 @@ module "dev_postresql_database" {
administrator_password = local.database_administrator_password
log_analytics_workspace_id = module.dev_app_insights[0].log_analytics_workspace_id
sku_name = local.postgresql_sku_name
private_dns_zone_id = null
}

resource "azurerm_postgresql_flexible_server_firewall_rule" "dev_postresql_database_allow_access_rule_local_ip" {
count = var.environment == "dev" ? 1 : 0
name = "allow-access-from-local-ip"
server_id = module.dev_postresql_database[0].dev_database_server_id
start_ip_address = local.myip
end_ip_address = local.myip
}

# Demo purposes only: assign current user as admin for the dev DB
resource "azurerm_postgresql_flexible_server_active_directory_administrator" "dev-contoso-ad-admin" {
count = var.environment == "dev" ? 1 : 0
server_name = module.dev_postresql_database[0].dev_database_name
resource_group_name = azurerm_resource_group.dev[0].name
tenant_id = data.azuread_client_config.current.tenant_id
object_id = data.azuread_client_config.current.object_id
principal_name = data.azuread_client_config.current.object_id
principal_type = "User"
}

resource "azurerm_postgresql_flexible_server_database" "dev_postresql_database_db" {
Expand Down
Loading

0 comments on commit 856caaa

Please sign in to comment.