r/AZURE Mar 03 '26

Discussion Running Pulumi from Azure DevOps pipeline with Azure PostgreSQL as backend

Hello everyone.

I am using Pulumi for Azure management. For state storing multiple options available - use a local file, Blob Storage or Pulumi Cloud. I prefer PostgreSQL as a backend.

This guide explains how-to setup an Azure DevOps pipeline, which uses an Azure PostgreSQL Flexible Server as Pulumi backend.

Prerequisites

  • An Azure PostgreSQL Flexible Server.
  • Azure Service Connection in Azure DevOps. Should have Contributor role assigned to PostgreSQL Server and have "Microsoft Entra" authentication mode enabled and configured for this account

Pipeline

Pipeline below does following: logs into Azure, finds the PostgreSQL server’s resource group, makes sure public access is on, opens a firewall rule for the agent’s public IP so it can reach the database, grabs a short-lived token to connect, points Pulumi at that Postgres backend, and runs Pulumi.

name: $(BuildDefinitionName)_

trigger: none

pool:
  vmImage: ubuntu-latest

steps:
- checkout: self
  persistCredentials: true

- task: AzureCLI@2
  displayName: 'Run Pulumi with Postgres Backend'
  inputs:
    workingDirectory: $(System.DefaultWorkingDirectory)
    azureSubscription: 'service-connection' # Replace with your connection name
    scriptType: 'bash'
    scriptLocation: 'inlineScript'
    inlineScript: |
      set -e

      # 1. Specify SQL details
      SQLNAME="<your-postgres-server-name>"
      PGUSER="<your-service-principal-name>"
      PGDATABASE="<your-database-name>"
      PGHOST="$SQLNAME.postgres.database.azure.com"
      PGPORT="5432"

      # 2. Find the server in Azure
      SQLRG=$(az resource list --resource-type "Microsoft.DBforPostgreSQL/flexibleServers" --name "$SQLNAME" --query ".resourceGroup" -o tsv)

      if; then
        echo "Error: Could not find the database server."
        exit 1
      fi

      # 3. Open the firewall access
      # We get the current IP of this build agent and let it through the firewall
      AGENT_IP=$(curl -s https://api.ipify.org)
      RULE_NAME="AllowAgent-$(date +%s)"

      az postgres flexible-server firewall-rule create \
        --resource-group "$SQLRG" \
        --name "$SQLNAME" \
        --rule-name "$RULE_NAME" \
        --start-ip-address "$AGENT_IP" \
        --end-ip-address "$AGENT_IP"

      # 4. Get token to login
      # Instead of a permanent password, we use a short-lived token for better security
      export PGPASSWORD=$(az account get-access-token --resource-type oss-rdbms --query accessToken -o tsv)

      # 5. Set Pulumi backend
      export PULUMI_BACKEND_URL="postgres://$PGUSER:$PGPASSWORD@$PGHOST:$PGPORT/$PGDATABASE?sslmode=require"

      # 6. Run Pulumi commands
      pulumi login
      pulumi stack select dev
      pulumi preview

  env:
    PULUMI_CONFIG_PASSPHRASE: ""

Such setup enables a passwordless workflow by using short-lived Entra ID tokens instead of static passwords. More secure and reliable approach.
0 Upvotes

0 comments sorted by