Skip to content

Commit

Permalink
Use postgresql instead of redis for statestore (#201)
Browse files Browse the repository at this point in the history
* Use postgresql instead of redis for statestore

Postgres is both a state store with real transactions and it is
better suited to for handling Dapr workflows. As such, and given it
**is** the recommended state store for Workflows, it makes sense to
use it for the state store E2E tests.

Once we release to Dapr 1.12.0 we can upgrade it to use AAD
authentication.

Signed-off-by: Tiago Alves Macambira <[email protected]>

* Apply suggestions from code review

Signed-off-by: Tiago Alves Macambira <[email protected]>

---------

Signed-off-by: Tiago Alves Macambira <[email protected]>
  • Loading branch information
tmacam authored Oct 3, 2023
1 parent de3c963 commit 693401a
Show file tree
Hide file tree
Showing 3 changed files with 210 additions and 11 deletions.
32 changes: 32 additions & 0 deletions deploy/aks/daprComponents/statestore-postgresql-component.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
@secure()
param kubeConfig string
param kubernetesNamespace string

@secure()
param connectionString string

import '[email protected]' with {
namespace: 'default'
kubeConfig: kubeConfig
}

resource daprIoComponentStatestore 'dapr.io/Component@v1alpha1' = {
metadata: {
name: 'statestore'
namespace: kubernetesNamespace
}
spec: {
type: 'state.postgresql'
version: 'v1'
metadata: [
{
name: 'connectionString'
value: connectionString
}
{
name: 'actorStateStore'
value: 'true'
}
]
}
}
20 changes: 9 additions & 11 deletions deploy/aks/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -160,33 +160,31 @@ module servicebus 'services/servicebus.bicep' = {
}
}


module redis 'services/redis.bicep' = {
name: '${clusterName}--services--redis'
// Postgresql
module postgresql 'services/postgresql.bicep' = {
name: '${clusterName}--services--postgres'
params: {
solutionName: solutionName
aadAdminName: managedIdentity.name
aadAdminObjectid: managedIdentity.properties.principalId
location: location
enableNonSslPort : false // Just to be explicit here: using TLS port 6380
// diagnosticsEnabled: false - https://github.com/Azure/azure-quickstart-templates/issues/13566
allowAzureIPsFirewall: true
}
}

//
// Dapr Components
//

module statestoreComponent 'daprComponents/statestore-component.bicep' = {
module statestoreComponent 'daprComponents/statestore-postgresql-component.bicep' = {
name: '${clusterName}--component--redis-statestore'
params: {
kubeConfig: aks.listClusterAdminCredential().kubeconfigs[0].value
kubernetesNamespace: longhaulNamespace.outputs.kubernetesNamespace

redisEnableTLS: redis.outputs.redisEnableTLS
redisHostnameAndPort: redis.outputs.redisHostnameAndPort
redisPassword: redis.outputs.redisPassword
connectionString: postgresql.outputs.connectionString
}
dependsOn: [
redis
postgresql
daprExtension
longhaulNamespace
]
Expand Down
169 changes: 169 additions & 0 deletions deploy/aks/services/postgresql.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
@description('Used to create a unique name for this postgres instance')
param solutionName string

@description('Server Name for Azure Database for PostgreSQL Flexible Server instance')
param serverName string = '${solutionName}-postgres'

@description('Database administrator login name')
@minLength(1)
param administratorLogin string = 'pgadmin${uniqueString(resourceGroup().id)}'

@description('Database administrator password')
@minLength(8)
@secure()
param administratorLoginPassword string = 'pgpass-${uniqueString(resourceGroup().id)}'

@description('Azure database for PostgreSQL pricing tier')
@allowed([
'Burstable'
'Basic'
'GeneralPurpose'
'MemoryOptimized'
])
param skuTier string = 'Burstable'

@description('Azure database for PostgreSQL Flexible Server sku name ')
param skuName string = 'Standard_B1ms'

@description('Azure database for PostgreSQL Flexible Server Storage Size in GB ')
param storageSize int = 32

@description('PostgreSQL version')
@allowed([
'11'
'12'
'13'
'14'
'15'
])
param postgresqlVersion string = '15'

@description('Location for all resources.')
param location string = resourceGroup().location

@description('PostgreSQL Flexible Server backup retention days')
param backupRetentionDays int = 7

@description('Geo-Redundant Backup setting')
@allowed([
'Disabled'
'Enabled'
])
param geoRedundantBackup string = 'Disabled'

@description('High Availability Mode')
@allowed([
'Disabled'
'ZoneRedundant'
'SameZone'
])
param haMode string = 'Disabled'

@description('Active Directory Authetication')
@allowed([
'Disabled'
'Enabled'
])
param isActiveDirectoryAuthEnabled string = 'Enabled'

@description('PostgreSQL Authetication')
@allowed([
'Disabled'
'Enabled'
])
param isPostgreSQLAuthEnabled string = 'Enabled'

@description('The Object ID of the Azure AD admin.')
param aadAdminObjectid string

@description('Azure AD admin name.')
param aadAdminName string

@description('Azure AD admin Type')
@allowed([
'User'
'Group'
'ServicePrincipal'
])
param aadAdminType string = 'ServicePrincipal'


param allowAzureIPsFirewall bool = false
param allowAllIPsFirewall bool = false

resource server 'Microsoft.DBforPostgreSQL/flexibleServers@2022-12-01' = {
name: serverName
location: location
sku: {
name: skuName
tier: skuTier
}
properties: {
createMode: 'Default'
version: postgresqlVersion
administratorLogin: administratorLogin
administratorLoginPassword: administratorLoginPassword
authConfig: {
activeDirectoryAuth: isActiveDirectoryAuthEnabled
passwordAuth: isPostgreSQLAuthEnabled
tenantId: subscription().tenantId
}
storage: {
storageSizeGB: storageSize
}
backup: {
backupRetentionDays: backupRetentionDays
geoRedundantBackup: geoRedundantBackup
}
highAvailability: {
mode: haMode
}
}
}

// AAD support requires Dapr 1.12.0 or later
resource addAddUser 'Microsoft.DBforPostgreSQL/flexibleServers/administrators@2022-12-01' = {
parent: server
name: '${aadAdminObjectid}'
dependsOn: [
server
]
properties: {
tenantId: subscription().tenantId
principalType: aadAdminType
principalName: aadAdminName
}
}

// Postgres examples nudge strongly towards using a private network to
// secure connectivity to the database. This is a good idea but seems
// too much for a demo and to mix with AKS.
//
// References:
// * https://github.com/Azure-Samples/dotNET-FrontEnd-to-BackEnd-on-Azure-Container-Apps/blob/2b85ffa3bf0359f3e89ee222375afa4f4fc6060a/infra/core/database/postgresql/flexibleserver.bicep#L46
// * https://github.com/Azure/ResourceModules/tree/50c54a404803d9f76f30dbcd8ab03797fabd78f7/modules/db-for-postgre-sql/flexible-server

resource firewall_all 'Microsoft.DBforPostgreSQL/flexibleServers/firewallRules@2022-12-01' = if (allowAllIPsFirewall) {
name: 'allow-all-IPs'
parent: server
properties: {
startIpAddress: '0.0.0.0'
endIpAddress: '255.255.255.255'
}
}

resource firewall_azure 'Microsoft.DBforPostgreSQL/flexibleServers/firewallRules@2022-12-01' = if (allowAzureIPsFirewall) {
name: 'allow-all-azure-internal-IPs'
parent: server
properties: {
startIpAddress: '0.0.0.0'
endIpAddress: '0.0.0.0'
}
}


var serverHostname = server.properties.fullyQualifiedDomainName

var databaseName = 'postgres' // we could probably create our own but that's for next time

output connectionString string = 'host=${serverHostname} port=5432 database=${databaseName} user=${administratorLogin} password=${administratorLoginPassword} sslmode=require'

0 comments on commit 693401a

Please sign in to comment.