Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Data/postgreSqlDatabases/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ A list of available Recipes for this resource type, including links to the Bicep
|Platform| IaC Language| Recipe Name | Stage |
|---|---|---|---|
| Kubernetes | Bicep | kubernetes-postgresql.bicep | Alpha |
| Kubernetes | Terraform | main.tf | Alpha |
| Azure | Bicep | azure-postgresql.bicep | Alpha |

## Recipe Input Properties

Expand Down
227 changes: 227 additions & 0 deletions Data/postgreSqlDatabases/recipes/azure/bicep/azure-postgresql.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
extension kubernetes with {
kubeConfig: ''
namespace: context.runtime.kubernetes.namespace
} as kubernetes

@description('Information about what resource is calling this Recipe. Generated by Radius.')
param context object

@description('Location for the PostgreSQL Flexible Server. Defaults to the resource group location.')
param postgresqlLocation string = resourceGroup().location

@description('PostgreSQL major version.')
param postgresqlVersion string = '16'

@description('Storage size in GB.')
param storageSizeGb int = 32

@description('Size tier for the PostgreSQL Flexible Server. Affects the underlying SKU and performance characteristics.')
param size string = context.resource.properties.?size ?? 'S'

@description('Number of days to retain automated backups.')
@minValue(7)
@maxValue(35)
param backupRetentionDays int = 7

@description('Whether to enable geo-redundant backups for the server.')
@allowed([
'Enabled'
'Disabled'
])
param geoRedundantBackup string = 'Disabled'

@description('High availability mode for the PostgreSQL Flexible Server.')
@allowed([
'Disabled'
'SameZone'
'ZoneRedundant'
])
param highAvailabilityMode string = 'Disabled'

//////////////////////////////////////////
// Common Radius variables
//////////////////////////////////////////

var resourceName = context.resource.name
var applicationName = context.application != null ? context.application.name : ''
var environmentName = context.environment != null ? context.environment.name : ''

//////////////////////////////////////////
// Secrets from Kubernetes
//////////////////////////////////////////

// Radius creates a Kubernetes Secret from the Radius.Security/secrets resource.
// Read it directly using the secretName property.
var secretName = context.resource.properties.secretName

resource dbSecret 'core/Secret@v1' existing = {
metadata: {
name: secretName
namespace: context.runtime.kubernetes.namespace
}
}

var adminUsername = base64ToString(string(dbSecret.data.USERNAME))
var adminPassword = base64ToString(string(dbSecret.data.PASSWORD))

//////////////////////////////////////////
// PostgreSQL variables
//////////////////////////////////////////

// var database = context.resource.properties.?database ?? 'postgres_db'
var database = resourceName ?? 'postgres_db'
var initSql = context.resource.properties.?initSql ?? ''
var hasInitSql = initSql != ''
var port = 5432

var uniqueSuffix = uniqueString(context.resource.id, resourceGroup().id)
var serverName = '${resourceName}-${take(uniqueSuffix, 6)}'
var postgresHost = '${serverName}.postgres.database.azure.com'

var skuMap = {
S: {
name: 'Standard_B1ms'
tier: 'Burstable'
}
M: {
name: 'Standard_D2s_v3'
tier: 'GeneralPurpose'
}
L: {
name: 'Standard_E2ds_v4'
tier: 'MemoryOptimized'
}
}

var tags = {
'radapp.io-resource': resourceName
'radapp.io-application': applicationName
'radapp.io-environment': environmentName
}

//////////////////////////////////////////
// PostgreSQL Flexible Server
//////////////////////////////////////////

resource postgresServer 'Microsoft.DBforPostgreSQL/flexibleServers@2024-08-01' = {
name: serverName
location: postgresqlLocation
tags: tags
sku: {
name: skuMap[size].name
tier: skuMap[size].tier
}
properties: {
createMode: 'Default'
authConfig: {
activeDirectoryAuth: 'Disabled'
passwordAuth: 'Enabled'
}
version: postgresqlVersion
administratorLogin: adminUsername
administratorLoginPassword: adminPassword
storage: {
storageSizeGB: storageSizeGb
}
backup: {
backupRetentionDays: backupRetentionDays
geoRedundantBackup: geoRedundantBackup
}
highAvailability: {
mode: highAvailabilityMode
}
}
}
Comment thread
willtsai marked this conversation as resolved.

//////////////////////////////////////////
// Firewall rule & database
//////////////////////////////////////////

resource firewallRule 'Microsoft.DBforPostgreSQL/flexibleServers/firewallRules@2024-08-01' = {
parent: postgresServer
name: 'AllowAllAzureServices'
properties: {
startIpAddress: '0.0.0.0'
endIpAddress: '0.0.0.0'
}
}

resource postgresDb 'Microsoft.DBforPostgreSQL/flexibleServers/databases@2024-08-01' = {
parent: postgresServer
name: database
properties: {
charset: 'UTF8'
collation: 'en_US.utf8'
}
}

//////////////////////////////////////////
// Init SQL deployment script (optional)
//////////////////////////////////////////

// When `initSql` is provided, run it against the newly created database using
// `psql` inside an Azure CLI deployment script container.
resource initSqlScript 'Microsoft.Resources/deploymentScripts@2023-08-01' = if (hasInitSql) {
name: 'init-sql-${uniqueSuffix}'
location: postgresqlLocation
tags: tags
kind: 'AzureCLI'
properties: {
azCliVersion: '2.60.0'
timeout: 'PT10M'
retentionInterval: 'PT1H'
cleanupPreference: 'OnSuccess'
environmentVariables: [
{
name: 'PGHOST'
value: postgresHost
}
{
name: 'PGUSER'
value: adminUsername
}
{
name: 'PGPASSWORD'
#disable-next-line use-secure-value-for-secure-inputs
secureValue: adminPassword
}
{
name: 'PGDATABASE'
value: database
}
{
name: 'PGPORT'
value: string(port)
}
{
name: 'PGSSLMODE'
value: 'require'
}
{
name: 'INIT_SQL'
#disable-next-line use-secure-value-for-secure-inputs
secureValue: initSql
}
]
scriptContent: '''
set -euo pipefail
apk add --no-cache postgresql-client >/dev/null
printf '%s' "$INIT_SQL" | psql --quiet -v ON_ERROR_STOP=1 -f -
'''
}
dependsOn: [
firewallRule
]
}

//////////////////////////////////////////
// Output Radius result
//////////////////////////////////////////

output result object = {
values: {
host: postgresHost
port: port
database: database
}
}
Loading