feat: deploy loadbalanced libreddit instance
This commit is contained in:
commit
a3c30cc5cb
20 changed files with 956 additions and 0 deletions
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
plan
|
||||||
|
.terraform/
|
||||||
|
.pytest_cache/
|
||||||
|
venv/
|
||||||
|
__pycache__/
|
||||||
|
ansible/inventory/hosts.ini
|
||||||
|
terraform.tfstate
|
||||||
|
terraform.tfstate.backup
|
||||||
|
.terraform/
|
||||||
|
.terraform.lock.hcl
|
||||||
|
bullseye
|
105
Makefile
Normal file
105
Makefile
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
# SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
|
||||||
|
define configure_ping
|
||||||
|
ansible-playbook -i ./ansible/inventory/hosts.ini -f 10 ./ansible/ping.yml
|
||||||
|
endef
|
||||||
|
|
||||||
|
define configure_base
|
||||||
|
ansible-playbook -i ./ansible/inventory/hosts.ini -f 10 ./ansible/playbook.yml
|
||||||
|
endef
|
||||||
|
|
||||||
|
define configure_loadbalance
|
||||||
|
ansible-playbook -i ./ansible/inventory/hosts.ini -f 10 ./ansible/loadbalance.yml
|
||||||
|
endef
|
||||||
|
|
||||||
|
define configure_libreddit
|
||||||
|
ansible-playbook -i ./ansible/inventory/hosts.ini -f 10 ./ansible/libreddit.yml
|
||||||
|
endef
|
||||||
|
|
||||||
|
define test_base
|
||||||
|
. ./venv/bin/activate && \
|
||||||
|
cd tests/ && \
|
||||||
|
py.test --hosts='ansible://all' \
|
||||||
|
-n 10 \
|
||||||
|
--verbose \
|
||||||
|
--ansible-inventory='../ansible/inventory/hosts.ini' \
|
||||||
|
test_basic.py
|
||||||
|
|
||||||
|
endef
|
||||||
|
|
||||||
|
define test_libreddit
|
||||||
|
. ./venv/bin/activate && \
|
||||||
|
cd tests/ && \
|
||||||
|
py.test --hosts='ansible://bullseye_libreddit' \
|
||||||
|
-n 10 \
|
||||||
|
--verbose \
|
||||||
|
--ansible-inventory='../ansible/inventory/hosts.ini' \
|
||||||
|
test_libreddit.py
|
||||||
|
endef
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
define test_loadbalance
|
||||||
|
. ./venv/bin/activate && \
|
||||||
|
cd tests/ && \
|
||||||
|
py.test --hosts='ansible://bullseye_loadbalance' \
|
||||||
|
-n 10 \
|
||||||
|
--verbose \
|
||||||
|
--ansible-inventory='../ansible/inventory/hosts.ini' \
|
||||||
|
test_loadbalance.py
|
||||||
|
endef
|
||||||
|
|
||||||
|
|
||||||
|
configure:
|
||||||
|
$(call configure_ping)
|
||||||
|
$(call configure_base)
|
||||||
|
$(call configure_libreddit)
|
||||||
|
$(call configure_loadbalance)
|
||||||
|
|
||||||
|
configure.ping:
|
||||||
|
$(call configure_ping)
|
||||||
|
|
||||||
|
configure.base:
|
||||||
|
$(call configure_ping)
|
||||||
|
$(call configure_base)
|
||||||
|
|
||||||
|
configure.libreddit:
|
||||||
|
$(call configure_ping)
|
||||||
|
$(call configure_libreddit)
|
||||||
|
|
||||||
|
configure.loadbalance:
|
||||||
|
$(call configure_ping)
|
||||||
|
$(call configure_loadbalance)
|
||||||
|
|
||||||
|
|
||||||
|
lint:
|
||||||
|
terraform fmt
|
||||||
|
ansible-lint --write ./ansible/playbook.yml
|
||||||
|
ansible-lint --write ./ansible/shutdown.yml
|
||||||
|
ansible-lint --write ./ansible/loadbalance.yml
|
||||||
|
ansible-lint --write ./ansible/libreddit.yml
|
||||||
|
. ./venv/bin/activate && black tests/
|
||||||
|
|
||||||
|
on:
|
||||||
|
./scripts/on.sh
|
||||||
|
virsh list
|
||||||
|
|
||||||
|
shutdown:
|
||||||
|
ansible-playbook -i ./ansible/inventory/hosts.ini -f 10 ./ansible/shutdown.yml
|
||||||
|
|
||||||
|
test:
|
||||||
|
$(call test_base)
|
||||||
|
$(call test_loadbalance)
|
||||||
|
$(call test_libreddit)
|
||||||
|
|
||||||
|
test.base:
|
||||||
|
$(call test_base)
|
||||||
|
|
||||||
|
test.loadbalance:
|
||||||
|
$(call test_loadbalance)
|
||||||
|
|
||||||
|
test.libreddit:
|
||||||
|
$(call test_libreddit)
|
158
ansible/.gitignore
vendored
Normal file
158
ansible/.gitignore
vendored
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
inventory/
|
||||||
|
.env
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.py,cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
cover/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
.pybuilder/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
|
# .python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# poetry
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||||
|
#poetry.lock
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||||
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# pytype static type analyzer
|
||||||
|
.pytype/
|
||||||
|
|
||||||
|
# Cython debug symbols
|
||||||
|
cython_debug/
|
||||||
|
|
||||||
|
# PyCharm
|
||||||
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||||
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||||
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
|
#.idea/
|
||||||
|
keys
|
||||||
|
htmlcov/
|
||||||
|
tmp/
|
||||||
|
static/
|
19
ansible/init.sh
Executable file
19
ansible/init.sh
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
|
||||||
|
ansible live \
|
||||||
|
-m ansible.builtin.ping \
|
||||||
|
-i ./ansible/inventory
|
||||||
|
|
||||||
|
ansible live \
|
||||||
|
-m ansible.builtin.apt \
|
||||||
|
-f 10 \
|
||||||
|
-a "update_cache=yes upgrade=safe" \
|
||||||
|
-i ./ansible/inventory/
|
||||||
|
|
||||||
|
|
||||||
|
ansible live \
|
||||||
|
-m ansible.builtin.apt \
|
||||||
|
-f 10 \
|
||||||
|
-a "name=nginx,git,curl,wget,vim,zip,nginx" \
|
||||||
|
-i ./ansible/inventory/
|
63
ansible/libreddit.yml
Normal file
63
ansible/libreddit.yml
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
# SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
---
|
||||||
|
- name: Deploy libreddit
|
||||||
|
hosts: bullseye_libreddit
|
||||||
|
remote_user: atm
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Ensure all VMs are reachable
|
||||||
|
ansible.builtin.ping:
|
||||||
|
|
||||||
|
- name: Create /etc/apt/keyrings dir
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /etc/apt/keyrings
|
||||||
|
state: directory
|
||||||
|
recurse: true
|
||||||
|
|
||||||
|
- name: Add Docker GPG apt Key
|
||||||
|
ansible.builtin.apt_key:
|
||||||
|
url: https://download.docker.com/linux/debian/gpg
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Add Docker Repository
|
||||||
|
ansible.builtin.apt_repository:
|
||||||
|
repo: deb https://download.docker.com/linux/debian buster stable
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Update apt and install docker-ce
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: docker-ce
|
||||||
|
update_cache: true
|
||||||
|
|
||||||
|
- name: Install Docker Module for Python
|
||||||
|
ansible.builtin.pip:
|
||||||
|
name: docker
|
||||||
|
|
||||||
|
- name: Ensure docker group is present
|
||||||
|
ansible.builtin.group:
|
||||||
|
name: docker
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Add user atm to docker group
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: atm
|
||||||
|
groups: docker,users,admin
|
||||||
|
|
||||||
|
- name: Deploy libreddit
|
||||||
|
ansible.builtin.docker_container:
|
||||||
|
name: libreddit
|
||||||
|
state: started
|
||||||
|
image: "spikecodes/libreddit"
|
||||||
|
pull: true
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
|
||||||
|
- name: Allow port 8080
|
||||||
|
community.general.ufw:
|
||||||
|
state: enabled
|
||||||
|
proto: tcp
|
||||||
|
rule: allow
|
||||||
|
port: "8080"
|
83
ansible/loadbalance.yml
Normal file
83
ansible/loadbalance.yml
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
# SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
---
|
||||||
|
- name: Configure loadbalancers
|
||||||
|
hosts: bullseye_loadbalance
|
||||||
|
remote_user: root
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Ensure all VMs are reachable
|
||||||
|
ansible.builtin.ping:
|
||||||
|
- name: Update package cache
|
||||||
|
ansible.builtin.apt:
|
||||||
|
update_cache: true
|
||||||
|
upgrade: safe
|
||||||
|
|
||||||
|
- name: Install git, zip, nginx, wget, curl & other utils
|
||||||
|
ansible.builtin.apt:
|
||||||
|
update_cache: true
|
||||||
|
pkg:
|
||||||
|
- nginx
|
||||||
|
- ca-certificates
|
||||||
|
- ufw
|
||||||
|
|
||||||
|
- name: Add user atm to docker group
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: atm
|
||||||
|
groups: users,admin
|
||||||
|
|
||||||
|
- name: Set logging
|
||||||
|
community.general.ufw:
|
||||||
|
logging: "on"
|
||||||
|
|
||||||
|
- name: Allow port 22 and enable UFW
|
||||||
|
community.general.ufw:
|
||||||
|
state: enabled
|
||||||
|
rule: allow
|
||||||
|
proto: tcp
|
||||||
|
port: "22"
|
||||||
|
|
||||||
|
- name: Allow port 80
|
||||||
|
community.general.ufw:
|
||||||
|
state: enabled
|
||||||
|
proto: tcp
|
||||||
|
rule: allow
|
||||||
|
port: "80"
|
||||||
|
|
||||||
|
- name: Allow port 443
|
||||||
|
community.general.ufw:
|
||||||
|
state: enabled
|
||||||
|
proto: tcp
|
||||||
|
rule: allow
|
||||||
|
port: "443"
|
||||||
|
|
||||||
|
- name: Enable and start ufw service
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: ufw
|
||||||
|
enabled: true
|
||||||
|
state: started
|
||||||
|
|
||||||
|
- name: Copy the Nginx config file and restart nginx
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: ./assets/nginx.cfg
|
||||||
|
dest: /etc/nginx/sites-available/nginx.cfg
|
||||||
|
|
||||||
|
- name: Create symlink
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: /etc/nginx/sites-available/nginx.cfg
|
||||||
|
dest: /etc/nginx/sites-enabled/default
|
||||||
|
state: link
|
||||||
|
|
||||||
|
- name: Enable and start nginx service
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: nginx
|
||||||
|
enabled: true
|
||||||
|
state: started
|
||||||
|
|
||||||
|
- name: Enable and start nginx service
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: nginx
|
||||||
|
enabled: true
|
||||||
|
state: restarted
|
12
ansible/ping.yml
Normal file
12
ansible/ping.yml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
---
|
||||||
|
- name: Configure webservers
|
||||||
|
hosts: [bullseye_libreddit,bullseye_loadbalance]
|
||||||
|
remote_user: root
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Ensure all VMs are reachable
|
||||||
|
ansible.builtin.ping:
|
50
ansible/playbook.yml
Normal file
50
ansible/playbook.yml
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
# SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
---
|
||||||
|
- name: Configure webservers
|
||||||
|
hosts: [bullseye_libreddit,bullseye_loadbalance]
|
||||||
|
remote_user: root
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Ensure all VMs are reachable
|
||||||
|
ansible.builtin.ping:
|
||||||
|
- name: Update package cache
|
||||||
|
ansible.builtin.apt:
|
||||||
|
update_cache: true
|
||||||
|
upgrade: safe
|
||||||
|
|
||||||
|
- name: Install git, zip, nginx, wget, curl & other utils
|
||||||
|
ansible.builtin.apt:
|
||||||
|
update_cache: true
|
||||||
|
pkg:
|
||||||
|
- git
|
||||||
|
- wget
|
||||||
|
- curl
|
||||||
|
- gpg
|
||||||
|
- ca-certificates
|
||||||
|
- zip
|
||||||
|
- python3-pip
|
||||||
|
- virtualenv
|
||||||
|
- ufw
|
||||||
|
- python3-setuptools
|
||||||
|
|
||||||
|
|
||||||
|
- name: Set logging
|
||||||
|
community.general.ufw:
|
||||||
|
logging: "on"
|
||||||
|
|
||||||
|
- name: Allow port 22 and enable UFW
|
||||||
|
community.general.ufw:
|
||||||
|
state: enabled
|
||||||
|
rule: allow
|
||||||
|
proto: tcp
|
||||||
|
port: "22"
|
||||||
|
|
||||||
|
|
||||||
|
- name: Enable and start ufw service
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: ufw
|
||||||
|
enabled: true
|
||||||
|
state: started
|
8
ansible/shutdown.yml
Normal file
8
ansible/shutdown.yml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
- name: Shutdown machines
|
||||||
|
hosts: [bullseye_loadbalance,bullseye_app]
|
||||||
|
remote_user: root
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Ensure all VMs are reachable
|
||||||
|
community.general.shutdown:
|
23
cloud_init.cfg
Normal file
23
cloud_init.cfg
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#cloud-config
|
||||||
|
# vim: syntax=yaml
|
||||||
|
|
||||||
|
users:
|
||||||
|
- name: root
|
||||||
|
ssh_authorized_keys:
|
||||||
|
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC/wXdHpwpY/4ubhYTmuNdGepQpj1kchvTUTApxMZyfyVW4uzrPRTYsle1y9QbTBV35qLkNajRC/wmC5/xPchdXpsJpuD9st1HMhLeR8qwaPyptiYJYT+z/WisWw2k6oWhG3QKvPoRtBdW9nhZnkG+O6zkuGXiRHpS7j2VVboDPpWEe1UdELQFVCwfraRal2g3ENFZ/9V1UrW/4ahRnQnSxERplZUm/fgSxQtmXubTkW68ut7yasBsrKFffMm8JztW0tWgTlTKONd3LCjv4juM0t5+cJDotNDnUR86Tq2PG8io7no/h8BWtazmjdpfGgn02ibX26BkdU0LDEYbJt5q9/Fh9TGk2ZwcMQeyepO1AWQgkmHXZWZELqu6MLQpqdtsOjHp9k0MeSpuIbdwzgf10Ydy7vK1z8irS24tVNNnJaMBwOlVOPwfyztHRADPkFcv2lKSjS1uyKR0FIkV8Kvs4txaIjmwv2LfMg6lF5W6j3ZPLyeE4cplJP0DDjzorSanu31xVnqVb3A8V9awsJ/4H7d59bI99c7QHL4K3fBVP3O0gqd31xAVRsdGs5Tj2P+RpiI6o5JJiOa1+DuBdWzrVIXYchQ30ZjaJp1wTNsYLmAsjeYuQZE2tf1xvywdzD4MB4avugDEWikzRWN9V5PHDZr1bamTCCjOrb2PRCd7eSQ== aravinth7820@gmail.com
|
||||||
|
- name: atm
|
||||||
|
gecos: Aravinth Manivannan
|
||||||
|
groups: users, admin
|
||||||
|
sudo: ALL=(ALL) NOPASSWD:ALL
|
||||||
|
shell: /bin/bash
|
||||||
|
lock_passwd: true
|
||||||
|
plain_text_passwd: fooabr12
|
||||||
|
ssh_authorized_keys:
|
||||||
|
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC/wXdHpwpY/4ubhYTmuNdGepQpj1kchvTUTApxMZyfyVW4uzrPRTYsle1y9QbTBV35qLkNajRC/wmC5/xPchdXpsJpuD9st1HMhLeR8qwaPyptiYJYT+z/WisWw2k6oWhG3QKvPoRtBdW9nhZnkG+O6zkuGXiRHpS7j2VVboDPpWEe1UdELQFVCwfraRal2g3ENFZ/9V1UrW/4ahRnQnSxERplZUm/fgSxQtmXubTkW68ut7yasBsrKFffMm8JztW0tWgTlTKONd3LCjv4juM0t5+cJDotNDnUR86Tq2PG8io7no/h8BWtazmjdpfGgn02ibX26BkdU0LDEYbJt5q9/Fh9TGk2ZwcMQeyepO1AWQgkmHXZWZELqu6MLQpqdtsOjHp9k0MeSpuIbdwzgf10Ydy7vK1z8irS24tVNNnJaMBwOlVOPwfyztHRADPkFcv2lKSjS1uyKR0FIkV8Kvs4txaIjmwv2LfMg6lF5W6j3ZPLyeE4cplJP0DDjzorSanu31xVnqVb3A8V9awsJ/4H7d59bI99c7QHL4K3fBVP3O0gqd31xAVRsdGs5Tj2P+RpiI6o5JJiOa1+DuBdWzrVIXYchQ30ZjaJp1wTNsYLmAsjeYuQZE2tf1xvywdzD4MB4avugDEWikzRWN9V5PHDZr1bamTCCjOrb2PRCd7eSQ== aravinth7820@gmail.com
|
||||||
|
|
||||||
|
ssh_pwauth: true
|
||||||
|
chpasswd:
|
||||||
|
list: |
|
||||||
|
root:foobar12
|
||||||
|
atm:foobar12
|
||||||
|
expire: False
|
210
conf.tf
Normal file
210
conf.tf
Normal file
|
@ -0,0 +1,210 @@
|
||||||
|
terraform {
|
||||||
|
required_version = ">= 0.13"
|
||||||
|
required_providers {
|
||||||
|
libvirt = {
|
||||||
|
source = "dmacvicar/libvirt"
|
||||||
|
version = "~> 0.7.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# instance the provider
|
||||||
|
provider "libvirt" {
|
||||||
|
uri = "qemu:///system"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "libvirt_pool" "bullseye_basic" {
|
||||||
|
name = "bullseye_basic"
|
||||||
|
type = "dir"
|
||||||
|
path = "/home/atm/code/libvirt/pool/bullseye_basic"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# We fetch the latest bullseye_basic release image from their mirrors
|
||||||
|
resource "libvirt_volume" "debian-bullseye-qcow2" {
|
||||||
|
name = "debian-bullseye-qcow2"
|
||||||
|
pool = libvirt_pool.bullseye_basic.name
|
||||||
|
source = "/home/atm/disk-images/debian/11/cloud/debian-11-genericcloud-amd64.qcow2"
|
||||||
|
format = "qcow2"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "loadbalance_count" {
|
||||||
|
default = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
variable "libreddit_count" {
|
||||||
|
default = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
resource "libvirt_volume" "domain_bullseye_loadbalance_volume" {
|
||||||
|
name = "domain_bullseye_loadbalance_volume-${count.index}"
|
||||||
|
base_volume_id = libvirt_volume.debian-bullseye-qcow2.id
|
||||||
|
count = var.loadbalance_count
|
||||||
|
pool = libvirt_pool.bullseye_basic.name
|
||||||
|
size = 85368709120
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
resource "libvirt_volume" "domain_bullseye_libreddit_volume" {
|
||||||
|
name = "domain_bullseye_libreddit_volume-${count.index}"
|
||||||
|
base_volume_id = libvirt_volume.debian-bullseye-qcow2.id
|
||||||
|
pool = libvirt_pool.bullseye_basic.name
|
||||||
|
count = var.libreddit_count
|
||||||
|
size = 85368709120
|
||||||
|
}
|
||||||
|
|
||||||
|
data "template_file" "user_data" {
|
||||||
|
template = file("${path.module}/cloud_init.cfg")
|
||||||
|
}
|
||||||
|
|
||||||
|
data "template_file" "network_config" {
|
||||||
|
template = file("${path.module}/network_config.cfg")
|
||||||
|
}
|
||||||
|
|
||||||
|
# for more info about paramater check this out
|
||||||
|
# https://github.com/dmacvicar/terraform-provider-libvirt/blob/loadbalance/website/docs/r/cloudinit.html.markdown
|
||||||
|
# Use CloudInit to add our ssh-key to the instance
|
||||||
|
# you can add also meta_data field
|
||||||
|
resource "libvirt_cloudinit_disk" "commoninit" {
|
||||||
|
name = "commoninit.iso"
|
||||||
|
user_data = data.template_file.user_data.rendered
|
||||||
|
network_config = data.template_file.network_config.rendered
|
||||||
|
pool = libvirt_pool.bullseye_basic.name
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create the libreddit machine
|
||||||
|
resource "libvirt_domain" "domain_bullseye_libreddit" {
|
||||||
|
count = var.libreddit_count
|
||||||
|
|
||||||
|
name = "bullseye_libreddit_${count.index}"
|
||||||
|
memory = "3000"
|
||||||
|
vcpu = 4
|
||||||
|
|
||||||
|
cloudinit = libvirt_cloudinit_disk.commoninit.id
|
||||||
|
|
||||||
|
network_interface {
|
||||||
|
network_name = "default"
|
||||||
|
wait_for_lease = true
|
||||||
|
}
|
||||||
|
|
||||||
|
# IMPORTANT: this is a known bug on cloud images, since they expect a console
|
||||||
|
# we need to pass it
|
||||||
|
# https://bugs.launchpad.net/cloud-images/+bug/1573095
|
||||||
|
console {
|
||||||
|
type = "pty"
|
||||||
|
target_port = "0"
|
||||||
|
target_type = "serial"
|
||||||
|
}
|
||||||
|
|
||||||
|
console {
|
||||||
|
type = "pty"
|
||||||
|
target_type = "virtio"
|
||||||
|
target_port = "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
disk {
|
||||||
|
volume_id = element(libvirt_volume.domain_bullseye_libreddit_volume.*.id, count.index)
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics {
|
||||||
|
type = "spice"
|
||||||
|
listen_type = "address"
|
||||||
|
autoport = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create the machine
|
||||||
|
resource "libvirt_domain" "domain_bullseye_loadbalance" {
|
||||||
|
count = var.loadbalance_count
|
||||||
|
|
||||||
|
name = "bullseye_loadbalance_${count.index}"
|
||||||
|
memory = "3000"
|
||||||
|
vcpu = 4
|
||||||
|
|
||||||
|
cloudinit = libvirt_cloudinit_disk.commoninit.id
|
||||||
|
|
||||||
|
network_interface {
|
||||||
|
network_name = "default"
|
||||||
|
wait_for_lease = true
|
||||||
|
}
|
||||||
|
|
||||||
|
# IMPORTANT: this is a known bug on cloud images, since they expect a console
|
||||||
|
# we need to pass it
|
||||||
|
# https://bugs.launchpad.net/cloud-images/+bug/1573095
|
||||||
|
console {
|
||||||
|
type = "pty"
|
||||||
|
target_port = "0"
|
||||||
|
target_type = "serial"
|
||||||
|
}
|
||||||
|
|
||||||
|
console {
|
||||||
|
type = "pty"
|
||||||
|
target_type = "virtio"
|
||||||
|
target_port = "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
disk {
|
||||||
|
volume_id = element(libvirt_volume.domain_bullseye_loadbalance_volume.*.id, count.index)
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics {
|
||||||
|
type = "spice"
|
||||||
|
listen_type = "address"
|
||||||
|
autoport = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
locals {
|
||||||
|
libreddit_vm_ips = [for i in libvirt_domain.domain_bullseye_libreddit : i.network_interface.0.addresses[0]]
|
||||||
|
libreddit_vm_names = [for i in libvirt_domain.domain_bullseye_libreddit : i.name]
|
||||||
|
libreddit_vm_map = [for i in libvirt_domain.domain_bullseye_libreddit : {
|
||||||
|
ip = i.network_interface.0.addresses[0],
|
||||||
|
name = i.name
|
||||||
|
}]
|
||||||
|
|
||||||
|
loadbalance_vm_ips = [for i in libvirt_domain.domain_bullseye_loadbalance : i.network_interface.0.addresses[0]]
|
||||||
|
loadbalance_vm_names = [for i in libvirt_domain.domain_bullseye_loadbalance : i.name]
|
||||||
|
loadbalance_vm_map = [for i in libvirt_domain.domain_bullseye_loadbalance : {
|
||||||
|
ip = i.network_interface.0.addresses[0],
|
||||||
|
name = i.name
|
||||||
|
}]
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
output "bullseye_libreddit_ip" {
|
||||||
|
value = local.libreddit_vm_map
|
||||||
|
}
|
||||||
|
|
||||||
|
output "bullseye_loadbalance_ip" {
|
||||||
|
value = local.loadbalance_vm_map
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "local_file" "hosts_yml" {
|
||||||
|
content = templatefile("./templates/hosts.yml.tftpl",
|
||||||
|
{
|
||||||
|
libreddit_vm_ips = local.libreddit_vm_ips,
|
||||||
|
libreddit_vm_names = local.libreddit_vm_names,
|
||||||
|
libreddit_vms = local.libreddit_vm_map,
|
||||||
|
|
||||||
|
loadbalance_vm_ips = local.loadbalance_vm_ips,
|
||||||
|
loadbalance_vm_names = local.loadbalance_vm_names,
|
||||||
|
loadbalance_vms = local.loadbalance_vm_map
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
filename = "./ansible/inventory/hosts.ini"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "local_file" "nginx_loadbalance_conf" {
|
||||||
|
content = templatefile("./templates/nginx-libreddit.tftpl",
|
||||||
|
{
|
||||||
|
libreddit_vm_ips = local.libreddit_vm_ips,
|
||||||
|
libreddit_vm_names = local.libreddit_vm_names,
|
||||||
|
libreddit_vms = local.libreddit_vm_map,
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
filename = "./ansible/assets/nginx.cfg"
|
||||||
|
}
|
4
network_config.cfg
Normal file
4
network_config.cfg
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
version: 2
|
||||||
|
ethernets:
|
||||||
|
ens3:
|
||||||
|
dhcp4: true
|
31
requirements.txt
Normal file
31
requirements.txt
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
ansible==8.1.0
|
||||||
|
ansible-core==2.15.1
|
||||||
|
certifi==2023.5.7
|
||||||
|
cffi==1.15.1
|
||||||
|
charset-normalizer==3.2.0
|
||||||
|
contextvars==2.4
|
||||||
|
cryptography==41.0.2
|
||||||
|
distro==1.8.0
|
||||||
|
execnet==2.0.2
|
||||||
|
idna==3.4
|
||||||
|
immutables==0.19
|
||||||
|
iniconfig==2.0.0
|
||||||
|
Jinja2==3.1.2
|
||||||
|
jmespath==1.0.1
|
||||||
|
looseversion==1.3.0
|
||||||
|
MarkupSafe==2.1.3
|
||||||
|
msgpack==1.0.5
|
||||||
|
packaging==23.1
|
||||||
|
pluggy==1.2.0
|
||||||
|
psutil==5.9.5
|
||||||
|
pycparser==2.21
|
||||||
|
pycryptodomex==3.18.0
|
||||||
|
pytest==7.4.0
|
||||||
|
pytest-testinfra==8.1.0
|
||||||
|
pytest-xdist==3.3.1
|
||||||
|
PyYAML==6.0
|
||||||
|
pyzmq==25.0.2
|
||||||
|
requests==2.31.0
|
||||||
|
resolvelib==1.0.1
|
||||||
|
salt==3006.1
|
||||||
|
urllib3==2.0.3
|
7
scripts/on.sh
Executable file
7
scripts/on.sh
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
|
||||||
|
for vm in $(virsh list --all --name --state-shutoff); do \
|
||||||
|
echo "[*] Starting vm: $vm"; \
|
||||||
|
virsh start $vm; \
|
||||||
|
done
|
9
templates/hosts.yml.tftpl
Normal file
9
templates/hosts.yml.tftpl
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[bullseye_loadbalance]
|
||||||
|
%{ for vm in loadbalance_vms ~}
|
||||||
|
${vm.name} ansible_host=${vm.ip} ansible_user=root
|
||||||
|
%{ endfor ~}
|
||||||
|
|
||||||
|
[bullseye_libreddit]
|
||||||
|
%{ for vm in libreddit_vms ~}
|
||||||
|
${vm.name} ansible_host=${vm.ip} ansible_user=root
|
||||||
|
%{ endfor ~}
|
22
templates/nginx-libreddit.tftpl
Normal file
22
templates/nginx-libreddit.tftpl
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
upstream libreddit {
|
||||||
|
%{ for vm in libreddit_vms ~}
|
||||||
|
server ${vm.ip}:8080; #${vm.name}
|
||||||
|
%{ endfor ~}
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
|
||||||
|
listen 80 default_server;
|
||||||
|
listen [::]:80 default_server;
|
||||||
|
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
|
||||||
|
proxy_read_timeout 300s;
|
||||||
|
|
||||||
|
proxy_pass http://libreddit; #pass all requests processed to the libreddit upstream servers
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
9
tests/requirements.txt
Normal file
9
tests/requirements.txt
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
attrs==22.1.0
|
||||||
|
iniconfig==1.1.1
|
||||||
|
packaging==21.3
|
||||||
|
pluggy==1.0.0
|
||||||
|
py==1.11.0
|
||||||
|
pyparsing==3.0.9
|
||||||
|
pytest==7.1.3
|
||||||
|
pytest-testinfra==6.8.0
|
||||||
|
tomli==2.0.1
|
45
tests/test_basic.py
Normal file
45
tests/test_basic.py
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
# SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def test_packages_are_installed(host):
|
||||||
|
packages = [
|
||||||
|
"git",
|
||||||
|
"wget",
|
||||||
|
"curl",
|
||||||
|
"gpg",
|
||||||
|
"ca-certificates",
|
||||||
|
"zip",
|
||||||
|
"python3-pip",
|
||||||
|
"virtualenv",
|
||||||
|
"python3-setuptools",
|
||||||
|
]
|
||||||
|
for p in packages:
|
||||||
|
print(f"[*] Checking if {p} is installed")
|
||||||
|
pkg = host.package(p)
|
||||||
|
assert pkg.is_installed
|
||||||
|
|
||||||
|
|
||||||
|
def test_ssh_is_listening(host):
|
||||||
|
socket = host.socket(f"tcp://0.0.0.0:22")
|
||||||
|
assert socket.is_listening
|
||||||
|
|
||||||
|
|
||||||
|
def test_ufw_service_running_and_enabled(host):
|
||||||
|
service = host.service("ufw")
|
||||||
|
assert service.is_running
|
||||||
|
assert service.is_enabled
|
||||||
|
|
||||||
|
|
||||||
|
def test_ssh_service_running_and_enabled(host):
|
||||||
|
service = host.service("ssh")
|
||||||
|
assert service.is_running
|
||||||
|
assert service.is_enabled
|
||||||
|
|
||||||
|
|
||||||
|
def test_ssh_is_installed(host):
|
||||||
|
pkg = host.package("openssh-server")
|
||||||
|
assert pkg.is_installed
|
40
tests/test_libreddit.py
Normal file
40
tests/test_libreddit.py
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
# SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def test_packages_are_installed(host):
|
||||||
|
packages = [
|
||||||
|
"ufw",
|
||||||
|
"docker-ce",
|
||||||
|
]
|
||||||
|
for p in packages:
|
||||||
|
print(f"[*] Checking if {p} is installed")
|
||||||
|
pkg = host.package(p)
|
||||||
|
assert pkg.is_installed
|
||||||
|
|
||||||
|
def test_docker_is_installed(host):
|
||||||
|
keyring_dir = host.file("/etc/apt/keyrings")
|
||||||
|
assert keyring_dir.exists
|
||||||
|
assert keyring_dir.is_directory
|
||||||
|
|
||||||
|
def test_docker_is_installed(host):
|
||||||
|
keyring_dir = host.file("/etc/apt/keyrings")
|
||||||
|
assert keyring_dir.exists
|
||||||
|
assert keyring_dir.is_directory
|
||||||
|
|
||||||
|
|
||||||
|
def test_ufw_service_running_and_enabled(host):
|
||||||
|
service = host.service("ufw")
|
||||||
|
assert service.is_running
|
||||||
|
assert service.is_enabled
|
||||||
|
|
||||||
|
def test_libreddit_docker_img(host):
|
||||||
|
libreddit = host.docker("libreddit")
|
||||||
|
assert libreddit.is_running
|
||||||
|
|
||||||
|
def test_libreddit_is_listening(host):
|
||||||
|
socket = host.socket(f"tcp://0.0.0.0:8080")
|
||||||
|
assert socket.is_listening
|
47
tests/test_loadbalance.py
Normal file
47
tests/test_loadbalance.py
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
# SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def test_packages_are_installed(host):
|
||||||
|
packages = [
|
||||||
|
"nginx",
|
||||||
|
"ufw",
|
||||||
|
"git",
|
||||||
|
"nginx",
|
||||||
|
"wget",
|
||||||
|
"curl",
|
||||||
|
"gpg",
|
||||||
|
"ca-certificates",
|
||||||
|
"zip",
|
||||||
|
"python3-pip",
|
||||||
|
"virtualenv",
|
||||||
|
"python3-setuptools",
|
||||||
|
]
|
||||||
|
for p in packages:
|
||||||
|
print(f"[*] Checking if {p} is installed")
|
||||||
|
pkg = host.package(p)
|
||||||
|
assert pkg.is_installed
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_nginx_service_running_and_enabled(host):
|
||||||
|
service = host.service("nginx")
|
||||||
|
assert service.is_running
|
||||||
|
assert service.is_enabled
|
||||||
|
|
||||||
|
def test_config_is_present(host):
|
||||||
|
file = host.file("/etc/nginx/sites-available/nginx.cfg")
|
||||||
|
assert file.exists
|
||||||
|
assert file.is_file
|
||||||
|
|
||||||
|
sym_file = host.file("/etc/nginx/sites-enabled/default")
|
||||||
|
assert sym_file.exists
|
||||||
|
assert sym_file.is_symlink
|
||||||
|
assert sym_file.linked_to == file
|
||||||
|
|
||||||
|
def test_nginx_is_listening(host):
|
||||||
|
socket = host.socket(f"tcp://0.0.0.0:80")
|
||||||
|
assert socket.is_listening
|
Loading…
Add table
Reference in a new issue