Provision Ansible Postgres on Mac

Share this post on:

I added a new database to my demo platform: Postgres. This code helps me provision Ansible Postgres on Mac for demo purposes or simple functional testing, and it is an extension of previous work I showed in String Search.

The script does a postgres install via Homebrew for Mac M1 and starts it up, then creates the database, user, etc. needed for the demo. Finally, it populates using my “million table” sql.

Most of this uses the Community.Postgres Ansible module found here: https://docs.ansible.com/ansible/latest/collections/community/postgresql/index.html

For the full code, including inventory and group_vars files, see https://github.com/dataindataout/xtest_ansible.

Install Postgres

Assumes you are on Mac. This was the cleanest way I found to install on Mac M1.

- name: Ensure Postgres 14 and dependencies are installed
  hosts: pg1
    - name: Install postgres via homebrew
        name: postgresql@14
        path: /opt/homebrew/bin
        state: present
    - name: Install psycopg2
        name: psycopg2-binary
        state: present

Start Postgres

I would like to refactor this to parameterize some of the directories.

- name: Start Postgres
  hosts: pg1
    - name: Find out if pg has been initialized
        path: "/opt/homebrew/var/postgresql@14/pg_hba.conf"
      register: postgres_data
    - name: Initialize PostgreSQL if needed
      shell: "{{ pg_executable_dir }}/pg_ctl initdb --pgdata=/opt/homebrew/var/postgresql@14"
      when: not postgres_data.stat.exists
    - name: Restart postgres
      shell: "{{ pg_executable_dir }}/pg_ctl restart --pgdata=/opt/homebrew/var/postgresql@14 --log=/opt/homebrew/var/postgresql@14/server.log"

Create Ansible Postgres database, user, etc.

Because this is a local demo installation, and not a production installation, I am using my local user instead of the ‘postgres’ user. The ansible_user_id variable is your local user found when gathering facts.

- name: Create postgres assets
  hosts: pg1
    - name: "Create app database"
        state: present
        login_user: "{{ ansible_user_id }}"
        db: postgres
        name: "{{ db_name }}"

    - name: "Create db user"
        state: present
        login_user: "{{ ansible_user_id }}"
        db: postgres
        name: "{{ db_user }}"
        password: "{{ db_password }}"

    - name: "Grant db user access to app db"
        login_user: "{{ ansible_user_id }}"
        db: postgres
        type: database
        database: "{{ db_name }}"
        roles: "{{ db_user }}"
        grant_option: no
        privs: all

    - name: "Allow md5 connection for the db user"
        dest: "/opt/homebrew/var/postgresql@14/pg_hba.conf"
        contype: host
        databases: all
        method: md5
        users: "{{ db_user }}"
        create: true

    - name: Restart postgres
      shell: "{{ pg_executable_dir }}/pg_ctl restart --pgdata=/opt/homebrew/var/postgresql@14 --log=/opt/homebrew/var/postgresql@14/server.log"

Populate data using Ansible Postgres

If this was a larger population script, or if I was loading from a database dump, I’d do something else, but this was a simple way to run the handful of queries to populate the generated million table.

- name: Populate data on postgres instance
  hosts: pg1
    - name: Load sql script
        login_user: "{{ ansible_user_id }}"
        db: "{{ db_name }}"
          - create table if not exists milliontable(name varchar(10), age integer)
          - truncate table milliontable
          - insert into milliontable (name, age) select substr(md5(random()::text), 1, 10), (random() * 70 + 10)::integer from generate_series(1, 1000000)
How to Provision Postgres on Mac using Ansible, on a background of a card catalog as a metaphor for databases
Databases all in a row

Author: Valerie Parham-Thompson

View all posts by Valerie Parham-Thompson >