Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
inventory.ini

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
94 changes: 94 additions & 0 deletions backend/ansible/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
![Ansible](https://img.shields.io/badge/ansible-%231A1918.svg?style=for-the-badge&logo=ansible&logoColor=white)![Postgres](https://img.shields.io/badge/postgres-%23316192.svg?style=for-the-badge&logo=postgresql&logoColor=white)![Debian](https://img.shields.io/badge/Debian-D70A53?style=for-the-badge&logo=debian&logoColor=white)

# infra/vps

## requirements

- a linux server (debian) with ssh enabled and you have sudo privilege
- have Ansible installed on local machine
- macOS: `brew install ansible`

## `inventory.ini` file

create a `inventory.ini` file at the root of this directory
and fill it out with your server's information:

- server url
- linux user's username

__don't commit this file with your private information__

``ìni
[linux_vps]
<my_server.com> ansible_user=<my_server_username>

```

## ansible update debian server

play only the check tasks to list what packages are getting upgraded

```bash
ansible-playbook --tags check --ask-become-pass update_debian.yml
```

perform the upgrade

```bash
ansible-playbook --ask-become-pass update_debian.yml
```

## ansible installs and configure postgresql database on Debian server

### test connection to vps first

```bash
ansible -i inventory.ini linux_vps -m ping

# expect success
```

### sensitive value in versionned file

we are using `ansible-vault` command-line tool to create, encrypt, decrypt, and
safely use versionned secrets in files

```bash
# create a new encrypted secrets file
ansible-vault create | edit <file_name>.yml

# will open a vi editor where you you can edit key-value (ini style) secrets
```

### run the playbook with the Vault password

Runs the playbook

- will prompt `BECOME` for your server 'sudo' password
- will prompt `Vault password` for your secret file (ansible-vault) password

```bash
ansible-playbook \
--ask-vault-pass \
--ask-become-pass \
install_postgresql.yml
```

## from local machine

postgresql database is only available from server's localhost network

### ssh tunnel from local machine to server

in order to connect to it from an IDE like DBeaver, establish an ssh tunnel
(leave the terminal open to keep connection open)

```bash
ssh -L 5432:localhost:5432 m@dodeb.socratic.dev
```

### DBeaver IDE

| host | Database | authentitification | username | password |
| --------- | -------- | ------------------ | -------- | ------------------- |
| localhost | devdb | Database native | devuser | `<db_password.yml>` |
4 changes: 4 additions & 0 deletions backend/ansible/ansible.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[defaults]
ask_sudo_pass = True
inventory = inventory.ini
roles_path = ./roles
6 changes: 6 additions & 0 deletions backend/ansible/db_password.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
$ANSIBLE_VAULT;1.1;AES256
66626138373030663431653437323164376233303533333236353632366535393263396365626339
3236376335326437663337303063656332353961633630610a626637333964346138633365306235
65343131323336393862643239363739353037613339633737623962646561326261346439613337
3631376636373363660a373136626437666630643165656135666633303566306464653063366432
39656264626664613137356264613838363365393830343838313864363665643631
6 changes: 6 additions & 0 deletions backend/ansible/install_app.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
- name: Set up Fastapi app
hosts: all
become: true
roles:
- role: fastapi_app
8 changes: 8 additions & 0 deletions backend/ansible/install_postgresql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
- name: Set up PostgreSQL Database
hosts: all
become: true
vars_files:
- db_password.yml
roles:
- role: postgresql
21 changes: 21 additions & 0 deletions backend/ansible/roles/fastapi_app/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
- name: Verify Python version
command: python3 --version
register: python_version_output
failed_when: python_version_output.rc != 0
listen: Verify Python version

- name: Debug Python version
debug:
msg: "Python version: {{ python_version_output.stdout }}"
listen: Verify Python version

- name: Verify pipenv installation
command: pipenv --version
register: pipenv_version_output
failed_when: pipenv_version_output.rc != 0
listen: Verify pipenv installation

- name: Debug pipenv version
debug:
msg: "Pipenv version: {{ pipenv_version_output.stdout }}"
listen: Verify pipenv installation
10 changes: 10 additions & 0 deletions backend/ansible/roles/fastapi_app/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
- name: Install required Python packages
apt:
name:
- python3-pip
state: present
notify: Verify Python version

- name: Install pipenv using pip
command: pip3 install pipenv --break-system-packages
notify: Verify pipenv installation
Empty file.
9 changes: 9 additions & 0 deletions backend/ansible/roles/postgresql/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
- name: restart postgresql
service:
name: postgresql
state: restarted

- name: reload postgresql
service:
name: postgresql
state: reloaded
135 changes: 135 additions & 0 deletions backend/ansible/roles/postgresql/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
- name: Install required Python packages
apt:
name:
- python3-psycopg2
- python3-pip
state: present

- name: Import PostgreSQL signing key
apt_key:
url: https://www.postgresql.org/media/keys/ACCC4CF8.asc
state: present

- name: Add PostgreSQL APT repository
apt_repository:
repo: "deb http://apt.postgresql.org/pub/repos/apt/ {{ ansible_distribution_release }}-pgdg main"
state: present
filename: "pgdg"

- name: Install PostgreSQL
apt:
name:
- "postgresql-{{ postgresql_version }}"
- "postgresql-client-{{ postgresql_version }}"
- postgresql-contrib
- libpq-dev
state: present

- name: Check if PostgreSQL is initialized
ansible.builtin.stat:
path: "{{ postgresql_data_dir }}/pg_hba.conf"
register: postgres_data

- name: Empty data dir
ansible.builtin.file:
path: "{{ postgresql_data_dir }}"
state: absent
when: not postgres_data.stat.exists

- name: Initialize PostgreSQL
ansible.builtin.shell: "{{ postgresql_bin_path }}/initdb -D {{ postgresql_data_dir }}"
become: true
become_user: postgres
when: not postgres_data.stat.exists

- name: Configure unix_socket_directories in postgresql.conf
lineinfile:
path: "/etc/postgresql/{{ postgresql_version }}/main/postgresql.conf"
regexp: "^#?unix_socket_directories"
line: "unix_socket_directories = '/var/run/postgresql'"
state: present
notify:
- restart postgresql

- name: Ensure /var/run/postgresql exists
file:
path: "/var/run/postgresql"
state: directory
owner: postgres
group: postgres
mode: "2775"

- name: Start and enable service
ansible.builtin.service:
name: postgresql
state: started
enabled: true

- name: temporary trust authentication for postgres user
lineinfile:
path: "/etc/postgresql/{{ postgresql_version }}/main/pg_hba.conf"
regexp: '^local\s+all\s+postgres.*$'
line: "local all postgres trust"
notify:
- reload postgresql
tags:
- authentication

# Force the execution of handlers to ensure PostgreSQL is reloaded
- name: Ensure PostgreSQL is reloaded before creating the database
meta: flush_handlers

- name: Create development database
postgresql_db:
name: "{{ db_name }}"
state: present
tags:
- db
- db-setup

- name: Create development user
postgresql_user:
name: "{{ db_user }}"
password: "{{ dev_db_password }}"
state: present
tags:
- user
- user-setup

- name: Grant ownership of the database to devuser
postgresql_db:
name: "{{ db_name }}"
owner: "{{ db_user }}"
state: present
tags:
- permissions
- ownership

- name: Create schema dev_schema
postgresql_query:
db: "{{ db_name }}"
query: "CREATE SCHEMA IF NOT EXISTS dev_schema AUTHORIZATION {{ db_user
}};"
tags:
- schema
- schema-setup

- name: Configure PostgreSQL authentication for postgres user
lineinfile:
path: "/etc/postgresql/{{ postgresql_version }}/main/pg_hba.conf"
regexp: '^local\s+all\s+postgres.*$'
line: "local all postgres peer"
notify:
- restart postgresql
tags:
- authentication

- name: Configure PostgreSQL authentication for all local users
lineinfile:
path: "/etc/postgresql/{{ postgresql_version }}/main/pg_hba.conf"
regexp: '^local\s+all\s+all.*$'
line: "local all local scram-sha-256"
notify:
- restart postgresql
tags:
- authentication
7 changes: 7 additions & 0 deletions backend/ansible/roles/postgresql/vars/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
postgresql_version: "17"
db_name: "devdb"
db_user: "devuser"
dev_db_password: "{{ db_password }}"
postgresql_bin_path: "/usr/lib/postgresql/{{ postgresql_version }}/bin"
postgresql_data_dir: "/var/lib/postgresql/{{ postgresql_version }}/main"
ansible_ssh_pipelining: true
42 changes: 42 additions & 0 deletions backend/ansible/update_debian.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
- name: Update Debian Machine
hosts: all
become: true

tasks:
- name: Update apt cache
apt:
update_cache: yes
tags:
- update

- name: List upgradable packages
command: apt list --upgradable
register: upgradable_packages
changed_when: false
tags:
- check

- name: Print upgradable packages
debug:
msg: "{{ upgradable_packages.stdout_lines }}"
tags:
- check

- name: Upgrade all packages
apt:
upgrade: dist
tags:
- upgrade

- name: Remove unused packages
apt:
autoremove: yes
tags:
- cleanup

- name: Clean up apt cache
apt:
autoclean: yes
tags:
- cleanup
Loading