From 8f79ed5f98b04ccf7a4951046b8b89061f933cb0 Mon Sep 17 00:00:00 2001 From: Manuel Carrer Date: Wed, 2 Oct 2024 16:49:30 +0200 Subject: [PATCH] Refactor and fix ansible-lint issues (Part 1) --- .gitignore | 2 - ansible/.gitignore | 6 + ansible/bigip.yml | 40 +- ansible/configure.yml | 14 +- ansible/deploy.yml | 7 +- ansible/group_vars/servers.yaml | 0 ansible/host_vars/lard-a.yml | 2 + ansible/host_vars/lard-b.yaml | 2 + ansible/inventory.yml | 4 +- ansible/provision.yml | 11 +- ansible/readme.md | 101 ++-- ansible/rejoin.yml | 6 +- ansible/requirements.txt | 5 +- ansible/requirements.yml | 7 + ansible/roles/addsshkeys/defaults/main.yml | 2 + ansible/roles/addsshkeys/tasks/main.yml | 8 +- ansible/roles/bigip/defaults/main.yml | 3 + ansible/roles/bigip/tasks/main.yml | 72 +-- ansible/roles/deploy/defaults/main.yml | 4 + ansible/roles/deploy/tasks/main.yml | 16 +- ansible/roles/movefloatingip/tasks/main.yml | 4 +- .../movefloatingip/tasks/movefloatingip.yml | 80 +-- .../networks/tasks/create-ipalias-network.yml | 76 +-- .../networks/tasks/create-project-network.yml | 50 +- .../tasks/create-project-security-group.yml | 38 +- ansible/roles/networks/tasks/main.yml | 18 +- .../roles/networks/tasks/open-for-ping.yml | 11 +- ansible/roles/networks/vars/main.yml | 205 +++---- .../tasks/create-primary.yml | 515 +++++++++--------- .../tasks/create-standby.yml | 259 ++++----- .../roles/primarystandbysetup/tasks/main.yml | 5 +- ansible/roles/rejoin/tasks/main.yml | 3 +- .../roles/rejoin/tasks/rejoin_old_primary.yml | 82 +-- ansible/roles/ssh/tasks/main.yml | 3 +- ansible/roles/ssh/tasks/share-ssh-keys.yml | 118 ++-- ansible/roles/switchover/tasks/main.yml | 4 +- ansible/roles/switchover/tasks/switchover.yml | 110 ++-- ansible/roles/vm/tasks/create-project-vm.yml | 160 +++--- ansible/roles/vm/tasks/main.yml | 4 +- ansible/roles/vm/vars/main.yml | 25 +- .../vm_format/tasks/format-mount-disk.yml | 76 +-- .../vm_format/tasks/install-postgres.yml | 270 ++++----- ansible/roles/vm_format/tasks/main.yml | 11 +- ansible/roles/vm_format/tasks/netplan.yml | 108 ++-- ansible/switchover.yml | 19 +- ingestion/src/main.rs | 4 +- ingestion/src/permissions.rs | 3 +- 47 files changed, 1324 insertions(+), 1249 deletions(-) create mode 100644 ansible/group_vars/servers.yaml create mode 100644 ansible/host_vars/lard-a.yml create mode 100644 ansible/host_vars/lard-b.yaml create mode 100644 ansible/requirements.yml create mode 100644 ansible/roles/addsshkeys/defaults/main.yml create mode 100644 ansible/roles/bigip/defaults/main.yml create mode 100644 ansible/roles/deploy/defaults/main.yml diff --git a/.gitignore b/.gitignore index f4fe9061..e420ee4b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1 @@ target/* -ansible/roles/deploy/files/resources -ansible/roles/deploy/files/lard_ingestion diff --git a/ansible/.gitignore b/ansible/.gitignore index 99ed0d43..89364e80 100644 --- a/ansible/.gitignore +++ b/ansible/.gitignore @@ -1 +1,7 @@ notes.txt +ansible.cfg +.yamlfmt +.run.sh + +roles/deploy/files/resources +roles/deploy/files/lard_ingestion diff --git a/ansible/bigip.yml b/ansible/bigip.yml index 5fc6dcf8..a92217d8 100644 --- a/ansible/bigip.yml +++ b/ansible/bigip.yml @@ -1,52 +1,28 @@ -- name: Copy schema for bigip +--- +- name: Create what is needed for the bigip load balancers + hosts: servers + remote_user: ubuntu vars: ostack_cloud: lard ostack_region: Ostack2-EXT - hosts: localhost # need to seperate this since done from localhost gather_facts: false pre_tasks: # copy file, so we have an .sql file to apply locally - - name: Create a directory if it does not exist + - name: Create a directory if it does not exist ansible.builtin.file: path: /etc/postgresql/16/db/bigip state: directory mode: '0755' become: true - delegate_to: '{{ hostvars[groups["servers"][0]].ansible_host }}' - remote_user: ubuntu + - name: Copy the schema to the remote 1 ansible.builtin.copy: src: ./roles/bigip/vars/bigip.sql dest: /etc/postgresql/16/db/bigip/bigip.sql mode: '0755' become: true - delegate_to: '{{ hostvars[groups["servers"][0]].ansible_host }}' - remote_user: ubuntu - - name: Create a directory if it does not exist - ansible.builtin.file: - path: /etc/postgresql/16/db/bigip - state: directory - mode: '0755' - become: true - delegate_to: '{{ hostvars[groups["servers"][1]].ansible_host }}' - remote_user: ubuntu - - name: Copy the schema to the remote 2 - ansible.builtin.copy: - src: ./roles/bigip/vars/bigip.sql - dest: /etc/postgresql/16/db/bigip/bigip.sql - mode: '0755' - become: true - delegate_to: '{{ hostvars[groups["servers"][1]].ansible_host }}' - remote_user: ubuntu -- name: Create what is needed for the bigip load balancers - hosts: servers - remote_user: ubuntu - vars: - ostack_cloud: lard - ostack_region: Ostack2-EXT - gather_facts: false # loops over both servers roles: - - role: bigip - # will fail to create table in the standby (since read only) \ No newline at end of file + - role: bigip + # will fail to create table in the standby (since read only) diff --git a/ansible/configure.yml b/ansible/configure.yml index ff586fd0..7469733f 100644 --- a/ansible/configure.yml +++ b/ansible/configure.yml @@ -1,3 +1,4 @@ +--- - name: Mount disks and install stuff on the VMs hosts: servers remote_user: ubuntu @@ -5,19 +6,18 @@ ostack_cloud: lard ipalias_network_name: ipalias ostack_region: Ostack2-EXT - # loops over both servers pre_tasks: - name: List ansible_hosts_all difference from ansible_host (aka the vm not currently being iterated on) ansible.builtin.debug: - msg: "{{ (ansible_play_hosts_all | difference([inventory_hostname])) | first }}" + msg: "{{ (ansible_play_hosts_all | difference([inventory_hostname])) | first }}" roles: - - role: addsshkeys + - role: addsshkeys - role: vm_format vars: - name_stuff: '{{ inventory_hostname }}' # name of current vm for finding ipalias port + name_stuff: "{{ inventory_hostname }}" # name of current vm for finding ipalias port - role: ssh vars: - vm_ip: '{{ ansible_host }}' # the current vm's ip + vm_ip: "{{ ansible_host }}" # the current vm's ip - name: Setup primary and standby vars: @@ -26,10 +26,10 @@ hosts: localhost gather_facts: false - roles: + roles: - role: primarystandbysetup vars: primary_name: lard-a primary_ip: '{{ hostvars[groups["servers"][0]].ansible_host }}' # the first one is a standby_name: lard-b - standby_ip: '{{ hostvars[groups["servers"][1]].ansible_host }}' # the second one is b \ No newline at end of file + standby_ip: '{{ hostvars[groups["servers"][1]].ansible_host }}' # the second one is b diff --git a/ansible/deploy.yml b/ansible/deploy.yml index 97afdb85..de117433 100644 --- a/ansible/deploy.yml +++ b/ansible/deploy.yml @@ -1,12 +1,11 @@ +--- - name: Deploy binaries hosts: lard-a # deploy to lard-a for now, might need to define a separate VM later? remote_user: ubuntu vars: ostack_cloud: lard ostack_region: Ostack2-EXT - become: true - become_user: root + # become: true + # become_user: root roles: - role: deploy - # vars: - # deploy_ip: '{{ hostvars[...].ansible_host }}' diff --git a/ansible/group_vars/servers.yaml b/ansible/group_vars/servers.yaml new file mode 100644 index 00000000..e69de29b diff --git a/ansible/host_vars/lard-a.yml b/ansible/host_vars/lard-a.yml new file mode 100644 index 00000000..508207ec --- /dev/null +++ b/ansible/host_vars/lard-a.yml @@ -0,0 +1,2 @@ +--- +ansible_host: 123.123.123.123 diff --git a/ansible/host_vars/lard-b.yaml b/ansible/host_vars/lard-b.yaml new file mode 100644 index 00000000..508207ec --- /dev/null +++ b/ansible/host_vars/lard-b.yaml @@ -0,0 +1,2 @@ +--- +ansible_host: 123.123.123.123 diff --git a/ansible/inventory.yml b/ansible/inventory.yml index a0a62a07..4dbbf192 100644 --- a/ansible/inventory.yml +++ b/ansible/inventory.yml @@ -1,6 +1,8 @@ +--- servers: hosts: + # TODO: add flag to filter when server is primary/secondary? lard-a: ansible_host: 157.249.*.* lard-b: - ansible_host: 157.249.*.* \ No newline at end of file + ansible_host: 157.249.*.* diff --git a/ansible/provision.yml b/ansible/provision.yml index 11bd242b..0ba19a5e 100644 --- a/ansible/provision.yml +++ b/ansible/provision.yml @@ -1,4 +1,5 @@ -- name: setup networks and 2 vms +--- +- name: Setup networks and 2 vms vars: ostack_cloud: lard ipalias_network_name: ipalias @@ -10,11 +11,11 @@ - role: networks - role: vm # in A vars: - name_stuff: lard-a - availability_zone: ext-a + vm_name: lard-a + vm_availability_zone: ext-a vm_ip: '{{ hostvars[groups["servers"][0]].ansible_host }}' - role: vm # in B vars: - name_stuff: lard-b - availability_zone: ext-b + vm_name_stuff: lard-b + vm_availability_zone: ext-b vm_ip: '{{ hostvars[groups["servers"][1]].ansible_host }}' diff --git a/ansible/readme.md b/ansible/readme.md index f2f0a5f1..a7aea7a1 100644 --- a/ansible/readme.md +++ b/ansible/readme.md @@ -1,6 +1,7 @@ ## README for LARD setup on openstack(2) #### Useful ansible commands: + ``` ansible-inventory -i inventory.yml --graph @@ -8,67 +9,68 @@ ansible servers -m ping -u ubuntu -i inventory.yml ``` #### Dependencies to install -``` -pip3 install wheel # so you can allow downloading of binary python packages - -pip install -r requirements.txt - -ansible-galaxy collection install openstack.cloud - -ansible-galaxy collection install community.postgresql - -ansible-galaxy collection install community.general -ansible-galaxy collection install ansible.posix +```terminal +python3 -m venv {your_dir} +source {your_dir}/bin/activate -ansible-galaxy collection install ansible.utils - -``` +pip install -r requirements.txt +ansible-galaxy collection install -fr requirements.yml +``` ### Get access to OpenStack -You need to create application credentials in the project you are going to create the instances in, so that the ansible scripts can connect to the right ostack_cloud which in our case needs to be called lard. -The file should exist here: -~/.config/openstack/clouds.yml +You need to create application credentials in the project you are going to +create the instances in, so that the ansible scripts can connect to the right +ostack_cloud which in our case needs to be called lard. + +The file should exist in `~/.config/openstack/clouds.yml`. -If have MET access see what is written at the start of the readme here: -https://gitlab.met.no/it/infra/ostack-ansible21x-examples +If have MET access see what is written at the start of the readme [here](https://gitlab.met.no/it/infra/ostack-ansible21x-examples). -Or in the authentication section here: -https://gitlab.met.no/it/infra/ostack-doc/-/blob/master/ansible-os.md?ref_type=heads +Or in the authentication section [here](https://gitlab.met.no/it/infra/ostack-doc/-/blob/master/ansible-os.md?ref_type=heads). ### Add your public key to the Ostack GUI -Go to "Compute" then "Key Pairs" and import your public key for use in the provisioning step. + +Go to "Compute" then "Key Pairs" and import your public key for use in the provisioning step. ### Provision! -The IPs in inventory.yml should correspond to floating ips you have requested in the network section of the open stack GUI. If you need to delete the old VMs (compute -> instances) and Volumes (volumes -> volumes) you can do so in the ostack GUI. *For some reason when deleting things to build up again one of the IPs did not get disassociated properly, and I had to do this manually (network -> floating IPs).* -The vars for the network and addssh tasks are encrypted with ansible-vault (ansible-vault decrypt roles/networks/vars/main.yml, ansible-vault decrypt roles/addshhkeys/vars/main.yml, ansible-vault decrypt roles/vm_format/vars/main.yml). -But if this has been setup before in the ostack project, these have likely already been run and therefore already exits so you could comment out this role from provision.yml. -Passwords are in ci_cd variables https://gitlab.met.no/met/obsklim/bakkeobservasjoner/lagring-og-distribusjon/db-products/poda/-/settings/ci_cd +The IPs in inventory.yml should correspond to floating ips you have requested in the network section of the open stack GUI. If you need to delete the old VMs (compute -> instances) and Volumes (volumes -> volumes) you can do so in the ostack GUI. *For some reason when deleting things to build up again one of the IPs did not get disassociated properly, and I had to do this manually (network -> floating IPs).* -``` +The vars for the network and addssh tasks are encrypted with ansible-vault +(ansible-vault decrypt roles/networks/vars/main.yml, ansible-vault decrypt +roles/addshhkeys/vars/main.yml, ansible-vault decrypt +roles/vm_format/vars/main.yml). But if this has been setup before in the ostack +project, these have likely already been run and therefore already exits so you +could comment out this role from provision.yml. Passwords are in ci_cd +variables +https://gitlab.met.no/met/obsklim/bakkeobservasjoner/lagring-og-distribusjon/db-products/poda/-/settings/ci_cd + +```terminal ansible-playbook -i inventory.yml -e ostack_key_name=xxx provision.yml ``` After provisioning the next steps may need to ssh into the hosts, and thus you need to add them to your known hosts. Ansible appears to be crap at this, so its best to do it before running the next step by going: -`ssh ubuntu@157.249.*.*` +`ssh ubuntu@157.249.*.*` For all the VMs. If cleaning up from tearing down a previous set of VMs you may also need to remove them first: `ssh-keygen -f "/home/louiseo/.ssh/known_hosts" -R "157.249.*.*"` ### Configure! -The third IP being passed in here is the one that gets associated with the primary, and moved when doing a switchover. -*NOTE:* The floating IP association times out, but this is ignored as it is a known bug. -``` +The third IP being passed in here is the one that gets associated with the primary, and moved when doing a switchover. +*NOTE:* The floating IP association times out, but this is ignored as it is a known bug. + +```term ansible-playbook -i inventory.yml -e primary_floating_ip='157.249.*.*' -e db_password=xxx -e repmgr_password=xxx configure.yml ``` -The parts to do with the floating ip that belongs to the primary (ipalias) are based on: +The parts to do with the floating ip that belongs to the primary (ipalias) are based on: https://gitlab.met.no/ansible-roles/ipalias/-/tree/master?ref_type=heads ### Connect to database + ``` PGPASSWORD=xxx psql -h 157.249.*.* -p 5432 -U lard_user -d lard ``` @@ -76,6 +78,7 @@ PGPASSWORD=xxx psql -h 157.249.*.* -p 5432 -U lard_user -d lard ### Checking the cluster Become postgres user: sudo su postgres + ``` postgres@lard-b:/home/ubuntu$ repmgr -f /etc/repmgr.conf node check Node "lard-b": @@ -88,6 +91,7 @@ Node "lard-b": Missing physical replication slots: OK (node has no missing physical replication slots) Configured data directory: OK (configured "data_directory" is "/mnt/ssd-b/16/main") ``` + ``` postgres@lard-a:/home/ubuntu$ repmgr -f /etc/repmgr.conf node check Node "lard-a": @@ -101,12 +105,13 @@ Node "lard-a": Configured data directory: OK (configured "data_directory" is "/mnt/ssd-b/16/main") ``` -While a few of the configurations are found in /etc/postgresql/16/main/postgresql.conf (particularly in the ansible block at the end), many of them +While a few of the configurations are found in /etc/postgresql/16/main/postgresql.conf (particularly in the ansible block at the end), many of them can only be seen in /mnt/ssd-b/16/main/postgresql.auto.conf (need sudo to see contents). ### Perform switchover -This should only be used when both VMs are up and running, like in the case of planned maintenance on one datarom. -Then we would use this script to switch the primary to the datarom that will stay available ahead of time. + +This should only be used when both VMs are up and running, like in the case of planned maintenance on one datarom. +Then we would use this script to switch the primary to the datarom that will stay available ahead of time. *Make sure you are aware which one is the master, and put the names the right way around in this call.* @@ -118,8 +123,9 @@ This should also be possible to do manually, but might need to follow what is do `repmgr standby switchover -f /etc/repmgr.conf --siblings-follow` (need to be postgres user) ### Promote standby (assuming the primary is down) -Make sure you are know which one you want to promote! -This is used in the case where the primary has gone down (e.g. unplanned downtime of a datarom). + +Make sure you are know which one you want to promote!\ +This is used in the case where the primary has gone down (e.g. unplanned downtime of a datarom). **Manually:** SSH into the standby @@ -132,25 +138,28 @@ You can the check the status again (and now the old primary will say failed) Then move the ip in the ostack gui (see in network -> floating ips, dissasociate it then associated it with the ipalias port on the other VM) #### Later, when the old primary comes back up -The cluster will be in a slightly confused state, because this VM still thinks its a primary (although repmgr tells it the other one is running as a primary as well). If the setup is running as asynchronous we could lose data that wasn't copied over before the crash, if running synchronously then there should be no data loss. + +The cluster will be in a slightly confused state, because this VM still thinks its a primary (although repmgr tells it the other one is running as a primary as well). If the setup is running as asynchronous we could lose data that wasn't copied over before the crash, if running synchronously then there should be no data loss. SSH into the new primary `repmgr -f /etc/repmgr.conf cluster show` says: + - node "lard-a" (ID: 1) is running but the repmgr node record is inactive SSH into the old primary `repmgr -f /etc/repmgr.conf cluster show` says: -- node "lard-b" (ID: 2) is registered as standby but running as primary +- node "lard-b" (ID: 2) is registered as standby but running as primary With a **playbook** (rejoin_ip is the ip of the node that has been down and should now be a standby not a primary): + ``` ansible-playbook -i inventory.yml -e rejoin_ip=157.249.*.* -e primary_ip=157.249.*.* rejoin.yml ``` -Or **manually**: +Or **manually**: Make sure the pg process is stopped (see fast stop command) if it isn't already Become postgres user: @@ -161,15 +170,17 @@ Perform a rejoin `repmgr node rejoin -f /etc/repmgr.conf -d 'host=157.249.*.* user=repmgr dbname=repmgr connect_timeout=2' --force-rewind=/usr/lib/postgresql/16/bin/pg_rewind --verbose` ### for testing: -Take out one of the replicas (or can shut off instance in the openstack GUI): + +Take out one of the replicas (or can shut off instance in the openstack GUI): `sudo pg_ctlcluster 16 main -m fast stop` For bringing it back up (or turn it back on): `sudo pg_ctlcluster 16 main start` ### for load balancing at MET -This role creates a user and basic db for the loadbalancer to test the health of the db. Part of the role is allowed to fail on the secondary ("cannot execute ___ in a read-only transaction"), as it should pass on the primary and be replicated over. The hba conf change needs to be run on both. -The vars are encrypted, so run: ansible-vault decrypt roles/bigip/vars/main.yml +This role creates a user and basic db for the loadbalancer to test the health of the db. Part of the role is allowed to fail on the secondary ("cannot execute \_\_\_ in a read-only transaction"), as it should pass on the primary and be replicated over. The hba conf change needs to be run on both. + +The vars are encrypted, so run: ansible-vault decrypt roles/bigip/vars/main.yml Then run the bigip role on the VMs: @@ -177,6 +188,6 @@ Then run the bigip role on the VMs: ansible-playbook -i inventory.yml -e bigip_password=xxx bigip.yml ``` -### Links: +### Links: -https://www.enterprisedb.com/postgres-tutorials/postgresql-replication-and-automatic-failover-tutorial#replication \ No newline at end of file +https://www.enterprisedb.com/postgres-tutorials/postgresql-replication-and-automatic-failover-tutorial#replication diff --git a/ansible/rejoin.yml b/ansible/rejoin.yml index 701d1cb9..d8964f72 100644 --- a/ansible/rejoin.yml +++ b/ansible/rejoin.yml @@ -1,9 +1,9 @@ +--- - name: Rejoin hosts: servers remote_user: ubuntu - # loops over both servers roles: - role: rejoin vars: - vm_ip: '{{ ansible_host }}' # the current vm's ip - when: ansible_host == rejoin_ip # only run on the one that needs to be rejoined \ No newline at end of file + rejoin_vm_ip: "{{ ansible_host }}" # the current vm's ip + when: ansible_host == rejoin_ip # only run on the one that needs to be rejoined diff --git a/ansible/requirements.txt b/ansible/requirements.txt index 29772cb6..b5450ad9 100644 --- a/ansible/requirements.txt +++ b/ansible/requirements.txt @@ -1,8 +1,11 @@ ansible-core~=2.15.0 ansible-lint~=6.17.0 +# ansible-core~=2.17.4 +# ansible-lint~=24.9.2 powerline-status powerline-gitstatus netaddr~=0.7.19 openstacksdk~=1.3.0 python-openstackclient~=6.2.0 -psycopg2-binary \ No newline at end of file +psycopg2-binary +wheel diff --git a/ansible/requirements.yml b/ansible/requirements.yml new file mode 100644 index 00000000..45323db2 --- /dev/null +++ b/ansible/requirements.yml @@ -0,0 +1,7 @@ +--- +collections: + - ansible.posix + - ansible.utils + - community.general + - community.postgresql + - openstack.cloud diff --git a/ansible/roles/addsshkeys/defaults/main.yml b/ansible/roles/addsshkeys/defaults/main.yml new file mode 100644 index 00000000..84d7d121 --- /dev/null +++ b/ansible/roles/addsshkeys/defaults/main.yml @@ -0,0 +1,2 @@ +--- +authorize_keys_list: [] diff --git a/ansible/roles/addsshkeys/tasks/main.yml b/ansible/roles/addsshkeys/tasks/main.yml index 5881bf29..f6f91e60 100644 --- a/ansible/roles/addsshkeys/tasks/main.yml +++ b/ansible/roles/addsshkeys/tasks/main.yml @@ -1,9 +1,9 @@ ---- +--- - name: Add users keys to authorized_keys - ansible.builtin.authorized_key: + ansible.posix.authorized_key: user: ubuntu # this is the username on the remotehost whose authorized keys are being modified state: present key: "{{ item.key }}" - loop: '{{ authorized_keys_list }}' + loop: "{{ authorize_keys_list }}" loop_control: - label: "adding {{ item.name }} key to authorized_keys" \ No newline at end of file + label: "adding {{ item.name }} key to authorized_keys" diff --git a/ansible/roles/bigip/defaults/main.yml b/ansible/roles/bigip/defaults/main.yml new file mode 100644 index 00000000..26e26f42 --- /dev/null +++ b/ansible/roles/bigip/defaults/main.yml @@ -0,0 +1,3 @@ +--- +bigip_password: "" +bigip_load_balancer_ips: [] diff --git a/ansible/roles/bigip/tasks/main.yml b/ansible/roles/bigip/tasks/main.yml index a0813d75..6017c325 100644 --- a/ansible/roles/bigip/tasks/main.yml +++ b/ansible/roles/bigip/tasks/main.yml @@ -1,41 +1,41 @@ ---- +--- - name: Create bigip user and basic database - block: - # create user - - name: Create bigip user - community.postgresql.postgresql_user: - name: bigip - #db: bigip - password: '{{ bigip_password }}' - become: true - become_user: postgres - # create database - - name: Create a bigip database, with owner bigip - community.postgresql.postgresql_db: - name: bigip - owner: bigip - become: true - become_user: postgres - # create the schema - - name: Create the schema in bigip - community.postgresql.postgresql_script: - db: bigip - path: /etc/postgresql/16/db/bigip/bigip.sql - become: true - become_user: postgres - - name: Grant bigip priveleges on bigip database for table test - community.postgresql.postgresql_privs: - database: bigip - objs: test # only have rights on table test - privs: SELECT - role: bigip - grant_option: true - become: true - become_user: postgres # this is allowed to fail on the secondary, should work on the primary and be replicated over ignore_errors: true + block: + # create user + - name: Create bigip user + community.postgresql.postgresql_user: + name: bigip + # db: bigip + password: "{{ bigip_password }}" + become: true + become_user: postgres + # create database + - name: Create a bigip database, with owner bigip + community.postgresql.postgresql_db: + name: bigip + owner: bigip + become: true + become_user: postgres + # create the schema + - name: Create the schema in bigip + community.postgresql.postgresql_script: + db: bigip + path: /etc/postgresql/16/db/bigip/bigip.sql + become: true + become_user: postgres + - name: Grant bigip priveleges on bigip database for table test + community.postgresql.postgresql_privs: + database: bigip + objs: test # only have rights on table test + privs: SELECT + role: bigip + grant_option: true + become: true + become_user: postgres -# loop over the two ips of the load balancers, to add to hba conf +# loop over the two ips of the load balancers, to add to hba conf - name: Change hba conf to allow connections from bigip (load balancer) without an encrypted password community.postgresql.postgresql_pg_hba: dest: /etc/postgresql/16/main/pg_hba.conf @@ -45,6 +45,6 @@ databases: bigip users: bigip become: true - loop: '{{ load_balancer_ips }}' + loop: "{{ bigip_load_balancer_ips }}" loop_control: - label: "adding {{ item.address }} to hba conf" \ No newline at end of file + label: "adding {{ item.address }} to hba conf" diff --git a/ansible/roles/deploy/defaults/main.yml b/ansible/roles/deploy/defaults/main.yml new file mode 100644 index 00000000..e68650bb --- /dev/null +++ b/ansible/roles/deploy/defaults/main.yml @@ -0,0 +1,4 @@ +--- +deploy_envars: + - LARD_CONN_STRING: "" + - STINFO_CONN_STRING: "" diff --git a/ansible/roles/deploy/tasks/main.yml b/ansible/roles/deploy/tasks/main.yml index 71695b0d..d83c8d8e 100644 --- a/ansible/roles/deploy/tasks/main.yml +++ b/ansible/roles/deploy/tasks/main.yml @@ -9,9 +9,9 @@ name: lard groups: lard shell: /sbin/nologin - append: yes + append: true state: present - create_home: no + create_home: false - name: Copy files to server ansible.builtin.copy: @@ -41,17 +41,17 @@ # become: yes - name: Import environment variables - ansible.builtin.command: systemctl import-environment LARD_STRING STINFO_STRING - environment: "{{ envars }}" - become: yes + ansible.builtin.command: systemctl import-environment LARD_CONN_STRING STINFO_CONN_STRING + environment: "{{ deploy_envars }}" + become: true - name: Start LARD ingestion service ansible.builtin.systemd: daemon_reload: true name: lard_ingestion state: restarted - enabled: yes + enabled: true - name: Unset environment variables - ansible.builtin.command: systemctl unset-environment LARD_STRING STINFO_STRING - become: yes + ansible.builtin.command: systemctl unset-environment LARD_CONN_STRING STINFO_CONN_STRING + become: true diff --git a/ansible/roles/movefloatingip/tasks/main.yml b/ansible/roles/movefloatingip/tasks/main.yml index a627098a..67bc885b 100644 --- a/ansible/roles/movefloatingip/tasks/main.yml +++ b/ansible/roles/movefloatingip/tasks/main.yml @@ -1,3 +1,3 @@ -# roles/movefloatingip/tasks/main.yml +--- - name: Movefloatingip - import_tasks: movefloatingip.yml \ No newline at end of file + ansible.builtin.import_tasks: movefloatingip.yml diff --git a/ansible/roles/movefloatingip/tasks/movefloatingip.yml b/ansible/roles/movefloatingip/tasks/movefloatingip.yml index 26ab05ce..eb4a9ccd 100644 --- a/ansible/roles/movefloatingip/tasks/movefloatingip.yml +++ b/ansible/roles/movefloatingip/tasks/movefloatingip.yml @@ -4,56 +4,56 @@ # however it means that the stuff writing to the primary needs to be # robust enough to handle getting told the db is in a read only state for a short period. - name: Move primary floating ip + # unfortunately it seems that attaching the floating ip results in a timeout + # even though it actually succeeds + ignore_errors: true block: - # remove from old primary - - name: Detach floating ip address that we keep connected to the primary - openstack.cloud.floating_ip: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - server: '{{ name_primary }}' - state: absent - network: public - floating_ip_address: '{{ primary_floating_ip }}' + # remove from old primary + - name: Detach floating ip address that we keep connected to the primary + openstack.cloud.floating_ip: + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + server: "{{ name_primary }}" + state: absent + network: public + floating_ip_address: "{{ primary_floating_ip }}" - - name: Gather information about new primary server - openstack.cloud.server_info: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - name: '{{ name_standby }}' - register: new_primary_server + - name: Gather information about new primary server + openstack.cloud.server_info: + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + name: "{{ name_standby }}" + register: new_primary_server - - name: Print out the ipalias port information for the server - ansible.builtin.debug: - msg: "Server {{ new_primary_server.servers[0].addresses.ipalias }}" + - name: Print out the ipalias port information for the server + ansible.builtin.debug: + msg: "Server {{ new_primary_server.servers[0].addresses.ipalias }}" - # add to what is now primary (used to be standby) - - name: Attach floating ip address that we keep connected to the primary - openstack.cloud.floating_ip: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - server: '{{ new_primary_server.servers[0].id }}' - state: present - reuse: true - network: public - fixed_address: '{{ new_primary_server.servers[0].addresses.ipalias[0].addr }}' - floating_ip_address: '{{ primary_floating_ip }}' - wait: true - timeout: 60 - when: new_primary_server.servers[0].addresses.ipalias | length <=1 - # unfortunately it seems that attaching the floating ip results in a timeout - # even though it actually succeeds - ignore_errors: true + # add to what is now primary (used to be standby) + - name: Attach floating ip address that we keep connected to the primary + openstack.cloud.floating_ip: + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + server: "{{ new_primary_server.servers[0].id }}" + state: present + reuse: true + network: public + fixed_address: "{{ new_primary_server.servers[0].addresses.ipalias[0].addr }}" + floating_ip_address: "{{ primary_floating_ip }}" + wait: true + timeout: 60 + when: new_primary_server.servers[0].addresses.ipalias | length <=1 - name: Check floating ip is attached openstack.cloud.floating_ip_info: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - floating_ip_address: '{{ primary_floating_ip }}' - register: fip + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + floating_ip_address: "{{ primary_floating_ip }}" + register: fip # this will not run if the ip is not now on the right vm - name: Print out the floating ip information to confirm its ok ansible.builtin.debug: msg: "Floating ip {{ fip }}" become: true - when: fip.floating_ips[0].port_details.device_id == new_primary_server.servers[0].id \ No newline at end of file + when: fip.floating_ips[0].port_details.device_id == new_primary_server.servers[0].id diff --git a/ansible/roles/networks/tasks/create-ipalias-network.yml b/ansible/roles/networks/tasks/create-ipalias-network.yml index 7b8ee6dc..d722e1ec 100644 --- a/ansible/roles/networks/tasks/create-ipalias-network.yml +++ b/ansible/roles/networks/tasks/create-ipalias-network.yml @@ -1,42 +1,42 @@ --- - - name: Create ipalias network - openstack.cloud.network: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - name: '{{ ipalias_network_name }}' - external: false - state: present - run_once: true +- name: Create ipalias network + openstack.cloud.network: + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + name: "{{ ipalias_network_name }}" + external: false + state: present + run_once: true - - name: Create ipalias network subnet - openstack.cloud.subnet: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - network_name: '{{ ipalias_network_name }}' - name: '{{ ipalias_network_name }}-subnet' - cidr: 192.168.20.0/24 - state: present - dns_nameservers: '{{ met_dns[ostack_region] }}' - run_once: true +- name: Create ipalias network subnet + openstack.cloud.subnet: + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + network_name: "{{ ipalias_network_name }}" + name: "{{ ipalias_network_name }}-subnet" + cidr: 192.168.20.0/24 + state: present + dns_nameservers: "{{ met_dns[ostack_region] }}" + run_once: true - - name: Connect ipalias network to public network - openstack.cloud.router: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - state: present - name: ipalias-router - network: public - interfaces: - - '{{ ipalias_network_name }}-subnet' - run_once: true +- name: Connect ipalias network to public network + openstack.cloud.router: + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + state: present + name: ipalias-router + network: public + interfaces: + - "{{ ipalias_network_name }}-subnet" + run_once: true - - name: Remove default gateway for subnet - openstack.cloud.subnet: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - network_name: '{{ ipalias_network_name }}' - name: '{{ ipalias_network_name }}-subnet' - cidr: '{{ ipalias_ostack_network_cidr }}' - no_gateway_ip: true - state: present - run_once: true +- name: Remove default gateway for subnet + openstack.cloud.subnet: + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + network_name: "{{ ipalias_network_name }}" + name: "{{ ipalias_network_name }}-subnet" + cidr: "{{ ipalias_ostack_network_cidr }}" + no_gateway_ip: true + state: present + run_once: true diff --git a/ansible/roles/networks/tasks/create-project-network.yml b/ansible/roles/networks/tasks/create-project-network.yml index 1eff31cc..eb20aab9 100644 --- a/ansible/roles/networks/tasks/create-project-network.yml +++ b/ansible/roles/networks/tasks/create-project-network.yml @@ -1,28 +1,28 @@ --- - - name: Create private network - openstack.cloud.network: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - state: present - name: '{{ ostack_network_name }}' - external: false +- name: Create private network + openstack.cloud.network: + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + state: present + name: "{{ ostack_network_name }}" + external: false - - name: Create private network subnet - openstack.cloud.subnet: - state: present - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - network_name: '{{ ostack_network_name }}' - name: '{{ ostack_network_name }}-subnet' - cidr: '{{ ostack_network_cidr }}' - dns_nameservers: '{{ met_dns[ostack_region] }}' +- name: Create private network subnet + openstack.cloud.subnet: + state: present + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + network_name: "{{ ostack_network_name }}" + name: "{{ ostack_network_name }}-subnet" + cidr: "{{ ostack_network_cidr }}" + dns_nameservers: "{{ met_dns[ostack_region] }}" - - name: Connect private network to public network - openstack.cloud.router: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - state: present - name: public-router - network: public - interfaces: - - '{{ ostack_network_name }}-subnet' +- name: Connect private network to public network + openstack.cloud.router: + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + state: present + name: public-router + network: public + interfaces: + - "{{ ostack_network_name }}-subnet" diff --git a/ansible/roles/networks/tasks/create-project-security-group.yml b/ansible/roles/networks/tasks/create-project-security-group.yml index e4ebe625..bf243d9b 100644 --- a/ansible/roles/networks/tasks/create-project-security-group.yml +++ b/ansible/roles/networks/tasks/create-project-security-group.yml @@ -1,21 +1,21 @@ --- - - name: Create security groups - openstack.cloud.security_group: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - name: '{{ item }}' - description: Created with Ansible - loop: '{{ security_groups | map(attribute="name") | list | unique }}' +- name: Create security groups + openstack.cloud.security_group: + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + name: "{{ item }}" + description: Created with Ansible + loop: '{{ security_groups | map(attribute="name") | list | unique }}' - - name: Populate security groups - openstack.cloud.security_group_rule: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - security_group: '{{ item.name }}' - protocol: tcp - port_range_max: "{{ item.rule.port }}" - port_range_min: "{{ item.rule.port }}" - remote_ip_prefix: "{{ item.rule.subnet }}" - loop: '{{ security_groups }}' - loop_control: - label: "updating security group {{ item.name }} with rule {{ item.rule }}" +- name: Populate security groups + openstack.cloud.security_group_rule: + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + security_group: "{{ item.name }}" + protocol: tcp + port_range_max: "{{ item.rule.port }}" + port_range_min: "{{ item.rule.port }}" + remote_ip_prefix: "{{ item.rule.subnet }}" + loop: "{{ security_groups }}" + loop_control: + label: "updating security group {{ item.name }} with rule {{ item.rule }}" diff --git a/ansible/roles/networks/tasks/main.yml b/ansible/roles/networks/tasks/main.yml index 10a5623c..109af55e 100644 --- a/ansible/roles/networks/tasks/main.yml +++ b/ansible/roles/networks/tasks/main.yml @@ -1,12 +1,14 @@ +--- # roles/networks/tasks/main.yml - - name: Create the project network (if it doesn't exist) - import_tasks: create-project-network.yml +- name: Create the project network (if it doesn't exist) + ansible.builtion.import_tasks: create-project-network.yml - - name: Create the project security group (if it doesn't exist) - import_tasks: create-project-security-group.yml +- name: Create the project security group (if it doesn't exist) + ansible.builtion.import_tasks: create-project-security-group.yml - - name: Create the ipalias network (if it doesn't exist) - import_tasks: create-ipalias-network.yml +- name: Create the ipalias network (if it doesn't exist) + ansible.builtion.import_tasks: create-ipalias-network.yml - - name: Create ping security group - import_tasks: open-for-ping.yml \ No newline at end of file +- name: Create ping security group + ansible.builtion.import_tasks: + - open-for-ping.yml diff --git a/ansible/roles/networks/tasks/open-for-ping.yml b/ansible/roles/networks/tasks/open-for-ping.yml index 0e383f15..7cddbc47 100644 --- a/ansible/roles/networks/tasks/open-for-ping.yml +++ b/ansible/roles/networks/tasks/open-for-ping.yml @@ -1,15 +1,16 @@ +--- ### stuff needed for ping - name: Create ping security group openstack.cloud.security_group: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" name: ping description: Created with Ansible - name: Populate ping security group openstack.cloud.security_group_rule: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" security_group: ping protocol: icmp - remote_ip_prefix: "157.249.0.0/16" \ No newline at end of file + remote_ip_prefix: "157.249.0.0/16" diff --git a/ansible/roles/networks/vars/main.yml b/ansible/roles/networks/vars/main.yml index 4071b6ba..2ec80501 100644 --- a/ansible/roles/networks/vars/main.yml +++ b/ansible/roles/networks/vars/main.yml @@ -1,102 +1,105 @@ $ANSIBLE_VAULT;1.1;AES256 -63316462303232663161396533306631623963643536613865363931316530333935323339343165 -3334393663303564313730656263323461313133336263350a663637386337626430306430353138 -64326339663966643130363865373431656663333234666465363630616366376235346662373366 -3365333964303362660a646139336135343265613032353636616561323435366530633865323635 -63626239636465633662666262356665333162653563376266373530323562396561626535363366 -37333131353737353033313461613839366161623936656666396131646239303464623165616630 -66333866316231356161333464383062383634383530636162366464353361316532393033373963 -61646134623938633761303536646432616237316364323434646634393465363438616532313236 -61613639663835313635306265663263373639333062383937633932636166333437626461663932 -36643666613763626261316333386332623166333433306661623531623232323662396364643133 -31356665663935343436646136393935653439306332656332303834363730623937363930353737 -36323564396333326433653463313136663331623862663239663234613135333162316466383136 -39376638633063643732343764366535323166663063323034306637376665336632653264613763 -36613139376237373035393236336331653235656435303631323730323163373938666635383038 -66323662316137393137613235373261626639623331376632653935343066303034653534316236 -35653339313864313835316462383164323633323332366133343839376463623966353635363934 -35616636326432336631613736363638663439336232623064643631663830313330623736366632 -36643031383032353738653131643262383936396166353331336137333265393561626163633464 -37616662646363663933656530366633626338386530613835626533306164396336383561616533 -39636539653134366232346330386239396133313132363437313238306333623232356462386434 -37343662646562353031616535346336613131343838616532623366613136386639363763323734 -33646138313162393763653363633435623965376332633463313264333636663238366666376161 -36626365333937323430363035353439653338633838326331303830666261653866323634633434 -32343738636636356539643762393534333739623539326234613639633435636165626433616337 -35666564636463623765393232336432386636343133383537363061343064613336663665316666 -33386535376165303966306530653161383735323761363534326335653732346633333865366135 -63303464303138653937646264316164613265353934316334366335626231363832613365363532 -65343636643937376136386235366235643363343166353462663730346161393362623730643965 -39303062666266376431326333663933356465373233653835363866636237363565376662643430 -31656236623131646633643632366233633066653762323438383538366232363634353331313366 -66396331326434343362663931353866373234306663623631383330333533656139623565313336 -36303136333535613537393231613135613935323436303037376134653831353530666266376130 -32353834343461393133646134333065663239326535313831366630303361333566376532346462 -37363635366634323531616536393431656365613436666433616530356538376531656130366531 -37656130303132356432363930626632356336653235396362643062363662336530646333356538 -30373738353836363137306363613433376232366239623134643035343066653863623766653837 -62313039663666313033636331346131386632303430623034326664396663356262336363366265 -31393937373261353963623064653737343137376461353231656365373934326263376464643964 -33336566643131643163636162343862646665623139653639643439613261323366333634326438 -63633932333866346164616166343063386234383732333863333034346436356637653665626463 -34366234643339343162373663623136303236313266356164373362636237393631303866383034 -62616630663132613566336663633265356561646662333764383563353966383930613137653833 -62383661643739313230316332626236366435326662303831343936336166313033373561363037 -39393239613531643437346466383234393263643034363066366262316535313532326639356637 -66313762626232373839626638343465663935333061383839373963353833623932616433373336 -30363465623362326466323166353266346239326134376230633631653739393430326663316133 -61356431393665646664623135306538326430336137383931316165663561306262353239653765 -30636563626665363337623135346663383330626663373633336337623662353562393732646665 -37633636336564386364343632636532376536366165623032636266363765343864306234613735 -32306431393261313230326666616162303664396464303236643666336566313065663562613766 -65316132613339343864383635636433333933356664336435343134666536396162663031353532 -32373765323733656533353965333564393132656238333136663838396137336439393730303738 -34653130386130333038643833656235633531333839663462656262336262396362643766653064 -36633832346431346538306263356366613661393535356333386537383464373436623339623334 -34353038383563393334373134353734666564353639643763346166373862323866613839373539 -38643130346665336634393466356263383733613134333162653265393065633434616261323462 -65346264376534343735643039396538376637326639663966643939656663373636396566643638 -37366666623031323138356164363038393538383261313832366262636535643163663832613037 -31336136626134336661626464623439636533303731643639353664343163346332623032396430 -64383433643832343962343130636230626165376466386635363332633563333865633830383830 -66626334626433626339363837633235316636393163383464373638316132386363393739306230 -34343033393533303135343830333531626238393964306137323564623962313032633562366139 -35323261323531663335613039613764353262343433646537393830356135333265326238396663 -32636261623163633737666565666631663736333964363839373234633663343662366364646161 -63613365386335373637353633326434373632393334613131386439303339346530316334326364 -30336662653037656339393230323866643536643366383232393038323138323532636235653832 -61376338323839383539313364633936643934303264616131626233396563656163383836653132 -39393131393730343935663562386537313032383835663963653365343738373437303263313435 -32316365633333326131363034323463373065653930376365633834396137653634303038323364 -30303739363230353235666233636464373635396433616535643364666638656339653065366637 -35303531656665333334636535613631623133303662373235393231396234333566396435633839 -34663063366163653761336661386633656664313464663437323036373533323464373634616237 -64633666663033623234376630393361616638303166393230626336666236643462363565656431 -30626239323963376361353065383261383033326238613635643062373439616266313361306633 -64393263343130663765326562366266366538373130316638613734613134333030613831383938 -62393263343337306230363733326638366538393230313631383033313738346536656361623338 -34323131356230376530623035613133636434643766383162623363633464366661353031303863 -31396135333236373631363162326235313037343461656430376330383266613733656162616431 -31373231653361313465653233613537386661303737633730613033633334343964336665623639 -63393763343962346439653335333366346238643435666631356338366637316634373861383631 -38316563313866663561626632306635383062633237343038653032396266666666336436636138 -31666330323531393362366535326538626463633439393237633131376366393136386264306433 -33663434373662383632653264386566643132613938373062333635666138393136353035663666 -61636539353038363331306465383336303564633664623061326665383565616334363336313635 -37336664313334663237343762373362306239303362613966313765396666656663646636376338 -34633266343763306566633261343535653238663433613238633331306135626165366265613539 -35313334353238633532636139663363383130373066643230653535613964323061373862633433 -66343661323030666534373866363130316265346535303266616663316333666665626432386334 -36323865313661313365353666663563313232316531373761323534366266353462656132373738 -61393134656139393966636334326338643434626134333637626364326263333534643338383038 -34313339626263613566376539633737333532356131363561626364303738653066366337343935 -33323235616564316538356431623164373836356365323766613136323266616365646465613134 -30326161623665636166383636653266323739663236326162356238663865303463663964383463 -35396535623263316364366537626630643131633866396639386139373137663366636332373034 -66366231393932373230363161623039623463353732323962393361643238613130633835386231 -66373534363562663163333532653664313664306539303362346535663131303037383231616362 -30663635343563393163616333396534366637303430633264643161653865643264386262396166 -64626562396238643566326361336538646436353166343639383533386635356436306666396531 -38333836353961626431646635343032346232613464336531633862386439353131376130656632 -35356639303162663862663036396337336233613534613431303165646239316466366535613834 -3839 +38346131353064383463313564326435653835663261633735393438313936666162636561343736 +3062376431363262353562343331303439323836336133660a336139643062313432646162386432 +39623765323761363737643066613165303635633733653864636132626463333362323830323339 +6431306366393836320a626439313235376335656239393564313563613732363063353939663164 +62666331333262376535386334373161336239623330393964396332653964353061643339346434 +66636434316436383037373533373031643736646638653638373566636661383336393132386366 +39323836326232333233663333306539643461323563613865316331363563316261643165663335 +63626163343263333139306531343466326230313464626134626330653433306261616530623936 +36643138313465396330343062363531663863343036656538313466333065663832326266393234 +31366530623939323861366631613732636336343561323530363137363236353335343033616363 +35373631393230363831343733643963643630383436346230343865313134333437396230633165 +35623662323232663732326136633332303537616238356164333934396131353339623832393332 +39666539373462646462333662353562326232636537643264346261346238626136316262303636 +61326531386233343362313564333766376562393164616233393139616534366537666431303233 +38353035373537626539363434666531643334663737636533313938353539376231326464636661 +39363836626534373838343937633736623932393365656635613035376634333831373934333835 +63613463343735383939303634623132366636333861323236376162353336343761343631333536 +37396266373033626436666539376133373133336339663330663632666232353764656632363235 +66343964646562623731323162373331356138636362646364373335616665643162346563383636 +35376433343162366131643861643161623430323536353066633231393936356264373464373530 +35306130386630613438623038646338656538326235666566303366623033303765616430666662 +35313338633463313637303937636239366637613134653966616630373231636163393564636465 +32343662613437613738306537333033613639336265323838613935653136633137316231343732 +63613434393561313834313263666565323064633238326236663530646565613330663239346430 +30646636306538653462393366363336336436623834343562643732306230353031306131376366 +35626335613732373564343733333930353831626331346531303364393563623032303330663231 +33643537306664633861343665356230626263626334313366366239323064303638613362326639 +61333963343838666461393032643061313830616461373434336265316161316561343862306234 +65333466326264623231323564643666326638633366346563656631316633653732343633303838 +34373636396137326533643838626139313031376335303362636333366439313830666338303538 +37386635626532353566353065346466306534653233373264333138616330616530663162653833 +39633837303433396462326636633233353262343539333564663832376465343230383331633835 +30626462363339343331336431393233613535376363373534346635313165333861303866336631 +31343439386163613438346331333962316530393833356232656639313333326363376233633535 +37316532393539616365663765353538346135353963363831316362343264353431326465306634 +33356438316161623562356130633538653233653130633365646166626430346164356365363463 +63356534303034393337636237623137323261373434376433343065333031316261646232643336 +37653965666536383332616635336434643233643230623735376635383733366532643637336163 +34383531333937396362633338333133613836653365366265353561653436313737646130333865 +39663037633332653138356438336233666635363332623036393863386131613932306638323133 +33363532643936656538353333623365636338343533636634626532623065303964393066623064 +31373433326530626465363134363630383935613063366664313661636161623239346661623932 +62663264346439373637306535353336373863633163633836303565313761643662303731386365 +64313062313837646330363561303836626331333035393137323461363437626139393333663139 +63636638353938313365643664386637666166653463343361356563303433333638636438336536 +30633137653933653332373134346163336333353732373861343231616664626362616636666462 +39636135653164626366663837323234656465343832323134663939393134366439623038663138 +32623165356638643361343536316237613334366233633462383733303139393763643662376366 +39616138353333356336303336353035376361636239656161343035393537646163666637303538 +37393266643430363036386233336139383537626234376365613032303739323565323230623866 +64376465383639643065323131623665633765353832336662326132653366646131366337303030 +66373462383961653266656230626638663833353038356361363538663034313735346365313934 +61626532623536393634356165386665333238386262373964373230643230353930343533613365 +61303935313131643633353663303164613737363731663164306361613861343235303138333439 +30313333636334653332636130386663636637363530336463336330643936306230373862313866 +34626137623630366633396365363231656130386561343037333330643462383038386263313835 +33386161363366616464386230326462646533306339366664313665393836633132623566386137 +63626666636132633265616261653835643533343531636536306663303637613831303533646636 +39663539336465646666396430366639393366656665343237613839666433353165396262343038 +63326461626330306235396230656338356236356461616265666463623533366434643130313364 +61666639353062333332383364616332326338373034336631653961306666373136336439356438 +66653466336333626266326434303662633139323066366535323063396233333139646165326636 +64396139316262323232393161303363616134376436313437353761626339383266316231313561 +62613037373763613439643462386239306664346135353537626238373334643630373165626230 +39333563633236396266376238383230333536336439633966383463623565623830396237306531 +66633933393837646330373165666234643334343365353134386664633964643335633362646432 +35383933356133653339353732373963616335633131353237323636333464343665616335653934 +66396339626536653331613062643939326235353765396464383761616330393363643362636166 +38653130653035643762633564313233356338336466303865346665643063376263633765353731 +30653538303738323238636564373762613562653665326163363363643964666631393464633734 +62323464353562376162393334343464623065646337623361376639363630666665346364656262 +37623833636366316333666264653831376630626539333033343830653533326238333866633866 +36613935646261373935613362633661616438666635313464323439663636373030363633623736 +36616137663035363730376133396131323132353032643466363366646138386633393663373431 +37373164616561373330303037373264626235323866633763323663636231613563643536623365 +37653864613838386332383934373732636230663034633965323038396138343032323461366238 +66646137353936616235343332343335376632636164623465646439316339313266643964643534 +31626632616261343433373266663639366539313631376466613831393631656536356435343331 +39616565623861636662336137353836383664363662393864336666633237366434326537333939 +63333964346432306635623639323831353434643837326231383531623730326639626233386365 +33663464366435613931303163373738343461306439653665356634376432323938316237396364 +33336334346137663062663865356463616138343135373438333361393237333538386364323463 +66393537313861616134626633356431626238643135366263323833386133313837656464396235 +38663738663638323566626561356362303030646363306539636630336435323166613465386536 +66333433366531373733663163663063393563613465316164653635346362373138343935613736 +63656262633632636165326130393035656436663363613839616662636538623363616362353736 +32343963376138663638373734323864393035393532373836613037313932616534313637363733 +62613636363365623531306565366562343933336236343765303963336637323662626565656235 +35313030393536346365366364353634636561613430626430396239633433336638366133356466 +30353631396564653261366561373639656134323266626261656636346463366430356563333163 +66386231383564633831656666626435663362633761373435363731643839396265643335616466 +64653562663962383166393632646637613266383735666431616333376432633661373037333037 +32663836643636643434656664636430313330303063303437653331353563646332356437656639 +31306564656364386536313934633636633636346634613966353634383164363039393935316561 +62333366343862303761306266313730353563656139343664383232646436356438656238383630 +32306438303661313030663565343364313263626266396239353536616165333965663038663631 +39323265306531643438346233316162626562313361346662343139613735646137656339356534 +38343636393934383235666561333630306335363463326438663134656662616635363638653661 +37316465613364336562313934343731636234306131363861356430313531613431323965333034 +31626439643863653464343562396565333637643431653763616235393063323765336233323565 +33383965363164363962326137666165633737323362633761373663356634613566313863333833 +35306566386232363439373937613737343963643564373366346232373435663864353965383835 +36383731333563323431303530396436353264633662663765663936336561666165643138636536 +31643333333436386235 diff --git a/ansible/roles/primarystandbysetup/tasks/create-primary.yml b/ansible/roles/primarystandbysetup/tasks/create-primary.yml index 2876bc7e..58266584 100644 --- a/ansible/roles/primarystandbysetup/tasks/create-primary.yml +++ b/ansible/roles/primarystandbysetup/tasks/create-primary.yml @@ -1,12 +1,20 @@ -# set up a role and provide suitable entries in pg_hba.conf with the database field set to replication +--- +# set up a role and provide suitable entries in pg_hba.conf with the database +# field set to replication -# ensure max_wal_senders is set to a sufficiently large value in the conf file (also possibly max_replication_slots?) -# When running a standby server, you must set this parameter to the same or higher value than on the primary server. Otherwise, queries will not be allowed in the standby server. +# ensure max_wal_senders is set to a sufficiently large value in the conf file +# (also possibly max_replication_slots?) +# When running a standby server, you must set this parameter to the same or +# higher value than on the primary server. Otherwise, queries will not be +# allowed in the standby server. -# set wal_keep_size to a value large enough to ensure that WAL segments are not recycled too early, or configure a replication slot for the standby? +# set wal_keep_size to a value large enough to ensure that WAL segments are not +# recycled too early, or configure a replication slot for the standby? # if there is a WAL archive accessible to the standby this may not be needed? -# On systems that support the keepalive socket option, setting tcp_keepalives_idle, tcp_keepalives_interval and tcp_keepalives_count helps the primary promptly notice a broken connection. +# On systems that support the keepalive socket option, setting +# tcp_keepalives_idle, tcp_keepalives_interval and tcp_keepalives_count helps +# the primary promptly notice a broken connection. # example auth # Allow the user "foo" from host 192.168.1.100 to connect to the primary @@ -14,258 +22,279 @@ # # TYPE DATABASE USER ADDRESS METHOD # host replication foo 192.168.1.100/32 md5 ---- - - name: Create a new database with name lard - community.postgresql.postgresql_db: - name: lard - become: true - become_user: postgres - delegate_to: '{{ primary_ip }}' - remote_user: ubuntu +- name: Create a new database with name lard + community.postgresql.postgresql_db: + name: lard + become: true + become_user: postgres + delegate_to: "{{ primary_ip }}" + remote_user: ubuntu - - name: Copy the db folder to the remote - ansible.builtin.copy: - src: ../../../../db/ - dest: /etc/postgresql/16/db/ - mode: '0755' - become: true - delegate_to: '{{ primary_ip }}' - remote_user: ubuntu +- name: Copy the db folder to the remote + ansible.builtin.copy: + src: ../../../../db/ + dest: /etc/postgresql/16/db/ + mode: "0755" + become: true + delegate_to: "{{ primary_ip }}" + remote_user: ubuntu - - name: Create the public schema in lard - community.postgresql.postgresql_script: - db: lard - path: /etc/postgresql/16/db/public.sql - become: true - become_user: postgres - delegate_to: '{{ primary_ip }}' - remote_user: ubuntu +# - name: Import sql files +# ansible.builtin.command: - - name: Create the data partitions - community.postgresql.postgresql_script: - db: lard - path: /etc/postgresql/16/db/partition.sql - become: true - become_user: postgres - delegate_to: "{{ primary_ip }}" - remote_user: ubuntu +# - name: Create schemas and tables in lard +# community.postgresql.postgresql_script: +# db: lard +# path: "/etc/postgresql/16/db/{{ item }}" +# become: true +# become_user: postgres +# delegate_to: "{{ primary_ip }}" +# remote_user: ubuntu +# loop: - - name: Create the labels schema in lard - community.postgresql.postgresql_script: - db: lard - path: /etc/postgresql/16/db/labels.sql - become: true - become_user: postgres - delegate_to: '{{ primary_ip }}' - remote_user: ubuntu +# TODO: loop over the sql files in order (needs prepending IDs) +- name: Create the public schema in lard + community.postgresql.postgresql_script: + db: lard + path: /etc/postgresql/16/db/public.sql + become: true + become_user: postgres + delegate_to: "{{ primary_ip }}" + remote_user: ubuntu - - name: Connect to lard database, create user - community.postgresql.postgresql_user: - db: lard - name: lard_user - password: '{{ db_password }}' - role_attr_flags: SUPERUSER # not desired, but the privelege granting doesn't seem to work? - become: true - become_user: postgres - delegate_to: '{{ primary_ip }}' - remote_user: ubuntu - # - name: Grant lard_user priveleges on lard database - # community.postgresql.postgresql_privs: - # type: database - # db: lard - # privs: ALL - # role: lard_user - # become: true - # become_user: postgres +- name: Create the data partitions + community.postgresql.postgresql_script: + db: lard + path: /etc/postgresql/16/db/partition.sql + become: true + become_user: postgres + delegate_to: "{{ primary_ip }}" + remote_user: ubuntu - # MAKE IT THE PRIMARY - - name: Set wal_level parameter - community.postgresql.postgresql_set: - name: wal_level - value: replica # https://www.postgresql.org/docs/current/runtime-config-wal.html#GUC-WAL-LEVEL - become: true - become_user: postgres - delegate_to: '{{ primary_ip }}' - remote_user: ubuntu - - name: Set hot_standby parameter - community.postgresql.postgresql_set: - name: hot_standby - value: true - become: true - become_user: postgres - delegate_to: '{{ primary_ip }}' - remote_user: ubuntu - - name: Set hot_standby_feedback parameter - community.postgresql.postgresql_set: - name: hot_standby_feedback - value: true - become: true - become_user: postgres - delegate_to: '{{ primary_ip }}' - remote_user: ubuntu - - name: Set max_wal_senders parameter - community.postgresql.postgresql_set: - name: max_wal_senders - value: 10 - become: true - become_user: postgres - delegate_to: '{{ primary_ip }}' - remote_user: ubuntu - - name: Set wal_log_hints parameter # needs to be enabled to use pg_rewind - # https://www.postgresql.org/docs/current/app-pgrewind.html - community.postgresql.postgresql_set: - name: wal_log_hints - value: true - become: true - become_user: postgres - delegate_to: '{{ primary_ip }}' - remote_user: ubuntu - - name: Set max_replication_slots parameter - community.postgresql.postgresql_set: - name: max_replication_slots - value: 10 - become: true - become_user: postgres - delegate_to: '{{ primary_ip }}' - remote_user: ubuntu - # make it SYNCHRONOUS REPLICATION (without the next two settings it would be asynchronous) - - name: Set synchronous_standby_names parameter - community.postgresql.postgresql_set: - name: synchronous_standby_names # https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-SYNCHRONOUS-STANDBY-NAMES - value: "*" # all the standbys - become: true - become_user: postgres - delegate_to: '{{ primary_ip }}' - remote_user: ubuntu - - name: Set synchronous_commit parameter - community.postgresql.postgresql_set: - name: synchronous_commit # https://www.postgresql.org/docs/current/runtime-config-wal.html#GUC-SYNCHRONOUS-COMMIT - value: on # will not give standby query consistency (tradeoff for better write performance), but will give standby durable commit after OS crash - become: true - become_user: postgres - delegate_to: '{{ primary_ip }}' - remote_user: ubuntu +- name: Create the labels schema in lard + community.postgresql.postgresql_script: + db: lard + path: /etc/postgresql/16/db/labels.sql + become: true + become_user: postgres + delegate_to: "{{ primary_ip }}" + remote_user: ubuntu - # repmgr - # https://www.repmgr.org/docs/current/quickstart-repmgr-conf.html - - name: Create a repmgr.conf if it does not exist - ansible.builtin.file: - path: /etc/repmgr.conf - state: touch - mode: '0755' - become: true - delegate_to: '{{ primary_ip }}' - remote_user: ubuntu - - name: Set contents of repmgr.conf - ansible.builtin.copy: - dest: "/etc/repmgr.conf" - content: | - node_id=1 - node_name='{{ primary_name }}' - conninfo='host={{ primary_ip }} user=repmgr dbname=repmgr connect_timeout=2' - data_directory='/mnt/ssd-b/16/main' - service_start_command='sudo /bin/systemctl start postgresql.service' - service_stop_command='sudo /bin/systemctl stop postgresql.service' - service_restart_command='sudo /bin/systemctl restart postgresql.service' - service_reload_command='sudo /bin/systemctl reload postgresql.service' - mode: '0755' - become: true - delegate_to: '{{ primary_ip }}' - remote_user: ubuntu +- name: Connect to lard database, create user + community.postgresql.postgresql_user: + db: lard + name: lard_user + password: "{{ db_password }}" + role_attr_flags: SUPERUSER # not desired, but the privelege granting doesn't seem to work? + become: true + become_user: postgres + delegate_to: "{{ primary_ip }}" + remote_user: ubuntu +# - name: Grant lard_user priveleges on lard database +# community.postgresql.postgresql_privs: +# type: database +# db: lard +# privs: ALL +# role: lard_user +# become: true +# become_user: postgres - # https://www.repmgr.org/docs/current/quickstart-primary-register.html - - name: Run repmgr to register the primary - ansible.builtin.command: repmgr -f /etc/repmgr.conf primary register -F # only need -F if rerunning - become: true - become_user: postgres - delegate_to: '{{ primary_ip }}' - remote_user: ubuntu - register: register_primary_results - - name: Print out the register_primary_results - ansible.builtin.debug: - msg: "repmgr {{ register_primary_results }}" - delegate_to: '{{ primary_ip }}' - remote_user: ubuntu +# MAKE IT THE PRIMARY +- name: Set wal_level parameter + community.postgresql.postgresql_set: + name: wal_level + value: replica # https://www.postgresql.org/docs/current/runtime-config-wal.html#GUC-WAL-LEVEL + become: true + become_user: postgres + delegate_to: "{{ primary_ip }}" + remote_user: ubuntu + +- name: Set hot_standby parameter + community.postgresql.postgresql_set: + name: hot_standby + value: true + become: true + become_user: postgres + delegate_to: "{{ primary_ip }}" + remote_user: ubuntu + +- name: Set hot_standby_feedback parameter + community.postgresql.postgresql_set: + name: hot_standby_feedback + value: true + become: true + become_user: postgres + delegate_to: "{{ primary_ip }}" + remote_user: ubuntu + +- name: Set max_wal_senders parameter + community.postgresql.postgresql_set: + name: max_wal_senders + value: 10 + become: true + become_user: postgres + delegate_to: "{{ primary_ip }}" + remote_user: ubuntu + +- name: Set wal_log_hints parameter # needs to be enabled to use pg_rewind + # https://www.postgresql.org/docs/current/app-pgrewind.html + community.postgresql.postgresql_set: + name: wal_log_hints + value: true + become: true + become_user: postgres + delegate_to: "{{ primary_ip }}" + remote_user: ubuntu - # # STUFF FOR REPLICATION (do not need if using repmgr) - # - name: Create replicator user with replication priveleges - # community.postgresql.postgresql_user: - # name: replicator - # password: '{{ replicator_password }}' - # role_attr_flags: REPLICATION - # become: true - # become_user: postgres +- name: Set max_replication_slots parameter + community.postgresql.postgresql_set: + name: max_replication_slots + value: 10 + become: true + become_user: postgres + delegate_to: "{{ primary_ip }}" + remote_user: ubuntu - # # also specifically allow the replicator user - # - name: Change hba conf to allow replicator to connect - # community.postgresql.postgresql_pg_hba: - # dest: /etc/postgresql/16/main/pg_hba.conf - # databases: replication - # contype: host - # users: replicator - # #address: all - # address: '{{ standby_host }}' - # method: trust # seems to hang with md5, how to make auth work? - # become: true +# make it SYNCHRONOUS REPLICATION (without the next two settings it would be asynchronous) +- name: Set synchronous_standby_names parameter + community.postgresql.postgresql_set: + name: synchronous_standby_names # https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-SYNCHRONOUS-STANDBY-NAMES + value: "*" # all the standbys + become: true + become_user: postgres + delegate_to: "{{ primary_ip }}" + remote_user: ubuntu - # # create replication slot - # - name: Create physical replication slot if doesn't exist - # become_user: postgres - # community.postgresql.postgresql_slot: - # slot_name: replication_slot - # #db: lard - # become: true +- name: Set synchronous_commit parameter + community.postgresql.postgresql_set: + name: synchronous_commit # https://www.postgresql.org/docs/current/runtime-config-wal.html#GUC-SYNCHRONOUS-COMMIT + value: "on" # will not give standby query consistency (tradeoff for better write performance), but will give standby durable commit after OS crash + become: true + become_user: postgres + delegate_to: "{{ primary_ip }}" + remote_user: ubuntu - # make sure these changes take effect? - - name: Restart service postgres - ansible.builtin.systemd_service: - name: postgresql - state: restarted - become: true - delegate_to: '{{ primary_ip }}' - remote_user: ubuntu +# repmgr +# https://www.repmgr.org/docs/current/quickstart-repmgr-conf.html +- name: Create a repmgr.conf if it does not exist + ansible.builtin.file: + path: /etc/repmgr.conf + state: touch + mode: "0755" + become: true + delegate_to: "{{ primary_ip }}" + remote_user: ubuntu - ### now move back to default of operating from localhost - - name: Attach primary floating ip - block: - - name: Gather information about primary server - openstack.cloud.server_info: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - name: '{{ primary_name }}' - become: false - register: primary_server +- name: Set contents of repmgr.conf + ansible.builtin.copy: + dest: "/etc/repmgr.conf" + content: | + node_id=1 + node_name='{{ primary_name }}' + conninfo='host={{ primary_ip }} user=repmgr dbname=repmgr connect_timeout=2' + data_directory='/mnt/ssd-b/16/main' + service_start_command='sudo /bin/systemctl start postgresql.service' + service_stop_command='sudo /bin/systemctl stop postgresql.service' + service_restart_command='sudo /bin/systemctl restart postgresql.service' + service_reload_command='sudo /bin/systemctl reload postgresql.service' + mode: "0755" + become: true + delegate_to: "{{ primary_ip }}" + remote_user: ubuntu - - name: Print out the ipalias port information for the server - ansible.builtin.debug: - msg: "Server {{ primary_server.servers[0].addresses.ipalias }}" - - # give the primary a particular floating ip - - name: Attach floating ip address that we keep connected to the primary - openstack.cloud.floating_ip: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - server: '{{ primary_server.servers[0].id }}' - reuse: true - network: public - fixed_address: '{{ primary_server.servers[0].addresses.ipalias[0].addr }}' - floating_ip_address: '{{ primary_floating_ip }}' - wait: true - timeout: 60 - when: primary_server.servers[0].addresses.ipalias | length <=1 - # unfortunately it seems that attaching the floating ip results in a timeout - # even though it actually succeeds - ignore_errors: true +# https://www.repmgr.org/docs/current/quickstart-primary-register.html +- name: Run repmgr to register the primary + ansible.builtin.command: repmgr -f /etc/repmgr.conf primary register -F # only need -F if rerunning + become: true + become_user: postgres + delegate_to: "{{ primary_ip }}" + remote_user: ubuntu + register: register_primary_results +- name: Print out the register_primary_results + ansible.builtin.debug: + msg: "repmgr {{ register_primary_results }}" + delegate_to: "{{ primary_ip }}" + remote_user: ubuntu - - name: Check floating ip is attached - openstack.cloud.floating_ip_info: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - floating_ip_address: '{{ primary_floating_ip }}' - register: fip +# # STUFF FOR REPLICATION (do not need if using repmgr) +# - name: Create replicator user with replication priveleges +# community.postgresql.postgresql_user: +# name: replicator +# password: '{{ replicator_password }}' +# role_attr_flags: REPLICATION +# become: true +# become_user: postgres - # this will not run if the ip is not now on the vm - - name: Print out the floating ip information to confirm its ok +# # also specifically allow the replicator user +# - name: Change hba conf to allow replicator to connect +# community.postgresql.postgresql_pg_hba: +# dest: /etc/postgresql/16/main/pg_hba.conf +# databases: replication +# contype: host +# users: replicator +# #address: all +# address: '{{ standby_host }}' +# method: trust # seems to hang with md5, how to make auth work? +# become: true + +# # create replication slot +# - name: Create physical replication slot if doesn't exist +# become_user: postgres +# community.postgresql.postgresql_slot: +# slot_name: replication_slot +# #db: lard +# become: true + +# make sure these changes take effect? +- name: Restart service postgres + ansible.builtin.systemd_service: + name: postgresql + state: restarted + become: true + delegate_to: "{{ primary_ip }}" + remote_user: ubuntu + +### now move back to default of operating from localhost +- name: Attach primary floating ip + # unfortunately it seems that attaching the floating ip results in a timeout + # even though it actually succeeds + ignore_errors: true + block: + - name: Gather information about primary server + openstack.cloud.server_info: + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + name: "{{ primary_name }}" + become: false + register: primary_server + + - name: Print out the ipalias port information for the server ansible.builtin.debug: - msg: "Floating ip {{ fip }}" - when: fip.floating_ips[0].port_details.device_id == primary_server.servers[0].id + msg: "Server {{ primary_server.servers[0].addresses.ipalias }}" + + # give the primary a particular floating ip + - name: Attach floating ip address that we keep connected to the primary + openstack.cloud.floating_ip: + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + server: "{{ primary_server.servers[0].id }}" + reuse: true + network: public + fixed_address: "{{ primary_server.servers[0].addresses.ipalias[0].addr }}" + floating_ip_address: "{{ primary_floating_ip }}" + wait: true + timeout: 60 + when: primary_server.servers[0].addresses.ipalias | length <=1 + +- name: Check floating ip is attached + openstack.cloud.floating_ip_info: + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + floating_ip_address: "{{ primary_floating_ip }}" + register: fip + +# this will not run if the ip is not now on the vm +- name: Print out the floating ip information to confirm its ok + ansible.builtin.debug: + msg: "Floating ip {{ fip }}" + when: fip.floating_ips[0].port_details.device_id == primary_server.servers[0].id diff --git a/ansible/roles/primarystandbysetup/tasks/create-standby.yml b/ansible/roles/primarystandbysetup/tasks/create-standby.yml index d565243e..5cbfd5ed 100644 --- a/ansible/roles/primarystandbysetup/tasks/create-standby.yml +++ b/ansible/roles/primarystandbysetup/tasks/create-standby.yml @@ -1,149 +1,154 @@ +--- # create standby.signal file in data directory -# configure streaming WAL +# configure streaming WAL # primary_conninfo needs a libpq connection string (ip address + other details needed to connect to primary server) # since we want the standby to be able to operate as the primary, we need to configure the WAL archiving, connections, and auth like the primary # example: -#primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass options=''-c wal_sender_timeout=5000''' -#restore_command = 'cp /path/to/archive/%f %p' -#archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' +# primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass options=''-c wal_sender_timeout=5000''' +# restore_command = 'cp /path/to/archive/%f %p' +# archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' # add the following line to the postgresql.conf file on the standby # The standby connects to the primary that is running on host 192.168.1.50 # and port 5432 as the user "foo" whose password is "foopass". -#primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' +# primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' # use the replication slot on the primary (in file after the primary_conninfo) -#primary_slot_name = 'node_a_slot' ---- - # repmgr - # https://www.repmgr.org/docs/current/quickstart-standby-clone.html - # must be done before the standby is put into read only mode (therefore not idempotent) - - name: Create a repmgr.conf if it does not exist - ansible.builtin.file: - path: /etc/repmgr.conf - state: touch - mode: '0755' - become: true - delegate_to: '{{ standby_ip }}' - remote_user: ubuntu - - name: Set contents of repmgr.conf - ansible.builtin.copy: - dest: "/etc/repmgr.conf" - content: | - node_id=2 - node_name='{{ standby_name }}' - conninfo='host={{ standby_ip }} user=repmgr dbname=repmgr connect_timeout=2' - data_directory='/mnt/ssd-b/16/main' - service_start_command='sudo /bin/systemctl start postgresql.service' - service_stop_command='sudo /bin/systemctl stop postgresql.service' - service_restart_command='sudo /bin/systemctl restart postgresql.service' - service_reload_command='sudo /bin/systemctl reload postgresql.service' - mode: '0755' - become: true - delegate_to: '{{ standby_ip }}' - remote_user: ubuntu +# primary_slot_name = 'node_a_slot' +# repmgr +# https://www.repmgr.org/docs/current/quickstart-standby-clone.html +# must be done before the standby is put into read only mode (therefore not idempotent) +- name: Create a repmgr.conf if it does not exist + ansible.builtin.file: + path: /etc/repmgr.conf + state: touch + mode: "0755" + become: true + delegate_to: "{{ standby_ip }}" + remote_user: ubuntu +- name: Set contents of repmgr.conf + ansible.builtin.copy: + dest: "/etc/repmgr.conf" + content: | + node_id=2 + node_name='{{ standby_name }}' + conninfo='host={{ standby_ip }} user=repmgr dbname=repmgr connect_timeout=2' + data_directory='/mnt/ssd-b/16/main' + service_start_command='sudo /bin/systemctl start postgresql.service' + service_stop_command='sudo /bin/systemctl stop postgresql.service' + service_restart_command='sudo /bin/systemctl restart postgresql.service' + service_reload_command='sudo /bin/systemctl reload postgresql.service' + mode: "0755" + become: true + delegate_to: "{{ standby_ip }}" + remote_user: ubuntu - - name: Stop service postgres, if running - ansible.builtin.systemd_service: - name: postgresql - state: stopped - become: true - delegate_to: '{{ standby_ip }}' - remote_user: ubuntu +- name: Stop service postgres, if running + ansible.builtin.systemd_service: + name: postgresql + state: stopped + become: true + delegate_to: "{{ standby_ip }}" + remote_user: ubuntu - # https://www.repmgr.org/docs/current/quickstart-standby-clone.html - - name: Run repmgr to dry run clone - ansible.builtin.command: repmgr -h '{{ primary_ip }}' -U repmgr -d repmgr -f /etc/repmgr.conf standby clone --dry-run - become: true - become_user: postgres - delegate_to: '{{ standby_ip }}' - remote_user: ubuntu - register: dry_run_clone_results - - name: Print out the dry_run_clone_results - ansible.builtin.debug: - msg: "repmgr {{ dry_run_clone_results }}" +# TODO: add change_when to fix lint? +# https://www.repmgr.org/docs/current/quickstart-standby-clone.html +- name: Run repmgr to dry run clone + ansible.builtin.command: repmgr -h '{{ primary_ip }}' -U repmgr -d repmgr -f /etc/repmgr.conf standby clone --dry-run + become: true + become_user: postgres + delegate_to: "{{ standby_ip }}" + remote_user: ubuntu + register: dry_run_clone_results +- name: Print out the dry_run_clone_results + ansible.builtin.debug: + msg: "repmgr {{ dry_run_clone_results }}" - - name: Run repmgr to clone standby from primary - ansible.builtin.command: repmgr -h '{{ primary_ip }}' -U repmgr -d repmgr -f /etc/repmgr.conf standby clone -F - become: true - register: clone_results - become_user: postgres - delegate_to: '{{ standby_ip }}' - remote_user: ubuntu - - name: Print out the clone_results - ansible.builtin.debug: - msg: "repmgr {{ clone_results }}" +# TODO: add change_when to fix lint? +- name: Run repmgr to clone standby from primary + ansible.builtin.command: repmgr -h '{{ primary_ip }}' -U repmgr -d repmgr -f /etc/repmgr.conf standby clone -F + become: true + register: clone_results + become_user: postgres + delegate_to: "{{ standby_ip }}" + remote_user: ubuntu +- name: Print out the clone_results + ansible.builtin.debug: + msg: "repmgr {{ clone_results }}" - # try to clean up so can run standby clone ? - # - name: Recursively remove directory - # ansible.builtin.file: - # path: /mnt/ssd-b/16/main - # state: absent - # become: true - # - name: Create a main directory if it does not exist - # ansible.builtin.file: - # path: /mnt/ssd-b/16/main - # state: directory - # mode: '0700' - # become: true - # become_user: postgres +# try to clean up so can run standby clone ? +# - name: Recursively remove directory +# ansible.builtin.file: +# path: /mnt/ssd-b/16/main +# state: absent +# become: true +# - name: Create a main directory if it does not exist +# ansible.builtin.file: +# path: /mnt/ssd-b/16/main +# state: directory +# mode: '0700' +# become: true +# become_user: postgres - # https://www.postgresql.org/docs/current/app-pgbasebackup.html - # NOTE: this part is not idempotent, so if a db is already in the dir, it will fail - # hence the stuff above that means this should not be run on a database with data!!! - # not needed if using repmgr, since clone calls this - # - name: Run pg_basebackup to initialize the replica / standby - # ansible.builtin.shell: export PGPASSWORD="{{ replicator_password }}" && pg_basebackup --pgdata=/mnt/ssd-b/16/main -R --slot=replication_slot --user=replicator --host={{ primary_host }} --port=5432 - # args: - # executable: /bin/bash - # become: true - # become_user: postgres - # register: basebackup_results +# https://www.postgresql.org/docs/current/app-pgbasebackup.html +# NOTE: this part is not idempotent, so if a db is already in the dir, it will fail +# hence the stuff above that means this should not be run on a database with data!!! +# not needed if using repmgr, since clone calls this +# - name: Run pg_basebackup to initialize the replica / standby +# ansible.builtin.shell: | +# export PGPASSWORD="{{ replicator_password }}" && +# pg_basebackup --pgdata=/mnt/ssd-b/16/main -R --slot=replication_slot --user=replicator --host={{ primary_host }} --port=5432 +# args: +# executable: /bin/bash +# become: true +# become_user: postgres +# register: basebackup_results - # - name: Print out the basebackup_results - # debug: msg="backup {{ basebackup_results }}" +# - name: Print out the basebackup_results +# debug: msg="backup {{ basebackup_results }}" - - name: Restart service postgres - ansible.builtin.systemd_service: - name: postgresql - state: restarted - become: true - delegate_to: '{{ standby_ip }}' - remote_user: ubuntu +- name: Restart service postgres + ansible.builtin.systemd_service: + name: postgresql + state: restarted + become: true + delegate_to: "{{ standby_ip }}" + remote_user: ubuntu - - name: Waits for port 5432 to be available, don't check for initial 10 seconds - ansible.builtin.wait_for: - host: 0.0.0.0 - port: 5432 - delay: 10 - state: started - delegate_to: '{{ standby_ip }}' - remote_user: ubuntu +- name: Waits for port 5432 to be available, don't check for initial 10 seconds + ansible.builtin.wait_for: + host: 0.0.0.0 + port: 5432 + delay: 10 + state: started + delegate_to: "{{ standby_ip }}" + remote_user: ubuntu - # https://www.repmgr.org/docs/current/quickstart-register-standby.html - - name: Run repmgr to register the standby - ansible.builtin.command: repmgr -f /etc/repmgr.conf standby register - become: true - become_user: postgres - delegate_to: '{{ standby_ip }}' - remote_user: ubuntu - register: register_standby_results - - name: Print out the register_standby_results - ansible.builtin.debug: - msg: "repmgr {{ register_standby_results }}" +# TODO: add change_when to fix lint? +# https://www.repmgr.org/docs/current/quickstart-register-standby.html +- name: Run repmgr to register the standby + ansible.builtin.command: repmgr -f /etc/repmgr.conf standby register + become: true + become_user: postgres + delegate_to: "{{ standby_ip }}" + remote_user: ubuntu + register: register_standby_results +- name: Print out the register_standby_results + ansible.builtin.debug: + msg: "repmgr {{ register_standby_results }}" - # run some sql... to confirm clone? - - name: Do some sql to test for the existence of lard...? - community.postgresql.postgresql_query: - db: lard - query: select count(*) from timeseries - register: query_results - become: true - become_user: postgres - delegate_to: '{{ standby_ip }}' - remote_user: ubuntu - - name: Print out the query - ansible.builtin.debug: - msg: "Query {{ query_results }}" +# run some sql... to confirm clone? +- name: Do some sql to test for the existence of lard...? + community.postgresql.postgresql_query: + db: lard + query: select count(*) from timeseries + register: query_results + become: true + become_user: postgres + delegate_to: "{{ standby_ip }}" + remote_user: ubuntu +- name: Print out the query + ansible.builtin.debug: + msg: "Query {{ query_results }}" diff --git a/ansible/roles/primarystandbysetup/tasks/main.yml b/ansible/roles/primarystandbysetup/tasks/main.yml index d1d6f048..964dffcd 100644 --- a/ansible/roles/primarystandbysetup/tasks/main.yml +++ b/ansible/roles/primarystandbysetup/tasks/main.yml @@ -1,7 +1,8 @@ +--- # roles/primarystandbysetup/tasks/main.yml - name: Turn a vm into the primary - import_tasks: create-primary.yml + ansible.builtin.import_tasks: create-primary.yml # note, may in the future want to make multiple standbys - name: Turn a vm into the standby - import_tasks: create-standby.yml + ansible.builtin.import_tasks: create-standby.yml diff --git a/ansible/roles/rejoin/tasks/main.yml b/ansible/roles/rejoin/tasks/main.yml index 82fad6c4..b2352916 100644 --- a/ansible/roles/rejoin/tasks/main.yml +++ b/ansible/roles/rejoin/tasks/main.yml @@ -1,3 +1,4 @@ +--- # roles/rejoin/tasks/main.yml - name: Rejoin an old primary to cluster as standby - import_tasks: rejoin_old_primary.yml + ansible.builtin.import_tasks: rejoin_old_primary.yml diff --git a/ansible/roles/rejoin/tasks/rejoin_old_primary.yml b/ansible/roles/rejoin/tasks/rejoin_old_primary.yml index e28d92ba..d387a2d2 100644 --- a/ansible/roles/rejoin/tasks/rejoin_old_primary.yml +++ b/ansible/roles/rejoin/tasks/rejoin_old_primary.yml @@ -1,39 +1,49 @@ ---- - - name: stop service postgres - ansible.builtin.systemd_service: - name: postgresql - state: stopped - become: true +--- +- name: Stop service postgres + ansible.builtin.systemd_service: + name: postgresql + state: stopped + become: true - - name: Dry run of rejoin - ansible.builtin.command: repmgr node rejoin -f /etc/repmgr.conf -d 'host='{{ primary_ip }}' user=repmgr dbname=repmgr connect_timeout=2' --force-rewind=/usr/lib/postgresql/16/bin/pg_rewind --verbose --dry-run - become: true - become_user: postgres - register: rejoin_dry_run_results - - name: Print out the rejoin_dry_run_results - ansible.builtin.debug: - msg: "repmgr {{ rejoin_dry_run_results }}" +# TODO: add changed_when to fix lint? +- name: Dry run of rejoin + ansible.builtin.command: > + repmgr node rejoin + -f /etc/repmgr.conf -d 'host='{{ primary_ip }}' user=repmgr dbname=repmgr connect_timeout=2' + --force-rewind=/usr/lib/postgresql/16/bin/pg_rewind --verbose --dry-run + become: true + become_user: postgres + register: rejoin_dry_run_results +- name: Print out the rejoin_dry_run_results + ansible.builtin.debug: + msg: "repmgr {{ rejoin_dry_run_results }}" - - name: Rejoin old primary as standby - ansible.builtin.command: repmgr node rejoin -f /etc/repmgr.conf -d 'host='{{ primary_ip }}' user=repmgr dbname=repmgr connect_timeout=2' --force-rewind=/usr/lib/postgresql/16/bin/pg_rewind --verbose - become: true - become_user: postgres - register: rejoin_results - - name: Print out the rejoin_results - ansible.builtin.debug: - msg: "repmgr {{ rejoin_results }}" - - - name: start service postgres - ansible.builtin.systemd_service: - name: postgresql - state: started - become: true +# TODO: add changed_when to fix lint? +- name: Rejoin old primary as standby + ansible.builtin.command: > + repmgr node rejoin + -f /etc/repmgr.conf -d 'host='{{ primary_ip }}' user=repmgr dbname=repmgr connect_timeout=2' + --force-rewind=/usr/lib/postgresql/16/bin/pg_rewind --verbose + become: true + become_user: postgres + register: rejoin_results +- name: Print out the rejoin_results + ansible.builtin.debug: + msg: "repmgr {{ rejoin_results }}" - - name: Check cluster - ansible.builtin.command: repmgr -f /etc/repmgr.conf cluster show - become: true - become_user: postgres - register: status_results - - name: Print out the status_results - ansible.builtin.debug: - msg: "repmgr {{ status_results }}" \ No newline at end of file +- name: Start service postgres + ansible.builtin.systemd_service: + name: postgresql + state: started + become: true + +# TODO: add changed_when to fix lint? +- name: Check cluster + ansible.builtin.command: repmgr -f /etc/repmgr.conf cluster show + become: true + become_user: postgres + register: status_results + +- name: Print out the status_results + ansible.builtin.debug: + msg: "repmgr {{ status_results }}" diff --git a/ansible/roles/ssh/tasks/main.yml b/ansible/roles/ssh/tasks/main.yml index 1f968d65..b5e71f38 100644 --- a/ansible/roles/ssh/tasks/main.yml +++ b/ansible/roles/ssh/tasks/main.yml @@ -1,3 +1,4 @@ +--- # roles/ssh/tasks/main.yml - name: Share the ssh keys one way between 2 particular VMs - import_tasks: share-ssh-keys.yml + ansible.builtin.import_tasks: share-ssh-keys.yml diff --git a/ansible/roles/ssh/tasks/share-ssh-keys.yml b/ansible/roles/ssh/tasks/share-ssh-keys.yml index 389f4b15..327eca80 100644 --- a/ansible/roles/ssh/tasks/share-ssh-keys.yml +++ b/ansible/roles/ssh/tasks/share-ssh-keys.yml @@ -1,60 +1,60 @@ --- - # find the other vm, that is not currently being iterated over (this will need to be changed if more than 2) - - name: Setting host facts for other_vm - ansible.builtin.set_fact: - other_vm: '{{ (ansible_play_hosts_all | difference([inventory_hostname])) | first }}' - - - name: List other vm - ansible.builtin.debug: - msg: "{{ other_vm }}" - - - name: Create user postgres - ansible.builtin.user: - name: postgres - generate_ssh_key: true - ssh_key_bits: 2048 - ssh_key_file: .ssh/id_rsa - force: true - register: ssh_keys - become: true - # Another way to generate a ssh key... - # - name: Force regenerate an OpenSSH keypair if it already exists - # community.crypto.openssh_keypair: - # path: .ssh/id_rsa - # force: true - # owner: postgres # should be this user's key - # register: ssh_keys - # become: true - - - name: List generated SSH key - ansible.builtin.debug: - msg: "{{ ssh_keys.ssh_public_key }}" - - - name: Add the key to authorized_key on the other vm - ansible.posix.authorized_key: - user: postgres - state: present - key: '{{ ssh_keys.ssh_public_key }}' - become: true - delegate_to: '{{ other_vm }}' - - - name: Get the host key - ansible.builtin.set_fact: - hostkey: '{{ ansible_ssh_host_key_ecdsa_public }}' - - - name: List host key - ansible.builtin.debug: - msg: "{{ hostkey }}" - - - name: List vm ip - ansible.builtin.debug: - msg: "{{ vm_ip }}" - - - name: Add the vm to known_hosts on the other vm - ansible.builtin.known_hosts: - path: ~postgres/.ssh/known_hosts # need this for the postgres user - name: '{{ vm_ip }}' - key: '{{ vm_ip }} ecdsa-sha2-nistp256 {{ hostkey }}' - state: present - become: true - delegate_to: '{{ other_vm }}' \ No newline at end of file +# find the other vm, that is not currently being iterated over (this will need to be changed if more than 2) +- name: Setting host facts for other_vm + ansible.builtin.set_fact: + other_vm: "{{ (ansible_play_hosts_all | difference([inventory_hostname])) | first }}" + +- name: List other vm + ansible.builtin.debug: + msg: "{{ other_vm }}" + +- name: Create user postgres + ansible.builtin.user: + name: postgres + generate_ssh_key: true + ssh_key_bits: 2048 + ssh_key_file: .ssh/id_rsa + force: true + register: ssh_keys + become: true +# Another way to generate a ssh key... +# - name: Force regenerate an OpenSSH keypair if it already exists +# community.crypto.openssh_keypair: +# path: .ssh/id_rsa +# force: true +# owner: postgres # should be this user's key +# register: ssh_keys +# become: true + +- name: List generated SSH key + ansible.builtin.debug: + msg: "{{ ssh_keys.ssh_public_key }}" + +- name: Add the key to authorized_key on the other vm + ansible.posix.authorized_key: + user: postgres + state: present + key: "{{ ssh_keys.ssh_public_key }}" + become: true + delegate_to: "{{ other_vm }}" + +- name: Get the host key + ansible.builtin.set_fact: + hostkey: "{{ ansible_ssh_host_key_ecdsa_public }}" + +- name: List host key + ansible.builtin.debug: + msg: "{{ hostkey }}" + +- name: List vm ip + ansible.builtin.debug: + msg: "{{ vm_ip }}" + +- name: Add the vm to known_hosts on the other vm + ansible.builtin.known_hosts: + path: ~postgres/.ssh/known_hosts # need this for the postgres user + name: "{{ vm_ip }}" + key: "{{ vm_ip }} ecdsa-sha2-nistp256 {{ hostkey }}" + state: present + become: true + delegate_to: "{{ other_vm }}" diff --git a/ansible/roles/switchover/tasks/main.yml b/ansible/roles/switchover/tasks/main.yml index 0fab67d6..8c68fd75 100644 --- a/ansible/roles/switchover/tasks/main.yml +++ b/ansible/roles/switchover/tasks/main.yml @@ -1,4 +1,4 @@ +--- # roles/switchover/tasks/main.yml - name: Switchover - import_tasks: switchover.yml - + ansible.builtin.import_tasks: switchover.yml diff --git a/ansible/roles/switchover/tasks/switchover.yml b/ansible/roles/switchover/tasks/switchover.yml index 1573d7a1..00eec259 100644 --- a/ansible/roles/switchover/tasks/switchover.yml +++ b/ansible/roles/switchover/tasks/switchover.yml @@ -1,60 +1,62 @@ +--- # assume the db is already there and synched, so now want to turn into a standby / replica # and want to turn the current standby into the primary ---- - - name: Restart service postgres (primary) - ansible.builtin.systemd_service: - name: postgresql - state: restarted - become: true - delegate_to: '{{ primary_ip }}' - remote_user: ubuntu +- name: Restart service postgres (primary) + ansible.builtin.systemd_service: + name: postgresql + state: restarted + become: true + delegate_to: "{{ primary_ip }}" + remote_user: ubuntu - # try to avoid issue: https://github.com/EnterpriseDB/repmgr/issues/703 - - name: Restart service postgres (standby) - ansible.builtin.systemd_service: - name: postgresql - state: restarted - become: true - delegate_to: '{{ standby_ip }}' - remote_user: ubuntu +# try to avoid issue: https://github.com/EnterpriseDB/repmgr/issues/703 +- name: Restart service postgres (standby) + ansible.builtin.systemd_service: + name: postgresql + state: restarted + become: true + delegate_to: "{{ standby_ip }}" + remote_user: ubuntu - # can now just do this with repmgr - # https://www.repmgr.org/docs/current/preparing-for-switchover.html - # need the two instances to be able to ssh to each other! - # siblings-follow only really needed if have multiple standbys... - - name: Dry run of switching the standby and primary - ansible.builtin.command: repmgr standby switchover -f /etc/repmgr.conf --siblings-follow --dry-run - become: true - become_user: postgres - delegate_to: '{{ standby_ip }}' - remote_user: ubuntu - register: switchover_dry_run_results - - name: Print out the switchover_dry_run_results - ansible.builtin.debug: - msg: "repmgr {{ switchover_dry_run_results }}" - ## see preparing for switchover if things go wrong despite dry run, there is mention of --force-rewind - ## which would use pg_rewind to try to fix divergent timelines... +# can now just do this with repmgr +# https://www.repmgr.org/docs/current/preparing-for-switchover.html +# need the two instances to be able to ssh to each other! +# siblings-follow only really needed if have multiple standbys... +- name: Dry run of switching the standby and primary + ansible.builtin.command: repmgr standby switchover -f /etc/repmgr.conf --siblings-follow --dry-run + become: true + become_user: postgres + delegate_to: "{{ standby_ip }}" + remote_user: ubuntu + register: switchover_dry_run_results - ## https://www.repmgr.org/docs/current/switchover-execution.html - ## https://www.repmgr.org/docs/current/switchover-troubleshooting.html - - name: Switch the standby and primary - ansible.builtin.command: repmgr standby switchover -f /etc/repmgr.conf --siblings-follow - become: true - become_user: postgres - delegate_to: '{{ standby_ip }}' - remote_user: ubuntu - register: switchover_results - - name: Print out the switchover_results - ansible.builtin.debug: - msg: "repmgr {{ switchover_results }}" +- name: Print out the switchover_dry_run_results + ansible.builtin.debug: + msg: "repmgr {{ switchover_dry_run_results }}" +## see preparing for switchover if things go wrong despite dry run, there is mention of --force-rewind +## which would use pg_rewind to try to fix divergent timelines... - - name: Check cluster - ansible.builtin.command: repmgr -f /etc/repmgr.conf cluster show - become: true - become_user: postgres - delegate_to: '{{ standby_ip }}' - remote_user: ubuntu - register: status_results - - name: Print out the status_results - ansible.builtin.debug: - msg: "repmgr {{ status_results }}" +## https://www.repmgr.org/docs/current/switchover-execution.html +## https://www.repmgr.org/docs/current/switchover-troubleshooting.html +- name: Switch the standby and primary + ansible.builtin.command: repmgr standby switchover -f /etc/repmgr.conf --siblings-follow + become: true + become_user: postgres + delegate_to: "{{ standby_ip }}" + remote_user: ubuntu + register: switchover_results +- name: Print out the switchover_results + ansible.builtin.debug: + msg: "repmgr {{ switchover_results }}" + +- name: Check cluster + ansible.builtin.command: repmgr -f /etc/repmgr.conf cluster show + become: true + become_user: postgres + delegate_to: "{{ standby_ip }}" + remote_user: ubuntu + register: status_results + +- name: Print out the status_results + ansible.builtin.debug: + msg: "repmgr {{ status_results }}" diff --git a/ansible/roles/vm/tasks/create-project-vm.yml b/ansible/roles/vm/tasks/create-project-vm.yml index 408d14cf..12673cf3 100644 --- a/ansible/roles/vm/tasks/create-project-vm.yml +++ b/ansible/roles/vm/tasks/create-project-vm.yml @@ -1,89 +1,89 @@ ---- - - name: Create VM - openstack.cloud.server: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - availability_zone: '{{ availability_zone }}' - name: '{{ name_stuff }}' - image: '{{ ostack_image }}' - flavor: '{{ ostack_flavor }}' - network: '{{ ostack_network_name }}' - key_name: '{{ ostack_key_name }}' - security_groups: '{{ security_groups_list }}' - state: '{{ ostack_state }}' - # do not give ip, since want to assign a specific one in next step (so as to reuse the ones we have) - auto_ip: false - register: server +--- +- name: Create VM + openstack.cloud.server: + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + availability_zone: "{{ availability_zone }}" + name: "{{ name_stuff }}" + image: "{{ ostack_image }}" + flavor: "{{ ostack_flavor }}" + network: "{{ ostack_network_name }}" + key_name: "{{ ostack_key_name }}" + security_groups: "{{ security_groups_list }}" + state: "{{ ostack_state }}" + # do not give ip, since want to assign a specific one in next step (so as to reuse the ones we have) + auto_ip: false + register: server - - name: Print out the server information - ansible.builtin.debug: - msg: "Server {{ lookup('ansible.builtin.dict', server) }}" +- name: Print out the server information + ansible.builtin.debug: + msg: "Server {{ lookup('ansible.builtin.dict', server) }}" - - name: Attach floating ip address - openstack.cloud.floating_ip: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - server: '{{ server.server.id }}' - reuse: true - network: public - floating_ip_address: '{{ vm_ip }}' - wait: true - timeout: 60 +- name: Attach floating ip address + openstack.cloud.floating_ip: + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + server: "{{ server.server.id }}" + reuse: true + network: public + floating_ip_address: "{{ vm_ip }}" + wait: true + timeout: 60 - - name: Create Volume - openstack.cloud.volume: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - availability_zone: '{{ availability_zone }}' - name: '{{ name_stuff }}' - volume_type: '{{ volume_type }}' - size: '{{ volume_size }}' - register: volume +- name: Create Volume + openstack.cloud.volume: + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + availability_zone: "{{ availability_zone }}" + name: "{{ name_stuff }}" + volume_type: "{{ volume_type }}" + size: "{{ volume_size }}" + register: volume - - name: Print out the volume information - ansible.builtin.debug: - msg: "Volume {{ lookup('ansible.builtin.dict', volume) }}" +- name: Print out the volume information + ansible.builtin.debug: + msg: "Volume {{ lookup('ansible.builtin.dict', volume) }}" - - name: Attach a volume to a compute host - openstack.cloud.server_volume: - state: present - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - volume: '{{ volume.volume.id }}' - server: '{{ server.server.id }}' - device: /dev/vdb +- name: Attach a volume to a compute host + openstack.cloud.server_volume: + state: present + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + volume: "{{ volume.volume.id }}" + server: "{{ server.server.id }}" + device: /dev/vdb - - name: Create port for ipalias and set security groups - openstack.cloud.port: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - state: present - name: 'ipalias-{{ name_stuff }}' - network: '{{ ipalias_network_name }}' - security_groups: '{{ security_groups_list }}' +- name: Create port for ipalias and set security groups + openstack.cloud.port: + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + state: present + name: "ipalias-{{ name_stuff }}" + network: "{{ ipalias_network_name }}" + security_groups: "{{ security_groups_list }}" - - name: Get port info - openstack.cloud.port_info: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - port: 'ipalias-{{ name_stuff }}' - register: ipalias_port +- name: Get port info + openstack.cloud.port_info: + cloud: "{{ ostack_cloud }}" + region_name: "{{ ostack_region }}" + port: "ipalias-{{ name_stuff }}" + register: ipalias_port - - name: Print out the port information - ansible.builtin.debug: - msg: "Port {{ lookup('ansible.builtin.dict', ipalias_port) }}" +- name: Print out the port information + ansible.builtin.debug: + msg: "Port {{ lookup('ansible.builtin.dict', ipalias_port) }}" - - name: Add the ipalias network to server - ansible.builtin.command: # noqa no-changed-when - argv: - - openstack - - --os-cloud - - '{{ ostack_cloud }}' - - --os-region-name - - '{{ ostack_region }}' - - server - - add - - port - - '{{ server.server.id }}' - - 'ipalias-{{ name_stuff }}' - when: ipalias_port.ports.0.device_id | length <=0 +- name: Add the ipalias network to server + ansible.builtin.command: # noqa no-changed-when + argv: + - openstack + - --os-cloud + - "{{ ostack_cloud }}" + - --os-region-name + - "{{ ostack_region }}" + - server + - add + - port + - "{{ server.server.id }}" + - "ipalias-{{ name_stuff }}" + when: ipalias_port.ports.0.device_id | length <=0 diff --git a/ansible/roles/vm/tasks/main.yml b/ansible/roles/vm/tasks/main.yml index 589fc0ef..1bdd7a27 100644 --- a/ansible/roles/vm/tasks/main.yml +++ b/ansible/roles/vm/tasks/main.yml @@ -1,4 +1,4 @@ +--- # roles/vms/tasks/main.yml - name: Create a VM - import_tasks: create-project-vm.yml - + ansible.builtin.import_tasks: create-project-vm.yml diff --git a/ansible/roles/vm/vars/main.yml b/ansible/roles/vm/vars/main.yml index d079f5bd..4be7336c 100644 --- a/ansible/roles/vm/vars/main.yml +++ b/ansible/roles/vm/vars/main.yml @@ -1,12 +1,13 @@ - # VM config - ostack_flavor: m1.xxlarge - ostack_image: met-jammy-latest - ostack_state: present - ostack_network_name: lard - security_groups_list: - - default - - ssh_usernet - - postgres - - ping - volume_type: __DEFAULT__ - volume_size: 900 \ No newline at end of file +# VM config +--- +vm_ostack_flavor: m1.xxlarge +vm_ostack_image: met-jammy-latest +vm_ostack_state: present +vm_ostack_network_name: lard +vm_security_groups_list: + - default + - ssh_usernet + - postgres + - ping +vm_volume_type: __DEFAULT__ +vm_volume_size: 900 diff --git a/ansible/roles/vm_format/tasks/format-mount-disk.yml b/ansible/roles/vm_format/tasks/format-mount-disk.yml index 5917fa77..5d6d20a3 100644 --- a/ansible/roles/vm_format/tasks/format-mount-disk.yml +++ b/ansible/roles/vm_format/tasks/format-mount-disk.yml @@ -1,45 +1,45 @@ --- - - name: Create /mnt/ssd-data - ansible.builtin.file: - path: /mnt/ssd-data - state: directory - owner: ubuntu # change to postgres? - group: ubuntu # change to postgres? - mode: 'u=rw,g=rws,o=r' - become: true +- name: Create /mnt/ssd-data + ansible.builtin.file: + path: /mnt/ssd-data + state: directory + owner: ubuntu # change to postgres? + group: ubuntu # change to postgres? + mode: 'u=rw,g=rws,o=r' + become: true - - name: Create ext4 filesystem on {{ mount_point }} - community.general.filesystem: - dev: '{{ mount_point }}' - fstype: ext4 - become: true +- name: Create ext4 filesystem on {{ mount_point }} + community.general.filesystem: + dev: '{{ mount_point }}' + fstype: ext4 + become: true - - name: Read device information (always use unit when probing) - community.general.parted: - device: '{{ mount_point }}' - unit: MiB - register: sdb_info - become: true +- name: Read device information (always use unit when probing) + community.general.parted: + device: '{{ mount_point }}' + unit: MiB + register: sdb_info + become: true - - name: Print out the device information - ansible.builtin.debug: - msg: "Partitions {{ sdb_info.partitions }}" +- name: Print out the device information + ansible.builtin.debug: + msg: "Partitions {{ sdb_info.partitions }}" - # this also changes the fstab so its still there when rebooted! - - name: Mount the disk from {{ mount_point }} - ansible.posix.mount: - path: /mnt/ssd-data - src: '{{ mount_point }}' - fstype: ext4 - state: mounted - become: true +# this also changes the fstab so its still there when rebooted! +- name: Mount the disk from {{ mount_point }} + ansible.posix.mount: + path: /mnt/ssd-data + src: '{{ mount_point }}' + fstype: ext4 + state: mounted + become: true - - name: Fetch the UUID of {{ mount_point }} - ansible.builtin.command: blkid --match-tag UUID --output value '{{ mount_point }}' - changed_when: false - register: blkid_cmd - become: true +- name: Fetch the UUID of {{ mount_point }} + ansible.builtin.command: blkid --match-tag UUID --output value '{{ mount_point }}' + changed_when: false + register: blkid_cmd + become: true - - name: Print out the UUID - ansible.builtin.debug: - msg: "UUID {{ blkid_cmd.stdout }}" +- name: Print out the UUID + ansible.builtin.debug: + msg: "UUID {{ blkid_cmd.stdout }}" diff --git a/ansible/roles/vm_format/tasks/install-postgres.yml b/ansible/roles/vm_format/tasks/install-postgres.yml index 58642405..6d2d5184 100644 --- a/ansible/roles/vm_format/tasks/install-postgres.yml +++ b/ansible/roles/vm_format/tasks/install-postgres.yml @@ -1,136 +1,136 @@ --- - - name: Add postgres apt key by id from a keyserver - ansible.builtin.apt_key: - url: https://www.postgresql.org/media/keys/ACCC4CF8.asc - state: present - become: true - - - name: Add postgres repository into sources list - ansible.builtin.apt_repository: - repo: deb https://apt.postgresql.org/pub/repos/apt jammy-pgdg main - state: present - become: true - - - name: Install a list of packages - ansible.builtin.apt: - pkg: - - nano - - postgresql-16 - - postgresql-16-repmgr # https://www.repmgr.org/docs/current/install-requirements.html - - pip # needed for installing psycopg2 - - acl # needed for becoming unpriveleged user (such as postgres) - update_cache: true - become: true - - - name: Install psycopg2 python package # dependency for postgres ansible stuff? - ansible.builtin.pip: - name: psycopg2-binary - become: true - - - name: Install openstacksdk python package - ansible.builtin.pip: - name: openstacksdk - become: true - - # make is so the data is actually kept on the ssd mount... - - ### synch the postgres stuff over to new directory, but stop postgres first - - name: Stop service postgres, if running - ansible.builtin.systemd_service: - name: postgresql - state: stopped - become: true - - - name: Run rsync - ansible.builtin.command: rsync -av /var/lib/postgresql/ /mnt/ssd-b/ - become: true - - ## change where data is stored and open up network wise - - name: Comment out original data_directory - ansible.builtin.replace: - dest: /etc/postgresql/16/main/postgresql.conf - regexp: '^data_directory' - replace: '#data_directory' - become: true - - - name: Modify postgresql config - ansible.builtin.blockinfile: - dest: /etc/postgresql/16/main/postgresql.conf - block: | - data_directory = '/mnt/ssd-b/16/main' - listen_addresses = '*' - become: true - - # probably want to restrict this once we know what will connect? - # but the security group rules should take care of limiting to met ranges - - name: Change hba conf to allow connections - community.postgresql.postgresql_pg_hba: - dest: /etc/postgresql/16/main/pg_hba.conf - contype: host - address: all # can we put met internal ip range(s)? - method: md5 - # users and database default to all - become: true - - # make sure these changes take effect - - name: Start up postgres service again - ansible.builtin.systemd_service: - name: postgresql - state: started - become: true - - # REPMGR - - name: Create repmgr user # https://www.repmgr.org/docs/current/quickstart-repmgr-user-database.html - community.postgresql.postgresql_user: - name: repmgr - password: '{{ repmgr_password }}' - role_attr_flags: SUPERUSER - become: true - become_user: postgres - - - name: Create a repmgr database, with owner repmgr - community.postgresql.postgresql_db: - name: repmgr - owner: repmgr - become: true - become_user: postgres - - - name: Change hba conf to allow repmgr to connect for replication - community.postgresql.postgresql_pg_hba: - dest: /etc/postgresql/16/main/pg_hba.conf - databases: replication - contype: host - users: repmgr - address: all - # address: '{{ standby_host }}' - method: trust - become: true - - - name: Change hba conf to allow repmgr to connect to the repmgr db - community.postgresql.postgresql_pg_hba: - dest: /etc/postgresql/16/main/pg_hba.conf - databases: repmgr - contype: host - users: repmgr - address: all - # address: '{{ standby_host }}' - method: trust - become: true - - - name: Restart postgres - ansible.builtin.systemd_service: - name: postgresql - state: restarted - become: true - - - name: Allow the postgres user to run /bin/systemctl restart, stop, start postgres - community.general.sudoers: - name: postgresql - user: postgres - commands: - - /bin/systemctl restart postgresql.service - - /bin/systemctl stop postgresql.service - - /bin/systemctl start postgresql.service - - /bin/systemctl reload postgresql.service - nopassword: true - become: true +- name: Add postgres apt key by id from a keyserver + ansible.builtin.apt_key: + url: https://www.postgresql.org/media/keys/ACCC4CF8.asc + state: present + become: true + +- name: Add postgres repository into sources list + ansible.builtin.apt_repository: + repo: deb https://apt.postgresql.org/pub/repos/apt jammy-pgdg main + state: present + become: true + +- name: Install a list of packages + ansible.builtin.apt: + pkg: + - nano + - postgresql-16 + - postgresql-16-repmgr # https://www.repmgr.org/docs/current/install-requirements.html + - pip # needed for installing psycopg2 + - acl # needed for becoming unpriveleged user (such as postgres) + update_cache: true + become: true + +- name: Install psycopg2 python package # dependency for postgres ansible stuff? + ansible.builtin.pip: + name: psycopg2-binary + become: true + +- name: Install openstacksdk python package + ansible.builtin.pip: + name: openstacksdk + become: true + +# make is so the data is actually kept on the ssd mount... + +### synch the postgres stuff over to new directory, but stop postgres first +- name: Stop service postgres, if running + ansible.builtin.systemd_service: + name: postgresql + state: stopped + become: true + +- name: Run rsync + ansible.builtin.command: rsync -av /var/lib/postgresql/ /mnt/ssd-b/ + become: true + +## change where data is stored and open up network wise +- name: Comment out original data_directory + ansible.builtin.replace: + dest: /etc/postgresql/16/main/postgresql.conf + regexp: '^data_directory' + replace: '#data_directory' + become: true + +- name: Modify postgresql config + ansible.builtin.blockinfile: + dest: /etc/postgresql/16/main/postgresql.conf + block: | + data_directory = '/mnt/ssd-b/16/main' + listen_addresses = '*' + become: true + +# probably want to restrict this once we know what will connect? +# but the security group rules should take care of limiting to met ranges +- name: Change hba conf to allow connections + community.postgresql.postgresql_pg_hba: + dest: /etc/postgresql/16/main/pg_hba.conf + contype: host + address: all # can we put met internal ip range(s)? + method: md5 + # users and database default to all + become: true + +# make sure these changes take effect +- name: Start up postgres service again + ansible.builtin.systemd_service: + name: postgresql + state: started + become: true + +# REPMGR +- name: Create repmgr user # https://www.repmgr.org/docs/current/quickstart-repmgr-user-database.html + community.postgresql.postgresql_user: + name: repmgr + password: '{{ repmgr_password }}' + role_attr_flags: SUPERUSER + become: true + become_user: postgres + +- name: Create a repmgr database, with owner repmgr + community.postgresql.postgresql_db: + name: repmgr + owner: repmgr + become: true + become_user: postgres + +- name: Change hba conf to allow repmgr to connect for replication + community.postgresql.postgresql_pg_hba: + dest: /etc/postgresql/16/main/pg_hba.conf + databases: replication + contype: host + users: repmgr + address: all + # address: '{{ standby_host }}' + method: trust + become: true + +- name: Change hba conf to allow repmgr to connect to the repmgr db + community.postgresql.postgresql_pg_hba: + dest: /etc/postgresql/16/main/pg_hba.conf + databases: repmgr + contype: host + users: repmgr + address: all + # address: '{{ standby_host }}' + method: trust + become: true + +- name: Restart postgres + ansible.builtin.systemd_service: + name: postgresql + state: restarted + become: true + +- name: Allow the postgres user to run /bin/systemctl restart, stop, start postgres + community.general.sudoers: + name: postgresql + user: postgres + commands: + - /bin/systemctl restart postgresql.service + - /bin/systemctl stop postgresql.service + - /bin/systemctl start postgresql.service + - /bin/systemctl reload postgresql.service + nopassword: true + become: true diff --git a/ansible/roles/vm_format/tasks/main.yml b/ansible/roles/vm_format/tasks/main.yml index 36d09ebb..13f7b39f 100644 --- a/ansible/roles/vm_format/tasks/main.yml +++ b/ansible/roles/vm_format/tasks/main.yml @@ -1,9 +1,10 @@ +--- # roles/vm_format/tasks/main.yml - name: netplan - import_tasks: netplan.yml - -- name: Format and mount the disk - import_tasks: format-mount-disk.yml + ansible.builtin.import_tasks: netplan.yml + +- name: Format and mount the disk + ansible.builtin.import_tasks: format-mount-disk.yml - name: Install postgres - import_tasks: install-postgres.yml \ No newline at end of file + ansible.builtin.import_tasks: install-postgres.yml diff --git a/ansible/roles/vm_format/tasks/netplan.yml b/ansible/roles/vm_format/tasks/netplan.yml index 118cb065..65df3bfb 100644 --- a/ansible/roles/vm_format/tasks/netplan.yml +++ b/ansible/roles/vm_format/tasks/netplan.yml @@ -1,61 +1,59 @@ --- - - name: Get port info - openstack.cloud.port_info: - cloud: '{{ ostack_cloud }}' - region_name: '{{ ostack_region }}' - port: 'ipalias-{{ name_stuff }}' - register: ipalias_port - delegate_to: localhost +- name: Get port info + openstack.cloud.port_info: + cloud: '{{ ostack_cloud }}' + region_name: '{{ ostack_region }}' + port: 'ipalias-{{ name_stuff }}' + register: ipalias_port + delegate_to: localhost - - name: Print out the port information - ansible.builtin.debug: - msg: "Port {{ lookup('ansible.builtin.dict', ipalias_port) }}" - delegate_to: localhost +- name: Print out the port information + ansible.builtin.debug: + msg: "Port {{ lookup('ansible.builtin.dict', ipalias_port) }}" + delegate_to: localhost - - name: IP alias netplan configuration - ansible.builtin.set_fact: - netplan_config: - network: - version: 2 - ethernets: - ens6: - dhcp4: true - dhcp4-overrides: - use-routes: false - match: - macaddress: '{{ ipalias_port.ports.0.mac_address }}' - set-name: ens6 - routes: - - to: 0.0.0.0/0 - via: '{{ ipalias_ostack_network_cidr | ansible.utils.ipaddr("net") | ansible.utils.ipaddr("1") | ansible.utils.ipaddr("address") }}' - table: 102 - routing-policy: - - from: '{{ ipalias_ostack_network_cidr }}' - table: 102 - become: true +- name: IP alias netplan configuration + ansible.builtin.set_fact: + netplan_config: + network: + version: 2 + ethernets: + ens6: + dhcp4: true + dhcp4-overrides: + use-routes: false + match: + macaddress: '{{ ipalias_port.ports.0.mac_address }}' + set-name: ens6 + routes: + - to: 0.0.0.0/0 + via: '{{ ipalias_ostack_network_cidr | ansible.utils.ipaddr("net") | ansible.utils.ipaddr("1") | ansible.utils.ipaddr("address") }}' + table: 102 + routing-policy: + - from: '{{ ipalias_ostack_network_cidr }}' + table: 102 + become: true - - name: Copy out ipalias netplan config - ansible.builtin.copy: - content: '{{ netplan_config | to_nice_yaml }}' - dest: /etc/netplan/90-ansible-ipalias.yaml - mode: '0644' - register: netplan_config - become: true +- name: Copy out ipalias netplan config + ansible.builtin.copy: + content: '{{ netplan_config | to_nice_yaml }}' + dest: /etc/netplan/90-ansible-ipalias.yaml + mode: '0644' + register: netplan_config + become: true - - name: Print out netplan config - ansible.builtin.debug: - msg: "Netplan {{ netplan_config }}" - - - name: Apply netplan - ansible.builtin.command: sudo netplan apply - async: 45 - poll: 0 - -# https://gitlab.met.no/ansible-roles/ipalias/-/blob/master/tasks/netplan.yml?ref_type=heads -# this times out and then the servers are uncreachable? -# - name: Reboot server to apply new netplan config, without hitting netplan bug -# ansible.builtin.reboot: # noqa no-handler +- name: Print out netplan config + ansible.builtin.debug: + msg: "Netplan {{ netplan_config }}" + # https://gitlab.met.no/ansible-roles/ipalias/-/blob/master/tasks/netplan.yml?ref_type=heads + # this times out and then the servers are uncreachable? + # - name: Reboot server to apply new netplan config, without hitting netplan bug + # ansible.builtin.reboot: # noqa no-handler # reboot_timeout: 3600 -# when: netplan_config is changed -# become: true - \ No newline at end of file + # when: netplan_config is changed + # become: true + +- name: Apply netplan + ansible.builtin.command: sudo netplan apply + async: 45 + poll: 0 diff --git a/ansible/switchover.yml b/ansible/switchover.yml index 48c7ec6b..e7cd16c4 100644 --- a/ansible/switchover.yml +++ b/ansible/switchover.yml @@ -1,3 +1,4 @@ +--- - name: Switch the primary and standby / replica hosts: localhost vars: @@ -5,15 +6,17 @@ ostack_region: Ostack2-EXT gather_facts: false pre_tasks: - - name: find primary ip from inventory + - name: Find primary ip from inventory ansible.builtin.set_fact: - primary_ip: '{{ item }}' - with_inventory_hostnames: '{{ name_primary }}' - - name: find standby ip from inventory + primary_ip: "{{ item }}" + with_inventory_hostnames: "{{ name_primary }}" + + - name: Find standby ip from inventory ansible.builtin.set_fact: - standby_ip: '{{ item }}' - with_inventory_hostnames: '{{ name_standby }}' + standby_ip: "{{ item }}" + with_inventory_hostnames: "{{ name_standby }}" + roles: # ensure the names are passed in the right way around for the current state! - - role: switchover - - role: movefloatingip \ No newline at end of file + - role: switchover + - role: movefloatingip diff --git a/ingestion/src/main.rs b/ingestion/src/main.rs index cabb6526..af176d23 100644 --- a/ingestion/src/main.rs +++ b/ingestion/src/main.rs @@ -15,7 +15,7 @@ async fn main() -> Result<(), Box> { if args.len() != 2 { panic!( - "USAGE: lard_ingestion \nEnv vars LARD_STRING and STINFO_STRING are also needed" + "USAGE: lard_ingestion \nEnv vars LARD_CONN_STRING and STINFO_CONN_STRING are also needed" // env var format: host={} user={} dbname={} ... ) } @@ -44,7 +44,7 @@ async fn main() -> Result<(), Box> { // Set up postgres connection pool let manager = - PostgresConnectionManager::new_from_stringlike(std::env::var("LARD_STRING")?, NoTls)?; + PostgresConnectionManager::new_from_stringlike(std::env::var("LARD_CONN_STRING")?, NoTls)?; let db_pool = bb8::Pool::builder().build(manager).await?; // Spawn kvkafka reader diff --git a/ingestion/src/permissions.rs b/ingestion/src/permissions.rs index 7489bddb..4f2c7f18 100644 --- a/ingestion/src/permissions.rs +++ b/ingestion/src/permissions.rs @@ -41,7 +41,8 @@ pub type StationPermitTable = HashMap; /// Get a fresh cache of permits from stinfosys pub async fn fetch_permits() -> Result<(ParamPermitTable, StationPermitTable), Error> { // get stinfo conn - let (client, conn) = tokio_postgres::connect(&std::env::var("STINFO_STRING")?, NoTls).await?; + let (client, conn) = + tokio_postgres::connect(&std::env::var("STINFO_CONN_STRING")?, NoTls).await?; // conn object independently performs communication with database, so needs it's own task. // it will return when the client is dropped