178 lines
6.8 KiB
YAML
178 lines
6.8 KiB
YAML
---
|
|
- name: Setup Postgres
|
|
hosts: postgres
|
|
gather_facts: yes
|
|
become: false
|
|
|
|
vars:
|
|
app: "{{ postgres }}"
|
|
app_name: postgres
|
|
postgres_container_name: "{{ postgres.dockercompose.services.postgres.container_name }}"
|
|
|
|
tasks:
|
|
- name: Deploy postgres Docker Compose configuration
|
|
include_role:
|
|
name: arcodange.factory.deploy_docker_compose
|
|
vars:
|
|
dockercompose_content: "{{ app.dockercompose }}"
|
|
app_owner: "{{ app.owner | default('pi') }}"
|
|
app_group: "{{ app.group | default('docker') }}"
|
|
|
|
- name: Deploy PostgreSQL
|
|
include_role:
|
|
name: deploy_postgresql
|
|
vars:
|
|
applications_databases:
|
|
gitea: "{{ gitea_database }}"
|
|
|
|
- name: Create auth_user for pgbouncer (connection pool component)
|
|
ansible.builtin.shell: |
|
|
docker exec -it {{ postgres_container_name }} psql -U postgres -d {{ database }} -tc "{{ pg_instruction.replace('$','\$') }}"
|
|
vars:
|
|
pg_instructions:
|
|
- >-
|
|
DO $$
|
|
BEGIN
|
|
CREATE ROLE {{ pgbouncer.auth_user }}
|
|
WITH LOGIN PASSWORD '{{ pgbouncer.auth_user_password }}';
|
|
EXCEPTION WHEN duplicate_object THEN RAISE NOTICE '%, skipping', SQLERRM USING ERRCODE = SQLSTATE;
|
|
END
|
|
$$;
|
|
- >-
|
|
CREATE OR REPLACE FUNCTION user_lookup(in i_username text, out uname text, out phash text)
|
|
RETURNS record AS $$
|
|
BEGIN
|
|
SELECT usename, passwd FROM pg_catalog.pg_shadow
|
|
WHERE usename = i_username INTO uname, phash;
|
|
RETURN;
|
|
END;
|
|
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
REVOKE ALL ON FUNCTION user_lookup FROM public;
|
|
GRANT EXECUTE ON FUNCTION user_lookup TO {{ pgbouncer.auth_user }};
|
|
database: "{{ database__pg_instruction[0] }}"
|
|
pg_instruction: "{{ database__pg_instruction[1] }}"
|
|
loop_control:
|
|
loop_var: database__pg_instruction
|
|
loop:
|
|
"{{ ['postgres', 'gitea'] | product(pg_instructions) }}"
|
|
|
|
# ---
|
|
|
|
- name: Change table owner (CronJob with dynamic roles and auto DB naming)
|
|
hosts: localhost
|
|
connection: local
|
|
gather_facts: false
|
|
|
|
collections:
|
|
- kubernetes.core
|
|
|
|
vars:
|
|
|
|
namespace: kube-system
|
|
cronjob_name: pg-fix-table-ownership
|
|
|
|
pg_conf: >-
|
|
{{ hostvars[groups.postgres[0]].postgres.dockercompose.services.postgres.environment }}
|
|
postgres_admin_credentials:
|
|
username: '{{ pg_conf.POSTGRES_USER }}'
|
|
password: '{{ pg_conf.POSTGRES_PASSWORD }}'
|
|
pg_host: "{{ hostvars[groups.postgres[0]]['preferred_ip'] }}"
|
|
|
|
tasks:
|
|
|
|
- name: Create Kubernetes Secret for PostgreSQL admin credentials
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: v1
|
|
kind: Secret
|
|
metadata:
|
|
name: postgres-admin-credentials
|
|
namespace: "{{ namespace }}"
|
|
type: Opaque
|
|
data:
|
|
username: "{{ postgres_admin_credentials.username | b64encode }}"
|
|
password: "{{ postgres_admin_credentials.password | b64encode }}"
|
|
|
|
- name: Create cronjob to change table owners (dynamic roles, auto DB)
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: batch/v1
|
|
kind: CronJob
|
|
metadata:
|
|
name: "{{ cronjob_name }}"
|
|
namespace: "{{ namespace }}"
|
|
spec:
|
|
schedule: "0 3 * * *" # Exécution quotidienne à 3h du matin
|
|
successfulJobsHistoryLimit: 1
|
|
failedJobsHistoryLimit: 3
|
|
jobTemplate:
|
|
spec:
|
|
backoffLimit: 0
|
|
template:
|
|
spec:
|
|
restartPolicy: Never
|
|
containers:
|
|
- name: psql
|
|
image: postgres:16.3
|
|
envFrom:
|
|
- secretRef:
|
|
name: postgres-admin-credentials
|
|
env:
|
|
- name: PGPASSWORD
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: postgres-admin-credentials
|
|
key: password
|
|
command:
|
|
- /bin/sh
|
|
- -c
|
|
args:
|
|
- |
|
|
set -eu
|
|
|
|
# Récupérer dynamiquement les rôles PostgreSQL
|
|
echo "Fetching roles from PostgreSQL..."
|
|
ROLES=$(psql \
|
|
-h {{ pg_host }} \
|
|
-U $username \
|
|
-d postgres \
|
|
-t -A \
|
|
-c "SELECT rolname FROM pg_roles WHERE rolname LIKE '%_role';")
|
|
|
|
echo "Roles found: $ROLES"
|
|
|
|
# Pour chaque rôle, changer le propriétaire des tables dans sa base associée
|
|
for role in $ROLES; do
|
|
# Déduire le nom de la base en retirant "_role"
|
|
DB_NAME="${role%_role}"
|
|
echo "Database for $role: $DB_NAME"
|
|
|
|
# Vérifier si la base existe
|
|
if psql -h {{ pg_host }} -U $username -d postgres -t -A -c "SELECT 1 FROM pg_database WHERE datname = '$DB_NAME';" | grep -q 1; then
|
|
echo "Changing owner to $role for all tables in $DB_NAME..."
|
|
psql \
|
|
-h {{ pg_host }} \
|
|
-U $username \
|
|
-d "$DB_NAME" \
|
|
-c "
|
|
DO \$\$
|
|
DECLARE
|
|
r RECORD;
|
|
BEGIN
|
|
FOR r IN
|
|
SELECT tablename
|
|
FROM pg_tables
|
|
WHERE schemaname = 'public'
|
|
LOOP
|
|
EXECUTE format('ALTER TABLE public.%I OWNER TO %I', r.tablename, '$role');
|
|
END LOOP;
|
|
END \$\$;
|
|
"
|
|
echo "Owner changed for $role in $DB_NAME"
|
|
else
|
|
echo "Database $DB_NAME does not exist, skipping..."
|
|
fi
|
|
done
|