Automating PostgreSQL User Password Configuration in Bash Scripts


2 views

When managing multiple PostgreSQL servers, setting up user passwords manually becomes inefficient. Here's how to automate password configuration for the postgres user using bash scripting.

The traditional method requires interactive sessions:

sudo -u postgres psql
\password postgres

This approach doesn't scale well for multiple servers or automated deployments.

PostgreSQL provides several methods for non-interactive password setting:

Method 1: Using psql with -c flag

sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD 'your_secure_password';"

Method 2: Environment Variable Approach

export PGPASSWORD='temporary_password'
psql -U postgres -h localhost -c "ALTER USER postgres WITH PASSWORD 'new_secure_password';"
unset PGPASSWORD

For production use, consider this complete script example:

#!/bin/bash

POSTGRES_PASSWORD="ComplexP@ssw0rd123!"

# Validate input
if [ -z "$POSTGRES_PASSWORD" ]; then
    echo "Error: Password not set" >&2
    exit 1
fi

# Set PostgreSQL user password
sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD '$POSTGRES_PASSWORD';" &> /dev/null

# Verify password change
if [ $? -eq 0 ]; then
    echo "PostgreSQL password updated successfully"
else
    echo "Failed to update PostgreSQL password" >&2
    exit 1
fi

When implementing this in scripts:

  • Never hardcode passwords in scripts
  • Use environment variables or secret management tools
  • Ensure script files have restricted permissions
  • Consider using password hashes instead of plain text

For automated deployments, you might use:

#!/bin/bash

read -s -p "Enter PostgreSQL password: " pg_password
echo

ansible all -i inventory.ini -m postgresql_user \
  -a "name=postgres password=$pg_password role_attr_flags=SUPERUSER" \
  --become --become-user=postgres

Common issues and solutions:

  • Permission denied: Ensure script runs with sudo
  • Connection refused: Verify PostgreSQL is running
  • Authentication failures: Check pg_hba.conf settings

When working with PostgreSQL in production environments, securely setting the postgres user password across multiple servers becomes crucial. The manual approach using sudo -u postgres psql followed by \password command works fine for single instances but doesn't scale well.

Here's a robust bash script solution that automates this process securely:

#!/bin/bash

NEW_PASSWORD="your_secure_password_here"

# Set PostgreSQL user password non-interactively
sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD '${NEW_PASSWORD}';"

# Verify password change
sudo -u postgres psql -c "\conninfo"

For better security practices, consider these enhancements:

#!/bin/bash

# Generate random password if not provided
if [ -z "$1" ]; then
  NEW_PASSWORD=$(openssl rand -base64 32)
  echo "Generated password: ${NEW_PASSWORD}"
else
  NEW_PASSWORD="$1"
fi

# Export password to avoid shell history exposure
export PGPASSWORD="${NEW_PASSWORD}"

# Execute password change
sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD '${NEW_PASSWORD}';"

# Clean up environment variable
unset PGPASSWORD

For multi-server deployment using SSH:

#!/bin/bash

read -s -p "Enter new PostgreSQL password: " NEW_PASSWORD
echo

SERVERS=("server1.example.com" "server2.example.com" "server3.example.com")

for server in "${SERVERS[@]}"; do
  echo "Updating ${server}..."
  ssh admin@${server} "sudo -u postgres psql -c \"ALTER USER postgres WITH PASSWORD '${NEW_PASSWORD}';\""
done

Add proper error handling for production scripts:

#!/bin/bash

set -euo pipefail

LOG_FILE="postgres_password_update.log"
NEW_PASSWORD=${1:-}

if [ -z "${NEW_PASSWORD}" ]; then
  echo "Usage: $0 [password]"
  exit 1
fi

{
  echo "$(date) - Starting password update"
  if ! sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD '${NEW_PASSWORD}';"; then
    echo "Failed to update password" >&2
    exit 1
  fi
  echo "$(date) - Password updated successfully"
} >> "${LOG_FILE}" 2>&1