ansible: playbook for postgres and gitea

This commit is contained in:
2024-07-18 10:36:12 +02:00
parent 0e2ea5cb36
commit f4b54d2941
25 changed files with 408 additions and 54 deletions

View File

@@ -16,7 +16,7 @@ ENV PATH=/home/arcodange/.local/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bi
RUN pip install ansible-core jmespath
ENV GALAXY_SERVER=https://beta-galaxy.ansible.com/api/
RUN ansible-galaxy collection install --token 11bebd8fd1ad4009f700bdedbeb80b19743ce3d3 \
community.general ansible.posix
community.general community.docker ansible.posix
ENV ANSIBLE_HOST_KEY_CHECKING=False
ENV ANSIBLE_FORCE_COLOR=True=True

View File

@@ -36,3 +36,11 @@ which brew && brew install coreutils # if on macos
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa
```
## dev
### test an expression
```sh
ansible -i ,localhost -c local localhost -m raw -a "echo hello world {{ inventory_hostname }} : {{ hostvars | to_nice_json | regex_replace(\"['\n]\",' ') }}"
```

View File

@@ -0,0 +1,13 @@
# to add/mount a partitiion, use the gparted utility to create it beforehand witht the matching name/label
hard_disk__partitions:
gitea_data:
- gitea
pg_data:
- postgres
hard_disk__applications:
postgres: "{{ postgres }}"
gitea: "{{ gitea }}"
hard_disk__postgres_databases:
gitea: "{{ gitea_database }}"

View File

@@ -0,0 +1,43 @@
gitea_partition: |-
{{
hard_disk__partitions | dict2items | selectattr(
'value', 'contains', 'gitea'
) | map(attribute='key') | first
}}
gitea_database:
db_name: gitea
db_user: gitea
db_password: gitea
gitea:
partition: "{{ gitea_partition }}"
database:
dockercompose:
name: arcodange_factory
networks:
gitea:
name: arcodange_factory_gitea
external: true
services:
gitea:
image: gitea/gitea:1.22.1
container_name: gitea
restart: always
environment:
USER_UID: 1000
USER_GID: 1000
GITEA__database__DB_TYPE: postgres
GITEA__database__HOST: postgres:5432
GITEA__database__NAME: "{{ gitea_database.db_name }}"
GITEA__database__USER: "{{ gitea_database.db_user }}"
GITEA__database__PASSWD: "{{ gitea_database.db_password }}"
networks:
- gitea
ports:
- "80:3000"
- "2222:22"
volumes:
- /arcodange/{{gitea_partition}}/gitea/data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro

View File

@@ -0,0 +1,28 @@
postgres_partition: |-
{{
hard_disk__partitions | dict2items | selectattr(
'value', 'contains', 'postgres'
) | map(attribute='key') | first
}}
postgres:
partition: "{{ postgres_partition }}"
dockercompose:
name: arcodange_factory
networks:
gitea:
external: false
services:
postgres:
image: postgres:16.3-alpine
container_name: postgres
restart: always
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
networks:
- gitea
ports:
- "5432"
volumes:
- /arcodange/{{postgres_partition}}/postgres/data:/var/lib/postgresql/data

View File

@@ -34,4 +34,4 @@ gitea:
all:
children:
raspberry:
raspberries:

View File

@@ -0,0 +1,48 @@
# Setup factory services
```mermaid
%%{init: { 'logLevel': 'debug', 'theme': 'base', 'rough':true } }%%
flowchart
net[Internet]
subgraph "Local Network (livebox)"
net_rules{network rules}
subgraph pi2
Out[0.0.0.0/pi<u>2</u>.home/gitea.home]
subgraph Docker
subgraph gitea_network
subgraph postgres_service
end
subgraph gitea_service
end
end
end
subgraph Hard Disk
subgraph pg_data partition
pg_scripts[scripts]
pg_data_dir[data]
end
subgraph gitea_data partition
gitea_scripts[scripts]
gitea_data_dir[data]
end
end
end
end
postgres_service --o pg_data_dir
gitea_service --o gitea_data_dir
postgres_service <-.:5432.-> Out
gitea_service <-.:443,80.-> Out
net -. "https://rg-evry.changeip.co:5<u>2</u><i>443</i>" .- net_rules -. :<i>443</i> .-> Out
net -. "http://rg-evry.changeip.co:5<u>2</u>0<i>80</i>" .- net_rules -. :<i>80</i> .-> Out
subgraph scripts
dc><u>docker-compose.yml</u>\ndescribing docker container service\nexposed ports\nand data volume]
end
gitea_scripts -.- scripts
pg_scripts -.- scripts
```
🏹💻🪽

View File

@@ -0,0 +1,40 @@
---
- name: Setup Gitea
hosts: hard_disk
gather_facts: yes
become: false
vars:
applications: "{{ hard_disk__applications }}"
tasks:
- name: Deploy gitea Docker Compose configuration
include_role:
name: arcodange.factory.deploy_docker_compose
vars:
app_name: "{{ app.name }}"
dockercompose_content: "{{ app.conf.dockercompose }}"
partition: "{{ app.conf.partition }}"
app_owner: "{{ app.conf.owner | default('pi') }}"
app_group: "{{ app.conf.group | default('docker') }}"
loop: "{{ applications | dict2items(key_name='name', value_name='conf') }}"
loop_control:
loop_var: app
label: "{{ app.name }}"
when: app.name == 'gitea'
- name: Deploy Gitea
include_role:
name: deploy_gitea
vars:
app_name: gitea
partition: "{{ applications.gitea.partition }}"
gitea_container_name: "{{ applications.gitea.dockercompose.services.gitea.container_name }}"
postgres_host: |-
{{ applications.gitea.dockercompose.services.gitea.environment.GITEA__database__HOST }}
postgres_db: |-
{{ applications.gitea.dockercompose.services.gitea.environment.GITEA__database__NAME }}
postgres_user: |-
{{ applications.gitea.dockercompose.services.gitea.environment.GITEA__database__USER }}
postgres_password: |-
{{ applications.gitea.dockercompose.services.gitea.environment.GITEA__database__PASSWD }}

View File

@@ -12,9 +12,16 @@
become: yes
vars:
mount_points:
- gitea_data
- pg_data
mount_points: |
{{
(
hard_disk__partitions
| default( {
'gitea_data':[],
'pg_data':[]
} )
).keys() | list
}}
verify_partitions: true # Change this to false if you don't want to verify partitions
tasks:

View File

@@ -0,0 +1,34 @@
---
- name: Setup Postgres
hosts: hard_disk
gather_facts: yes
become: false
vars:
applications: "{{ hard_disk__applications }}"
applications_databases: "{{ hard_disk__postgres_databases }}"
tasks:
- name: Deploy postgres Docker Compose configuration
include_role:
name: arcodange.factory.deploy_docker_compose
vars:
app_name: "{{ app.name }}"
dockercompose_content: "{{ app.conf.dockercompose }}"
partition: "{{ app.conf.partition }}"
app_owner: "{{ app.conf.owner | default('pi') }}"
app_group: "{{ app.conf.group | default('docker') }}"
loop: "{{ applications | dict2items(key_name='name', value_name='conf') }}"
loop_control:
loop_var: app
label: "{{ app.name }}"
when: app.name == 'postgres'
- name: Deploy PostgreSQL
include_role:
name: deploy_postgresql
vars:
app_name: postgres
partition: "{{ applications.postgres.partition }}"
postgres_container_name: "{{ applications.postgres.dockercompose.services.postgres.container_name }}"
# applications_databases: "{{ applications_databases }}" # kept for documentation purposes

View File

@@ -0,0 +1,7 @@
---
app_owner: pi
app_group: docker
app_name: gitea
partition: gitea_data
config_path: /arcodange/{{ partition }}/{{ app_name }}/config
data_path: /arcodange/{{ partition }}/{{ app_name }}/data

View File

@@ -0,0 +1,38 @@
---
- name: Ensure Docker is running
service:
name: docker
state: started
enabled: yes
- name: Create configuration directory
file:
path: "{{ config_path }}"
state: directory
owner: "{{ app_owner }}"
group: "{{ app_group }}"
- name: Template the app.ini file
template:
src: app.ini.j2
dest: "{{ config_path }}/app.ini"
owner: "{{ app_owner }}"
group: "{{ app_group }}"
- name: Deploy Gitea with Docker Compose
community.docker.docker_compose_v2:
project_src: "/arcodange/{{ partition }}/{{ app_name }}"
pull: missing
state: present
register: deploy_result
- name: Wait for Gitea to be ready
shell: |
until docker exec -i {{ gitea_container_name }} curl -sSf http://localhost:3000/; do
sleep 1
done
retries: 30
delay: 10
register: result
until: result.rc == 0
when: deploy_result.changed

View File

@@ -0,0 +1,18 @@
[server]
PROTOCOL = http
DOMAIN = localhost
HTTP_PORT = 3000
ROOT_URL = http://localhost:3000/
DISABLE_SSH = false
SSH_PORT = 22
START_SSH_SERVER = true
OFFLINE_MODE = false
[database]
DB_TYPE = postgres
HOST = {{ postgres_host }}
NAME = {{ postgres_db }}
USER = {{ postgres_user }}
PASSWD = {{ postgres_password }}
SSL_MODE = disable
PATH = data/gitea.db

View File

@@ -0,0 +1,4 @@
partition: pg_data
app_name: postgres
postgres_container_name: postgres
applications_databases: {}

View File

@@ -0,0 +1,28 @@
---
- name: Check if database {{ db_config.db_name }} exists
shell: |
docker exec -it {{ postgres_container_name }} psql -U postgres -tc "SELECT 1 FROM pg_database WHERE datname = '{{ db_config.db_name }}';"
register: db_check
changed_when: false
- name: Create database {{ db_config.db_name }} if it does not exist
shell: |
docker exec -it {{ postgres_container_name }} psql -U postgres -c "CREATE DATABASE {{ db_config.db_name }};"
when: db_check.stdout.find('1') == -1
changed_when: true
- name: Check if user {{ db_config.db_user }} exists
shell: |
docker exec -it {{ postgres_container_name }} psql -U postgres -tc "SELECT 1 FROM pg_roles WHERE rolname='{{ db_config.db_user }}';"
register: user_check
changed_when: false
- name: Create user {{ db_config.db_user }} if it does not exist
shell: |
docker exec -it {{ postgres_container_name }} psql -U postgres -c "CREATE USER {{ db_config.db_user }} WITH PASSWORD '{{ db_config.db_password }}';"
when: user_check.stdout.find('1') == -1
changed_when: true
- name: Grant ownership of database {{ db_config.db_name }} to user {{ db_config.db_user }}
shell: |
docker exec -i {{ postgres_container_name }} psql -U postgres -c "ALTER DATABASE {{ db_config.db_name }} OWNER TO {{ db_config.db_user }};"

View File

@@ -0,0 +1,35 @@
---
- name: Ensure Docker is running
service:
name: docker
state: started
enabled: yes
- name: Deploy PostgreSQL with Docker Compose
community.docker.docker_compose_v2:
project_src: "/arcodange/{{ partition }}/{{ app_name }}"
pull: missing
state: present
register: deploy_result
- name: Create database and user for applications_databases
when: deploy_result.changed
block:
- name: Wait for PostgreSQL to be ready
shell: |
until docker exec -it {{ postgres_container_name }} pg_isready; do
sleep 1
done
retries: 30
delay: 10
register: result
until: result.rc == 0
- name: Iterate over applications_databases
include_tasks: create_db_and_user.yml
vars:
db_config: "{{ app.conf }}"
loop: "{{ applications_databases | dict2items(key_name='name', value_name='conf') }}"
loop_control:
loop_var: app
label: "{{ app.name }}"

View File

@@ -1,2 +0,0 @@
---
# handlers file for roles/setup_partition

View File

@@ -1,34 +0,0 @@
galaxy_info:
author: your name
description: your role description
company: your company (optional)
# If the issue tracker for your role is not on github, uncomment the
# next line and provide a value
# issue_tracker_url: http://example.com/issue/tracker
# Choose a valid license ID from https://spdx.org - some suggested licenses:
# - BSD-3-Clause (default)
# - MIT
# - GPL-2.0-or-later
# - GPL-3.0-only
# - Apache-2.0
# - CC-BY-4.0
license: license (GPL-2.0-or-later, MIT, etc)
min_ansible_version: 2.1
# If this a Container Enabled role, provide the minimum Ansible Container version.
# min_ansible_container_version:
galaxy_tags: []
# List tags for your role here, one per line. A tag is a keyword that describes
# and categorizes the role. Users find roles by searching for tags. Be sure to
# remove the '[]' above, if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
# Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.

View File

@@ -1,5 +0,0 @@
---
- hosts: localhost
remote_user: root
roles:
- roles/setup_partition

View File

@@ -1,2 +0,0 @@
---
# vars file for roles/setup_partition

View File

@@ -3,10 +3,14 @@
hosts: raspberries:&local
tasks:
- name: hello world
ansible.builtin.debug:
msg: Hello world!
- ansible.builtin.ping:
- name: setup hard disk
ansible.builtin.import_playbook: hard_disk.yml
tags: never
- name: setup factory postgres
ansible.builtin.import_playbook: postgres.yml
- name: setup factory gitea
ansible.builtin.import_playbook: gitea.yml

View File

@@ -0,0 +1,43 @@
---
- name: Create application directory
file:
path: "/arcodange/{{ partition }}/{{ app_name }}"
state: directory
owner: "{{ app_owner }}"
group: "{{ app_group }}"
- name: Create data directory
file:
path: "/arcodange/{{ partition }}/{{ app_name }}/data"
state: directory
owner: "{{ app_owner }}"
group: "{{ app_group }}"
mode: '0775'
ignore_errors: true # app container might have set its own permissions on previous run
- name: Create scripts directory
file:
path: "/arcodange/{{ partition }}/{{ app_name }}/scripts"
state: directory
owner: "{{ app_owner }}"
group: "{{ app_group }}"
mode: '0755'
- name: Write docker-compose.yml
copy:
content: "{{ dockercompose_content | to_nice_yaml }}"
dest: "/arcodange/{{ partition }}/{{ app_name }}/docker-compose.yml"
owner: "{{ app_owner }}"
group: "{{ app_group }}"
mode: '0644'
- name: Write docker-compose script
copy:
content: |
#!/bin/bash
set -ex
docker compose -f /arcodange/{{ partition }}/{{ app_name }}/docker-compose.yml "$@"
dest: "/arcodange/{{ partition }}/{{ app_name }}/scripts/docker-compose"
owner: "{{ app_owner }}"
group: "{{ app_group }}"
mode: '0755'

View File

@@ -7,4 +7,5 @@ if [ "$(id -u)" = '0' ]; then
fi
# Exécuter le reste des commandes en tant que non-root
for col in `find /home/arcodange/code/ -name galaxy.yml`; do ansible-galaxy collection install `dirname $col`; done
exec "$@"