Postgres
Example: postgres resource based on Azure Database for PostgresSQL
Using this examples requires the “Enable Private Endpoints for PostgreSQL flexible servers” preview feature to be enabled.
Configuration
This example configures a postgres-instance and postgres Resource Definition using Azure Database for PostgreSQL - Flexible Server.
The postgres-instance
represent the actual server and is provisioned only once for the entire environment.
Workloads use the postgres
resource to dynamically create databases on this server, the
respective score definition would look like:
resources:
...
db:
type: postgres
Infrastructure setup
graph TD;
subgraph Database Resource Group
subgraph server["Azure Database for PostgreSQL - Flexible Server"]
database["SQL Database"]
end
end
subgraph Workload Resource Group
subgraph Workload Virtual Network
pip["Private IP"]
server -- private endpoint --> pip
subgraph AKS Cluster
workload-pod["Workload Pod"]
end
workload-pod --> pip
end
end
Orchestrator setup
graph LR;
workload_1 --> db_1["db_1, resource_type: postgres"]
workload_2 --> db_2["db_2, resource_type: postgres"]
workload_2 --> shared.db_1["shared.db_1, resource_type: postgres"]
workload_3 --> shared.db_1["shared.db_1, resource_type: postgres"]
db_1 --> server["main-postgres, resource_type: postgres-instance"]
db_2 --> server
shared.db_1 --> server
Terraform docs
Requirements
Name | Version |
---|---|
terraform | >= 1.3.0 |
azuread | ~> 2.47 |
azurerm | ~> 3.91 |
humanitec | ~> 1.0 |
Providers
Name | Version |
---|---|
azuread | ~> 2.47 |
azurerm | ~> 3.91 |
humanitec | ~> 1.0 |
Modules
Name | Source | Version |
---|---|---|
postgres | ../../humanitec-resource-defs/postgres/basic | n/a |
postgres_instance | ../../humanitec-resource-defs/postgres-instance/basic | n/a |
Resources
Name | Type |
---|---|
azuread_application.humanitec_provisioner | resource |
azuread_service_principal.humanitec_provisioner | resource |
azuread_service_principal_password.humanitec_provisioner | resource |
azurerm_role_assignment.resource_group_resource | resource |
azurerm_role_assignment.resource_group_workload | resource |
humanitec_application.example | resource |
humanitec_resource_account.humanitec_provisioner | resource |
humanitec_resource_definition_criteria.postgres | resource |
humanitec_resource_definition_criteria.postgres_instance | resource |
azurerm_resource_group.resource | data source |
azurerm_resource_group.workload | data source |
Inputs
Name | Description | Type | Default | Required |
---|---|---|---|---|
resource_group_name | Specifies the Name of the Resource Group within which this database will reside. | string |
n/a | yes |
subnet_name | The name of the subnet where the Private Endpoint will be allocated. | string |
n/a | yes |
subscription_id | The Subscription ID which should be used. | string |
n/a | yes |
virtual_network_name | The name of the virtual network where Private Endpoint will be allocated. | string |
n/a | yes |
workload_resource_group_name | The name of the resource group where the Private Endpoint will be allocated. | string |
n/a | yes |
administrator_login | The Administrator login for the PostgreSQL Server. | string |
"" |
no |
administrator_password | The Password associated with the administrator_login for the PostgreSQL Server. | string |
"" |
no |
name | Name of the example application. | string |
"hum-rp-postgres-example" |
no |
prefix | Prefix of the created resources | string |
"hum-rp-postgres-ex-" |
no |
resource_packs_azure_rev | Azure Resource Pack git branch. | string |
"refs/heads/main" |
no |
resource_packs_azure_url | Azure Resource Pack git url. | string |
"https://github.com/humanitec-architecture/resource-packs-azure.git" |
no |
main.tf
(view on GitHub)
:
# Service principal used by Humanitec to provision resources
data "azurerm_resource_group" "resource" {
name = var.resource_group_name
}
data "azurerm_resource_group" "workload" {
name = var.workload_resource_group_name
}
resource "azuread_application" "humanitec_provisioner" {
display_name = var.name
}
resource "azuread_service_principal" "humanitec_provisioner" {
client_id = azuread_application.humanitec_provisioner.client_id
}
resource "azuread_service_principal_password" "humanitec_provisioner" {
service_principal_id = azuread_service_principal.humanitec_provisioner.object_id
}
resource "azurerm_role_assignment" "resource_group_resource" {
scope = data.azurerm_resource_group.resource.id
role_definition_name = "Contributor"
principal_id = azuread_service_principal.humanitec_provisioner.object_id
}
resource "azurerm_role_assignment" "resource_group_workload" {
scope = data.azurerm_resource_group.workload.id
role_definition_name = "Contributor"
principal_id = azuread_service_principal.humanitec_provisioner.object_id
}
resource "humanitec_resource_account" "humanitec_provisioner" {
id = var.name
name = var.name
type = "azure"
credentials = jsonencode({
"appId" : azuread_service_principal.humanitec_provisioner.client_id,
"displayName" : azuread_application.humanitec_provisioner.display_name,
"password" : azuread_service_principal_password.humanitec_provisioner.value,
"tenant" : azuread_service_principal.humanitec_provisioner.application_tenant_id
})
depends_on = [
# Otherwise the account looses permissions before the resources are deleted
azurerm_role_assignment.resource_group_resource,
azurerm_role_assignment.resource_group_workload
]
}
# Example application and resource definition criteria
# Define the shared postgres-instance resource id and class
locals {
postgres_instance_res_id = "main-postgres"
postgres_instance_class = "default"
}
resource "humanitec_application" "example" {
id = var.name
name = var.name
}
module "postgres_instance" {
source = "github.com/humanitec-architecture/resource-packs-azure?ref=v2024-06-14//humanitec-resource-defs/postgres-instance/basic"
prefix = var.prefix
resource_packs_azure_url = var.resource_packs_azure_url
resource_packs_azure_rev = var.resource_packs_azure_rev
append_logs_to_error = true
driver_account = humanitec_resource_account.humanitec_provisioner.id
subscription_id = var.subscription_id
resource_group_name = data.azurerm_resource_group.resource.name
administrator_login = var.administrator_login
administrator_password = var.administrator_password
virtual_network_name = var.virtual_network_name
subnet_name = var.subnet_name
workload_resource_group_name = data.azurerm_resource_group.workload.name
}
resource "humanitec_resource_definition_criteria" "postgres_instance" {
resource_definition_id = module.postgres_instance.id
app_id = humanitec_application.example.id
res_id = local.postgres_instance_res_id
class = local.postgres_instance_class
force_delete = true
}
module "postgres" {
source = "github.com/humanitec-architecture/resource-packs-azure?ref=v2024-06-14//humanitec-resource-defs/postgres/basic"
prefix = var.prefix
resource_packs_azure_url = var.resource_packs_azure_url
resource_packs_azure_rev = var.resource_packs_azure_rev
append_logs_to_error = true
driver_account = humanitec_resource_account.humanitec_provisioner.id
subscription_id = var.subscription_id
instance_resource = "postgres-instance.${local.postgres_instance_class}#${local.postgres_instance_res_id}"
}
resource "humanitec_resource_definition_criteria" "postgres" {
resource_definition_id = module.postgres.id
app_id = humanitec_application.example.id
force_delete = true
}
providers.tf
(view on GitHub)
:
terraform {
required_providers {
azuread = {
source = "hashicorp/azuread"
version = "~> 2.47"
}
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.91"
}
humanitec = {
source = "humanitec/humanitec"
version = "~> 1.0"
}
}
required_version = ">= 1.3.0"
}
provider "humanitec" {
}
provider "azuread" {
}
provider "azurerm" {
features {}
subscription_id = var.subscription_id
}
terraform.tfvars.example
(view on GitHub)
:
# The Administrator login for the PostgreSQL Server.
administrator_login = ""
# The Password associated with the administrator_login for the PostgreSQL Server.
administrator_password = ""
# Name of the example application.
name = "hum-rp-postgres-example"
# Prefix of the created resources
prefix = "hum-rp-postgres-ex-"
# Specifies the Name of the Resource Group within which this database will reside.
resource_group_name = ""
# Azure Resource Pack git branch.
resource_packs_azure_rev = "refs/tags/v2024-06-14"
# Azure Resource Pack git url.
resource_packs_azure_url = "https://github.com/humanitec-architecture/resource-packs-azure.git"
# The name of the subnet where the Private Endpoint will be allocated.
subnet_name = ""
# The Subscription ID which should be used.
subscription_id = ""
# The name of the virtual network where Private Endpoint will be allocated.
virtual_network_name = ""
# The name of the resource group where the Private Endpoint will be allocated.
workload_resource_group_name = ""
variables.tf
(view on GitHub)
:
variable "prefix" {
description = "Prefix of the created resources"
type = string
default = "hum-rp-postgres-ex-"
}
variable "name" {
description = "Name of the example application."
type = string
default = "hum-rp-postgres-example"
}
variable "resource_packs_azure_url" {
description = "Azure Resource Pack git url."
type = string
default = "https://github.com/humanitec-architecture/resource-packs-azure.git"
}
variable "resource_packs_azure_rev" {
description = "Azure Resource Pack git branch."
type = string
default = "refs/tags/v2024-06-14"
}
variable "subscription_id" {
description = "The Subscription ID which should be used."
type = string
}
variable "resource_group_name" {
description = "Specifies the Name of the Resource Group within which this database will reside."
type = string
}
variable "administrator_login" {
description = "The Administrator login for the PostgreSQL Server."
type = string
default = ""
}
variable "administrator_password" {
description = "The Password associated with the administrator_login for the PostgreSQL Server."
type = string
default = ""
}
variable "virtual_network_name" {
description = "The name of the virtual network where Private Endpoint will be allocated."
type = string
}
variable "subnet_name" {
description = "The name of the subnet where the Private Endpoint will be allocated."
type = string
}
variable "workload_resource_group_name" {
description = "The name of the resource group where the Private Endpoint will be allocated."
type = string
}