new version
Some checks failed
Ansible Minecraft CI/CD / Ansible Lint (push) Successful in 8s
Ansible Minecraft CI/CD / Syntax Check (push) Failing after 7s
Ansible Minecraft CI/CD / Deploy to Staging (push) Has been skipped
Ansible Minecraft CI/CD / Deploy to Production (push) Has been skipped

This commit is contained in:
2025-08-27 15:11:08 +02:00
parent 3e64946953
commit 8f0877cd53
105 changed files with 911 additions and 2540 deletions

View File

@@ -1,145 +1,140 @@
name: Ansible Minecraft Server CI/CD name: Ansible Minecraft CI/CD
on: on:
push: push:
branches: [ main, develop ] branches: [ main, develop ]
pull_request: pull_request:
branches: [ main ] branches: [ main ]
workflow_dispatch:
inputs:
environment:
description: 'Environment to deploy'
required: true
default: 'staging'
type: choice
options:
- staging
- production
jobs: jobs:
lint: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
name: Ansible Lint
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Set up Python - name: Setup Python
uses: actions/setup-python@v4 uses: actions/setup-python@v4
with: with:
python-version: '3.11' python-version: '3.11'
- name: Install dependencies - name: Install dependencies
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install ansible ansible-lint yamllint pip install ansible ansible-lint yamllint
- name: Run yamllint - name: Lint YAML files
run: | run: |
yamllint -c .yamllint . yamllint .
continue-on-error: true continue-on-error: true
- name: Run ansible-lint - name: Lint Ansible playbooks
run: | run: |
ansible-lint --exclude .gitea/ . ansible-lint --parseable-severity site.yml roles/
continue-on-error: true continue-on-error: true
- name: Validate ansible syntax syntax-check:
run: |
ansible-playbook site.yml --syntax-check
test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
name: Syntax Check
needs: lint needs: lint
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Set up Python - name: Setup Python
uses: actions/setup-python@v4 uses: actions/setup-python@v4
with: with:
python-version: '3.11' python-version: '3.11'
- name: Install Ansible - name: Install Ansible
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install ansible pip install ansible
- name: Install Ansible collections
run: |
ansible-galaxy collection install -r requirements.yml
- name: Test playbook structure
run: |
# Verify all roles exist
for role in 01-server_hardening 02-installation-java 03-Installation-Minecraft 04-backups 05-Update; do
if [ ! -d "roles/$role" ]; then
echo "Role $role not found"
exit 1
fi
done
- name: Check inventory files
run: |
ansible-inventory -i inventories/staging/hosts.yml --list
ansible-inventory -i inventories/production/hosts.yml --list
deploy:
runs-on: ubuntu-latest
needs: [lint, test]
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install Ansible
run: |
python -m pip install --upgrade pip
pip install ansible
- name: Install collections - name: Install collections
run: | run: |
ansible-galaxy collection install -r requirements.yml ansible-galaxy collection install -r requirements.yml
- name: Check syntax
run: |
ansible-playbook --syntax-check site.yml -i inventories/staging/hosts.yml
deploy-staging:
runs-on: ubuntu-latest
name: Deploy to Staging
needs: [lint, syntax-check]
if: github.ref == 'refs/heads/develop'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install Ansible
run: |
python -m pip install --upgrade pip
pip install ansible
- name: Install collections
run: |
ansible-galaxy collection install -r requirements.yml
- name: Setup SSH key - name: Setup SSH key
run: | run: |
mkdir -p ~/.ssh mkdir -p ~/.ssh
echo "${{ secrets.ANSIBLE_SSH_KEY }}" > ~/.ssh/ansible_key echo "${{ secrets.ANSIBLE_SSH_PRIVATE_KEY }}" | base64 -d > ~/.ssh/id_rsa
chmod 600 ~/.ssh/ansible_key chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H ${{ secrets.STAGING_HOST }} >> ~/.ssh/known_hosts
- name: Setup vault password - name: Deploy to staging
run: | run: |
echo "${{ secrets.ANSIBLE_VAULT_PASSWORD }}" > .vault_pass ansible-playbook site.yml -i inventories/staging/hosts.yml --check --diff
chmod 600 .vault_pass
- name: Determine environment
id: env
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
echo "environment=${{ github.event.inputs.environment }}" >> $GITHUB_OUTPUT
elif [ "${{ github.ref }}" == "refs/heads/main" ]; then
echo "environment=production" >> $GITHUB_OUTPUT
else
echo "environment=staging" >> $GITHUB_OUTPUT
fi
- name: Deploy to environment
env: env:
ANSIBLE_HOST_KEY_CHECKING: false MINECRAFT_RCON_PASSWORD: ${{ secrets.MINECRAFT_RCON_PASSWORD }}
ANSIBLE_VAULT_PASSWORD_FILE: .vault_pass ANSIBLE_HOST_KEY_CHECKING: 'false'
run: |
ansible-playbook \
-i inventories/${{ steps.env.outputs.environment }}/hosts.yml \
site.yml \
--limit minecraft_servers \
--diff
- name: Clean up deploy-production:
if: always() runs-on: ubuntu-latest
name: Deploy to Production
needs: [lint, syntax-check]
if: github.ref == 'refs/heads/main'
environment: production
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install Ansible
run: | run: |
rm -f ~/.ssh/ansible_key python -m pip install --upgrade pip
rm -f .vault_pass pip install ansible
- name: Install collections
run: |
ansible-galaxy collection install -r requirements.yml
- name: Setup SSH key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.ANSIBLE_SSH_PRIVATE_KEY }}" | base64 -d > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H ${{ secrets.PRODUCTION_HOST }} >> ~/.ssh/known_hosts
- name: Deploy to production
run: |
ansible-playbook site.yml -i inventories/production/hosts.yml
env:
MINECRAFT_RCON_PASSWORD: ${{ secrets.MINECRAFT_RCON_PASSWORD }}
ANSIBLE_HOST_KEY_CHECKING: 'false'

View File

@@ -1,76 +1,30 @@
--- ---
# Configuration Ansible # Configuration globale Production
ansible_user: ansible environment: production
ansible_become: true python_interpreter: /usr/bin/python3
ansible_become_method: sudo
# Configuration réseau
ssh_port: 22
allowed_ssh_users: ["ansible", "minecraft"]
fail2ban_enabled: true
# Configuration Java
java_version: "17"
java_package: "openjdk-17-jdk"
# Configuration Minecraft # Configuration Minecraft
minecraft_version: "1.21.6" minecraft_version: "1.21.6"
minecraft_type: "spigot" spigot_build_tools_url: "https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar"
minecraft_user: minecraft minecraft_max_memory: "4G"
minecraft_group: minecraft minecraft_min_memory: "2G"
minecraft_base_dir: /opt/minecraft
minecraft_server_dir: /opt/minecraft/server
minecraft_sources_dir: /opt/minecraft/sources
minecraft_tools_dir: /opt/minecraft/tools
minecraft_backup_dir: /opt/minecraft/backups
# Configuration mémoire # Configuration backups
minecraft_memory_min: 2048 backup_enabled: true
minecraft_memory_max: 4096 backup_remote_host: "backup.example.com"
backup_local_path: "/opt/minecraft/backups"
# Configuration Java backup_remote_path: "/backups/minecraft"
java_version: 21
java_vendor: openjdk
# Configuration Réseau
server_port: 25565
rcon_port: 25575
enable_rcon: true
rcon_password: "{{ vault_rcon_password | default('ChangeMe123!') }}"
# Configuration serveur
server_name: "Production Minecraft Server"
max_players: 20
view_distance: 10
gamemode: survival
difficulty: normal
enable_command_block: false
online_mode: true
pvp: true
white_list: false
# Configuration Backup
backup_retention_daily: 7
backup_retention_weekly: 4
backup_retention_monthly: 3
backup_time_daily: "03:00"
backup_time_weekly: "04:00"
backup_time_monthly: "05:00"
# Configuration sécurité # Configuration sécurité
ssh_port: 22 firewall_enabled: true
firewall_allowed_tcp_ports: automatic_updates: false
- 22 hardening_enabled: true
- 25565
- 25575
firewall_allowed_udp_ports: []
# Administrateurs SSH (à remplir avec vos clés)
admin_ssh_keys: []
# - name: admin1
# key: "ssh-rsa AAAAB3..."
# Opérateurs Minecraft (à remplir)
minecraft_ops: []
# - name: "PlayerName"
# uuid: "uuid-here"
# level: 4
# bypassesPlayerLimit: true
# Plugins à installer
minecraft_plugins_list:
- name: "EssentialsX"
url: "https://github.com/EssentialsX/Essentials/releases/latest/download/EssentialsX.jar"
- name: "Vault"
url: "https://github.com/MilkBowl/Vault/releases/latest/download/Vault.jar"

View File

@@ -1,12 +1,19 @@
--- ---
all: minecraft_servers:
children: hosts:
minecraft_servers: minecraft-prod-01:
hosts: ansible_host: 10.0.1.10
minecraft-prod-01: ansible_user: ansible
ansible_host: 192.168.1.10 minecraft_server_name: "Production Server 01"
vars: minecraft_port: 25565
ansible_user: ansible minecraft_rcon_port: 25575
environment: production minecraft-prod-02:
minecraft_memory: 4096 ansible_host: 10.0.1.11
minecraft_port: 25565 ansible_user: ansible
minecraft_server_name: "Production Server 02"
minecraft_port: 25565
minecraft_rcon_port: 25575
vars:
environment: production
backup_retention_days: 90
update_schedule: "0 3 * * 0" # Dimanche 3h

View File

@@ -1,76 +1,28 @@
--- ---
# Configuration Ansible # Configuration globale Staging
ansible_user: ansible environment: staging
ansible_become: true python_interpreter: /usr/bin/python3
ansible_become_method: sudo
# Configuration réseau
ssh_port: 22
allowed_ssh_users: ["ansible", "minecraft", "developer"]
fail2ban_enabled: false
# Configuration Java
java_version: "17"
java_package: "openjdk-17-jdk"
# Configuration Minecraft # Configuration Minecraft
minecraft_version: "1.21.6" minecraft_version: "1.21.6"
minecraft_type: "spigot" spigot_build_tools_url: "https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar"
minecraft_user: minecraft minecraft_max_memory: "2G"
minecraft_group: minecraft minecraft_min_memory: "1G"
minecraft_base_dir: /opt/minecraft
minecraft_server_dir: /opt/minecraft/server
minecraft_sources_dir: /opt/minecraft/sources
minecraft_tools_dir: /opt/minecraft/tools
minecraft_backup_dir: /opt/minecraft/backups
# Configuration mémoire # Configuration backups
minecraft_memory_min: 2048 backup_enabled: true
minecraft_memory_max: 4096 backup_local_path: "/opt/minecraft/backups"
# Configuration Java
java_version: 21
java_vendor: openjdk
# Configuration Réseau
server_port: 25565
rcon_port: 25575
enable_rcon: true
rcon_password: "{{ vault_rcon_password | default('ChangeMe123!') }}"
# Configuration serveur
server_name: "Production Minecraft Server"
max_players: 20
view_distance: 10
gamemode: survival
difficulty: normal
enable_command_block: false
online_mode: true
pvp: true
white_list: false
# Configuration Backup
backup_retention_daily: 7
backup_retention_weekly: 4
backup_retention_monthly: 3
backup_time_daily: "03:00"
backup_time_weekly: "04:00"
backup_time_monthly: "05:00"
# Configuration sécurité # Configuration sécurité
ssh_port: 22 firewall_enabled: false
firewall_allowed_tcp_ports: automatic_updates: true
- 22 hardening_enabled: false
- 25565
- 25575
firewall_allowed_udp_ports: []
# Administrateurs SSH (à remplir avec vos clés)
admin_ssh_keys: []
# - name: admin1
# key: "ssh-rsa AAAAB3..."
# Opérateurs Minecraft (à remplir)
minecraft_ops: []
# - name: "PlayerName"
# uuid: "uuid-here"
# level: 4
# bypassesPlayerLimit: true
# Plugins à installer
minecraft_plugins_list:
- name: "EssentialsX"
url: "https://github.com/EssentialsX/Essentials/releases/latest/download/EssentialsX.jar"
- name: "Vault"
url: "https://github.com/MilkBowl/Vault/releases/latest/download/Vault.jar"

View File

@@ -1,12 +1,13 @@
--- ---
all: minecraft_servers:
children: hosts:
minecraft_servers: minecraft-staging-01:
hosts: ansible_host: 10.0.2.10
minecraft-staging-01: ansible_user: ansible
ansible_host: 192.168.2.10 minecraft_server_name: "Staging Server 01"
vars: minecraft_port: 25565
ansible_user: ansible minecraft_rcon_port: 25575
environment: staging vars:
minecraft_memory: 2048 environment: staging
minecraft_port: 25565 backup_retention_days: 30
update_schedule: "0 2 * * *" # Tous les jours 2h

View File

@@ -1,6 +1,8 @@
--- ---
collections: collections:
- name: ansible.posix
version: ">=1.5.4"
- name: community.general - name: community.general
version: ">=8.0.0" version: ">=7.0.0"
- name: ansible.posix
version: ">=1.5.0"
- name: community.crypto
version: ">=2.15.0"

View File

@@ -1,36 +1,22 @@
--- ---
# Configuration SSH par défaut # Configuration par défaut du durcissement serveur
hardening_packages:
- fail2ban
- ufw
- unattended-upgrades
- logrotate
- rsync
ssh_port: 22 ssh_port: 22
ssh_permit_root_login: "no" ssh_permit_root_login: "no"
ssh_password_authentication: "no" ssh_password_authentication: "no"
ssh_pubkey_authentication: "yes"
ssh_max_auth_tries: 3 ssh_max_auth_tries: 3
ssh_max_sessions: 10
ssh_client_alive_interval: 300 ssh_client_alive_interval: 300
ssh_client_alive_count_max: 2 ssh_client_alive_count_max: 2
# Configuration Firewall fail2ban_jail_ssh_enabled: true
firewall_allowed_tcp_ports: fail2ban_jail_ssh_maxretry: 3
- 22 fail2ban_jail_ssh_bantime: 3600
- 25565
- 25575
firewall_allowed_udp_ports: []
# Configuration Fail2ban ufw_default_incoming: deny
fail2ban_enabled: true ufw_default_outgoing: allow
fail2ban_bantime: 3600
fail2ban_findtime: 600
fail2ban_maxretry: 5
# Paquets de sécurité à installer
security_packages:
- ufw
- fail2ban
- unattended-upgrades
- apt-listchanges
- logwatch
- rkhunter
- chkrootkit
# Administrateurs SSH
admin_users: []

View File

@@ -1,23 +1,14 @@
--- ---
- name: restart ssh - name: restart ssh
ansible.builtin.systemd: ansible.builtin.service:
name: sshd name: ssh
state: restarted state: restarted
daemon_reload: true
listen: restart ssh service
- name: restart fail2ban - name: restart fail2ban
ansible.builtin.systemd: ansible.builtin.service:
name: fail2ban name: fail2ban
state: restarted state: restarted
daemon_reload: true
listen: restart fail2ban service
- name: reload ufw - name: enable ufw
community.general.ufw: community.general.ufw:
state: reloaded state: enabled
listen: reload firewall
- name: reload sysctl
ansible.builtin.command: sysctl -p
listen: reload sysctl settings

View File

@@ -1,6 +1,7 @@
--- ---
- name: Update apt cache for Debian/Ubuntu - name: Mise à jour du cache des paquets (Debian/Ubuntu)
ansible.builtin.apt: ansible.builtin.apt:
update_cache: yes update_cache: yes
cache_valid_time: 3600 cache_valid_time: 3600
when: ansible_os_family == "Debian" when: ansible_os_family == "Debian"
tags: [system-update]

View File

@@ -1,14 +0,0 @@
---
- name: Upgrade all packages
ansible.builtin.apt:
upgrade: dist
autoremove: yes
autoclean: yes
when: ansible_os_family == "Debian"
register: system_upgraded
- name: Install security packages
ansible.builtin.apt:
name: "{{ security_packages }}"
state: present
when: ansible_os_family == "Debian"

View File

@@ -0,0 +1,7 @@
---
- name: Installation des paquets de sécurité
ansible.builtin.apt:
name: "{{ hardening_packages }}"
state: present
when: ansible_os_family == "Debian"
notify: restart fail2ban

View File

@@ -1,11 +1,10 @@
--- ---
- name: Configure SSH daemon - name: Configuration SSH sécurisée
ansible.builtin.template: ansible.builtin.template:
src: sshd_config.j2 src: sshd_config.j2
dest: "{{ ssh_config_file }}" dest: "{{ ssh_config_path }}"
owner: root owner: root
group: root group: root
mode: '0600' mode: '0644'
backup: yes backup: yes
validate: '/usr/sbin/sshd -t -f %s' notify: restart ssh
notify: restart ssh service

View File

@@ -1,27 +1,9 @@
--- ---
- name: Install UFW firewall - name: Configuration UFW - politique par défaut
ansible.builtin.apt:
name: ufw
state: present
when: ansible_os_family == "Debian"
- name: Configure UFW defaults
community.general.ufw: community.general.ufw:
direction: "{{ item.direction }}" direction: "{{ item.direction }}"
policy: "{{ item.policy }}" policy: "{{ item.policy }}"
loop: with_items:
- { direction: 'incoming', policy: 'deny' } - { direction: 'incoming', policy: "{{ ufw_default_incoming }}" }
- { direction: 'outgoing', policy: 'allow' } - { direction: 'outgoing', policy: "{{ ufw_default_outgoing }}" }
notify: reload firewall notify: enable ufw
- name: Allow TCP ports
community.general.ufw:
rule: allow
port: "{{ item }}"
proto: tcp
loop: "{{ firewall_allowed_tcp_ports }}"
notify: reload firewall
- name: Enable UFW
community.general.ufw:
state: enabled

View File

@@ -1,23 +1,9 @@
--- ---
- name: Install fail2ban - name: Configuration Fail2Ban
ansible.builtin.apt:
name: fail2ban
state: present
when: ansible_os_family == "Debian"
- name: Configure fail2ban jail
ansible.builtin.template: ansible.builtin.template:
src: fail2ban.jail.local.j2 src: fail2ban-jail.local.j2
dest: "{{ fail2ban_config_dir }}/jail.local" dest: "{{ fail2ban_config_path }}"
owner: root owner: root
group: root group: root
mode: '0644' mode: '0644'
backup: yes notify: restart fail2ban
notify: restart fail2ban service
- name: Ensure fail2ban is started and enabled
ansible.builtin.systemd:
name: fail2ban
state: started
enabled: yes
daemon_reload: yes

View File

@@ -1,17 +1,8 @@
--- ---
- name: Create .ssh directory for ansible user - name: Ajout des clés SSH pour les administrateurs
ansible.builtin.file:
path: /home/ansible/.ssh
state: directory
owner: ansible
group: ansible
mode: '0700'
- name: Add SSH keys for administrators
ansible.posix.authorized_key: ansible.posix.authorized_key:
user: ansible user: "{{ item.user }}"
state: present state: present
key: "{{ item.key }}" key: "{{ item.key }}"
comment: "{{ item.name }}" comment: "{{ item.comment | default('Admin key') }}"
loop: "{{ admin_ssh_keys | default([]) }}" with_items: "{{ admin_ssh_keys | default([]) }}"
when: admin_ssh_keys is defined

View File

@@ -1,9 +0,0 @@
---
- name: Configure kernel parameters for security
ansible.posix.sysctl:
name: "{{ item.name }}"
value: "{{ item.value }}"
state: present
reload: yes
loop: "{{ hardening_sysctl_settings }}"
notify: reload sysctl settings

View File

@@ -1,23 +1,21 @@
--- ---
- name: restart ssh # Tâches principales du durcissement serveur
ansible.builtin.systemd: - import_tasks: 01-update-system.yml
name: sshd tags: [hardening, system-update]
state: restarted
daemon_reload: true
listen: restart ssh service
- name: restart fail2ban - import_tasks: 02-install-security-packages.yml
ansible.builtin.systemd: tags: [hardening, packages]
name: fail2ban
state: restarted
daemon_reload: true
listen: restart fail2ban service
- name: reload ufw - import_tasks: 03-configure-ssh.yml
community.general.ufw: tags: [hardening, ssh]
state: reloaded
listen: reload firewall
- name: reload sysctl - import_tasks: 04-configure-firewall.yml
ansible.builtin.command: sysctl -p tags: [hardening, firewall]
listen: reload sysctl settings when: firewall_enabled | default(true)
- import_tasks: 05-configure-fail2ban.yml
tags: [hardening, fail2ban]
when: fail2ban_enabled | default(true)
- import_tasks: 06-manage-ssh-keys.yml
tags: [hardening, ssh-keys]

View File

@@ -1,30 +1,12 @@
# {{ ansible_managed }} # Configuration Fail2Ban générée par Ansible
[DEFAULT] [DEFAULT]
ignoreip = 127.0.0.1/8 ::1 bantime = {{ fail2ban_jail_ssh_bantime }}
bantime = {{ fail2ban_bantime }} findtime = 600
findtime = {{ fail2ban_findtime }} maxretry = {{ fail2ban_jail_ssh_maxretry }}
maxretry = {{ fail2ban_maxretry }}
backend = systemd
[sshd] [sshd]
enabled = true enabled = {{ fail2ban_jail_ssh_enabled | lower }}
port = {{ ssh_port }} port = {{ ssh_port }}
filter = sshd filter = sshd
logpath = /var/log/auth.log logpath = /var/log/auth.log
maxretry = {{ fail2ban_maxretry }}
[sshd-ddos]
enabled = true
port = {{ ssh_port }}
filter = sshd-ddos
logpath = /var/log/auth.log
maxretry = 10
[minecraft]
enabled = true
port = {{ minecraft_port | default(25565) }}
filter = minecraft
logpath = {{ minecraft_server_dir | default('/opt/minecraft/server') }}/logs/latest.log
maxretry = 10
findtime = 600
bantime = 3600

View File

@@ -1,47 +1,21 @@
# {{ ansible_managed }} # Configuration SSH sécurisée générée par Ansible
# SSH Server Configuration
Port {{ ssh_port }} Port {{ ssh_port }}
Protocol 2 Protocol 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
# Logging # Authentification
SyslogFacility AUTH
LogLevel INFO
# Authentication
LoginGraceTime 120
PermitRootLogin {{ ssh_permit_root_login }} PermitRootLogin {{ ssh_permit_root_login }}
StrictModes yes
MaxAuthTries {{ ssh_max_auth_tries }}
MaxSessions {{ ssh_max_sessions }}
PubkeyAuthentication {{ ssh_pubkey_authentication }}
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication {{ ssh_password_authentication }} PasswordAuthentication {{ ssh_password_authentication }}
PermitEmptyPasswords no MaxAuthTries {{ ssh_max_auth_tries }}
ChallengeResponseAuthentication no PubkeyAuthentication yes
# Security # Sessions
IgnoreRhosts yes
HostbasedAuthentication no
X11Forwarding no
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
Compression delayed
# Client alive
ClientAliveInterval {{ ssh_client_alive_interval }} ClientAliveInterval {{ ssh_client_alive_interval }}
ClientAliveCountMax {{ ssh_client_alive_count_max }} ClientAliveCountMax {{ ssh_client_alive_count_max }}
# Allow only ansible user # Sécurité
AllowUsers ansible X11Forwarding no
# Disable unused features
UsePAM yes UsePAM yes
Banner none UseDNS no
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server # Utilisateurs autorisés
AllowUsers {{ allowed_ssh_users | join(' ') }}

View File

@@ -1,16 +0,0 @@
# {{ ansible_managed }}
# UFW Rules Configuration
# Allow SSH
-A ufw-user-input -p tcp --dport {{ ssh_port }} -j ACCEPT
# Allow Minecraft
-A ufw-user-input -p tcp --dport {{ minecraft_port | default(25565) }} -j ACCEPT
# Allow RCON if enabled
{% if enable_rcon | default(false) %}
-A ufw-user-input -p tcp --dport {{ rcon_port | default(25575) }} -j ACCEPT
{% endif %}
# Drop everything else
-A ufw-user-input -j DROP

View File

@@ -1,24 +1,14 @@
--- ---
# Variables spécifiques au rôle server_hardening # Variables spécifiques au hardening
hardening_sysctl_settings: required_packages_debian:
- name: net.ipv4.tcp_syncookies - curl
value: 1 - wget
- name: net.ipv4.conf.all.rp_filter - git
value: 1 - unzip
- name: net.ipv4.conf.default.rp_filter - htop
value: 1 - vim
- name: net.ipv4.conf.all.accept_source_route - sudo
value: 0 - systemd
- name: net.ipv4.conf.default.accept_source_route
value: 0
- name: net.ipv4.icmp_echo_ignore_broadcasts
value: 1
- name: net.ipv4.icmp_ignore_bogus_error_responses
value: 1
- name: net.ipv4.conf.all.log_martians
value: 1
- name: net.ipv4.conf.default.log_martians
value: 1
ssh_config_file: /etc/ssh/sshd_config ssh_config_path: /etc/ssh/sshd_config
fail2ban_config_dir: /etc/fail2ban fail2ban_config_path: /etc/fail2ban/jail.local

View File

@@ -1,5 +1,8 @@
--- ---
java_version: 21 # Configuration par défaut Java
java_vendor: openjdk java_version: "17"
java_home: /usr/lib/jvm/java-{{ java_version }}-openjdk-amd64 java_packages:
java_bin_path: "{{ java_home }}/bin" - openjdk-17-jdk
- openjdk-17-jre
java_home_path: "/usr/lib/jvm/java-17-openjdk-amd64"

View File

@@ -1,8 +1,4 @@
--- ---
- name: update java alternatives - name: update java alternatives
ansible.builtin.command: update-alternatives --config java ansible.builtin.command: update-java-alternatives --set java-1.{{ java_version }}.0-openjdk-amd64
listen: update java configuration failed_when: false
- name: reload environment
ansible.builtin.command: source /etc/environment
listen: reload system environment

View File

@@ -0,0 +1,6 @@
---
- name: Vérification de la présence de Java
ansible.builtin.command: "{{ java_version_check_command }}"
register: java_check
failed_when: false
changed_when: false

View File

@@ -0,0 +1 @@
02-install-java.yml

View File

@@ -1,21 +0,0 @@
---
- name: Remove old Java versions
ansible.builtin.apt:
name: "{{ item }}"
state: absent
purge: yes
loop:
- openjdk-8-jdk
- openjdk-8-jre
- openjdk-11-jdk
- openjdk-11-jre
- openjdk-17-jdk
- openjdk-17-jre
when: ansible_os_family == "Debian"
ignore_errors: yes
- name: Clean apt cache after removal
ansible.builtin.apt:
autoclean: yes
autoremove: yes
when: ansible_os_family == "Debian"

View File

@@ -1,24 +0,0 @@
---
- name: Add Java repository for Ubuntu
ansible.builtin.apt_repository:
repo: "{{ java_apt_repository.ubuntu }}"
state: present
when: ansible_distribution == "Ubuntu"
- name: Add backports repository for Debian
ansible.builtin.apt_repository:
repo: "{{ java_apt_repository.debian }}"
state: present
when: ansible_distribution == "Debian"
- name: Update apt cache
ansible.builtin.apt:
update_cache: yes
cache_valid_time: 3600
when: ansible_os_family == "Debian"
- name: Install Java packages
ansible.builtin.apt:
name: "{{ java_packages[ansible_distribution | lower] }}"
state: present
when: ansible_os_family == "Debian"

View File

@@ -0,0 +1,6 @@
---
- name: Validation de l'installation Java
ansible.builtin.command: java -version
register: java_validation
changed_when: false
failed_when: "'openjdk version' not in java_validation.stderr"

View File

@@ -1,27 +0,0 @@
---
- name: Set JAVA_HOME environment variable
ansible.builtin.lineinfile:
path: /etc/environment
line: "JAVA_HOME={{ java_home }}"
create: yes
state: present
- name: Add Java to PATH
ansible.builtin.lineinfile:
path: /etc/environment
line: 'PATH="{{ java_bin_path }}:$PATH"'
state: present
- name: Create Java profile script
ansible.builtin.template:
src: java.sh.j2
dest: /etc/profile.d/java.sh
owner: root
group: root
mode: '0644'
- name: Set default Java version
ansible.builtin.alternatives:
name: java
path: "{{ java_home }}/bin/java"
notify: update java configuration

View File

@@ -1,21 +0,0 @@
---
- name: Verify Java installation
ansible.builtin.command: "{{ java_home }}/bin/java -version"
register: java_version_output
changed_when: false
- name: Display Java version
ansible.builtin.debug:
msg: "Java version installed: {{ java_version_output.stderr_lines[0] }}"
- name: Verify Java compiler
ansible.builtin.command: "{{ java_home }}/bin/javac -version"
register: javac_version_output
changed_when: false
- name: Validate Java version matches requirement
ansible.builtin.assert:
that:
- "'{{ java_version }}' in java_version_output.stderr"
fail_msg: "Java version {{ java_version }} not properly installed"
success_msg: "Java version {{ java_version }} successfully installed"

View File

@@ -1,6 +0,0 @@
---
- name: Check if Java is installed
ansible.builtin.command: java -version
register: java_installed
failed_when: false
changed_when: false

View File

@@ -1,17 +1,11 @@
--- ---
- name: Include check Java tasks # Tâches principales installation Java
ansible.builtin.include_tasks: 01-check-java.yml - import_tasks: 01-check-java.yml
tags: [java, check]
- name: Include remove old Java tasks - import_tasks: 02-install-java.yml
ansible.builtin.include_tasks: 02-remove-old-java.yml tags: [java, install]
when: java_needs_update | default(false) when: java_installed is not defined or not java_installed
- name: Include install Java tasks - import_tasks: 03-validate-java.yml
ansible.builtin.include_tasks: 03-install-java.yml tags: [java, validate]
when: java_not_installed | default(false) or java_needs_update | default(false)
- name: Include configure Java tasks
ansible.builtin.include_tasks: 04-configure-java.yml
- name: Include validate installation tasks
ansible.builtin.include_tasks: 05-validate-installation.yml

View File

@@ -1,5 +0,0 @@
#!/bin/bash
# {{ ansible_managed }}
export JAVA_HOME={{ java_home }}
export PATH=$JAVA_HOME

View File

@@ -1,12 +1,4 @@
--- ---
java_packages: # Variables Java
debian: java_version_check_command: "java -version"
- "openjdk-{{ java_version }}-jdk" java_required_version: "17"
- "openjdk-{{ java_version }}-jre"
ubuntu:
- "openjdk-{{ java_version }}-jdk"
- "openjdk-{{ java_version }}-jre"
java_apt_repository:
debian: "deb http://deb.debian.org/debian {{ ansible_distribution_release }}-backports main"
ubuntu: "ppa:openjdk-r/ppa"

View File

@@ -1,57 +1,34 @@
--- ---
# Utilisateur et groupe # Configuration par défaut Minecraft
minecraft_user: minecraft minecraft_user: minecraft
minecraft_group: minecraft minecraft_group: minecraft
minecraft_home: /opt/minecraft
minecraft_version: "1.21.6"
minecraft_port: 25565
minecraft_rcon_port: 25575
minecraft_max_memory: "4G"
minecraft_min_memory: "2G"
# Répertoires # Répertoires
minecraft_base_dir: /opt/minecraft minecraft_sources_dir: "{{ minecraft_home }}/sources"
minecraft_server_dir: /opt/minecraft/server minecraft_server_dir: "{{ minecraft_home }}/server"
minecraft_sources_dir: /opt/minecraft/sources minecraft_tools_dir: "{{ minecraft_home }}/tools"
minecraft_tools_dir: /opt/minecraft/tools minecraft_backups_dir: "{{ minecraft_home }}/backups"
minecraft_logs_dir: "{{ minecraft_home }}/logs"
# Version et mémoire # URLs
minecraft_version: "1.21.6" spigot_build_tools_url: "https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar"
minecraft_memory_min: 1024 mcrcon_url: "https://github.com/Tiiffi/mcrcon/archive/refs/heads/master.zip"
minecraft_memory_max: 4096
# URLs de téléchargement
minecraft_build_tools_url: "https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar"
mcrcon_url: "https://github.com/Tiiffi/mcrcon/releases/latest/download/mcrcon-linux-x86_64.tar.gz"
# Configuration serveur # Configuration serveur
server_name: "Minecraft Server" server_properties:
server_port: 25565 server-port: "{{ minecraft_port }}"
max_players: 20 enable-rcon: "true"
view_distance: 10 rcon.port: "{{ minecraft_rcon_port }}"
gamemode: survival rcon.password: "{{ minecraft_rcon_password | default('changeme') }}"
difficulty: normal max-players: "20"
enable_command_block: false difficulty: "normal"
enable_rcon: true gamemode: "survival"
rcon_port: 25575 pvp: "true"
rcon_password: "{{ vault_rcon_password | default('ChangeMe123!') }}" spawn-protection: "16"
online_mode: true white-list: "false"
pvp: true
white_list: false
spawn_protection: 16
max_world_size: 29999984
level_seed: ""
level_type: "DEFAULT"
generate_structures: true
spawn_animals: true
spawn_monsters: true
spawn_npcs: true
# Service
minecraft_service_name: minecraft.service
minecraft_service_enabled: true
minecraft_service_state: started
# Plugins par défaut
minecraft_plugins_list:
- name: "EssentialsX"
url: "https://github.com/EssentialsX/Essentials/releases/latest/download/EssentialsX.jar"
- name: "Vault"
url: "https://github.com/MilkBowl/Vault/releases/latest/download/Vault.jar"
# Opérateurs
minecraft_ops: []

View File

@@ -1,24 +1,14 @@
--- ---
- name: restart minecraft
ansible.builtin.systemd:
name: "{{ minecraft_service_name }}"
state: restarted
daemon_reload: true
listen: restart minecraft server
- name: reload minecraft
ansible.builtin.systemd:
name: "{{ minecraft_service_name }}"
state: reloaded
listen: reload minecraft server
- name: reload systemd - name: reload systemd
ansible.builtin.systemd: ansible.builtin.systemd:
daemon_reload: true daemon_reload: yes
listen: reload systemd daemon
- name: restart rsyslog - name: enable minecraft service
ansible.builtin.systemd: ansible.builtin.service:
name: rsyslog name: minecraft
state: restarted enabled: yes
listen: restart rsyslog service
- name: restart minecraft
ansible.builtin.service:
name: minecraft
state: restarted

View File

@@ -1,31 +0,0 @@
---
galaxy_info:
author: Tips-Of-Mine
description: Installation et configuration complète d'un serveur Minecraft Spigot
company: Tips-Of-Mine
license: MIT
min_ansible_version: "2.14"
platforms:
- name: Debian
versions:
- bullseye # 11
- bookworm # 12
- trixie # 13
- buster # 10
- name: Ubuntu
versions:
- focal # 20.04
- jammy # 22.04
- noble # 24.04
galaxy_tags:
- minecraft
- spigot
- gaming
- server
- java
- backup
- monitoring
dependencies:
- role: 02-installation-java
when: java_required | default(true)

View File

@@ -1,23 +1,14 @@
--- ---
- name: Create minecraft group - name: Création du groupe minecraft
ansible.builtin.group: ansible.builtin.group:
name: "{{ minecraft_group }}" name: "{{ minecraft_group }}"
state: present state: present
system: yes
- name: Create minecraft user - name: Création de l'utilisateur minecraft
ansible.builtin.user: ansible.builtin.user:
name: "{{ minecraft_user }}" name: "{{ minecraft_user }}"
group: "{{ minecraft_group }}" group: "{{ minecraft_group }}"
groups: [] home: "{{ minecraft_home }}"
append: no
home: "{{ minecraft_base_dir }}"
shell: /bin/bash shell: /bin/bash
system: yes
create_home: yes create_home: yes
state: present state: present
comment: "Minecraft Server User"
- name: Set minecraft user password to never expire
ansible.builtin.command: chage -M -1 {{ minecraft_user }}
changed_when: false

View File

@@ -1,25 +1,15 @@
--- ---
- name: Create minecraft directories - name: Création des répertoires Minecraft
ansible.builtin.file: ansible.builtin.file:
path: "{{ item }}" path: "{{ item }}"
state: directory state: directory
owner: "{{ minecraft_user }}" owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}" group: "{{ minecraft_group }}"
mode: '0755' mode: '0755'
loop: "{{ minecraft_dirs }}" with_items:
- "{{ minecraft_sources_dir }}"
- name: Create .ssh directory for minecraft user - "{{ minecraft_server_dir }}"
ansible.builtin.file: - "{{ minecraft_tools_dir }}"
path: "{{ minecraft_base_dir }}/.ssh" - "{{ minecraft_backups_dir }}"
state: directory - "{{ minecraft_logs_dir }}"
owner: "{{ minecraft_user }}" - "{{ minecraft_server_dir }}/plugins"
group: "{{ minecraft_group }}"
mode: '0700'
- name: Set correct permissions on base directory
ansible.builtin.file:
path: "{{ minecraft_base_dir }}"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0755'
recurse: yes

View File

@@ -1,30 +1,8 @@
--- ---
- name: Install required packages for building - name: Téléchargement de BuildTools
ansible.builtin.apt:
name: "{{ build_packages }}"
state: present
update_cache: yes
when: ansible_os_family == "Debian"
- name: Check if BuildTools already exists
ansible.builtin.stat:
path: "{{ minecraft_sources_dir }}/{{ buildtools_jar }}"
register: buildtools_exists
- name: Download BuildTools
ansible.builtin.get_url: ansible.builtin.get_url:
url: "{{ minecraft_build_tools_url }}" url: "{{ spigot_build_tools_url }}"
dest: "{{ minecraft_sources_dir }}/{{ buildtools_jar }}" dest: "{{ minecraft_sources_dir }}/{{ build_tools_jar }}"
owner: "{{ minecraft_user }}" owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}" group: "{{ minecraft_group }}"
mode: '0644' mode: '0644'
force: yes
when: not buildtools_exists.stat.exists or force_download | default(false)
- name: Create work directory for compilation
ansible.builtin.file:
path: "{{ minecraft_sources_dir }}/work"
state: directory
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0755'

View File

@@ -1,52 +0,0 @@
---
- name: Check if Spigot is already compiled
ansible.builtin.stat:
path: "{{ minecraft_sources_dir }}/{{ spigot_jar_name }}"
register: spigot_compiled
- name: Remove old work directory if exists
ansible.builtin.file:
path: "{{ minecraft_sources_dir }}/work"
state: absent
when: not spigot_compiled.stat.exists
- name: Compile Spigot with BuildTools
ansible.builtin.shell: |
cd {{ minecraft_sources_dir }}
java -Xmx1024M -jar {{ buildtools_jar }} --rev {{ minecraft_version }} --compile-if-changed
args:
creates: "{{ minecraft_sources_dir }}/{{ spigot_jar_name }}"
become_user: "{{ minecraft_user }}"
when: not spigot_compiled.stat.exists
register: compile_result
async: 1800
poll: 30
- name: Wait for compilation to complete
ansible.builtin.async_status:
jid: "{{ compile_result.ansible_job_id }}"
register: job_result
until: job_result.finished
retries: 60
delay: 30
when: compile_result.ansible_job_id is defined
- name: Verify Spigot jar was created
ansible.builtin.stat:
path: "{{ minecraft_sources_dir }}/{{ spigot_jar_name }}"
register: spigot_jar_check
failed_when: not spigot_jar_check.stat.exists
- name: Copy compiled Spigot to server directory
ansible.builtin.copy:
src: "{{ minecraft_sources_dir }}/{{ spigot_jar_name }}"
dest: "{{ minecraft_server_dir }}/{{ spigot_jar_name }}"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0644'
remote_src: yes
- name: Clean up work directory
ansible.builtin.file:
path: "{{ minecraft_sources_dir }}/work"
state: absent

View File

@@ -0,0 +1,20 @@
---
- name: Installation des dépendances pour mcrcon
ansible.builtin.apt:
name:
- build-essential
- git
state: present
- name: Clone du repository mcrcon
ansible.builtin.git:
repo: https://github.com/Tiiffi/mcrcon.git
dest: "{{ minecraft_tools_dir }}/mcrcon"
version: master
become_user: "{{ minecraft_user }}"
- name: Compilation de mcrcon
ansible.builtin.command:
cmd: make
chdir: "{{ minecraft_tools_dir }}/mcrcon"
become_user: "{{ minecraft_user }}"

View File

@@ -0,0 +1,17 @@
---
- name: Compilation de Spigot
ansible.builtin.command:
cmd: "java -jar {{ build_tools_jar }} --rev {{ minecraft_version }}"
chdir: "{{ minecraft_sources_dir }}"
creates: "{{ minecraft_sources_dir }}/spigot-{{ minecraft_version }}.jar"
become_user: "{{ minecraft_user }}"
timeout: 1800
- name: Copie du JAR Spigot compilé
ansible.builtin.copy:
src: "{{ minecraft_sources_dir }}/spigot-{{ minecraft_version }}.jar"
dest: "{{ minecraft_server_dir }}/spigot.jar"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0644'
remote_src: yes

View File

@@ -1,57 +0,0 @@
---
- name: Create server.properties
ansible.builtin.template:
src: server.properties.j2
dest: "{{ minecraft_server_dir }}/server.properties"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0644'
backup: yes
- name: Accept EULA
ansible.builtin.template:
src: eula.txt.j2
dest: "{{ minecraft_server_dir }}/eula.txt"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0644'
- name: Create spigot.yml configuration
ansible.builtin.template:
src: spigot.yml.j2
dest: "{{ minecraft_server_dir }}/spigot.yml"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0644'
- name: Create bukkit.yml configuration
ansible.builtin.template:
src: bukkit.yml.j2
dest: "{{ minecraft_server_dir }}/bukkit.yml"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0644'
- name: Create start script
ansible.builtin.template:
src: start.sh.j2
dest: "{{ minecraft_base_dir }}/scripts/start.sh"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0755'
- name: Create stop script
ansible.builtin.template:
src: stop.sh.j2
dest: "{{ minecraft_base_dir }}/scripts/stop.sh"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0755'
- name: Store current version
ansible.builtin.copy:
content: "{{ minecraft_version }}"
dest: "{{ minecraft_server_dir }}/.version"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0644'

View File

@@ -0,0 +1,18 @@
---
- name: Génération de la configuration server.properties
ansible.builtin.template:
src: server.properties.j2
dest: "{{ minecraft_server_dir }}/server.properties"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0644'
notify: restart minecraft
- name: Acceptation de l'EULA
ansible.builtin.lineinfile:
path: "{{ minecraft_server_dir }}/eula.txt"
line: "eula=true"
create: yes
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0644'

View File

@@ -1,46 +0,0 @@
---
- name: Check if mcrcon is already installed
ansible.builtin.stat:
path: "{{ minecraft_tools_dir }}/mcrcon"
register: mcrcon_installed
- name: Download mcrcon
ansible.builtin.get_url:
url: "{{ mcrcon_url }}"
dest: "{{ minecraft_tools_dir }}/mcrcon.tar.gz"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0644'
when: not mcrcon_installed.stat.exists
- name: Extract mcrcon
ansible.builtin.unarchive:
src: "{{ minecraft_tools_dir }}/mcrcon.tar.gz"
dest: "{{ minecraft_tools_dir }}"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
remote_src: yes
creates: "{{ minecraft_tools_dir }}/mcrcon"
when: not mcrcon_installed.stat.exists
- name: Make mcrcon executable
ansible.builtin.file:
path: "{{ minecraft_tools_dir }}/mcrcon"
mode: '0755'
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
- name: Create mcrcon wrapper script
ansible.builtin.copy:
content: |
#!/bin/bash
{{ minecraft_tools_dir }}/mcrcon -H localhost -P {{ rcon_port }} -p "{{ rcon_password }}" "$@"
dest: "{{ minecraft_base_dir }}/scripts/rcon.sh"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0755'
- name: Clean up mcrcon archive
ansible.builtin.file:
path: "{{ minecraft_tools_dir }}/mcrcon.tar.gz"
state: absent

View File

@@ -1,36 +1,11 @@
--- ---
- name: Create minecraft systemd service - name: Création du service systemd Minecraft
ansible.builtin.template: ansible.builtin.template:
src: minecraft.service.j2 src: minecraft.service.j2
dest: "/etc/systemd/system/{{ minecraft_service_name }}" dest: /etc/systemd/system/minecraft.service
owner: root owner: root
group: root group: root
mode: '0644' mode: '0644'
notify: notify:
- reload systemd daemon - reload systemd
- restart minecraft server - enable minecraft service
- name: Reload systemd daemon
ansible.builtin.systemd:
daemon_reload: yes
- name: Enable minecraft service
ansible.builtin.systemd:
name: "{{ minecraft_service_name }}"
enabled: "{{ minecraft_service_enabled }}"
masked: no
- name: Start minecraft service
ansible.builtin.systemd:
name: "{{ minecraft_service_name }}"
state: "{{ minecraft_service_state }}"
when: minecraft_service_state == "started"
- name: Wait for server to be ready
ansible.builtin.wait_for:
port: "{{ server_port }}"
delay: 10
timeout: 120
state: started
host: 127.0.0.1
when: minecraft_service_state == "started"

View File

@@ -1,36 +1,8 @@
--- ---
- name: Configure logrotate for minecraft logs - name: Configuration de la rotation des logs
ansible.builtin.template: ansible.builtin.template:
src: minecraft-logrotate.j2 src: minecraft-logrotate.j2
dest: /etc/logrotate.d/minecraft dest: /etc/logrotate.d/minecraft
owner: root owner: root
group: root group: root
mode: '0644' mode: '0644'
- name: Create rsyslog configuration for minecraft
ansible.builtin.copy:
content: |
# Minecraft Server Logging
:programname, isequal, "minecraft" /var/log/minecraft.log
& stop
dest: /etc/rsyslog.d/30-minecraft.conf
owner: root
group: root
mode: '0644'
notify: restart rsyslog service
- name: Create minecraft log file
ansible.builtin.file:
path: /var/log/minecraft.log
state: touch
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0644'
modification_time: preserve
access_time: preserve
- name: Test logrotate configuration
ansible.builtin.command: logrotate -d /etc/logrotate.d/minecraft
register: logrotate_test
changed_when: false
failed_when: logrotate_test.rc != 0

View File

@@ -1,32 +1,9 @@
--- ---
- name: Check if ops.json exists - name: Génération du fichier ops.json
ansible.builtin.stat:
path: "{{ minecraft_server_dir }}/ops.json"
register: ops_file
- name: Create ops.json file
ansible.builtin.template: ansible.builtin.template:
src: ops.json.j2 src: ops.json.j2
dest: "{{ minecraft_server_dir }}/ops.json" dest: "{{ minecraft_server_dir }}/ops.json"
owner: "{{ minecraft_user }}" owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}" group: "{{ minecraft_group }}"
mode: '0644' mode: '0644'
backup: yes notify: restart minecraft
when: minecraft_ops is defined and minecraft_ops | length > 0
- name: Create empty ops.json if no ops defined
ansible.builtin.copy:
content: "[]"
dest: "{{ minecraft_server_dir }}/ops.json"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0644'
force: no
when: not ops_file.stat.exists and (minecraft_ops is not defined or minecraft_ops | length == 0)
- name: Set permissions on ops.json
ansible.builtin.file:
path: "{{ minecraft_server_dir }}/ops.json"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0644'

View File

@@ -1,39 +1,10 @@
--- ---
- name: Create plugins directory - name: Installation des plugins par défaut
ansible.builtin.file:
path: "{{ minecraft_server_dir }}/plugins"
state: directory
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0755'
- name: Download plugins
ansible.builtin.get_url: ansible.builtin.get_url:
url: "{{ item.url }}" url: "{{ item.url }}"
dest: "{{ minecraft_server_dir }}/plugins/{{ item.name }}.jar" dest: "{{ minecraft_server_dir }}/plugins/{{ item.name }}.jar"
owner: "{{ minecraft_user }}" owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}" group: "{{ minecraft_group }}"
mode: '0644' mode: '0644'
timeout: 30 with_items: "{{ minecraft_plugins | default([]) }}"
loop: "{{ minecraft_plugins_list }}" when: minecraft_plugins is defined
when: minecraft_plugins_list is defined and minecraft_plugins_list | length > 0
ignore_errors: yes
- name: Create plugins config directory
ansible.builtin.file:
path: "{{ minecraft_server_dir }}/plugins/{{ item.name }}"
state: directory
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0755'
loop: "{{ minecraft_plugins_list }}"
when: minecraft_plugins_list is defined and item.create_config_dir | default(false)
- name: Restart server to load new plugins
ansible.builtin.systemd:
name: "{{ minecraft_service_name }}"
state: restarted
when:
- minecraft_plugins_list is defined
- minecraft_plugins_list | length > 0
- restart_after_plugins | default(false)

View File

@@ -1,40 +1,31 @@
--- ---
- name: Include create user and group tasks # Tâches principales installation Minecraft
ansible.builtin.include_tasks: 01-create-user-group.yml - import_tasks: 01-create-user-group.yml
tags: ['minecraft-user'] tags: [minecraft, user]
- name: Include create directories tasks - import_tasks: 02-create-directories.yml
ansible.builtin.include_tasks: 02-create-directories.yml tags: [minecraft, directories]
tags: ['minecraft-dirs']
- name: Include download Spigot tasks - import_tasks: 03-download-spigot.yml
ansible.builtin.include_tasks: 03-download-spigot.yml tags: [minecraft, download]
tags: ['minecraft-download']
- name: Include compile Spigot tasks - import_tasks: 04-install-mcrcon.yml
ansible.builtin.include_tasks: 04-compile-spigot.yml tags: [minecraft, mcrcon]
tags: ['minecraft-compile']
- name: Include configure server tasks - import_tasks: 05-compile-spigot.yml
ansible.builtin.include_tasks: 05-configure-server.yml tags: [minecraft, compile]
tags: ['minecraft-config']
- name: Include install mcrcon tasks - import_tasks: 06-configure-minecraft.yml
ansible.builtin.include_tasks: 06-install-mcrcon.yml tags: [minecraft, configure]
tags: ['minecraft-mcrcon']
- name: Include create service tasks - import_tasks: 07-create-service.yml
ansible.builtin.include_tasks: 07-create-service.yml tags: [minecraft, service]
tags: ['minecraft-service']
- name: Include configure logrotate tasks - import_tasks: 08-configure-logrotate.yml
ansible.builtin.include_tasks: 08-configure-logrotate.yml tags: [minecraft, logrotate]
tags: ['minecraft-logs']
- name: Include manage ops tasks - import_tasks: 09-manage-ops.yml
ansible.builtin.include_tasks: 09-manage-ops.yml tags: [minecraft, ops]
tags: ['minecraft-ops']
- name: Include install plugins tasks - import_tasks: 10-install-plugins.yml
ansible.builtin.include_tasks: 10-install-plugins.yml tags: [minecraft, plugins]
tags: ['minecraft-plugins']

View File

@@ -1,12 +0,0 @@
[
{% for ip in minecraft_banned_ips | default([]) %}
{
"ip": "{{ ip.address }}",
"created": "{{ ip.created | default(ansible_date_time.iso8601) }}",
"source": "{{ ip.source | default('Server') }}",
"expires": "{{ ip.expires | default('forever') }}",
"reason": "{{ ip.reason | default('Banned by administrator') }}"
}{% if not loop.last %},{% endif %}
{% endfor %}
]

View File

@@ -1,13 +0,0 @@
[
{% for player in minecraft_banned_players | default([]) %}
{
"uuid": "{{ player.uuid }}",
"name": "{{ player.name }}",
"created": "{{ player.created | default(ansible_date_time.iso8601) }}",
"source": "{{ player.source | default('Server') }}",
"expires": "{{ player.expires | default('forever') }}",
"reason": "{{ player.reason | default('Banned by administrator') }}"
}{% if not loop.last %},{% endif %}
{% endfor %}
]

View File

@@ -1,39 +0,0 @@
# {{ ansible_managed }}
# This is the main configuration file for Bukkit.
# Bukkit version: {{ minecraft_version }}
settings:
allow-end: true
warn-on-overload: true
permissions-file: permissions.yml
update-folder: update
plugin-profiling: false
connection-throttle: 4000
query-plugins: true
deprecated-verbose: default
shutdown-message: Server closed
minimum-api: none
spawn-limits:
monsters: 70
animals: 10
water-animals: 5
water-ambient: 20
water-underground-creature: 5
axolotls: 5
ambient: 15
chunk-gc:
period-in-ticks: 600
ticks-per:
animal-spawns: 400
monster-spawns: 1
water-spawns: 1
water-ambient-spawns: 1
water-underground-creature-spawns: 1
axolotl-spawns: 1
ambient-spawns: 1
autosave: 6000
aliases: now-in-commands.yml

View File

@@ -1,30 +0,0 @@
# {{ ansible_managed }}
{{ minecraft_server_dir }}/logs/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0644 {{ minecraft_user }} {{ minecraft_group }}
sharedscripts
postrotate
# Demander au serveur de recharger les logs
if systemctl is-active --quiet {{ minecraft_service_name }}; then
{{ minecraft_tools_dir }}/mcrcon -H localhost -P {{ rcon_port }} -p "{{ rcon_password }}" "say Rotation des logs effectuée" > /dev/null 2>&1 || true
fi
endscript
}
/var/log/minecraft.log {
weekly
rotate 4
compress
delaycompress
missingok
notifempty
create 0644 {{ minecraft_user }} {{ minecraft_group }}
postrotate
systemctl reload rsyslog > /dev/null 2>&1 || true
endscript
}

View File

@@ -1,64 +0,0 @@
#!/bin/bash
# {{ ansible_managed }}
# Script de backup intégré pour Minecraft
BACKUP_DIR="{{ minecraft_backup_dir | default('/opt/minecraft/backups') }}"
SERVER_DIR="{{ minecraft_server_dir }}"
MCRCON="{{ minecraft_tools_dir }}/mcrcon"
RCON_PORT="{{ rcon_port }}"
RCON_PASS="{{ rcon_password }}"
DATE=$(date +%Y%m%d_%H%M%S)
# Créer le répertoire de backup si nécessaire
mkdir -p "$BACKUP_DIR"
# Fonction pour envoyer des commandes RCON
send_command() {
$MCRCON -H localhost -P $RCON_PORT -p "$RCON_PASS" "$1" 2>/dev/null
}
# Fonction de backup
perform_backup() {
echo "[$(date)] Démarrage du backup..."
# Avertir les joueurs
send_command "say Backup automatique dans 10 secondes..."
sleep 5
send_command "say Backup en cours, lag possible..."
# Forcer la sauvegarde
send_command "save-all flush"
sleep 2
# Désactiver l'auto-save temporairement
send_command "save-off"
# Créer le backup
tar -czf "$BACKUP_DIR/minecraft_backup_$DATE.tar.gz" \
-C "$(dirname $SERVER_DIR)" \
"$(basename $SERVER_DIR)" \
--exclude='*.log' \
--exclude='logs/*.gz' \
--exclude='crash-reports/*'
# Réactiver l'auto-save
send_command "save-on"
# Informer les joueurs
send_command "say Backup terminé!"
echo "[$(date)] Backup créé: minecraft_backup_$DATE.tar.gz"
# Nettoyer les vieux backups (garder les 7 derniers)
ls -t "$BACKUP_DIR"/minecraft_backup_*.tar.gz 2>/dev/null | tail -n +8 | xargs rm -f
}
# Vérifier si le serveur est actif
if systemctl is-active --quiet {{ minecraft_service_name }}; then
perform_backup
else
echo "[$(date)] Serveur inactif, backup sans RCON..."
tar -czf "$BACKUP_DIR/minecraft_backup_offline_$DATE.tar.gz" \
-C "$(dirname $SERVER_DIR)" \
"$(basename $SERVER_DIR)"
fi

View File

@@ -0,0 +1,13 @@
{{ minecraft_server_dir }}/logs/*.log {
daily
rotate {{ logrotate_config.rotate }}
size {{ logrotate_config.size }}
{% if logrotate_config.compress %}compress{% endif %}
{% if logrotate_config.delaycompress %}delaycompress{% endif %}
missingok
notifempty
create 644 {{ minecraft_user }} {{ minecraft_group }}
postrotate
systemctl reload minecraft || true
endscript
}

View File

@@ -1,133 +0,0 @@
#!/bin/bash
# {{ ansible_managed }}
# Script de monitoring pour le serveur Minecraft
SERVER_DIR="{{ minecraft_server_dir }}"
MCRCON="{{ minecraft_tools_dir }}/mcrcon"
RCON_PORT="{{ rcon_port }}"
RCON_PASS="{{ rcon_password }}"
SERVICE_NAME="{{ minecraft_service_name }}"
LOG_FILE="/var/log/minecraft-monitor.log"
# Fonction de log
log_message() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
# Fonction pour vérifier le statut
check_server_status() {
if ! systemctl is-active --quiet "$SERVICE_NAME"; then
echo "OFFLINE"
return 1
fi
# Tester RCON
if ! $MCRCON -H localhost -P $RCON_PORT -p "$RCON_PASS" "list" &>/dev/null; then
echo "RCON_FAILED"
return 2
fi
echo "ONLINE"
return 0
}
# Fonction pour obtenir les métriques
get_metrics() {
local status=$(check_server_status)
if [ "$status" = "ONLINE" ]; then
# Nombre de joueurs
local players=$($MCRCON -H localhost -P $RCON_PORT -p "$RCON_PASS" "list" 2>/dev/null | grep -oP '\d+(?= of a max)' || echo "0")
# TPS (si disponible avec un plugin)
local tps=$($MCRCON -H localhost -P $RCON_PORT -p "$RCON_PASS" "tps" 2>/dev/null || echo "N/A")
# Utilisation mémoire du processus
local pid=$(systemctl show -p MainPID "$SERVICE_NAME" | cut -d= -f2)
local mem="0"
if [ "$pid" != "0" ]; then
mem=$(ps -o rss= -p "$pid" 2>/dev/null | awk '{printf "%.2f", $1/1024}' || echo "0")
fi
# Utilisation CPU
local cpu="0"
if [ "$pid" != "0" ]; then
cpu=$(ps -o %cpu= -p "$pid" 2>/dev/null | awk '{print $1}' || echo "0")
fi
# Espace disque du serveur
local disk=$(du -sh "$SERVER_DIR" 2>/dev/null | cut -f1 || echo "N/A")
# Affichage JSON pour intégration
cat <<EOF
{
"status": "$status",
"players": $players,
"tps": "$tps",
"memory_mb": $mem,
"cpu_percent": $cpu,
"disk_usage": "$disk",
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
}
EOF
else
cat <<EOF
{
"status": "$status",
"players": 0,
"tps": "N/A",
"memory_mb": 0,
"cpu_percent": 0,
"disk_usage": "N/A",
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
}
EOF
fi
}
# Fonction de redémarrage automatique
auto_restart_check() {
local status=$(check_server_status)
case "$status" in
"OFFLINE")
log_message "ALERTE: Serveur hors ligne, tentative de redémarrage..."
systemctl restart "$SERVICE_NAME"
sleep 30
if check_server_status >/dev/null; then
log_message "INFO: Serveur redémarré avec succès"
else
log_message "ERREUR: Échec du redémarrage du serveur"
fi
;;
"RCON_FAILED")
log_message "AVERTISSEMENT: RCON ne répond pas, vérification..."
# Attendre 60 secondes avant de considérer comme critique
sleep 60
if [ "$(check_server_status)" = "RCON_FAILED" ]; then
log_message "ERREUR: RCON toujours en échec, redémarrage du serveur..."
systemctl restart "$SERVICE_NAME"
fi
;;
"ONLINE")
# Tout va bien
;;
esac
}
# Main
case "${1:-status}" in
status)
check_server_status
;;
metrics)
get_metrics
;;
monitor)
auto_restart_check
;;
*)
echo "Usage: $0 {status|metrics|monitor}"
exit 1
;;
esac

View File

@@ -1,54 +1,17 @@
# {{ ansible_managed }}
[Unit] [Unit]
Description=Minecraft Server (Spigot {{ minecraft_version }}) Description=Minecraft Spigot Server
After=network-online.target After=network.target
Wants=network-online.target
[Service] [Service]
Type=simple Type=forking
User={{ minecraft_user }} User={{ minecraft_user }}
Group={{ minecraft_group }} Group={{ minecraft_group }}
WorkingDirectory={{ minecraft_server_dir }} WorkingDirectory={{ minecraft_server_dir }}
ExecStart=/usr/bin/java -Xmx{{ minecraft_max_memory }} -Xms{{ minecraft_min_memory }} -jar spigot.jar nogui
# Start command with optimized JVM flags ExecStop={{ minecraft_tools_dir }}/mcrcon/mcrcon -H 127.0.0.1 -P {{ minecraft_rcon_port }} -p {{ minecraft_rcon_password | default('changeme') }} stop
ExecStart=/usr/bin/java \ KillMode=none
-Xms{{ minecraft_memory_min }}M \ TimeoutStopSec=120
-Xmx{{ minecraft_memory_max }}M \
{{ jvm_flags }} \
-jar {{ spigot_jar_name }} \
--nogui
# Stop command using mcrcon
ExecStop={{ minecraft_tools_dir }}/mcrcon -H localhost -P {{ rcon_port }} -p "{{ rcon_password }}" stop
# Restart settings
Restart=on-failure Restart=on-failure
RestartSec=10
StartLimitInterval=600
StartLimitBurst=3
# Security settings
PrivateTmp=yes
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths={{ minecraft_base_dir }}
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true
LockPersonality=true
# Resource limits
LimitNOFILE=100000
LimitNPROC=512
# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=minecraft
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View File

@@ -1,11 +1,10 @@
[ [
{% for op in minecraft_ops %} {% for admin in minecraft_admins | default([]) %}
{ {
"uuid": "{{ op.uuid }}", "uuid": "{{ admin.uuid }}",
"name": "{{ op.name }}", "name": "{{ admin.name }}",
"level": {{ op.level | default(4) }}, "level": {{ admin.level | default(4) }},
"bypassesPlayerLimit": {{ op.bypassesPlayerLimit | default(false) | lower }} "bypassesPlayerLimit": {{ admin.bypass_limit | default(false) | lower }}
}{% if not loop.last %},{% endif %} }{% if not loop.last %},{% endif %}
{% endfor %} {% endfor %}
] ]

View File

@@ -1,188 +0,0 @@
# {{ ansible_managed }}
# Paper configuration file - only used if Paper is detected
# Version: {{ minecraft_version }}
verbose: false
config-version: 28
settings:
console-has-all-permissions: false
region-file-cache-size: 256
incoming-packet-spam-threshold: 300
max-joins-per-tick: 3
track-plugin-scoreboards: false
suggest-player-names-when-null-tab-completions: true
use-display-name-in-quit-message: false
load-permissions-yml-before-plugins: true
bungee-online-mode: false
unsupported-settings:
allow-permanent-block-break-exploits: false
allow-piston-duplication: false
allow-headless-pistons: false
watchdog:
early-warning-every: 5000
early-warning-delay: 10000
spam-limiter:
recipe-spam-increment: 1
recipe-spam-limit: 20
tab-spam-increment: 1
tab-spam-limit: 500
book-size:
page-max: 2560
total-multiplier: 0.98
async-chunks:
enable: true
threads: -1
velocity-support:
enabled: false
online-mode: false
secret: ''
world-settings:
default:
fix-climbing-bypassing-cramming-rule: false
max-leash-distance: 10.0
show-sign-click-command-failure-msgs-to-player: false
piglins-guard-chests: true
should-remove-dragon: false
max-auto-save-chunks-per-tick: 24
baby-zombie-movement-modifier: 0.5
optimize-explosions: false
disable-teleportation-suffocation-check: false
fixed-chunk-inhabited-time: -1
use-vanilla-world-scoreboard-name-coloring: false
prevent-moving-into-unloaded-chunks: false
spawn-limits:
monsters: -1
animals: -1
water-animals: -1
water-ambient: -1
water-underground-creature: -1
axolotls: -1
ambient: -1
despawn-ranges:
monster:
soft: 32
hard: 128
creature:
soft: 32
hard: 128
ambient:
soft: 32
hard: 128
axolotls:
soft: 32
hard: 128
water-creature:
soft: 32
hard: 128
water-ambient:
soft: 32
hard: 64
water-underground-creature:
soft: 32
hard: 128
misc:
soft: 32
hard: 128
frosted-ice:
enabled: true
delay:
min: 20
max: 40
lootables:
auto-replenish: false
restrict-player-reloot: true
reset-seed-on-fill: true
max-refills: -1
refresh-min: 12h
refresh-max: 2d
filter-nbt-data-from-spawn-eggs-and-related: true
max-entity-collisions: 8
disable-creeper-lingering-effect: false
duplicate-uuid-resolver: saferegen
duplicate-uuid-saferegen-delete-range: 32
per-player-mob-spawns: true
experience-merge-max-value: -1
prevent-tnt-from-moving-in-water: false
falling-block-height-nerf: 0
tnt-entity-height-nerf: 0
slime-spawn-height:
swamp-biome:
maximum: 70
minimum: 50
slime-chunk:
maximum: 40
portal-search-radius: 128
portal-create-radius: 16
portal-search-vanilla-dimension-scaling: true
enable-treasure-maps: true
treasure-maps-find-already-discovered:
loot-tables: default
villager-trade: false
disable-thunder: false
disable-ice-and-snow: false
disable-explosion-knockback: false
keep-spawn-loaded: true
keep-spawn-loaded-range: 10
auto-save-interval: -1
disable-mob-spawner-spawn-egg-transformation: false
entities-target-with-follow-range: false
zombies-target-turtle-eggs: true
zombie-villager-infection-chance: -1.0
all-chunks-are-slime-chunks: false
mob-spawner-tick-rate: 1
light-queue-size: 20
grass-spread-tick-rate: 1
redstone-implementation: vanilla
armor-stands-tick: true
water-over-lava-flow-speed: 5
use-faster-eigencraft-redstone: false
disable-move-event: false
container-update-tick-rate: 1
non-player-arrow-despawn-rate: -1
creative-arrow-despawn-rate: -1
skeleton-horse-thunder-spawn-chance: 0.01
disable-ice-and-snow: false
iron-golems-can-spawn-in-air: false
count-all-mobs-for-spawning: false
delay-chunk-unloads-by: 10s
seed-based-feature-search: true
seed-based-feature-search-loads-chunks: true
water-flow-speed: 5
lava-flow-speed:
normal: 30
nether: 10
fix-items-merging-through-walls: false
prevent-lightning-strike-blocks-from-decaying: false
squid-spawn-height:
minimum: 45
maximum: 0
disable-pillager-patrols: false
game-mechanics:
scan-for-legacy-ender-dragon: true
disable-chest-cat-detection: false
nerf-pigmen-from-nether-portals: false
disable-player-crits: false
disable-sprint-interruption-on-attack: false
shield-blocking-delay: 5
disable-end-credits: false
disable-relative-projectile-velocity: false
disable-mob-spawner-spawn-egg-transformation: false
pillager-patrols:
spawn-chance: 0.2
spawn-delay:
per-player: false
ticks: 12000
start:
per-player: false
day: 5
max-growth-height:
cactus: 3
reeds: 3
bamboo:
max: 16
min: 11
fishing-time-range:
minimum: 100
maximum: 600

View File

@@ -1,54 +0,0 @@
# {{ ansible_managed }}
# Permissions configuration for Bukkit
# Default permissions
default:
default: true
permissions:
bukkit.command.help: true
bukkit.command.list: true
bukkit.command.me: true
bukkit.command.msg: true
bukkit.command.tell: true
bukkit.command.trigger: true
# Moderator permissions
moderator:
default: false
inheritance:
- default
permissions:
bukkit.command.kick: true
bukkit.command.ban: true
bukkit.command.ban.ip: true
bukkit.command.ban.list: true
bukkit.command.unban: true
bukkit.command.unban.ip: true
bukkit.command.pardon: true
bukkit.command.pardon.ip: true
bukkit.command.whitelist: true
bukkit.command.whitelist.add: true
bukkit.command.whitelist.remove: true
bukkit.command.whitelist.list: true
bukkit.command.whitelist.on: true
bukkit.command.whitelist.off: true
bukkit.command.whitelist.reload: true
# Admin permissions
admin:
default: false
inheritance:
- moderator
permissions:
bukkit.command.op: true
bukkit.command.op.give: true
bukkit.command.op.take: true
bukkit.command.save: true
bukkit.command.save.disable: true
bukkit.command.save.enable: true
bukkit.command.save.perform: true
bukkit.command.stop: true
bukkit.command.restart: true
bukkit.command.reload: true
bukkit.command.version: true
bukkit.command.plugins: true

View File

@@ -1,66 +1,38 @@
# {{ ansible_managed }} #Minecraft server properties généré par Ansible
# Minecraft server properties - Generated on {{ ansible_date_time.iso8601 }} generator-settings=
# Server Settings
server-port={{ server_port }}
server-ip=
max-tick-time=60000
enable-rcon={{ enable_rcon | lower }}
rcon.port={{ rcon_port }}
rcon.password={{ rcon_password }}
enable-query=false
query.port={{ server_port }}
# Gameplay
gamemode={{ gamemode }}
difficulty={{ difficulty }}
hardcore=false
pvp={{ pvp | lower }}
enable-command-block={{ enable_command_block | lower }}
max-players={{ max_players }}
online-mode={{ online_mode | lower }}
white-list={{ white_list | lower }}
enforce-whitelist={{ white_list | lower }}
op-permission-level=4 op-permission-level=4
player-idle-timeout=0
prevent-proxy-connections=false
hide-online-players=false
simulation-distance=10
# World
level-name=world
level-seed={{ level_seed }}
level-type={{ level_type }}
generate-structures={{ generate_structures | lower }}
spawn-protection={{ spawn_protection }}
max-world-size={{ max_world_size }}
max-build-height=319
view-distance={{ view_distance }}
spawn-animals={{ spawn_animals | lower }}
spawn-monsters={{ spawn_monsters | lower }}
spawn-npcs={{ spawn_npcs | lower }}
allow-nether=true allow-nether=true
level-name=world
# Performance enable-query=false
network-compression-threshold=256
rate-limit=0
sync-chunk-writes=true
use-native-transport=true
allow-flight=false allow-flight=false
announce-player-achievements=true
# Messages server-port={{ minecraft_port }}
motd={{ server_name }} max-world-size=29999984
resource-pack= level-type=default
resource-pack-prompt= enable-rcon={{ server_properties['enable-rcon'] }}
resource-pack-sha1= level-seed=
require-resource-pack=false
# Advanced
enable-jmx-monitoring=false
enable-status=true
entity-broadcast-range-percentage=100
force-gamemode=false force-gamemode=false
function-permission-level=2 server-ip=
initial-disabled-packs= max-build-height=256
initial-enabled-packs=vanilla spawn-npcs=true
text-filtering-config= white-list={{ server_properties['white-list'] }}
spawn-animals=true
hardcore=false
snooper-enabled=true
resource-pack-sha1=
online-mode=true
resource-pack=
pvp={{ server_properties['pvp'] }}
difficulty={{ server_properties['difficulty'] }}
enable-command-block=false
gamemode={{ server_properties['gamemode'] }}
player-idle-timeout=0
max-players={{ server_properties['max-players'] }}
max-tick-time=60000
spawn-monsters=true
view-distance=10
generate-structures=true
spawn-protection={{ server_properties['spawn-protection'] }}
motd=Un serveur Minecraft avec Spigot
rcon.port={{ minecraft_rcon_port }}
rcon.password={{ minecraft_rcon_password | default('changeme') }}

View File

@@ -1,130 +0,0 @@
# {{ ansible_managed }}
# This is the main configuration file for Spigot.
# Spigot version: {{ minecraft_version }}
settings:
debug: false
save-user-cache-on-stop-only: false
bungeecord: false
late-bind: false
sample-count: 12
player-shuffle: 0
user-cache-size: 1000
moved-wrongly-threshold: 0.0625
moved-too-quickly-multiplier: 10.0
timeout-time: 60
restart-on-crash: true
restart-script: {{ minecraft_base_dir }}/scripts/start.sh
netty-threads: 4
log-villager-deaths: true
log-named-deaths: true
attribute:
maxHealth:
max: 2048.0
movementSpeed:
max: 2048.0
attackDamage:
max: 2048.0
messages:
whitelist: You are not whitelisted on this server!
unknown-command: Unknown command. Type "/help" for help.
server-full: The server is full!
outdated-client: Outdated client! Please use {0}
outdated-server: Outdated server! I'm still on {0}
restart: Server is restarting
commands:
replace-commands:
- setblock
- summon
- testforblock
- tellraw
spam-exclusions:
- /skill
silent-commandblock-console: false
log: true
tab-complete: -1
send-namespaced: true
advancements:
disable-saving: false
disabled:
- minecraft:story/disabled
players:
disable-saving: false
world-settings:
default:
below-zero-generation-in-existing-chunks: true
merge-radius:
exp: 3.0
item: 2.5
growth:
cactus-modifier: 100
cane-modifier: 100
melon-modifier: 100
mushroom-modifier: 100
pumpkin-modifier: 100
sapling-modifier: 100
beetroot-modifier: 100
carrot-modifier: 100
potato-modifier: 100
wheat-modifier: 100
netherwart-modifier: 100
vine-modifier: 100
cocoa-modifier: 100
bamboo-modifier: 100
sweetberry-modifier: 100
kelp-modifier: 100
entity-activation-range:
animals: 32
monsters: 32
raiders: 48
misc: 16
tick-inactive-villagers: true
entity-tracking-range:
players: 48
animals: 48
monsters: 48
misc: 32
other: 64
ticks-per:
hopper-transfer: 8
hopper-check: 1
hopper-amount: 1
save-structure-info: true
dragon-death-sound-radius: 0
seed-village: 10387312
seed-desert: 14357617
seed-igloo: 14357618
seed-jungle: 14357619
seed-swamp: 14357620
seed-monument: 10387313
seed-shipwreck: 165745295
seed-ocean: 14357621
seed-outpost: 165745296
seed-endcity: 10387313
seed-slime: 987234911
seed-bastion: 30084232
seed-fortress: 30084232
seed-mansion: 10387319
seed-fossil: 14357921
seed-portal: 34222645
max-tnt-per-tick: 100
enable-zombie-pigmen-portal-spawns: true
item-despawn-rate: 6000
view-distance: default
simulation-distance: default
thunder-chance: 100000
wither-spawn-sound-radius: 0
arrow-despawn-rate: 1200
trident-despawn-rate: 1200
hanging-tick-frequency: 100
zombie-aggressive-towards-villager: true
nerf-spawner-mobs: false
mob-spawn-range: 8
end-portal-sound-radius: 0
config-version: 12

View File

@@ -1,17 +0,0 @@
#!/bin/bash
# {{ ansible_managed }}
# Configuration
SERVER_DIR="{{ minecraft_server_dir }}"
JAR_FILE="{{ spigot_jar_name }}"
MIN_RAM="{{ minecraft_memory_min }}M"
MAX_RAM="{{ minecraft_memory_max }}M"
# JVM Flags optimisés pour Minecraft
JVM_FLAGS="{{ jvm_flags }}"
# Aller dans le répertoire du serveur
cd "$SERVER_DIR" || exit 1
# Démarrer le serveur
exec java -Xms${MIN_RAM} -Xmx${MAX_RAM} ${JVM_FLAGS} -jar ${JAR_FILE} --nogui

View File

@@ -1,39 +0,0 @@
#!/bin/bash
# {{ ansible_managed }}
MCRCON="{{ minecraft_tools_dir }}/mcrcon"
RCON_HOST="localhost"
RCON_PORT="{{ rcon_port }}"
RCON_PASS="{{ rcon_password }}"
# Fonction pour envoyer des commandes au serveur
send_command() {
$MCRCON -H $RCON_HOST -P $RCON_PORT -p "$RCON_PASS" "$1"
}
# Avertir les joueurs
echo "Avertissement des joueurs..."
send_command "say Le serveur va redémarrer dans 60 secondes!"
sleep 30
send_command "say Le serveur va redémarrer dans 30 secondes!"
sleep 20
send_command "say Le serveur va redémarrer dans 10 secondes!"
sleep 5
for i in 5 4 3 2 1; do
send_command "say Arrêt dans $i..."
sleep 1
done
# Sauvegarder le monde
echo "Sauvegarde du monde..."
send_command "save-all"
sleep 5
# Arrêter le serveur
echo "Arrêt du serveur..."
send_command "stop"
echo "Serveur arrêté proprement."

View File

@@ -1,9 +0,0 @@
[
{% for player in minecraft_whitelist | default([]) %}
{
"uuid": "{{ player.uuid }}",
"name": "{{ player.name }}"
}{% if not loop.last %},{% endif %}
{% endfor %}
]

View File

@@ -1,32 +1,19 @@
--- ---
# Variables internes du rôle # Variables Minecraft
minecraft_service_name: minecraft
spigot_jar_name: "spigot-{{ minecraft_version }}.jar" spigot_jar_name: "spigot-{{ minecraft_version }}.jar"
buildtools_jar: "BuildTools.jar" build_tools_jar: "BuildTools.jar"
server_jar_path: "{{ minecraft_server_dir }}/{{ spigot_jar_name }}"
# Liste des répertoires à créer # Plugins par défaut
minecraft_dirs: default_plugins:
- "{{ minecraft_base_dir }}" - name: "WorldEdit"
- "{{ minecraft_server_dir }}" url: "https://dev.bukkit.org/projects/worldedit/files/latest"
- "{{ minecraft_sources_dir }}" - name: "Vault"
- "{{ minecraft_tools_dir }}" url: "https://dev.bukkit.org/projects/vault/files/latest"
- "{{ minecraft_server_dir }}/plugins"
- "{{ minecraft_server_dir }}/world"
- "{{ minecraft_server_dir }}/world_nether"
- "{{ minecraft_server_dir }}/world_the_end"
- "{{ minecraft_server_dir }}/logs"
- "{{ minecraft_server_dir }}/crash-reports"
- "{{ minecraft_base_dir }}/scripts"
# Packages requis pour la compilation # Configuration logs
build_packages: logrotate_config:
- git rotate: 30
- build-essential size: "100M"
- screen compress: true
- htop delaycompress: true
- iotop
- wget
- curl
# Configuration JVM
jvm_flags: "-XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1"

View File

@@ -1,11 +0,0 @@
---
backup_base_dir: /opt/minecraft/backups
backup_daily_dir: "{{ backup_base_dir }}/daily"
backup_weekly_dir: "{{ backup_base_dir }}/weekly"
backup_monthly_dir: "{{ backup_base_dir }}/monthly"
backup_retention_daily: 7
backup_retention_weekly: 4
backup_retention_monthly: 3
backup_time_daily: "03:00"
backup_time_weekly: "04:00"
backup_time_monthly: "05:00"

View File

@@ -2,5 +2,4 @@
- name: reload cron - name: reload cron
ansible.builtin.service: ansible.builtin.service:
name: cron name: cron
state: reloaded state: reloaded
listen: reload cron service

View File

@@ -1,9 +0,0 @@
---
- name: Create backup directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0755'
loop: "{{ backup_dirs }}"

View File

@@ -0,0 +1,12 @@
---
- name: Création de la structure des sauvegardes
ansible.builtin.file:
path: "{{ minecraft_backups_dir }}/{{ item }}"
state: directory
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0755'
with_items:
- daily
- weekly
- monthly

View File

@@ -1,6 +0,0 @@
---
- name: Install rsync
ansible.builtin.apt:
name: rsync
state: present
when: ansible_os_family == "Debian"

View File

@@ -0,0 +1,17 @@
---
- name: Création du script de sauvegarde quotidienne
ansible.builtin.template:
src: backup-daily.sh.j2
dest: "{{ backup_script_path }}/minecraft-backup-daily.sh"
owner: root
group: root
mode: '0755'
- name: Configuration cron pour sauvegarde quotidienne
ansible.builtin.cron:
name: "Minecraft Daily Backup"
minute: "0"
hour: "2"
job: "{{ backup_script_path }}/minecraft-backup-daily.sh"
user: "{{ minecraft_user }}"
state: present

View File

@@ -1,16 +0,0 @@
---
- name: Create backup script
ansible.builtin.template:
src: backup.sh.j2
dest: "{{ minecraft_base_dir }}/backup.sh"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0755'
- name: Create restore script
ansible.builtin.template:
src: restore.sh.j2
dest: "{{ minecraft_base_dir }}/restore.sh"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0755'

View File

@@ -0,0 +1,18 @@
---
- name: Création du script de sauvegarde hebdomadaire
ansible.builtin.template:
src: backup-weekly.sh.j2
dest: "{{ backup_script_path }}/minecraft-backup-weekly.sh"
owner: root
group: root
mode: '0755'
- name: Configuration cron pour sauvegarde hebdomadaire
ansible.builtin.cron:
name: "Minecraft Weekly Backup"
minute: "0"
hour: "3"
weekday: "0"
job: "{{ backup_script_path }}/minecraft-backup-weekly.sh"
user: "{{ minecraft_user }}"
state: present

View File

@@ -1,29 +0,0 @@
---
- name: Setup daily backup cron job
ansible.builtin.cron:
name: "Minecraft daily backup"
user: "{{ minecraft_user }}"
hour: "{{ backup_time_daily.split(':')[0] }}"
minute: "{{ backup_time_daily.split(':')[1] }}"
job: "{{ minecraft_base_dir }}/backup.sh daily"
notify: reload cron service
- name: Setup weekly backup cron job
ansible.builtin.cron:
name: "Minecraft weekly backup"
user: "{{ minecraft_user }}"
hour: "{{ backup_time_weekly.split(':')[0] }}"
minute: "{{ backup_time_weekly.split(':')[1] }}"
weekday: "0"
job: "{{ minecraft_base_dir }}/backup.sh weekly"
notify: reload cron service
- name: Setup monthly backup cron job
ansible.builtin.cron:
name: "Minecraft monthly backup"
user: "{{ minecraft_user }}"
hour: "{{ backup_time_monthly.split(':')[0] }}"
minute: "{{ backup_time_monthly.split(':')[1] }}"
day: "1"
job: "{{ minecraft_base_dir }}/backup.sh monthly"
notify: reload cron service

View File

@@ -0,0 +1,18 @@
---
- name: Création du script de sauvegarde mensuelle
ansible.builtin.template:
src: backup-monthly.sh.j2
dest: "{{ backup_script_path }}/minecraft-backup-monthly.sh"
owner: root
group: root
mode: '0755'
- name: Configuration cron pour sauvegarde mensuelle
ansible.builtin.cron:
name: "Minecraft Monthly Backup"
minute: "0"
hour: "4"
day: "1"
job: "{{ backup_script_path }}/minecraft-backup-monthly.sh"
user: "{{ minecraft_user }}"
state: present

View File

@@ -1,26 +0,0 @@
---
- name: Create restore script
ansible.builtin.template:
src: restore.sh.j2
dest: "{{ minecraft_base_dir }}/restore.sh"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0755'
- name: Stop minecraft server before restore
ansible.builtin.systemd:
name: "{{ minecraft_service_name }}"
state: stopped
when: restore_backup_type is defined
- name: Execute restore
ansible.builtin.command:
cmd: "{{ minecraft_base_dir }}/restore.sh {{ restore_backup_type }} {{ restore_backup_date | default('latest') }}"
become_user: "{{ minecraft_user }}"
when: restore_backup_type is defined
- name: Start minecraft server after restore
ansible.builtin.systemd:
name: "{{ minecraft_service_name }}"
state: started
when: restore_backup_type is defined

View File

@@ -0,0 +1,8 @@
---
- name: Création du script de restauration
ansible.builtin.template:
src: restore.sh.j2
dest: "{{ backup_script_path }}/minecraft-restore.sh"
owner: root
group: root
mode: '0755'

View File

@@ -1,16 +1,16 @@
--- ---
- name: Include create backup directories tasks # Tâches principales sauvegardes
ansible.builtin.include_tasks: 01-create-backup-dirs.yml - import_tasks: 01-create-backup-structure.yml
tags: [backup, structure]
- name: Include install rsync tasks - import_tasks: 02-setup-daily-backup.yml
ansible.builtin.include_tasks: 02-install-rsync.yml tags: [backup, daily]
- name: Include configure backup script tasks - import_tasks: 03-setup-weekly-backup.yml
ansible.builtin.include_tasks: 03-configure-backup-script.yml tags: [backup, weekly]
- name: Include setup cron tasks - import_tasks: 04-setup-monthly-backup.yml
ansible.builtin.include_tasks: 04-setup-cron.yml tags: [backup, monthly]
- name: Include restore backup tasks - import_tasks: 05-setup-restore-script.yml
ansible.builtin.include_tasks: 05-restore-backup.yml tags: [backup, restore]
when: restore_backup | default(false)

View File

@@ -0,0 +1,25 @@
#!/bin/bash
# Script de sauvegarde quotidienne Minecraft
set -e
BACKUP_DIR="{{ minecraft_backups_dir }}/daily"
SOURCE_DIR="{{ minecraft_server_dir }}"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="minecraft-daily-${DATE}"
RETENTION={{ backup_retention_daily }}
# Notification du début de sauvegarde
echo "$(date): Début de la sauvegarde quotidienne"
# Commande save-all via rcon si le serveur est en cours
{{ minecraft_tools_dir }}/mcrcon/mcrcon -H 127.0.0.1 -P {{ minecraft_rcon_port }} -p {{ minecraft_rcon_password | default('changeme') }} save-all || true
sleep 5
# Création de la sauvegarde
rsync {{ rsync_options }} --exclude 'logs' "${SOURCE_DIR}/" "${BACKUP_DIR}/${BACKUP_NAME}/"
# Nettoyage des anciennes sauvegardes
find "${BACKUP_DIR}" -type d -name "minecraft-daily-*" -mtime +${RETENTION} -exec rm -rf {} + 2>/dev/null || true
echo "$(date): Sauvegarde quotidienne terminée: ${BACKUP_NAME}"

View File

@@ -0,0 +1,24 @@
#!/bin/bash
# Script de sauvegarde mensuelle Minecraft
set -e
BACKUP_DIR="{{ minecraft_backups_dir }}/monthly"
SOURCE_DIR="{{ minecraft_server_dir }}"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="minecraft-monthly-${DATE}"
RETENTION={{ backup_retention_monthly }}
echo "$(date): Début de la sauvegarde mensuelle"
# Commande save-all via rcon
{{ minecraft_tools_dir }}/mcrcon/mcrcon -H 127.0.0.1 -P {{ minecraft_rcon_port }} -p {{ minecraft_rcon_password | default('changeme') }} save-all || true
sleep 10
# Création de la sauvegarde
rsync {{ rsync_options }} "${SOURCE_DIR}/" "${BACKUP_DIR}/${BACKUP_NAME}/"
# Nettoyage des anciennes sauvegardes (mois)
find "${BACKUP_DIR}" -type d -name "minecraft-monthly-*" -mtime +$((${RETENTION} * 30)) -exec rm -rf {} + 2>/dev/null || true
echo "$(date): Sauvegarde mensuelle terminée: ${BACKUP_NAME}"

View File

@@ -0,0 +1,24 @@
#!/bin/bash
# Script de sauvegarde hebdomadaire Minecraft
set -e
BACKUP_DIR="{{ minecraft_backups_dir }}/weekly"
SOURCE_DIR="{{ minecraft_server_dir }}"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="minecraft-weekly-${DATE}"
RETENTION={{ backup_retention_weekly }}
echo "$(date): Début de la sauvegarde hebdomadaire"
# Commande save-all via rcon
{{ minecraft_tools_dir }}/mcrcon/mcrcon -H 127.0.0.1 -P {{ minecraft_rcon_port }} -p {{ minecraft_rcon_password | default('changeme') }} save-all || true
sleep 5
# Création de la sauvegarde
rsync {{ rsync_options }} "${SOURCE_DIR}/" "${BACKUP_DIR}/${BACKUP_NAME}/"
# Nettoyage des anciennes sauvegardes (semaines)
find "${BACKUP_DIR}" -type d -name "minecraft-weekly-*" -mtime +$((${RETENTION} * 7)) -exec rm -rf {} + 2>/dev/null || true
echo "$(date): Sauvegarde hebdomadaire terminée: ${BACKUP_NAME}"

View File

@@ -1,69 +0,0 @@
#!/bin/bash
# {{ ansible_managed }}
BACKUP_TYPE=$1
BACKUP_BASE="{{ backup_base_dir }}"
SERVER_DIR="{{ minecraft_server_dir }}"
TOOLS_DIR="{{ minecraft_tools_dir }}"
RCON_CMD="{{ minecraft_tools_dir }}/mcrcon -H localhost -P {{ rcon_port }} -p {{ rcon_password }}"
DATE=$(date +%Y%m%d_%H%M%S)
# Function to clean old backups
clean_old_backups() {
local dir=$1
local keep=$2
ls -1t $dir/*.tar.gz 2>/dev/null | tail -n +$((keep+1)) | xargs rm -f
}
# Function to perform backup
perform_backup() {
local backup_dir=$1
local retention=$2
echo "Starting $BACKUP_TYPE backup at $(date)"
# Notify players
$RCON_CMD "say Server backup starting in 10 seconds..."
sleep 10
# Save world
$RCON_CMD "save-all"
sleep 5
# Disable auto-save
$RCON_CMD "save-off"
# Create backup
tar -czf "$backup_dir/minecraft_${BACKUP_TYPE}_${DATE}.tar.gz" \
-C "{{ minecraft_base_dir }}" \
server/ sources/ tools/ \
--exclude='*.log' \
--exclude='logs/*'
# Re-enable auto-save
$RCON_CMD "save-on"
# Clean old backups
clean_old_backups "$backup_dir" "$retention"
# Notify players
$RCON_CMD "say Server backup completed!"
echo "Backup completed at $(date)"
}
case "$BACKUP_TYPE" in
daily)
perform_backup "{{ backup_daily_dir }}" "{{ backup_retention_daily }}"
;;
weekly)
perform_backup "{{ backup_weekly_dir }}" "{{ backup_retention_weekly }}"
;;
monthly)
perform_backup "{{ backup_monthly_dir }}" "{{ backup_retention_monthly }}"
;;
*)
echo "Usage: $0 {daily|weekly|monthly}"
exit 1
;;
esac

View File

@@ -1,61 +1,53 @@
#!/bin/bash #!/bin/bash
# {{ ansible_managed }} # Script de restauration Minecraft
BACKUP_TYPE=$1 set -e
BACKUP_DATE=$2
BACKUP_BASE="{{ backup_base_dir }}"
SERVER_DIR="{{ minecraft_server_dir }}"
# Function to find backup file if [ $# -ne 2 ]; then
find_backup() { echo "Usage: $0 <type> <backup_name>"
local type=$1 echo "Types: daily, weekly, monthly"
local date=$2 echo "Exemple: $0 daily minecraft-daily-20240127_020000"
local dir=""
case "$type" in
daily) dir="{{ backup_daily_dir }}" ;;
weekly) dir="{{ backup_weekly_dir }}" ;;
monthly) dir="{{ backup_monthly_dir }}" ;;
*) echo "Invalid backup type"; exit 1 ;;
esac
if [ "$date" = "latest" ]; then
ls -1t $dir/*.tar.gz 2>/dev/null | head -n 1
else
ls $dir/*${date}*.tar.gz 2>/dev/null | head -n 1
fi
}
# Main restore process
BACKUP_FILE=$(find_backup "$BACKUP_TYPE" "$BACKUP_DATE")
if [ -z "$BACKUP_FILE" ]; then
echo "No backup found for type: $BACKUP_TYPE, date: $BACKUP_DATE"
exit 1 exit 1
fi fi
echo "Restoring from: $BACKUP_FILE" TYPE=$1
BACKUP_NAME=$2
BACKUP_DIR="{{ minecraft_backups_dir }}/${TYPE}"
TARGET_DIR="{{ minecraft_server_dir }}"
# Create restore directory if [ ! -d "${BACKUP_DIR}/${BACKUP_NAME}" ]; then
RESTORE_DIR="{{ minecraft_base_dir }}/restore_$(date +%Y%m%d_%H%M%S)" echo "Erreur: Sauvegarde ${BACKUP_NAME} introuvable dans ${BACKUP_DIR}"
mkdir -p "$RESTORE_DIR" exit 1
fi
# Extract backup echo "ATTENTION: Cette opération va remplacer les données actuelles du serveur."
tar -xzf "$BACKUP_FILE" -C "$RESTORE_DIR" read -p "Voulez-vous continuer? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Restauration annulée."
exit 1
fi
# Backup current server # Arrêt du serveur
echo "Backing up current server state..." echo "Arrêt du serveur Minecraft..."
tar -czf "{{ backup_base_dir }}/pre_restore_$(date +%Y%m%d_%H%M%S).tar.gz" \ systemctl stop minecraft || true
-C "{{ minecraft_base_dir }}" server/ sleep 5
# Restore files # Sauvegarde du répertoire actuel
echo "Restoring server files..." CURRENT_BACKUP="${TARGET_DIR}.backup-$(date +%Y%m%d_%H%M%S)"
rsync -av --delete "$RESTORE_DIR/server/" "$SERVER_DIR/" echo "Sauvegarde du répertoire actuel vers ${CURRENT_BACKUP}"
cp -r "${TARGET_DIR}" "${CURRENT_BACKUP}"
# Set permissions # Restauration
chown -R {{ minecraft_user }}:{{ minecraft_group }} "$SERVER_DIR" echo "Restauration de ${BACKUP_NAME}..."
rsync {{ rsync_options }} "${BACKUP_DIR}/${BACKUP_NAME}/" "${TARGET_DIR}/"
# Clean up # Correction des permissions
rm -rf "$RESTORE_DIR" chown -R {{ minecraft_user }}:{{ minecraft_group }} "${TARGET_DIR}"
echo "Restore completed successfully!" # Redémarrage du serveur
echo "Redémarrage du serveur Minecraft..."
systemctl start minecraft
echo "Restauration terminée avec succès."
echo "Sauvegarde de l'ancienne version disponible dans: ${CURRENT_BACKUP}"

View File

@@ -1,11 +1,10 @@
--- ---
backup_dirs: # Variables sauvegardes
- "{{ backup_base_dir }}" backup_script_path: /usr/local/bin
- "{{ backup_daily_dir }}" minecraft_backup_source: "{{ minecraft_server_dir }}"
- "{{ backup_weekly_dir }}" minecraft_backup_dest: "{{ minecraft_backups_dir }}"
- "{{ backup_monthly_dir }}"
backup_source_dirs: backup_types:
- "{{ minecraft_server_dir }}" - daily
- "{{ minecraft_sources_dir }}" - weekly
- "{{ minecraft_tools_dir }}" - monthly

View File

@@ -1,6 +1,6 @@
--- ---
update_check_ssh_keys: true # Configuration par défaut des mises à jour
update_check_system: true update_check_enabled: true
update_check_spigot: true update_system_packages: false
spigot_update_dir: "{{ minecraft_sources_dir }}/update" spigot_update_check_url: "https://hub.spigotmc.org/versions/"
spigot_previous_dir: "{{ minecraft_sources_dir }}/previous" update_backup_before: true

View File

@@ -1,13 +1,5 @@
--- ---
- name: restart services - name: restart minecraft
ansible.builtin.systemd: ansible.builtin.service:
name: "{{ item }}" name: minecraft
state: restarted state: restarted
loop:
- minecraft
- ssh
listen: restart updated services
- name: switch minecraft version
ansible.builtin.command: "{{ minecraft_base_dir }}/switch_version.sh"
listen: switch to new version

View File

@@ -1,30 +0,0 @@
---
galaxy_info:
author: Tips-Of-Mine
description: Système de mise à jour automatique pour Minecraft et le système
company: Tips-Of-Mine
license: MIT
min_ansible_version: "2.14"
platforms:
- name: Debian
versions:
- buster
- bullseye
- bookworm
- trixie
- name: Ubuntu
versions:
- focal
- jammy
- noble
galaxy_tags:
- update
- maintenance
- minecraft
- automation
dependencies:
- role: 02-installation-java
when: java_update_required | default(false)
- role: 03-Installation-Minecraft
when: minecraft_update_required | default(false)

View File

@@ -1,21 +1,9 @@
--- ---
- name: Check for new SSH keys in repository - name: Vérification des nouvelles clés SSH
ansible.builtin.set_fact:
ssh_keys_to_add: "{{ admin_ssh_keys | default([]) }}"
- name: Get current authorized keys
ansible.builtin.slurp:
src: /home/ansible/.ssh/authorized_keys
register: current_keys
ignore_errors: yes
- name: Add new SSH keys if found
ansible.posix.authorized_key: ansible.posix.authorized_key:
user: ansible user: "{{ item.user }}"
state: present state: present
key: "{{ item.key }}" key: "{{ item.key }}"
comment: "{{ item.name }}" comment: "{{ item.comment | default('Admin key') }}"
loop: "{{ ssh_keys_to_add }}" with_items: "{{ admin_ssh_keys | default([]) }}"
when: when: admin_ssh_keys is defined
- ssh_keys_to_add | length > 0
- item.key not in (current_keys.content | b64decode | default(''))

View File

@@ -1,26 +1,23 @@
--- ---
- name: Update apt cache - name: Vérification des mises à jour système disponibles
ansible.builtin.apt: ansible.builtin.apt:
update_cache: yes update_cache: yes
cache_valid_time: 3600 cache_valid_time: 3600
when: ansible_os_family == "Debian" when: ansible_os_family == "Debian"
- name: Check for available updates - name: Liste des paquets à mettre à jour
ansible.builtin.command: apt list --upgradable ansible.builtin.apt:
register: apt_updates upgrade: dist
changed_when: false dry_run: yes
register: system_updates_check
when: ansible_os_family == "Debian" when: ansible_os_family == "Debian"
- name: Display available updates - name: Application des mises à jour système si nécessaire
ansible.builtin.debug:
msg: "Available updates: {{ apt_updates.stdout_lines | length - 1 }} packages"
when: apt_updates is defined
- name: Perform system update if requested
ansible.builtin.apt: ansible.builtin.apt:
upgrade: safe upgrade: dist
autoremove: yes autoremove: yes
autoclean: yes autoclean: yes
when: when:
- ansible_os_family == "Debian" - ansible_os_family == "Debian"
- perform_system_update | default(false) - update_system_packages | default(false)
- system_updates_check.changed

View File

@@ -1,30 +1,22 @@
--- ---
- name: Get current Spigot version - name: Lecture de la version actuelle
ansible.builtin.slurp: ansible.builtin.slurp:
src: "{{ current_version_file }}" src: "{{ current_version_file }}"
register: current_version register: current_version_content
ignore_errors: yes failed_when: false
- name: Set current version fact - name: Définition de la version actuelle
ansible.builtin.set_fact: set_fact:
current_spigot_version: "{{ (current_version.content | b64decode).strip() if current_version is succeeded else 'unknown' }}" current_spigot_version: "{{ (current_version_content.content | b64decode).strip() if current_version_content.content is defined else 'unknown' }}"
- name: Check latest Spigot version - name: Vérification de la dernière version Spigot disponible
ansible.builtin.uri: ansible.builtin.uri:
url: "https://hub.spigotmc.org/versions/{{ minecraft_version }}.json" url: "{{ spigot_update_check_url }}{{ minecraft_version }}.json"
method: GET method: GET
return_content: yes return_content: yes
register: latest_version_info register: spigot_version_check
ignore_errors: yes failed_when: false
- name: Compare versions - name: Détermination si une mise à jour est disponible
ansible.builtin.set_fact: set_fact:
spigot_needs_update: "{{ current_spigot_version != minecraft_version }}" spigot_update_available: "{{ minecraft_version != current_spigot_version }}"
when: latest_version_info is succeeded
- name: Display version status
ansible.builtin.debug:
msg:
- "Current version: {{ current_spigot_version }}"
- "Target version: {{ minecraft_version }}"
- "Update needed: {{ spigot_needs_update | default(false) }}"

View File

@@ -0,0 +1,16 @@
---
- name: Création du répertoire de build temporaire
ansible.builtin.file:
path: "{{ temp_build_dir }}"
state: directory
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0755'
- name: Téléchargement de BuildTools pour la nouvelle version
ansible.builtin.get_url:
url: "{{ spigot_build_tools_url }}"
dest: "{{ temp_build_dir }}/BuildTools.jar"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0644'

View File

@@ -1,22 +0,0 @@
---
- name: Create update directory
ansible.builtin.file:
path: "{{ spigot_update_dir }}"
state: directory
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0755'
- name: Download latest BuildTools
ansible.builtin.get_url:
url: "{{ minecraft_build_tools_url }}"
dest: "{{ spigot_update_dir }}/BuildTools.jar"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0644'
force: yes
- name: Clean update directory
ansible.builtin.file:
path: "{{ spigot_update_dir }}/work"
state: absent

View File

@@ -0,0 +1,13 @@
---
- name: Compilation de la nouvelle version Spigot
ansible.builtin.command:
cmd: "java -jar BuildTools.jar --rev {{ minecraft_version }}"
chdir: "{{ temp_build_dir }}"
creates: "{{ temp_build_dir }}/spigot-{{ minecraft_version }}.jar"
become_user: "{{ minecraft_user }}"
timeout: 1800
register: spigot_compile_result
- name: Marquage du succès de compilation
set_fact:
spigot_compilation_success: "{{ spigot_compile_result.rc == 0 }}"

View File

@@ -1,25 +0,0 @@
---
- name: Compile new Spigot version
ansible.builtin.command:
cmd: "java -jar BuildTools.jar --rev {{ minecraft_version }}"
chdir: "{{ spigot_update_dir }}"
become_user: "{{ minecraft_user }}"
register: compile_result
- name: Verify compilation success
ansible.builtin.stat:
path: "{{ spigot_update_dir }}/spigot-{{ minecraft_version }}.jar"
register: new_jar
- name: Set update ready flag
ansible.builtin.set_fact:
spigot_update_ready: "{{ new_jar.stat.exists }}"
- name: Create staging directory
ansible.builtin.file:
path: "{{ update_staging_dir }}"
state: directory
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0755'
when: spigot_update_ready

View File

@@ -1,27 +0,0 @@
---
- name: Copy new jar to staging
ansible.builtin.copy:
src: "{{ spigot_update_dir }}/spigot-{{ minecraft_version }}.jar"
dest: "{{ update_staging_dir }}/spigot-{{ minecraft_version }}.jar"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0644'
remote_src: yes
- name: Copy current configuration to staging
ansible.builtin.synchronize:
src: "{{ minecraft_server_dir }}/"
dest: "{{ update_staging_dir }}/"
rsync_opts:
- "--exclude=*.jar"
- "--exclude=world*"
- "--exclude=logs"
- "--exclude=crash-reports"
delegate_to: "{{ inventory_hostname }}"
- name: Update jar reference in staging
ansible.builtin.replace:
path: "{{ update_staging_dir }}/start.sh"
regexp: 'spigot-.*\.jar'
replace: 'spigot-{{ minecraft_version }}.jar'
when: spigot_update_ready

View File

@@ -0,0 +1,31 @@
---
- name: Sauvegarde avant mise à jour
ansible.builtin.command:
cmd: "{{ backup_script_path }}/minecraft-backup-daily.sh"
when: update_backup_before | default(true)
- name: Génération du script de changement de version
ansible.builtin.template:
src: version-switch.sh.j2
dest: "{{ update_script_path }}/minecraft-version-switch.sh"
owner: root
group: root
mode: '0755'
- name: Exécution du changement de version
ansible.builtin.command:
cmd: "{{ update_script_path }}/minecraft-version-switch.sh {{ minecraft_version }}"
notify: restart minecraft
- name: Mise à jour du fichier de version
ansible.builtin.copy:
content: "{{ minecraft_version }}"
dest: "{{ current_version_file }}"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0644'
- name: Nettoyage du répertoire temporaire
ansible.builtin.file:
path: "{{ temp_build_dir }}"
state: absent

View File

@@ -1,49 +0,0 @@
---
- name: Create version switch script
ansible.builtin.template:
src: version-switch.sh.j2
dest: "{{ minecraft_base_dir }}/switch_version.sh"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0755'
- name: Stop Minecraft server
ansible.builtin.systemd:
name: minecraft
state: stopped
- name: Backup current version
ansible.builtin.command:
cmd: |
tar -czf {{ spigot_previous_dir }}/backup_$(date +%Y%m%d_%H%M%S).tar.gz \
-C {{ minecraft_server_dir }} .
become_user: "{{ minecraft_user }}"
- name: Switch to new version
ansible.builtin.command:
cmd: "{{ minecraft_base_dir }}/switch_version.sh"
become_user: "{{ minecraft_user }}"
register: switch_result
- name: Update version file
ansible.builtin.copy:
content: "{{ minecraft_version }}"
dest: "{{ current_version_file }}"
owner: "{{ minecraft_user }}"
group: "{{ minecraft_group }}"
mode: '0644'
- name: Start Minecraft server with new version
ansible.builtin.systemd:
name: minecraft
state: started
- name: Verify server is running
ansible.builtin.wait_for:
port: "{{ server_port }}"
timeout: 60
state: started
- name: Display update result
ansible.builtin.debug:
msg: "Successfully updated to Spigot {{ minecraft_version }}"

Some files were not shown because too many files have changed in this diff Show More