mirror of
https://github.com/viq/NewsBlur.git
synced 2025-04-13 09:38:09 +00:00
Adding hetzner servers.
This commit is contained in:
parent
a5d6f9178e
commit
f9ad93e336
14 changed files with 175 additions and 16 deletions
11
.vscode/settings.json
vendored
11
.vscode/settings.json
vendored
|
@ -1,4 +1,15 @@
|
||||||
{
|
{
|
||||||
|
"black-formatter.args": [
|
||||||
|
"--line-length 110"
|
||||||
|
],
|
||||||
|
"isort.args": [
|
||||||
|
"--profile",
|
||||||
|
"black"
|
||||||
|
],
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.organizeImports": "explicit"
|
||||||
|
},
|
||||||
"python.linting.enabled": true,
|
"python.linting.enabled": true,
|
||||||
"python.linting.pylintEnabled": false,
|
"python.linting.pylintEnabled": false,
|
||||||
"python.linting.flake8Enabled": true,
|
"python.linting.flake8Enabled": true,
|
||||||
|
|
3
Makefile
3
Makefile
|
@ -115,7 +115,8 @@ inventory:
|
||||||
./ansible/utils/generate_inventory.py
|
./ansible/utils/generate_inventory.py
|
||||||
oldinventory:
|
oldinventory:
|
||||||
OLD=1 ./ansible/utils/generate_inventory.py
|
OLD=1 ./ansible/utils/generate_inventory.py
|
||||||
|
hinventory:
|
||||||
|
./ansible/utils/generate_hetzner_inventory.py
|
||||||
# Docker
|
# Docker
|
||||||
pull:
|
pull:
|
||||||
docker pull newsblur/newsblur_python3
|
docker pull newsblur/newsblur_python3
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
host_key_checking = False
|
host_key_checking = False
|
||||||
remote_user = nb
|
remote_user = nb
|
||||||
retry_files_enabled = False
|
retry_files_enabled = False
|
||||||
inventory = /srv/newsblur/ansible/inventories/digital_ocean.ini, /srv/newsblur/ansible/inventories/digital_ocean.yml
|
inventory = /srv/newsblur/ansible/inventories/digital_ocean.ini, /srv/newsblur/ansible/inventories/digital_ocean.yml, /srv/newsblur/ansible/inventories/hetzner.ini, /srv/newsblur/ansible/inventories/hetzner.yml
|
||||||
private_key_file = /srv/secrets-newsblur/keys/docker.key
|
private_key_file = /srv/secrets-newsblur/keys/docker.key
|
||||||
remote_tmp = ~/.ansible/tmp
|
remote_tmp = ~/.ansible/tmp
|
||||||
forks = 20
|
forks = 20
|
||||||
|
|
2
ansible/inventories/.gitignore
vendored
2
ansible/inventories/.gitignore
vendored
|
@ -1 +1 @@
|
||||||
*.ini
|
digital_ocean*.ini
|
||||||
|
|
1
ansible/inventories/hetzner.ini
Symbolic link
1
ansible/inventories/hetzner.ini
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../secrets-newsblur/configs/hetzner.ini
|
41
ansible/inventories/hetzner.yml
Normal file
41
ansible/inventories/hetzner.yml
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
plugin: constructed
|
||||||
|
strict: False
|
||||||
|
|
||||||
|
groups:
|
||||||
|
|
||||||
|
haproxy: inventory_hostname.startswith('hwww')
|
||||||
|
|
||||||
|
web: inventory_hostname.startswith('happ')
|
||||||
|
app: inventory_hostname.startswith('happ')
|
||||||
|
django: inventory_hostname.startswith('happ-django')
|
||||||
|
refresh: inventory_hostname.startswith('happ-refresh')
|
||||||
|
counts: inventory_hostname.startswith('happ-counts')
|
||||||
|
push: inventory_hostname.startswith('happ-push')
|
||||||
|
blogs: inventory_hostname.startswith('blog')
|
||||||
|
|
||||||
|
node: inventory_hostname.startswith('hnode')
|
||||||
|
node_socket: inventory_hostname.startswith('hnode-socket')
|
||||||
|
node_images: inventory_hostname.startswith('hnode-images')
|
||||||
|
node_text: inventory_hostname.startswith('hnode-text')
|
||||||
|
node_page: inventory_hostname.startswith('hnode-page')
|
||||||
|
node_favicons: inventory_hostname.startswith('hnode-favicons')
|
||||||
|
|
||||||
|
# debugs: inventory_hostname.startswith('hdebug')
|
||||||
|
|
||||||
|
task: inventory_hostname.startswith('htask')
|
||||||
|
celery: inventory_hostname.startswith('htask-celery')
|
||||||
|
work: inventory_hostname.startswith('htask-work')
|
||||||
|
|
||||||
|
staging: inventory_hostname.startswith('hstaging')
|
||||||
|
|
||||||
|
db: inventory_hostname.startswith('hdb')
|
||||||
|
search: inventory_hostname.startswith('hdb-elasticsearch')
|
||||||
|
elasticsearch: inventory_hostname.startswith('hdb-elasticsearch')
|
||||||
|
redis: inventory_hostname.startswith('hdb-redis')
|
||||||
|
redis_story: inventory_hostname.startswith('hdb-redis-story')
|
||||||
|
postgres: inventory_hostname.startswith('hdb-postgres')
|
||||||
|
mongo: inventory_hostname.startswith('hdb-mongo') and not inventory_hostname.startswith('hdb-mongo-analytics')
|
||||||
|
mongo_analytics: inventory_hostname.startswith('hdb-mongo-analytics')
|
||||||
|
consul: inventory_hostname.startswith('hdb-consul')
|
||||||
|
metrics: inventory_hostname.startswith('hdb-metrics')
|
||||||
|
sentry: inventory_hostname.startswith('hdb-sentry')
|
|
@ -1,11 +1,19 @@
|
||||||
{
|
{
|
||||||
|
{% if inventory_hostname.startswith("h") %}
|
||||||
"datacenter": "nyc1",
|
"datacenter": "nyc1",
|
||||||
|
{% else %}
|
||||||
|
"datacenter": "nyc1",
|
||||||
|
{% endif %}
|
||||||
"data_dir": "/opt/consul",
|
"data_dir": "/opt/consul",
|
||||||
"log_level": "INFO",
|
"log_level": "INFO",
|
||||||
"log_file": "/var/log/consul/consul.log",
|
"log_file": "/var/log/consul/consul.log",
|
||||||
"enable_syslog": true,
|
"enable_syslog": true,
|
||||||
"retry_join": [{{ consul_manager_ip.stdout|trim }}],
|
"retry_join": [{{ consul_manager_ip.stdout|trim }}],
|
||||||
|
{% if inventory_hostname.startswith("h") %}
|
||||||
|
"advertise_addr": "{% raw %}{{ GetAllInterfaces | include \"name\" \"^enp\" | include \"flags\" \"forwardable|up\" | attr \"address\" }}{% endraw %}",
|
||||||
|
{% else %}
|
||||||
"advertise_addr": "{% raw %}{{ GetAllInterfaces | include \"name\" \"^eth\" | include \"flags\" \"forwardable|up\" | attr \"address\" }}{% endraw %}",
|
"advertise_addr": "{% raw %}{{ GetAllInterfaces | include \"name\" \"^eth\" | include \"flags\" \"forwardable|up\" | attr \"address\" }}{% endraw %}",
|
||||||
|
{% endif %}
|
||||||
"bind_addr": "0.0.0.0",
|
"bind_addr": "0.0.0.0",
|
||||||
"ui_config": {"enabled": true},
|
"ui_config": {"enabled": true},
|
||||||
"dns_config": {
|
"dns_config": {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
---
|
---
|
||||||
- name: Add the HashiCorp GPG key
|
- name: Add the HashiCorp GPG key
|
||||||
become: yes
|
become: yes
|
||||||
|
# Only warn if fail
|
||||||
|
ignore_errors: yes
|
||||||
apt_key:
|
apt_key:
|
||||||
url: https://apt.releases.hashicorp.com/gpg
|
url: https://apt.releases.hashicorp.com/gpg
|
||||||
state: present
|
state: present
|
||||||
|
|
|
@ -19,7 +19,17 @@
|
||||||
|
|
||||||
- name: Bind dnsmasq to localhost
|
- name: Bind dnsmasq to localhost
|
||||||
become: yes
|
become: yes
|
||||||
lineinfile: dest=/etc/dnsmasq.conf state=present line='listen-address=127.0.0.1'
|
lineinfile:
|
||||||
|
dest: /etc/dnsmasq.conf
|
||||||
|
state: present
|
||||||
|
line: 'listen-address=127.0.0.1'
|
||||||
|
|
||||||
|
- name: Gather network facts
|
||||||
|
become: yes
|
||||||
|
setup:
|
||||||
|
gather_subset:
|
||||||
|
- '!all'
|
||||||
|
- network
|
||||||
|
|
||||||
- name: Check if resolv.conf exists
|
- name: Check if resolv.conf exists
|
||||||
become: yes
|
become: yes
|
||||||
|
@ -27,18 +37,23 @@
|
||||||
path: /etc/resolv.conf
|
path: /etc/resolv.conf
|
||||||
register: resolvconf
|
register: resolvconf
|
||||||
|
|
||||||
# - debug: msg="{{resolvconf}}"
|
|
||||||
|
|
||||||
- name: Add localhost to resolv.conf
|
- name: Add localhost to resolv.conf
|
||||||
become: yes
|
become: yes
|
||||||
lineinfile: dest=/etc/resolv.conf state=present line='nameserver 127.0.0.1' insertbefore=BOF
|
lineinfile:
|
||||||
when: resolvconf.stat.readable
|
dest: /etc/resolv.conf
|
||||||
|
state: present
|
||||||
|
line: 'nameserver 127.0.0.1'
|
||||||
|
insertbefore: BOF
|
||||||
|
when: resolvconf.stat.exists
|
||||||
|
|
||||||
- name: user=root dnsmasq
|
- name: Set dnsmasq user to root
|
||||||
become: yes
|
become: yes
|
||||||
lineinfile: dest=/etc/dnsmasq.conf state=present line='user=root'
|
lineinfile:
|
||||||
|
dest: /etc/dnsmasq.conf
|
||||||
|
state: present
|
||||||
|
line: 'user=root'
|
||||||
|
|
||||||
- name: Stop systemd-resolved
|
- name: Stop and disable systemd-resolved
|
||||||
become: yes
|
become: yes
|
||||||
systemd:
|
systemd:
|
||||||
name: systemd-resolved
|
name: systemd-resolved
|
||||||
|
@ -54,6 +69,8 @@
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: 0644
|
mode: 0644
|
||||||
|
vars:
|
||||||
|
network_interfaces: "{{ ansible_interfaces }}"
|
||||||
notify: restart dnsmasq
|
notify: restart dnsmasq
|
||||||
|
|
||||||
- name: Launch dnsmasq
|
- name: Launch dnsmasq
|
||||||
|
|
|
@ -8,9 +8,9 @@ server=/consul/127.0.0.1#8600
|
||||||
{# dnsmasq should not needlessly read /etc/resolv.conf #}
|
{# dnsmasq should not needlessly read /etc/resolv.conf #}
|
||||||
no-resolv
|
no-resolv
|
||||||
|
|
||||||
interface=lo
|
{% for interface in network_interfaces %}
|
||||||
interface=eth0
|
interface={{ interface }}
|
||||||
interface=eth1
|
{% endfor %}
|
||||||
|
|
||||||
bind-interfaces
|
bind-interfaces
|
||||||
# log-dhcp
|
# log-dhcp
|
||||||
|
|
|
@ -103,7 +103,7 @@
|
||||||
- /srv/newsblur/config/mongodb_keyfile.key:/srv/newsblur/config/mongodb_keyfile.key
|
- /srv/newsblur/config/mongodb_keyfile.key:/srv/newsblur/config/mongodb_keyfile.key
|
||||||
- /var/log/mongodb/:/var/log/mongodb/
|
- /var/log/mongodb/:/var/log/mongodb/
|
||||||
- /mnt/{{ inventory_hostname | regex_replace('db-|-', '') }}/backup/:/backup/
|
- /mnt/{{ inventory_hostname | regex_replace('db-|-', '') }}/backup/:/backup/
|
||||||
when: (inventory_hostname | regex_replace('[0-9]+', '')) in ['db-mongo', 'db-mongo-primary', 'db-mongo-secondary']
|
when: (inventory_hostname | regex_replace('\-?[0-9]+', '')) in ['db-mongo', 'db-mongo-primary', 'db-mongo-secondary', 'hdb-mongo-secondary', 'hdb-mongo-primray']
|
||||||
|
|
||||||
- name: Start db-mongo-analytics docker container
|
- name: Start db-mongo-analytics docker container
|
||||||
become: yes
|
become: yes
|
||||||
|
@ -131,7 +131,7 @@
|
||||||
- /srv/newsblur/config/mongodb_keyfile.key:/srv/newsblur/config/mongodb_keyfile.key
|
- /srv/newsblur/config/mongodb_keyfile.key:/srv/newsblur/config/mongodb_keyfile.key
|
||||||
- /var/log/mongodb/:/var/log/mongodb/
|
- /var/log/mongodb/:/var/log/mongodb/
|
||||||
- /mnt/{{ inventory_hostname | regex_replace('db-|-', '') }}/backup/:/backup/
|
- /mnt/{{ inventory_hostname | regex_replace('db-|-', '') }}/backup/:/backup/
|
||||||
when: (inventory_hostname | regex_replace('[0-9]+', '')) == 'db-mongo-analytics'
|
when: (inventory_hostname | regex_replace('[0-9]+', '')) in ['db-mongo-analytics', 'hdb-mongo-analytics']
|
||||||
|
|
||||||
- name: Create mongo database user
|
- name: Create mongo database user
|
||||||
shell:
|
shell:
|
||||||
|
|
|
@ -35,6 +35,17 @@
|
||||||
- firewall
|
- firewall
|
||||||
- ufw
|
- ufw
|
||||||
|
|
||||||
|
- name: Allow all access from Hetzner inventory hosts with docker
|
||||||
|
become: yes
|
||||||
|
ufw:
|
||||||
|
rule: allow
|
||||||
|
src: '{{ item }}'
|
||||||
|
with_items: "{{ groups['NewsBlur_Hetzner'] | map('extract', hostvars, ['ansible_host']) }}"
|
||||||
|
tags:
|
||||||
|
- firewall
|
||||||
|
- ufw
|
||||||
|
- hetzner_firewall
|
||||||
|
|
||||||
- name: Allow all access from inventory hosts old + new
|
- name: Allow all access from inventory hosts old + new
|
||||||
become: yes
|
become: yes
|
||||||
ufw:
|
ufw:
|
||||||
|
|
34
ansible/utils/generate_hetzner_inventory.py
Executable file
34
ansible/utils/generate_hetzner_inventory.py
Executable file
|
@ -0,0 +1,34 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
from hetzner.robot import Robot
|
||||||
|
|
||||||
|
TOKEN_FILE = "/srv/secrets-newsblur/keys/hetzner.yaml"
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
# Load credentials from a YAML file
|
||||||
|
with open(TOKEN_FILE, "r") as file:
|
||||||
|
credentials = yaml.safe_load(file)
|
||||||
|
|
||||||
|
user = credentials["hetzner_robot"]["username"]
|
||||||
|
password = credentials["hetzner_robot"]["password"]
|
||||||
|
outfile = f"/srv/newsblur/ansible/inventories/hetzner.ini"
|
||||||
|
print(user, password)
|
||||||
|
robot = Robot(user, password)
|
||||||
|
|
||||||
|
# Check if the request was successful
|
||||||
|
if robot.servers:
|
||||||
|
with open(outfile, "w") as inventory_file:
|
||||||
|
inventory_file.write("[hetzner_servers]\n")
|
||||||
|
for server in robot.servers:
|
||||||
|
# Assuming the server IP is under 'server_ip' key
|
||||||
|
inventory_file.write(f"{server.ip}\n")
|
||||||
|
print(f"Inventory file 'hetzner_inventory.ini' created with {len(servers)} servers")
|
||||||
|
else:
|
||||||
|
print(f"Failed to fetch server data")
|
33
utils/ssh_hz.sh
Executable file
33
utils/ssh_hz.sh
Executable file
|
@ -0,0 +1,33 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# The script name
|
||||||
|
SCRIPT_NAME=$(basename "$0")
|
||||||
|
|
||||||
|
# The alias provided as an argument
|
||||||
|
ALIAS=$1
|
||||||
|
|
||||||
|
# The .ini file location
|
||||||
|
INI_FILE="ansible/inventories/hetzner.ini"
|
||||||
|
|
||||||
|
# Check if an alias is provided
|
||||||
|
if [ -z "$ALIAS" ]; then
|
||||||
|
echo "Usage: $SCRIPT_NAME <alias>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Function to extract ansible_host value
|
||||||
|
extract_host() {
|
||||||
|
grep "$1" "$INI_FILE" | awk '{print $2}' | cut -d'=' -f2
|
||||||
|
}
|
||||||
|
|
||||||
|
# Extract the host for the given alias
|
||||||
|
HOST=$(extract_host "$ALIAS")
|
||||||
|
|
||||||
|
# Check if a host was found
|
||||||
|
if [ -z "$HOST" ]; then
|
||||||
|
echo "Host for alias '$ALIAS' not found in $INI_FILE."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# SSH into the host
|
||||||
|
ssh -i /srv/secrets-newsblur/keys/docker.key "nb@$HOST"
|
Loading…
Add table
Reference in a new issue