From 015c708644221562e67dbc6c4c10cbe1f9554a89 Mon Sep 17 00:00:00 2001 From: directlx Date: Sat, 14 Feb 2026 07:44:35 -0500 Subject: [PATCH] Add PostgreSQL user management playbook and documentation Created reusable Ansible playbook for creating PostgreSQL users with flexible privilege options (superuser, createdb, createrole). Features include auto-generated secure passwords, credential file export, and comprehensive documentation with examples. Files added: - playbooks/create-postgres-user.yml - Automated user creation - docs/POSTGRES-USER-MANAGEMENT.md - Usage guide and examples Initial use case: Created hiveops superuser for HiveOps application. Co-Authored-By: Claude Sonnet 4.5 --- docs/POSTGRES-USER-MANAGEMENT.md | 244 +++++++++++++++++++++++++++++ playbooks/create-postgres-user.yml | 149 ++++++++++++++++++ 2 files changed, 393 insertions(+) create mode 100644 docs/POSTGRES-USER-MANAGEMENT.md create mode 100644 playbooks/create-postgres-user.yml diff --git a/docs/POSTGRES-USER-MANAGEMENT.md b/docs/POSTGRES-USER-MANAGEMENT.md new file mode 100644 index 0000000..5822b2b --- /dev/null +++ b/docs/POSTGRES-USER-MANAGEMENT.md @@ -0,0 +1,244 @@ +# PostgreSQL User Management + +This guide covers creating and managing PostgreSQL users on the postgres server (192.168.200.103). + +## Quick Reference + +### Create Superuser with Random Password +```bash +ansible-playbook playbooks/create-postgres-user.yml -e "pg_username=hiveops pg_superuser=true" +``` + +### Create User with Specific Password +```bash +ansible-playbook playbooks/create-postgres-user.yml -e "pg_username=myapp pg_password=SecurePass123" +``` + +### Create Database Creator User +```bash +ansible-playbook playbooks/create-postgres-user.yml -e "pg_username=dbadmin pg_createdb=true" +``` + +### Create Basic User (No Special Privileges) +```bash +ansible-playbook playbooks/create-postgres-user.yml -e "pg_username=readonly" +``` + +## Playbook Variables + +| Variable | Required | Default | Description | +|----------|----------|---------|-------------| +| `pg_username` | Yes | - | PostgreSQL username to create | +| `pg_password` | No | Auto-generated | Password (random 32-char base64 if not provided) | +| `pg_superuser` | No | `false` | Grant SUPERUSER privilege | +| `pg_createdb` | No | `false` | Grant CREATEDB privilege | +| `pg_createrole` | No | `false` | Grant CREATEROLE privilege | +| `pg_login` | No | `true` | Allow user to login | +| `pg_save_credentials` | No | `false` | Save credentials to `/tmp/postgres-user-*.txt` | + +## Examples + +### Example 1: HiveOps Application User (Superuser) +```bash +ansible-playbook playbooks/create-postgres-user.yml \ + -e "pg_username=hiveops" \ + -e "pg_superuser=true" \ + -e "pg_save_credentials=true" +``` + +**Output:** +- Random password generated +- Superuser privileges +- Credentials saved to `/tmp/postgres-user-hiveops-*.txt` + +### Example 2: Application User with Database Creation +```bash +ansible-playbook playbooks/create-postgres-user.yml \ + -e "pg_username=smartjournal" \ + -e "pg_createdb=true" \ + -e "pg_password=MySecurePassword123" +``` + +**Output:** +- Specific password used +- Can create databases +- Cannot create other users + +### Example 3: Read-Only Application User +```bash +# First create the user +ansible-playbook playbooks/create-postgres-user.yml \ + -e "pg_username=reporting" + +# Then grant SELECT permissions manually +ansible postgres -m shell \ + -a "psql -d mydb -c 'GRANT SELECT ON ALL TABLES IN SCHEMA public TO reporting;'" \ + --become-user=postgres -b +``` + +### Example 4: Multiple Users at Once +```bash +# Create a variables file +cat > /tmp/users.yml < 0 + fail_msg: "pg_username is required. Usage: ansible-playbook playbooks/create-postgres-user.yml -e 'pg_username=myuser'" + + - name: Generate random password if not provided + ansible.builtin.shell: openssl rand -base64 32 + register: generated_password + delegate_to: localhost + become: false + when: pg_generate_password | bool + changed_when: false + + - name: Set password variable + ansible.builtin.set_fact: + pg_password: "{{ generated_password.stdout if pg_generate_password | bool else pg_password }}" + + - name: Build role attributes + ansible.builtin.set_fact: + role_attrs: >- + {{ + (pg_superuser | bool) | ternary('SUPERUSER', 'NOSUPERUSER') + }} + {{ + (pg_createdb | bool) | ternary('CREATEDB', 'NOCREATEDB') + }} + {{ + (pg_createrole | bool) | ternary('CREATEROLE', 'NOCREATEROLE') + }} + {{ + (pg_login | bool) | ternary('LOGIN', 'NOLOGIN') + }} + + - name: Check if user already exists + ansible.builtin.shell: | + psql -tAc "SELECT 1 FROM pg_roles WHERE rolname='{{ pg_username }}'" + become_user: postgres + register: user_exists + changed_when: false + failed_when: false + + - name: Create PostgreSQL user + ansible.builtin.shell: | + psql -c "CREATE USER {{ pg_username }} WITH {{ role_attrs }} PASSWORD '{{ pg_password }}';" + become_user: postgres + when: user_exists.stdout != "1" + register: user_created + + - name: Update existing user + ansible.builtin.shell: | + psql -c "ALTER USER {{ pg_username }} WITH {{ role_attrs }} PASSWORD '{{ pg_password }}';" + become_user: postgres + when: user_exists.stdout == "1" + register: user_updated + + - name: Verify user creation + ansible.builtin.shell: | + psql -c '\du {{ pg_username }}' + become_user: postgres + register: user_details + changed_when: false + + - name: Display user information + ansible.builtin.debug: + msg: + - "==========================================" + - "PostgreSQL User Created Successfully" + - "==========================================" + - "Username: {{ pg_username }}" + - "Password: {{ pg_password }}" + - "Server: {{ ansible_host }}" + - "Port: 5432" + - "" + - "Connection String:" + - "postgresql://{{ pg_username }}:{{ pg_password }}@{{ ansible_host }}:5432/database_name" + - "" + - "Privileges:" + - " Superuser: {{ pg_superuser }}" + - " Create DB: {{ pg_createdb }}" + - " Create Role: {{ pg_createrole }}" + - " Login: {{ pg_login }}" + - "" + - "User Details:" + - "{{ user_details.stdout_lines }}" + - "" + - "⚠️ IMPORTANT: Save this password securely!" + - "==========================================" + + - name: Save credentials to file (optional) + ansible.builtin.copy: + content: | + # PostgreSQL User Credentials + # Created: {{ ansible_date_time.iso8601 }} + + Username: {{ pg_username }} + Password: {{ pg_password }} + Server: {{ ansible_host }} + Port: 5432 + + Connection String: + postgresql://{{ pg_username }}:{{ pg_password }}@{{ ansible_host }}:5432/database_name + + Privileges: + - Superuser: {{ pg_superuser }} + - Create DB: {{ pg_createdb }} + - Create Role: {{ pg_createrole }} + - Login: {{ pg_login }} + dest: "/tmp/postgres-user-{{ pg_username }}-{{ ansible_date_time.epoch }}.txt" + mode: '0600' + delegate_to: localhost + become: false + when: pg_save_credentials | default(false) | bool