I do want to apply migrations when fetching build artifact with ansible.
Some facts:
- Migrations are pure-sql
- Postresql is in cluster mode (no sharding)
- There are 2 hosts (api1 and api2)
- No "down-mechanics" required
Possible problems:
- How to choose which host should run migration (first ready or always primary)?
- How to track already applied scripts and avoid double applience?
My thoughts about how to solve this:
Using fs-layer:
- Every build artifact would contain sql-migrations
- Once deployed, primary host should diff existing migration files with new ones and apply new ones, save state by replacement old files with new ones
- Migrations are executed with
community.postgresql.postgresql_query
This way looks weird - fs is not reliable in my opinion and primary host can change (be destroed and etc.)
Using database:
- Every build artifact would contain sql-migrations
- Once deployed, first-ready host should query some table for applied migrations and apply new ones, save state by
community.postgresql.postgresql_queryinserting new migration names
This way looks better - db is still reliable, but is it possible using ansible?
I'm not familiar with python, so i can't accept solutions like "Write your own plugin" - I won't be able to support it in the future. And any NPM packages is not preferred, i'm limited to compiled solutions and built-in linux tools like python, bash, etc.
btw, playbook looks like:
---
- hosts: api
vars:
api_apps:
- name: "Api"
description: "API service"
exec: "/usr/local/bin/handler"
identifier: "handler"
env:
- name: PORT
value: "3000"
- name: DB_TYPE
value: 'postgres'
- name: DB_PATH
value: "postgres://{{hostvars['db01'].postgresql_users[0].name}}:{{hostvars['db01'].postgresql_users[0].pass}}@{{hostvars['db01'].private_ip}}:{{hostvars['db01'].postgresql_port}}/{{hostvars['db01'].postgresql_databases[0].name}}"
- name: ACCESS_CONTROL_ALLOW_ORIGIN
value: "\"*""
- name: ACCESS_CONTROL_MAX_AGE
value: 9600
tasks:
- block: # Pull and extract artifacts
- name: "[ api ] Pull release info"
uri:
url: "https://api.github.com/repos/<my_profile>/{{ item }}/releases/latest"
headers:
Authorization: "Bearer {{ github_token }}"
return_content: true
register: release_response
no_log: True
with_items:
- "<my_private_repo>"
- name: "[ api ] Pull latest artifact"
get_url:
url: "{{ item.json.assets[0].url }}"
headers:
Accept: "application\/octet-stream"
Authorization: "Bearer {{ github_token }}"
force: true
dest: "/tmp/{{ item.item }}.zip"
no_log: True
register: pulled_items
with_items: "{{ release_response.results }}"
- name: Extract archives
unarchive:
src: "/tmp/{{ item.item.item }}.zip"
dest: "/usr/local/bin"
remote_src: yes
no_log: True
with_items: "{{ pulled_items.results }}"
- name: create service templates
template:
src: "files/api/service.j2"
dest: "/etc/systemd/system/{{item.identifier}}.service"
with_items: "{{ api_apps }}"
no_log: False
- name: Start services
systemd:
state: restarted
daemon_reload: yes
name: "{{item.identifier}}"
with_items: "{{api_apps}}"