Initial Commit
This commit is contained in:
commit
da3f8ad7a4
24 changed files with 351 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
.DS_Store
|
||||||
|
.vault
|
||||||
|
secrets.enc
|
||||||
|
todo
|
2
LICENSE
Normal file
2
LICENSE
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# WIP
|
||||||
|
# currently (c) Sangelo 2023-2024
|
2
ansible.cfg
Normal file
2
ansible.cfg
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[defaults]
|
||||||
|
roles_path = roles/
|
0
inventory/beta.ini
Normal file
0
inventory/beta.ini
Normal file
23
inventory/group_vars/dockertest.yml
Normal file
23
inventory/group_vars/dockertest.yml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
proxmox_id: 100
|
||||||
|
common_firewall_enable: false
|
||||||
|
|
||||||
|
core_groups:
|
||||||
|
- name: "mgmt"
|
||||||
|
state: present
|
||||||
|
|
||||||
|
core_users:
|
||||||
|
- name: "sangelo"
|
||||||
|
password: "!"
|
||||||
|
groups: ["sudo"]
|
||||||
|
state: present
|
||||||
|
authorized_keys:
|
||||||
|
- "sangelo"
|
||||||
|
- "sangelo-access"
|
||||||
|
|
||||||
|
- name: "dockertest"
|
||||||
|
password: "{{ sec_dockertest_pass }}"
|
||||||
|
group: "docker"
|
||||||
|
state: present
|
||||||
|
authorized_keys:
|
||||||
|
- "sangelo"
|
||||||
|
- "sangelo-access"
|
0
inventory/host_vars/.gitkeep
Normal file
0
inventory/host_vars/.gitkeep
Normal file
0
inventory/prod.ini
Normal file
0
inventory/prod.ini
Normal file
2
inventory/test.ini
Normal file
2
inventory/test.ini
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[dockertest]
|
||||||
|
10.1.1.1
|
9
playbooks/test/dockertest.yml
Normal file
9
playbooks/test/dockertest.yml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
- name: install docker
|
||||||
|
hosts: dockertest
|
||||||
|
remote_user: root
|
||||||
|
|
||||||
|
roles:
|
||||||
|
- common
|
||||||
|
- core_docker
|
||||||
|
- core_users
|
10
roles/common/tasks/main.yml
Normal file
10
roles/common/tasks/main.yml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
- name: Run all common tasks
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: '{{ common_role }}'
|
||||||
|
loop:
|
||||||
|
- 'common_secure'
|
||||||
|
# - 'common_mgmt'
|
||||||
|
- 'common_tools'
|
||||||
|
- 'common_tweaks'
|
||||||
|
loop_control:
|
||||||
|
loop_var: common_role
|
16
roles/common_secure/defaults/main.yml
Normal file
16
roles/common_secure/defaults/main.yml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# Make a full system upgrade (using apt-get full-upgrade)
|
||||||
|
common_full_upgrade: false
|
||||||
|
|
||||||
|
# Install and configure UFW Firewall on the system
|
||||||
|
common_firewall_enable: true
|
||||||
|
common_firewall_reject: false # reject all connections by default
|
||||||
|
common_firewall_ssh: true # allow ssh connections
|
||||||
|
common_firewall_https: false # allow https connections
|
||||||
|
common_firewall_http: false # allow http connections
|
||||||
|
|
||||||
|
# Configure SSH to only accept SSH Keys
|
||||||
|
common_ssh_configure: true
|
||||||
|
|
||||||
|
# This locks the root account *password*, but still allows SSH Key and sudo logins
|
||||||
|
# To unlock the password, set this to false.
|
||||||
|
common_lock_root: true
|
1
roles/common_secure/files/sangelo.pub
Normal file
1
roles/common_secure/files/sangelo.pub
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFg9CWMZHj6ksnVsxsZf/6sP6ae1kP2FSMPcfguYmXs1 contact@sangelo.space
|
4
roles/common_secure/handlers/main.yml
Normal file
4
roles/common_secure/handlers/main.yml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
- name: restart ssh
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: sshd
|
||||||
|
state: restarted
|
99
roles/common_secure/tasks/main.yml
Normal file
99
roles/common_secure/tasks/main.yml
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
---
|
||||||
|
# roles/common_secure/tasks/main.yml
|
||||||
|
|
||||||
|
- name: Upgrade system packages
|
||||||
|
ansible.builtin.apt:
|
||||||
|
update_cache: true
|
||||||
|
upgrade: full
|
||||||
|
when: common_full_upgrade
|
||||||
|
|
||||||
|
- name: Install UFW Firewall
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: ufw
|
||||||
|
# update_cache: true
|
||||||
|
state: present
|
||||||
|
when: common_firewall_enable
|
||||||
|
|
||||||
|
- name: Enable UFW
|
||||||
|
community.general.ufw:
|
||||||
|
state: enabled
|
||||||
|
logging: 'on'
|
||||||
|
when: common_firewall_enable
|
||||||
|
|
||||||
|
- name: Disable UFW Firewall
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: ufw
|
||||||
|
state: absent
|
||||||
|
when: not common_firewall_enable
|
||||||
|
|
||||||
|
- name: Reject incoming connections by default
|
||||||
|
community.general.ufw:
|
||||||
|
policy: reject
|
||||||
|
comment: 'Reject all by default'
|
||||||
|
when: common_firewall_reject and common_firewall_enable
|
||||||
|
|
||||||
|
- name: Allow SSH Connections
|
||||||
|
community.general.ufw:
|
||||||
|
rule: limit
|
||||||
|
port: ssh
|
||||||
|
proto: tcp
|
||||||
|
comment: 'Allow SSH'
|
||||||
|
when: common_firewall_ssh and common_firewall_enable
|
||||||
|
|
||||||
|
- name: Allow HTTPS Connections
|
||||||
|
community.general.ufw:
|
||||||
|
rule: allow
|
||||||
|
port: https
|
||||||
|
proto: tcp
|
||||||
|
comment: 'Allow HTTPS'
|
||||||
|
when: common_firewall_https and common_firewall_enable
|
||||||
|
|
||||||
|
- name: Allow HTTP Connections
|
||||||
|
community.general.ufw:
|
||||||
|
rule: allow
|
||||||
|
port: http
|
||||||
|
proto: tcp
|
||||||
|
comment: 'Allow HTTP'
|
||||||
|
when: common_firewall_http and common_firewall_enable
|
||||||
|
|
||||||
|
- name: Configure SSH to disallow passwords
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/ssh/sshd_config
|
||||||
|
regexp: "{{ ssh_config_entry.regexp }}"
|
||||||
|
line: "{{ ssh_config_entry.line }}"
|
||||||
|
state: present
|
||||||
|
loop:
|
||||||
|
- { regexp: '^PasswordAuthentication', line: 'PasswordAuthentication no' }
|
||||||
|
loop_control:
|
||||||
|
loop_var: ssh_config_entry
|
||||||
|
notify: restart ssh
|
||||||
|
when: common_ssh_configure
|
||||||
|
|
||||||
|
- name: Add authorized ssh keys for root
|
||||||
|
ansible.posix.authorized_key:
|
||||||
|
user: root
|
||||||
|
state: present
|
||||||
|
key: "{{ lookup('file', ssh_key_file) }}"
|
||||||
|
loop: "{{ query('fileglob', '../files/*') }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: ssh_key_file
|
||||||
|
|
||||||
|
- name: Lock the root account
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: root
|
||||||
|
password_lock: "{{ 'no' if common_lock_root is defined and not common_lock_root else 'yes' }}"
|
||||||
|
|
||||||
|
# - name: Configure SSH to disallow root login
|
||||||
|
# ansible.builtin.lineinfile:
|
||||||
|
# path: /etc/ssh/sshd_config
|
||||||
|
# regexp: '^PermitRootLogin'
|
||||||
|
# line: 'PermitRootLogin no'
|
||||||
|
# state: present
|
||||||
|
# notify: restart ssh
|
||||||
|
# when: common_ssh_configure
|
||||||
|
|
||||||
|
# - name: Disable root shell
|
||||||
|
# ansible.builtin.user:
|
||||||
|
# name: root
|
||||||
|
# shell: /usr/sbin/nologin
|
||||||
|
# when: common_disable_root
|
9
roles/common_tools/tasks/main.yml
Normal file
9
roles/common_tools/tasks/main.yml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
# roles/common_tools/tasks/main.yml
|
||||||
|
- name: Install common tools
|
||||||
|
ansible.builtin.apt:
|
||||||
|
pkg:
|
||||||
|
- vim
|
||||||
|
- curl
|
||||||
|
update_cache: true
|
||||||
|
state: present
|
1
roles/common_tweaks/defaults/main.yml
Normal file
1
roles/common_tweaks/defaults/main.yml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
proxmox_id: "'PLEASE SET IN ANSIBLE'"
|
45
roles/common_tweaks/files/etc/update-motd.d/01-motd
Normal file
45
roles/common_tweaks/files/etc/update-motd.d/01-motd
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
source /etc/environment
|
||||||
|
|
||||||
|
# Function to get usage and colorize based on the percentage
|
||||||
|
get_usage_color() {
|
||||||
|
local usage=$1
|
||||||
|
if [ $usage -lt 60 ]; then
|
||||||
|
echo -e "\e[32m${usage}%\e[0m" # Dark Green for < 60%
|
||||||
|
elif [ $usage -lt 80 ]; then
|
||||||
|
echo -e "\e[92m${usage}%\e[0m" # Green for >= 60% and < 80%
|
||||||
|
elif [ $usage -lt 90 ]; then
|
||||||
|
echo -e "\e[93m${usage}%\e[0m" # Orange for >= 80% and < 90%
|
||||||
|
else
|
||||||
|
echo -e "\e[91m${usage}%\e[0m" # Red for >= 90%
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "===================="
|
||||||
|
|
||||||
|
# Hostname
|
||||||
|
echo "Connecting to: $(hostname) ($PROXMOX_ID)"
|
||||||
|
|
||||||
|
# CPU Usage
|
||||||
|
cpu_usage=$(grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage}')
|
||||||
|
cpu_color=$(get_usage_color ${cpu_usage%.*})
|
||||||
|
echo "CPU Usage: $cpu_color"
|
||||||
|
|
||||||
|
# RAM Usage
|
||||||
|
ram_usage=$(free | grep Mem | awk '{print $3/$2 * 100.0}')
|
||||||
|
ram_color=$(get_usage_color ${ram_usage%.*})
|
||||||
|
echo "RAM Usage: $ram_color"
|
||||||
|
|
||||||
|
# Disk Usage
|
||||||
|
disk_usage=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//g')
|
||||||
|
disk_color=$(get_usage_color $disk_usage)
|
||||||
|
echo "Disk Usage: $disk_color"
|
||||||
|
|
||||||
|
# Swap Usage
|
||||||
|
swap_usage=$(free | grep Swap | awk '{print $3/$2 * 100.0}')
|
||||||
|
swap_color=$(get_usage_color ${swap_usage%.*})
|
||||||
|
echo "Swap Usage: $swap_color"
|
||||||
|
|
||||||
|
echo -e "====================
|
||||||
|
"
|
42
roles/common_tweaks/tasks/main.yml
Normal file
42
roles/common_tweaks/tasks/main.yml
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
---
|
||||||
|
# roles/common_tweaks/tasks/main.yml
|
||||||
|
|
||||||
|
- name: Find existing files in /etc/update-motd.d
|
||||||
|
ansible.builtin.find:
|
||||||
|
paths: /etc/update-motd.d
|
||||||
|
register: files_to_remove
|
||||||
|
|
||||||
|
- name: Remove other files in /etc/update-motd.d
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item.path }}"
|
||||||
|
state: absent
|
||||||
|
with_items: "{{ files_to_remove.files }}"
|
||||||
|
when: item.path != '/etc/update-motd.d/01-motd'
|
||||||
|
|
||||||
|
- name: Copy 01-motd to /etc/update-motd.d on remote host
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: ../files/etc/update-motd.d/01-motd
|
||||||
|
dest: /etc/update-motd.d/01-motd
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Ensure /etc/motd is empty
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: ''
|
||||||
|
dest: /etc/motd
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Add Proxmox-ID to /etc/environment ({{ proxmox_id }})
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/environment
|
||||||
|
regexp: '^PROXMOX_ID='
|
||||||
|
line: 'PROXMOX_ID={{ proxmox_id }}'
|
||||||
|
create: yes
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Add a warning comment
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/environment
|
||||||
|
insertbefore: "^PROXMOX_ID="
|
||||||
|
line: "# Do not change the line below - it is set by Ansible"
|
||||||
|
create: yes
|
||||||
|
state: present
|
30
roles/core_docker/tasks/main.yml
Normal file
30
roles/core_docker/tasks/main.yml
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
---
|
||||||
|
# roles/core_docker/tasks/main.yml
|
||||||
|
|
||||||
|
- name: Install prerequisites
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- apt-transport-https
|
||||||
|
- ca-certificates
|
||||||
|
- curl
|
||||||
|
- software-properties-common
|
||||||
|
state: present
|
||||||
|
update_cache: yes
|
||||||
|
|
||||||
|
- name: Add Docker GPG Key
|
||||||
|
apt_key:
|
||||||
|
url: https://download.docker.com/linux/{{ distro }}/gpg
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Add Docker Repository
|
||||||
|
apt_repository:
|
||||||
|
repo: deb https://download.docker.com/linux/{{ distro }} {{ codename }} stable
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Install Docker
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- docker-ce
|
||||||
|
- docker-compose-plugin
|
||||||
|
state: present
|
||||||
|
update_cache: yes
|
5
roles/core_docker/vars/main.yml
Normal file
5
roles/core_docker/vars/main.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
# roles/core_docker/vars/main.yml
|
||||||
|
|
||||||
|
distro: "debian" # Replace with your debian-based distribution
|
||||||
|
codename: "bookworm" # Replace with your distribution codename
|
5
roles/core_users/defaults/main.yml
Normal file
5
roles/core_users/defaults/main.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
# roles/core_users/defaults/main.yml
|
||||||
|
|
||||||
|
# SSH keys directory path
|
||||||
|
ssh_keys_dir: "{{ role_path }}/files/ssh_keys"
|
1
roles/core_users/files/ssh_keys/sangelo-access.pub
Normal file
1
roles/core_users/files/ssh_keys/sangelo-access.pub
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFg9CWMZHj6ksnVsxsZf/6sP6ae1kP2FSMPcfguYmXs1 contact@sangelo.space
|
1
roles/core_users/files/ssh_keys/sangelo.pub
Normal file
1
roles/core_users/files/ssh_keys/sangelo.pub
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEYGOjYJ6UbBz77mXG8zR2YWlbA8jxknBifLYMck+02a contact@sangelo.space
|
40
roles/core_users/tasks/main.yml
Normal file
40
roles/core_users/tasks/main.yml
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
---
|
||||||
|
# roles/core_users/tasks/main.yml
|
||||||
|
|
||||||
|
# requires python3-jmespath to run (pipx inject ansible-core jmespath)
|
||||||
|
|
||||||
|
- name: Ensure groups exist
|
||||||
|
ansible.builtin.group:
|
||||||
|
name: "{{ group_item.name }}"
|
||||||
|
state: "{{ group_item.state | default('present') }}"
|
||||||
|
gid: "{{ group_item.gid | default(omit) }}"
|
||||||
|
system: "{{ group_item.system | default(omit) }}"
|
||||||
|
loop: "{{ core_groups }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: group_item
|
||||||
|
when: core_groups is defined
|
||||||
|
|
||||||
|
- name: Ensure users exist
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "{{ user_item.name }}"
|
||||||
|
state: "{{ user_item.state | default('present') }}"
|
||||||
|
password: "{{ user_item.password | default(omit) }}"
|
||||||
|
shell: "{{ user_item.shell | default('/bin/bash') }}"
|
||||||
|
system: "{{ user_item.system | default(omit) }}"
|
||||||
|
uid: "{{ user_item.uid | default(omit) }}"
|
||||||
|
group: "{{ user_item.group | default(omit) }}"
|
||||||
|
groups: "{{ user_item.groups | default(omit) }}"
|
||||||
|
append: "{{ user_item.append | default(omit) }}"
|
||||||
|
create_home: "{{ user_item.create_home | default(omit) }}"
|
||||||
|
home: "{{ user_item.home | default(omit) }}"
|
||||||
|
loop: "{{ core_users }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: user_item
|
||||||
|
when: core_users is defined
|
||||||
|
|
||||||
|
- name: Authorized keys
|
||||||
|
ansible.posix.authorized_key:
|
||||||
|
user: "{{ item.0.name }}"
|
||||||
|
state: present
|
||||||
|
key: "{{ lookup('file', ssh_keys_dir+'/'+item.1+'.pub') }}"
|
||||||
|
loop: "{{ query('subelements', core_users, 'authorized_keys', {'skip_missing': True}) }}"
|
Loading…
Reference in a new issue