diff --git a/.gitea/workflows/ci-cd.yml b/.gitea/workflows/ci-cd.yml index f633313..3360fab 100644 --- a/.gitea/workflows/ci-cd.yml +++ b/.gitea/workflows/ci-cd.yml @@ -1,145 +1,140 @@ -name: Ansible Minecraft Server CI/CD +name: Ansible Minecraft CI/CD on: push: branches: [ main, develop ] pull_request: branches: [ main ] - workflow_dispatch: - inputs: - environment: - description: 'Environment to deploy' - required: true - default: 'staging' - type: choice - options: - - staging - - production jobs: lint: runs-on: ubuntu-latest + name: Ansible Lint + steps: - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Python + uses: actions/checkout@v4 + + - name: Setup Python uses: actions/setup-python@v4 with: python-version: '3.11' - + - name: Install dependencies run: | python -m pip install --upgrade pip pip install ansible ansible-lint yamllint - - - name: Run yamllint + + - name: Lint YAML files run: | - yamllint -c .yamllint . + yamllint . continue-on-error: true - - name: Run ansible-lint + - name: Lint Ansible playbooks run: | - ansible-lint --exclude .gitea/ . + ansible-lint --parseable-severity site.yml roles/ continue-on-error: true - - - name: Validate ansible syntax - run: | - ansible-playbook site.yml --syntax-check - - test: + + syntax-check: runs-on: ubuntu-latest + name: Syntax Check needs: lint + steps: - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Python + 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 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 run: | 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 run: | mkdir -p ~/.ssh - echo "${{ secrets.ANSIBLE_SSH_KEY }}" > ~/.ssh/ansible_key - chmod 600 ~/.ssh/ansible_key + echo "${{ secrets.ANSIBLE_SSH_PRIVATE_KEY }}" | base64 -d > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + ssh-keyscan -H ${{ secrets.STAGING_HOST }} >> ~/.ssh/known_hosts - - name: Setup vault password + - name: Deploy to staging run: | - echo "${{ secrets.ANSIBLE_VAULT_PASSWORD }}" > .vault_pass - 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 + ansible-playbook site.yml -i inventories/staging/hosts.yml --check --diff env: - ANSIBLE_HOST_KEY_CHECKING: false - ANSIBLE_VAULT_PASSWORD_FILE: .vault_pass - run: | - ansible-playbook \ - -i inventories/${{ steps.env.outputs.environment }}/hosts.yml \ - site.yml \ - --limit minecraft_servers \ - --diff + MINECRAFT_RCON_PASSWORD: ${{ secrets.MINECRAFT_RCON_PASSWORD }} + ANSIBLE_HOST_KEY_CHECKING: 'false' - - name: Clean up - if: always() + deploy-production: + 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: | - rm -f ~/.ssh/ansible_key - rm -f .vault_pass \ No newline at end of file + python -m pip install --upgrade pip + 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' \ No newline at end of file diff --git a/inventories/production/group_vars/all.yml b/inventories/production/group_vars/all.yml index 7c8714b..819391c 100644 --- a/inventories/production/group_vars/all.yml +++ b/inventories/production/group_vars/all.yml @@ -1,76 +1,30 @@ --- -# Configuration Ansible -ansible_user: ansible -ansible_become: true -ansible_become_method: sudo +# Configuration globale Production +environment: production +python_interpreter: /usr/bin/python3 + +# 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 minecraft_version: "1.21.6" -minecraft_type: "spigot" -minecraft_user: minecraft -minecraft_group: minecraft -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 +spigot_build_tools_url: "https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar" +minecraft_max_memory: "4G" +minecraft_min_memory: "2G" -# Configuration mémoire -minecraft_memory_min: 2048 -minecraft_memory_max: 4096 - -# 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 backups +backup_enabled: true +backup_remote_host: "backup.example.com" +backup_local_path: "/opt/minecraft/backups" +backup_remote_path: "/backups/minecraft" # Configuration sécurité -ssh_port: 22 -firewall_allowed_tcp_ports: - - 22 - - 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" \ No newline at end of file +firewall_enabled: true +automatic_updates: false +hardening_enabled: true \ No newline at end of file diff --git a/inventories/production/hosts.yml b/inventories/production/hosts.yml index 6c17036..a3efbd0 100644 --- a/inventories/production/hosts.yml +++ b/inventories/production/hosts.yml @@ -1,12 +1,19 @@ --- -all: - children: - minecraft_servers: - hosts: - minecraft-prod-01: - ansible_host: 192.168.1.10 - vars: - ansible_user: ansible - environment: production - minecraft_memory: 4096 - minecraft_port: 25565 \ No newline at end of file +minecraft_servers: + hosts: + minecraft-prod-01: + ansible_host: 10.0.1.10 + ansible_user: ansible + minecraft_server_name: "Production Server 01" + minecraft_port: 25565 + minecraft_rcon_port: 25575 + minecraft-prod-02: + ansible_host: 10.0.1.11 + 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 \ No newline at end of file diff --git a/inventories/staging/group_vars/all.yml b/inventories/staging/group_vars/all.yml index 7c8714b..54e9a2d 100644 --- a/inventories/staging/group_vars/all.yml +++ b/inventories/staging/group_vars/all.yml @@ -1,76 +1,28 @@ --- -# Configuration Ansible -ansible_user: ansible -ansible_become: true -ansible_become_method: sudo +# Configuration globale Staging +environment: staging +python_interpreter: /usr/bin/python3 + +# 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 minecraft_version: "1.21.6" -minecraft_type: "spigot" -minecraft_user: minecraft -minecraft_group: minecraft -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 +spigot_build_tools_url: "https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar" +minecraft_max_memory: "2G" +minecraft_min_memory: "1G" -# Configuration mémoire -minecraft_memory_min: 2048 -minecraft_memory_max: 4096 - -# 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 backups +backup_enabled: true +backup_local_path: "/opt/minecraft/backups" # Configuration sécurité -ssh_port: 22 -firewall_allowed_tcp_ports: - - 22 - - 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" \ No newline at end of file +firewall_enabled: false +automatic_updates: true +hardening_enabled: false \ No newline at end of file diff --git a/inventories/staging/hosts.yml b/inventories/staging/hosts.yml index dddacca..04a52c2 100644 --- a/inventories/staging/hosts.yml +++ b/inventories/staging/hosts.yml @@ -1,12 +1,13 @@ --- -all: - children: - minecraft_servers: - hosts: - minecraft-staging-01: - ansible_host: 192.168.2.10 - vars: - ansible_user: ansible - environment: staging - minecraft_memory: 2048 - minecraft_port: 25565 \ No newline at end of file +minecraft_servers: + hosts: + minecraft-staging-01: + ansible_host: 10.0.2.10 + ansible_user: ansible + minecraft_server_name: "Staging Server 01" + minecraft_port: 25565 + minecraft_rcon_port: 25575 + vars: + environment: staging + backup_retention_days: 30 + update_schedule: "0 2 * * *" # Tous les jours 2h \ No newline at end of file diff --git a/requirements.yml b/requirements.yml index 0fc1e56..0411312 100644 --- a/requirements.yml +++ b/requirements.yml @@ -1,6 +1,8 @@ --- collections: - - name: ansible.posix - version: ">=1.5.4" - name: community.general - version: ">=8.0.0" \ No newline at end of file + version: ">=7.0.0" + - name: ansible.posix + version: ">=1.5.0" + - name: community.crypto + version: ">=2.15.0" \ No newline at end of file diff --git a/roles/01-server_hardening/defaults/main.yml b/roles/01-server_hardening/defaults/main.yml index 30ff066..d2feeb0 100644 --- a/roles/01-server_hardening/defaults/main.yml +++ b/roles/01-server_hardening/defaults/main.yml @@ -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_permit_root_login: "no" ssh_password_authentication: "no" -ssh_pubkey_authentication: "yes" ssh_max_auth_tries: 3 -ssh_max_sessions: 10 ssh_client_alive_interval: 300 ssh_client_alive_count_max: 2 -# Configuration Firewall -firewall_allowed_tcp_ports: - - 22 - - 25565 - - 25575 -firewall_allowed_udp_ports: [] +fail2ban_jail_ssh_enabled: true +fail2ban_jail_ssh_maxretry: 3 +fail2ban_jail_ssh_bantime: 3600 -# Configuration Fail2ban -fail2ban_enabled: true -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: [] \ No newline at end of file +ufw_default_incoming: deny +ufw_default_outgoing: allow \ No newline at end of file diff --git a/roles/01-server_hardening/handlers/main.yml b/roles/01-server_hardening/handlers/main.yml index 1e7bcab..7316146 100644 --- a/roles/01-server_hardening/handlers/main.yml +++ b/roles/01-server_hardening/handlers/main.yml @@ -1,23 +1,14 @@ --- - name: restart ssh - ansible.builtin.systemd: - name: sshd + ansible.builtin.service: + name: ssh state: restarted - daemon_reload: true - listen: restart ssh service - name: restart fail2ban - ansible.builtin.systemd: + ansible.builtin.service: name: fail2ban state: restarted - daemon_reload: true - listen: restart fail2ban service -- name: reload ufw +- name: enable ufw community.general.ufw: - state: reloaded - listen: reload firewall - -- name: reload sysctl - ansible.builtin.command: sysctl -p - listen: reload sysctl settings \ No newline at end of file + state: enabled \ No newline at end of file diff --git a/roles/01-server_hardening/tasks/01-update-system.yml b/roles/01-server_hardening/tasks/01-update-system.yml index e7b26a8..ca93bd2 100644 --- a/roles/01-server_hardening/tasks/01-update-system.yml +++ b/roles/01-server_hardening/tasks/01-update-system.yml @@ -1,6 +1,7 @@ --- -- name: Update apt cache for Debian/Ubuntu +- name: Mise à jour du cache des paquets (Debian/Ubuntu) ansible.builtin.apt: update_cache: yes cache_valid_time: 3600 - when: ansible_os_family == "Debian" \ No newline at end of file + when: ansible_os_family == "Debian" + tags: [system-update] \ No newline at end of file diff --git a/roles/01-server_hardening/tasks/02-install-packages.yml b/roles/01-server_hardening/tasks/02-install-packages.yml deleted file mode 100644 index 40f3916..0000000 --- a/roles/01-server_hardening/tasks/02-install-packages.yml +++ /dev/null @@ -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" \ No newline at end of file diff --git a/roles/01-server_hardening/tasks/02-install-security-packages.yml b/roles/01-server_hardening/tasks/02-install-security-packages.yml new file mode 100644 index 0000000..72a1a5c --- /dev/null +++ b/roles/01-server_hardening/tasks/02-install-security-packages.yml @@ -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 \ No newline at end of file diff --git a/roles/01-server_hardening/tasks/03-configure-ssh.yml b/roles/01-server_hardening/tasks/03-configure-ssh.yml index 2519115..468223e 100644 --- a/roles/01-server_hardening/tasks/03-configure-ssh.yml +++ b/roles/01-server_hardening/tasks/03-configure-ssh.yml @@ -1,11 +1,10 @@ --- -- name: Configure SSH daemon +- name: Configuration SSH sécurisée ansible.builtin.template: src: sshd_config.j2 - dest: "{{ ssh_config_file }}" + dest: "{{ ssh_config_path }}" owner: root group: root - mode: '0600' + mode: '0644' backup: yes - validate: '/usr/sbin/sshd -t -f %s' - notify: restart ssh service \ No newline at end of file + notify: restart ssh \ No newline at end of file diff --git a/roles/01-server_hardening/tasks/04-configure-firewall.yml b/roles/01-server_hardening/tasks/04-configure-firewall.yml index ed1299b..bfdf03c 100644 --- a/roles/01-server_hardening/tasks/04-configure-firewall.yml +++ b/roles/01-server_hardening/tasks/04-configure-firewall.yml @@ -1,27 +1,9 @@ --- -- name: Install UFW firewall - ansible.builtin.apt: - name: ufw - state: present - when: ansible_os_family == "Debian" - -- name: Configure UFW defaults +- name: Configuration UFW - politique par défaut community.general.ufw: direction: "{{ item.direction }}" policy: "{{ item.policy }}" - loop: - - { direction: 'incoming', policy: 'deny' } - - { direction: 'outgoing', policy: 'allow' } - notify: reload firewall - -- 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 \ No newline at end of file + with_items: + - { direction: 'incoming', policy: "{{ ufw_default_incoming }}" } + - { direction: 'outgoing', policy: "{{ ufw_default_outgoing }}" } + notify: enable ufw \ No newline at end of file diff --git a/roles/01-server_hardening/tasks/05-configure-fail2ban.yml b/roles/01-server_hardening/tasks/05-configure-fail2ban.yml index 3c5808c..fd6c2f7 100644 --- a/roles/01-server_hardening/tasks/05-configure-fail2ban.yml +++ b/roles/01-server_hardening/tasks/05-configure-fail2ban.yml @@ -1,23 +1,9 @@ --- -- name: Install fail2ban - ansible.builtin.apt: - name: fail2ban - state: present - when: ansible_os_family == "Debian" - -- name: Configure fail2ban jail +- name: Configuration Fail2Ban ansible.builtin.template: - src: fail2ban.jail.local.j2 - dest: "{{ fail2ban_config_dir }}/jail.local" + src: fail2ban-jail.local.j2 + dest: "{{ fail2ban_config_path }}" owner: root group: root mode: '0644' - backup: yes - notify: restart fail2ban service - -- name: Ensure fail2ban is started and enabled - ansible.builtin.systemd: - name: fail2ban - state: started - enabled: yes - daemon_reload: yes \ No newline at end of file + notify: restart fail2ban \ No newline at end of file diff --git a/roles/01-server_hardening/tasks/06-manage-ssh-keys.yml b/roles/01-server_hardening/tasks/06-manage-ssh-keys.yml index 696c1d4..35b718a 100644 --- a/roles/01-server_hardening/tasks/06-manage-ssh-keys.yml +++ b/roles/01-server_hardening/tasks/06-manage-ssh-keys.yml @@ -1,17 +1,8 @@ --- -- name: Create .ssh directory for ansible user - ansible.builtin.file: - path: /home/ansible/.ssh - state: directory - owner: ansible - group: ansible - mode: '0700' - -- name: Add SSH keys for administrators +- name: Ajout des clés SSH pour les administrateurs ansible.posix.authorized_key: - user: ansible + user: "{{ item.user }}" state: present key: "{{ item.key }}" - comment: "{{ item.name }}" - loop: "{{ admin_ssh_keys | default([]) }}" - when: admin_ssh_keys is defined \ No newline at end of file + comment: "{{ item.comment | default('Admin key') }}" + with_items: "{{ admin_ssh_keys | default([]) }}" \ No newline at end of file diff --git a/roles/01-server_hardening/tasks/07-additional-security.yml b/roles/01-server_hardening/tasks/07-additional-security.yml deleted file mode 100644 index 901b192..0000000 --- a/roles/01-server_hardening/tasks/07-additional-security.yml +++ /dev/null @@ -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 \ No newline at end of file diff --git a/roles/01-server_hardening/tasks/main.yml b/roles/01-server_hardening/tasks/main.yml index 1e7bcab..cb659ca 100644 --- a/roles/01-server_hardening/tasks/main.yml +++ b/roles/01-server_hardening/tasks/main.yml @@ -1,23 +1,21 @@ --- -- name: restart ssh - ansible.builtin.systemd: - name: sshd - state: restarted - daemon_reload: true - listen: restart ssh service +# Tâches principales du durcissement serveur +- import_tasks: 01-update-system.yml + tags: [hardening, system-update] -- name: restart fail2ban - ansible.builtin.systemd: - name: fail2ban - state: restarted - daemon_reload: true - listen: restart fail2ban service +- import_tasks: 02-install-security-packages.yml + tags: [hardening, packages] -- name: reload ufw - community.general.ufw: - state: reloaded - listen: reload firewall +- import_tasks: 03-configure-ssh.yml + tags: [hardening, ssh] -- name: reload sysctl - ansible.builtin.command: sysctl -p - listen: reload sysctl settings \ No newline at end of file +- import_tasks: 04-configure-firewall.yml + tags: [hardening, firewall] + 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] \ No newline at end of file diff --git a/roles/01-server_hardening/templates/fail2ban-jail.local.j2 b/roles/01-server_hardening/templates/fail2ban-jail.local.j2 index 94b3330..0e2fb3e 100644 --- a/roles/01-server_hardening/templates/fail2ban-jail.local.j2 +++ b/roles/01-server_hardening/templates/fail2ban-jail.local.j2 @@ -1,30 +1,12 @@ -# {{ ansible_managed }} +# Configuration Fail2Ban générée par Ansible + [DEFAULT] -ignoreip = 127.0.0.1/8 ::1 -bantime = {{ fail2ban_bantime }} -findtime = {{ fail2ban_findtime }} -maxretry = {{ fail2ban_maxretry }} -backend = systemd +bantime = {{ fail2ban_jail_ssh_bantime }} +findtime = 600 +maxretry = {{ fail2ban_jail_ssh_maxretry }} [sshd] -enabled = true +enabled = {{ fail2ban_jail_ssh_enabled | lower }} port = {{ ssh_port }} filter = sshd -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 \ No newline at end of file +logpath = /var/log/auth.log \ No newline at end of file diff --git a/roles/01-server_hardening/templates/sshd_config.j2 b/roles/01-server_hardening/templates/sshd_config.j2 index 3022846..327cfbc 100644 --- a/roles/01-server_hardening/templates/sshd_config.j2 +++ b/roles/01-server_hardening/templates/sshd_config.j2 @@ -1,47 +1,21 @@ -# {{ ansible_managed }} -# SSH Server Configuration - +# Configuration SSH sécurisée générée par Ansible Port {{ ssh_port }} Protocol 2 -HostKey /etc/ssh/ssh_host_rsa_key -HostKey /etc/ssh/ssh_host_ed25519_key -# Logging -SyslogFacility AUTH -LogLevel INFO - -# Authentication -LoginGraceTime 120 +# Authentification 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 }} -PermitEmptyPasswords no -ChallengeResponseAuthentication no +MaxAuthTries {{ ssh_max_auth_tries }} +PubkeyAuthentication yes -# Security -IgnoreRhosts yes -HostbasedAuthentication no -X11Forwarding no -PrintMotd no -PrintLastLog yes -TCPKeepAlive yes -Compression delayed - -# Client alive +# Sessions ClientAliveInterval {{ ssh_client_alive_interval }} ClientAliveCountMax {{ ssh_client_alive_count_max }} -# Allow only ansible user -AllowUsers ansible - -# Disable unused features +# Sécurité +X11Forwarding no UsePAM yes -Banner none -AcceptEnv LANG LC_* -Subsystem sftp /usr/lib/openssh/sftp-server \ No newline at end of file +UseDNS no + +# Utilisateurs autorisés +AllowUsers {{ allowed_ssh_users | join(' ') }} \ No newline at end of file diff --git a/roles/01-server_hardening/templates/ufw-rules.j2 b/roles/01-server_hardening/templates/ufw-rules.j2 deleted file mode 100644 index 5b4a048..0000000 --- a/roles/01-server_hardening/templates/ufw-rules.j2 +++ /dev/null @@ -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 \ No newline at end of file diff --git a/roles/01-server_hardening/vars/main.yml b/roles/01-server_hardening/vars/main.yml index bdc2485..15cb638 100644 --- a/roles/01-server_hardening/vars/main.yml +++ b/roles/01-server_hardening/vars/main.yml @@ -1,24 +1,14 @@ --- -# Variables spécifiques au rôle server_hardening -hardening_sysctl_settings: - - name: net.ipv4.tcp_syncookies - value: 1 - - name: net.ipv4.conf.all.rp_filter - value: 1 - - name: net.ipv4.conf.default.rp_filter - value: 1 - - name: net.ipv4.conf.all.accept_source_route - value: 0 - - 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 +# Variables spécifiques au hardening +required_packages_debian: + - curl + - wget + - git + - unzip + - htop + - vim + - sudo + - systemd -ssh_config_file: /etc/ssh/sshd_config -fail2ban_config_dir: /etc/fail2ban \ No newline at end of file +ssh_config_path: /etc/ssh/sshd_config +fail2ban_config_path: /etc/fail2ban/jail.local \ No newline at end of file diff --git a/roles/02-installation-java/defaults/main.yml b/roles/02-installation-java/defaults/main.yml index 302f0e3..4949d28 100644 --- a/roles/02-installation-java/defaults/main.yml +++ b/roles/02-installation-java/defaults/main.yml @@ -1,5 +1,8 @@ --- -java_version: 21 -java_vendor: openjdk -java_home: /usr/lib/jvm/java-{{ java_version }}-openjdk-amd64 -java_bin_path: "{{ java_home }}/bin" \ No newline at end of file +# Configuration par défaut Java +java_version: "17" +java_packages: + - openjdk-17-jdk + - openjdk-17-jre + +java_home_path: "/usr/lib/jvm/java-17-openjdk-amd64" \ No newline at end of file diff --git a/roles/02-installation-java/handlers/main.yml b/roles/02-installation-java/handlers/main.yml index 6914d6e..b150db0 100644 --- a/roles/02-installation-java/handlers/main.yml +++ b/roles/02-installation-java/handlers/main.yml @@ -1,8 +1,4 @@ --- - name: update java alternatives - ansible.builtin.command: update-alternatives --config java - listen: update java configuration - -- name: reload environment - ansible.builtin.command: source /etc/environment - listen: reload system environment \ No newline at end of file + ansible.builtin.command: update-java-alternatives --set java-1.{{ java_version }}.0-openjdk-amd64 + failed_when: false \ No newline at end of file diff --git a/roles/02-installation-java/tasks/01-check-java.yml b/roles/02-installation-java/tasks/01-check-java.yml new file mode 100644 index 0000000..12c6955 --- /dev/null +++ b/roles/02-installation-java/tasks/01-check-java.yml @@ -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 \ No newline at end of file diff --git a/roles/02-installation-java/tasks/02-install-java.yml b/roles/02-installation-java/tasks/02-install-java.yml new file mode 100644 index 0000000..e2c8669 --- /dev/null +++ b/roles/02-installation-java/tasks/02-install-java.yml @@ -0,0 +1 @@ +02-install-java.yml \ No newline at end of file diff --git a/roles/02-installation-java/tasks/02-remove-old-java.yml b/roles/02-installation-java/tasks/02-remove-old-java.yml deleted file mode 100644 index e3ec0ec..0000000 --- a/roles/02-installation-java/tasks/02-remove-old-java.yml +++ /dev/null @@ -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" \ No newline at end of file diff --git a/roles/02-installation-java/tasks/03-install-java.yml b/roles/02-installation-java/tasks/03-install-java.yml deleted file mode 100644 index 285af52..0000000 --- a/roles/02-installation-java/tasks/03-install-java.yml +++ /dev/null @@ -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" \ No newline at end of file diff --git a/roles/02-installation-java/tasks/03-validate-java.yml b/roles/02-installation-java/tasks/03-validate-java.yml new file mode 100644 index 0000000..b6329be --- /dev/null +++ b/roles/02-installation-java/tasks/03-validate-java.yml @@ -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" \ No newline at end of file diff --git a/roles/02-installation-java/tasks/04-configure-java.yml b/roles/02-installation-java/tasks/04-configure-java.yml deleted file mode 100644 index bf3376b..0000000 --- a/roles/02-installation-java/tasks/04-configure-java.yml +++ /dev/null @@ -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 \ No newline at end of file diff --git a/roles/02-installation-java/tasks/05-validate-installation.yml b/roles/02-installation-java/tasks/05-validate-installation.yml deleted file mode 100644 index 59dfa6f..0000000 --- a/roles/02-installation-java/tasks/05-validate-installation.yml +++ /dev/null @@ -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" \ No newline at end of file diff --git a/roles/02-installation-java/tasks/1-check-java.yml b/roles/02-installation-java/tasks/1-check-java.yml deleted file mode 100644 index 4e4f060..0000000 --- a/roles/02-installation-java/tasks/1-check-java.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -- name: Check if Java is installed - ansible.builtin.command: java -version - register: java_installed - failed_when: false - changed_when: false \ No newline at end of file diff --git a/roles/02-installation-java/tasks/main.yml b/roles/02-installation-java/tasks/main.yml index b8e6700..2246036 100644 --- a/roles/02-installation-java/tasks/main.yml +++ b/roles/02-installation-java/tasks/main.yml @@ -1,17 +1,11 @@ --- -- name: Include check Java tasks - ansible.builtin.include_tasks: 01-check-java.yml +# Tâches principales installation Java +- import_tasks: 01-check-java.yml + tags: [java, check] -- name: Include remove old Java tasks - ansible.builtin.include_tasks: 02-remove-old-java.yml - when: java_needs_update | default(false) +- import_tasks: 02-install-java.yml + tags: [java, install] + when: java_installed is not defined or not java_installed -- name: Include install Java tasks - ansible.builtin.include_tasks: 03-install-java.yml - 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 \ No newline at end of file +- import_tasks: 03-validate-java.yml + tags: [java, validate] \ No newline at end of file diff --git a/roles/02-installation-java/templates/java.sh.j2 b/roles/02-installation-java/templates/java.sh.j2 deleted file mode 100644 index 7dfbadd..0000000 --- a/roles/02-installation-java/templates/java.sh.j2 +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -# {{ ansible_managed }} - -export JAVA_HOME={{ java_home }} -export PATH=$JAVA_HOME \ No newline at end of file diff --git a/roles/02-installation-java/vars/main.yml b/roles/02-installation-java/vars/main.yml index aaace3d..febbafc 100644 --- a/roles/02-installation-java/vars/main.yml +++ b/roles/02-installation-java/vars/main.yml @@ -1,12 +1,4 @@ --- -java_packages: - debian: - - "openjdk-{{ java_version }}-jdk" - - "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" \ No newline at end of file +# Variables Java +java_version_check_command: "java -version" +java_required_version: "17" \ No newline at end of file diff --git a/roles/03-installation-minecraft/defaults/main.yml b/roles/03-installation-minecraft/defaults/main.yml index 4ad99ad..b1d6bf1 100644 --- a/roles/03-installation-minecraft/defaults/main.yml +++ b/roles/03-installation-minecraft/defaults/main.yml @@ -1,57 +1,34 @@ --- -# Utilisateur et groupe +# Configuration par défaut Minecraft minecraft_user: 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 -minecraft_base_dir: /opt/minecraft -minecraft_server_dir: /opt/minecraft/server -minecraft_sources_dir: /opt/minecraft/sources -minecraft_tools_dir: /opt/minecraft/tools +minecraft_sources_dir: "{{ minecraft_home }}/sources" +minecraft_server_dir: "{{ minecraft_home }}/server" +minecraft_tools_dir: "{{ minecraft_home }}/tools" +minecraft_backups_dir: "{{ minecraft_home }}/backups" +minecraft_logs_dir: "{{ minecraft_home }}/logs" -# Version et mémoire -minecraft_version: "1.21.6" -minecraft_memory_min: 1024 -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" +# URLs +spigot_build_tools_url: "https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar" +mcrcon_url: "https://github.com/Tiiffi/mcrcon/archive/refs/heads/master.zip" # Configuration serveur -server_name: "Minecraft Server" -server_port: 25565 -max_players: 20 -view_distance: 10 -gamemode: survival -difficulty: normal -enable_command_block: false -enable_rcon: true -rcon_port: 25575 -rcon_password: "{{ vault_rcon_password | default('ChangeMe123!') }}" -online_mode: true -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: [] \ No newline at end of file +server_properties: + server-port: "{{ minecraft_port }}" + enable-rcon: "true" + rcon.port: "{{ minecraft_rcon_port }}" + rcon.password: "{{ minecraft_rcon_password | default('changeme') }}" + max-players: "20" + difficulty: "normal" + gamemode: "survival" + pvp: "true" + spawn-protection: "16" + white-list: "false" \ No newline at end of file diff --git a/roles/03-installation-minecraft/handlers/main.yml b/roles/03-installation-minecraft/handlers/main.yml index 10813be..3708a2b 100644 --- a/roles/03-installation-minecraft/handlers/main.yml +++ b/roles/03-installation-minecraft/handlers/main.yml @@ -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 ansible.builtin.systemd: - daemon_reload: true - listen: reload systemd daemon + daemon_reload: yes -- name: restart rsyslog - ansible.builtin.systemd: - name: rsyslog - state: restarted - listen: restart rsyslog service \ No newline at end of file +- name: enable minecraft service + ansible.builtin.service: + name: minecraft + enabled: yes + +- name: restart minecraft + ansible.builtin.service: + name: minecraft + state: restarted \ No newline at end of file diff --git a/roles/03-installation-minecraft/meta/main.yml b/roles/03-installation-minecraft/meta/main.yml deleted file mode 100644 index f83a076..0000000 --- a/roles/03-installation-minecraft/meta/main.yml +++ /dev/null @@ -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) \ No newline at end of file diff --git a/roles/03-installation-minecraft/tasks/01-create-user-group.yml b/roles/03-installation-minecraft/tasks/01-create-user-group.yml index af65107..cc46e23 100644 --- a/roles/03-installation-minecraft/tasks/01-create-user-group.yml +++ b/roles/03-installation-minecraft/tasks/01-create-user-group.yml @@ -1,23 +1,14 @@ --- -- name: Create minecraft group +- name: Création du groupe minecraft ansible.builtin.group: name: "{{ minecraft_group }}" state: present - system: yes -- name: Create minecraft user +- name: Création de l'utilisateur minecraft ansible.builtin.user: name: "{{ minecraft_user }}" group: "{{ minecraft_group }}" - groups: [] - append: no - home: "{{ minecraft_base_dir }}" + home: "{{ minecraft_home }}" shell: /bin/bash - system: yes create_home: yes - 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 \ No newline at end of file + state: present \ No newline at end of file diff --git a/roles/03-installation-minecraft/tasks/02-create-directories.yml b/roles/03-installation-minecraft/tasks/02-create-directories.yml index a7901be..c81c09b 100644 --- a/roles/03-installation-minecraft/tasks/02-create-directories.yml +++ b/roles/03-installation-minecraft/tasks/02-create-directories.yml @@ -1,25 +1,15 @@ --- -- name: Create minecraft directories +- name: Création des répertoires Minecraft ansible.builtin.file: path: "{{ item }}" state: directory owner: "{{ minecraft_user }}" group: "{{ minecraft_group }}" mode: '0755' - loop: "{{ minecraft_dirs }}" - -- name: Create .ssh directory for minecraft user - ansible.builtin.file: - path: "{{ minecraft_base_dir }}/.ssh" - state: directory - owner: "{{ minecraft_user }}" - 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 \ No newline at end of file + with_items: + - "{{ minecraft_sources_dir }}" + - "{{ minecraft_server_dir }}" + - "{{ minecraft_tools_dir }}" + - "{{ minecraft_backups_dir }}" + - "{{ minecraft_logs_dir }}" + - "{{ minecraft_server_dir }}/plugins" \ No newline at end of file diff --git a/roles/03-installation-minecraft/tasks/03-download-spigot.yml b/roles/03-installation-minecraft/tasks/03-download-spigot.yml index 92dd0a8..6ade615 100644 --- a/roles/03-installation-minecraft/tasks/03-download-spigot.yml +++ b/roles/03-installation-minecraft/tasks/03-download-spigot.yml @@ -1,30 +1,8 @@ --- -- name: Install required packages for building - 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 +- name: Téléchargement de BuildTools ansible.builtin.get_url: - url: "{{ minecraft_build_tools_url }}" - dest: "{{ minecraft_sources_dir }}/{{ buildtools_jar }}" + url: "{{ spigot_build_tools_url }}" + dest: "{{ minecraft_sources_dir }}/{{ build_tools_jar }}" owner: "{{ minecraft_user }}" group: "{{ minecraft_group }}" - 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' \ No newline at end of file + mode: '0644' \ No newline at end of file diff --git a/roles/03-installation-minecraft/tasks/04-compile-spigot.yml b/roles/03-installation-minecraft/tasks/04-compile-spigot.yml deleted file mode 100644 index 385ac09..0000000 --- a/roles/03-installation-minecraft/tasks/04-compile-spigot.yml +++ /dev/null @@ -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 \ No newline at end of file diff --git a/roles/03-installation-minecraft/tasks/04-install-mcrcon.yml b/roles/03-installation-minecraft/tasks/04-install-mcrcon.yml new file mode 100644 index 0000000..4fe5977 --- /dev/null +++ b/roles/03-installation-minecraft/tasks/04-install-mcrcon.yml @@ -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 }}" \ No newline at end of file diff --git a/roles/03-installation-minecraft/tasks/05-compile-spigot.yml b/roles/03-installation-minecraft/tasks/05-compile-spigot.yml new file mode 100644 index 0000000..64775d0 --- /dev/null +++ b/roles/03-installation-minecraft/tasks/05-compile-spigot.yml @@ -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 \ No newline at end of file diff --git a/roles/03-installation-minecraft/tasks/05-configure-server.yml b/roles/03-installation-minecraft/tasks/05-configure-server.yml deleted file mode 100644 index 7ab6776..0000000 --- a/roles/03-installation-minecraft/tasks/05-configure-server.yml +++ /dev/null @@ -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' \ No newline at end of file diff --git a/roles/03-installation-minecraft/tasks/06-configure-minecraft.yml b/roles/03-installation-minecraft/tasks/06-configure-minecraft.yml new file mode 100644 index 0000000..b8826d2 --- /dev/null +++ b/roles/03-installation-minecraft/tasks/06-configure-minecraft.yml @@ -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' \ No newline at end of file diff --git a/roles/03-installation-minecraft/tasks/06-install-mcrcon.yml b/roles/03-installation-minecraft/tasks/06-install-mcrcon.yml deleted file mode 100644 index 2cd0934..0000000 --- a/roles/03-installation-minecraft/tasks/06-install-mcrcon.yml +++ /dev/null @@ -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 \ No newline at end of file diff --git a/roles/03-installation-minecraft/tasks/07-create-service.yml b/roles/03-installation-minecraft/tasks/07-create-service.yml index 8dd1927..8db541b 100644 --- a/roles/03-installation-minecraft/tasks/07-create-service.yml +++ b/roles/03-installation-minecraft/tasks/07-create-service.yml @@ -1,36 +1,11 @@ --- -- name: Create minecraft systemd service +- name: Création du service systemd Minecraft ansible.builtin.template: src: minecraft.service.j2 - dest: "/etc/systemd/system/{{ minecraft_service_name }}" + dest: /etc/systemd/system/minecraft.service owner: root group: root mode: '0644' - notify: - - reload systemd daemon - - restart minecraft server - -- 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" \ No newline at end of file + notify: + - reload systemd + - enable minecraft service \ No newline at end of file diff --git a/roles/03-installation-minecraft/tasks/08-configure-logrotate.yml b/roles/03-installation-minecraft/tasks/08-configure-logrotate.yml index fafd293..2dffa42 100644 --- a/roles/03-installation-minecraft/tasks/08-configure-logrotate.yml +++ b/roles/03-installation-minecraft/tasks/08-configure-logrotate.yml @@ -1,36 +1,8 @@ --- -- name: Configure logrotate for minecraft logs +- name: Configuration de la rotation des logs ansible.builtin.template: src: minecraft-logrotate.j2 dest: /etc/logrotate.d/minecraft owner: root group: root - 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 \ No newline at end of file + mode: '0644' \ No newline at end of file diff --git a/roles/03-installation-minecraft/tasks/09-manage-ops.yml b/roles/03-installation-minecraft/tasks/09-manage-ops.yml index 8941f42..1b8b2e0 100644 --- a/roles/03-installation-minecraft/tasks/09-manage-ops.yml +++ b/roles/03-installation-minecraft/tasks/09-manage-ops.yml @@ -1,32 +1,9 @@ --- -- name: Check if ops.json exists - ansible.builtin.stat: - path: "{{ minecraft_server_dir }}/ops.json" - register: ops_file - -- name: Create ops.json file +- name: Génération du fichier ops.json ansible.builtin.template: src: ops.json.j2 dest: "{{ minecraft_server_dir }}/ops.json" owner: "{{ minecraft_user }}" group: "{{ minecraft_group }}" mode: '0644' - backup: yes - 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' \ No newline at end of file + notify: restart minecraft \ No newline at end of file diff --git a/roles/03-installation-minecraft/tasks/10-install-plugins.yml b/roles/03-installation-minecraft/tasks/10-install-plugins.yml index b34c7ef..53bf0e0 100644 --- a/roles/03-installation-minecraft/tasks/10-install-plugins.yml +++ b/roles/03-installation-minecraft/tasks/10-install-plugins.yml @@ -1,39 +1,10 @@ --- -- name: Create plugins directory - ansible.builtin.file: - path: "{{ minecraft_server_dir }}/plugins" - state: directory - owner: "{{ minecraft_user }}" - group: "{{ minecraft_group }}" - mode: '0755' - -- name: Download plugins +- name: Installation des plugins par défaut ansible.builtin.get_url: url: "{{ item.url }}" dest: "{{ minecraft_server_dir }}/plugins/{{ item.name }}.jar" owner: "{{ minecraft_user }}" group: "{{ minecraft_group }}" mode: '0644' - timeout: 30 - loop: "{{ minecraft_plugins_list }}" - 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) \ No newline at end of file + with_items: "{{ minecraft_plugins | default([]) }}" + when: minecraft_plugins is defined \ No newline at end of file diff --git a/roles/03-installation-minecraft/tasks/main.yml b/roles/03-installation-minecraft/tasks/main.yml index e22e285..10c6d29 100644 --- a/roles/03-installation-minecraft/tasks/main.yml +++ b/roles/03-installation-minecraft/tasks/main.yml @@ -1,40 +1,31 @@ --- -- name: Include create user and group tasks - ansible.builtin.include_tasks: 01-create-user-group.yml - tags: ['minecraft-user'] +# Tâches principales installation Minecraft +- import_tasks: 01-create-user-group.yml + tags: [minecraft, user] -- name: Include create directories tasks - ansible.builtin.include_tasks: 02-create-directories.yml - tags: ['minecraft-dirs'] +- import_tasks: 02-create-directories.yml + tags: [minecraft, directories] -- name: Include download Spigot tasks - ansible.builtin.include_tasks: 03-download-spigot.yml - tags: ['minecraft-download'] +- import_tasks: 03-download-spigot.yml + tags: [minecraft, download] -- name: Include compile Spigot tasks - ansible.builtin.include_tasks: 04-compile-spigot.yml - tags: ['minecraft-compile'] +- import_tasks: 04-install-mcrcon.yml + tags: [minecraft, mcrcon] -- name: Include configure server tasks - ansible.builtin.include_tasks: 05-configure-server.yml - tags: ['minecraft-config'] +- import_tasks: 05-compile-spigot.yml + tags: [minecraft, compile] -- name: Include install mcrcon tasks - ansible.builtin.include_tasks: 06-install-mcrcon.yml - tags: ['minecraft-mcrcon'] +- import_tasks: 06-configure-minecraft.yml + tags: [minecraft, configure] -- name: Include create service tasks - ansible.builtin.include_tasks: 07-create-service.yml - tags: ['minecraft-service'] +- import_tasks: 07-create-service.yml + tags: [minecraft, service] -- name: Include configure logrotate tasks - ansible.builtin.include_tasks: 08-configure-logrotate.yml - tags: ['minecraft-logs'] +- import_tasks: 08-configure-logrotate.yml + tags: [minecraft, logrotate] -- name: Include manage ops tasks - ansible.builtin.include_tasks: 09-manage-ops.yml - tags: ['minecraft-ops'] +- import_tasks: 09-manage-ops.yml + tags: [minecraft, ops] -- name: Include install plugins tasks - ansible.builtin.include_tasks: 10-install-plugins.yml - tags: ['minecraft-plugins'] \ No newline at end of file +- import_tasks: 10-install-plugins.yml + tags: [minecraft, plugins] \ No newline at end of file diff --git a/roles/03-installation-minecraft/templates/banned-ips.json.j2 b/roles/03-installation-minecraft/templates/banned-ips.json.j2 deleted file mode 100644 index 2be0213..0000000 --- a/roles/03-installation-minecraft/templates/banned-ips.json.j2 +++ /dev/null @@ -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 %} -] \ No newline at end of file diff --git a/roles/03-installation-minecraft/templates/banned-players.json.j2 b/roles/03-installation-minecraft/templates/banned-players.json.j2 deleted file mode 100644 index 603fa06..0000000 --- a/roles/03-installation-minecraft/templates/banned-players.json.j2 +++ /dev/null @@ -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 %} -] \ No newline at end of file diff --git a/roles/03-installation-minecraft/templates/bukkit.yml.j2 b/roles/03-installation-minecraft/templates/bukkit.yml.j2 deleted file mode 100644 index 81779c2..0000000 --- a/roles/03-installation-minecraft/templates/bukkit.yml.j2 +++ /dev/null @@ -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 \ No newline at end of file diff --git a/roles/03-installation-minecraft/templates/logrotate-minecraft.j2 b/roles/03-installation-minecraft/templates/logrotate-minecraft.j2 deleted file mode 100644 index 2e562a7..0000000 --- a/roles/03-installation-minecraft/templates/logrotate-minecraft.j2 +++ /dev/null @@ -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 -} \ No newline at end of file diff --git a/roles/03-installation-minecraft/templates/minecraft-backup.sh.j2 b/roles/03-installation-minecraft/templates/minecraft-backup.sh.j2 deleted file mode 100644 index 5a0314e..0000000 --- a/roles/03-installation-minecraft/templates/minecraft-backup.sh.j2 +++ /dev/null @@ -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 \ No newline at end of file diff --git a/roles/03-installation-minecraft/templates/minecraft-logrotate.j2 b/roles/03-installation-minecraft/templates/minecraft-logrotate.j2 new file mode 100644 index 0000000..d67f708 --- /dev/null +++ b/roles/03-installation-minecraft/templates/minecraft-logrotate.j2 @@ -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 +} \ No newline at end of file diff --git a/roles/03-installation-minecraft/templates/minecraft-monitor.sh.j2 b/roles/03-installation-minecraft/templates/minecraft-monitor.sh.j2 deleted file mode 100644 index 67faaaf..0000000 --- a/roles/03-installation-minecraft/templates/minecraft-monitor.sh.j2 +++ /dev/null @@ -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 </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 \ No newline at end of file diff --git a/roles/03-installation-minecraft/templates/minecraft.service.j2 b/roles/03-installation-minecraft/templates/minecraft.service.j2 index f080b26..942d681 100644 --- a/roles/03-installation-minecraft/templates/minecraft.service.j2 +++ b/roles/03-installation-minecraft/templates/minecraft.service.j2 @@ -1,54 +1,17 @@ -# {{ ansible_managed }} [Unit] -Description=Minecraft Server (Spigot {{ minecraft_version }}) -After=network-online.target -Wants=network-online.target +Description=Minecraft Spigot Server +After=network.target [Service] -Type=simple +Type=forking User={{ minecraft_user }} Group={{ minecraft_group }} WorkingDirectory={{ minecraft_server_dir }} - -# Start command with optimized JVM flags -ExecStart=/usr/bin/java \ - -Xms{{ minecraft_memory_min }}M \ - -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 +ExecStart=/usr/bin/java -Xmx{{ minecraft_max_memory }} -Xms{{ minecraft_min_memory }} -jar spigot.jar nogui +ExecStop={{ minecraft_tools_dir }}/mcrcon/mcrcon -H 127.0.0.1 -P {{ minecraft_rcon_port }} -p {{ minecraft_rcon_password | default('changeme') }} stop +KillMode=none +TimeoutStopSec=120 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] WantedBy=multi-user.target \ No newline at end of file diff --git a/roles/03-installation-minecraft/templates/ops.json.j2 b/roles/03-installation-minecraft/templates/ops.json.j2 index 58e60aa..83a7e90 100644 --- a/roles/03-installation-minecraft/templates/ops.json.j2 +++ b/roles/03-installation-minecraft/templates/ops.json.j2 @@ -1,11 +1,10 @@ [ -{% for op in minecraft_ops %} +{% for admin in minecraft_admins | default([]) %} { - "uuid": "{{ op.uuid }}", - "name": "{{ op.name }}", - "level": {{ op.level | default(4) }}, - "bypassesPlayerLimit": {{ op.bypassesPlayerLimit | default(false) | lower }} + "uuid": "{{ admin.uuid }}", + "name": "{{ admin.name }}", + "level": {{ admin.level | default(4) }}, + "bypassesPlayerLimit": {{ admin.bypass_limit | default(false) | lower }} }{% if not loop.last %},{% endif %} - {% endfor %} ] \ No newline at end of file diff --git a/roles/03-installation-minecraft/templates/paper.yml.j2 b/roles/03-installation-minecraft/templates/paper.yml.j2 deleted file mode 100644 index 3ccf063..0000000 --- a/roles/03-installation-minecraft/templates/paper.yml.j2 +++ /dev/null @@ -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 \ No newline at end of file diff --git a/roles/03-installation-minecraft/templates/permissions.yml.j2 b/roles/03-installation-minecraft/templates/permissions.yml.j2 deleted file mode 100644 index 19988ab..0000000 --- a/roles/03-installation-minecraft/templates/permissions.yml.j2 +++ /dev/null @@ -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 \ No newline at end of file diff --git a/roles/03-installation-minecraft/templates/server.properties.j2 b/roles/03-installation-minecraft/templates/server.properties.j2 index bce7db6..f3968b8 100644 --- a/roles/03-installation-minecraft/templates/server.properties.j2 +++ b/roles/03-installation-minecraft/templates/server.properties.j2 @@ -1,66 +1,38 @@ -# {{ ansible_managed }} -# Minecraft server properties - Generated on {{ ansible_date_time.iso8601 }} - -# 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 }} +#Minecraft server properties généré par Ansible +generator-settings= 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 - -# Performance -network-compression-threshold=256 -rate-limit=0 -sync-chunk-writes=true -use-native-transport=true +level-name=world +enable-query=false allow-flight=false - -# Messages -motd={{ server_name }} -resource-pack= -resource-pack-prompt= -resource-pack-sha1= -require-resource-pack=false - -# Advanced -enable-jmx-monitoring=false -enable-status=true -entity-broadcast-range-percentage=100 +announce-player-achievements=true +server-port={{ minecraft_port }} +max-world-size=29999984 +level-type=default +enable-rcon={{ server_properties['enable-rcon'] }} +level-seed= force-gamemode=false -function-permission-level=2 -initial-disabled-packs= -initial-enabled-packs=vanilla -text-filtering-config= \ No newline at end of file +server-ip= +max-build-height=256 +spawn-npcs=true +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') }} \ No newline at end of file diff --git a/roles/03-installation-minecraft/templates/spigot.yml.j2 b/roles/03-installation-minecraft/templates/spigot.yml.j2 deleted file mode 100644 index ad94202..0000000 --- a/roles/03-installation-minecraft/templates/spigot.yml.j2 +++ /dev/null @@ -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 \ No newline at end of file diff --git a/roles/03-installation-minecraft/templates/start.sh.j2 b/roles/03-installation-minecraft/templates/start.sh.j2 deleted file mode 100644 index 9979e29..0000000 --- a/roles/03-installation-minecraft/templates/start.sh.j2 +++ /dev/null @@ -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 \ No newline at end of file diff --git a/roles/03-installation-minecraft/templates/stop.sh.j2 b/roles/03-installation-minecraft/templates/stop.sh.j2 deleted file mode 100644 index b08b881..0000000 --- a/roles/03-installation-minecraft/templates/stop.sh.j2 +++ /dev/null @@ -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." \ No newline at end of file diff --git a/roles/03-installation-minecraft/templates/whitelist.json.j2 b/roles/03-installation-minecraft/templates/whitelist.json.j2 deleted file mode 100644 index 07623bb..0000000 --- a/roles/03-installation-minecraft/templates/whitelist.json.j2 +++ /dev/null @@ -1,9 +0,0 @@ -[ -{% for player in minecraft_whitelist | default([]) %} - { - "uuid": "{{ player.uuid }}", - "name": "{{ player.name }}" - }{% if not loop.last %},{% endif %} - -{% endfor %} -] \ No newline at end of file diff --git a/roles/03-installation-minecraft/vars/main.yml b/roles/03-installation-minecraft/vars/main.yml index b336899..a52e963 100644 --- a/roles/03-installation-minecraft/vars/main.yml +++ b/roles/03-installation-minecraft/vars/main.yml @@ -1,32 +1,19 @@ --- -# Variables internes du rôle +# Variables Minecraft +minecraft_service_name: minecraft spigot_jar_name: "spigot-{{ minecraft_version }}.jar" -buildtools_jar: "BuildTools.jar" -server_jar_path: "{{ minecraft_server_dir }}/{{ spigot_jar_name }}" +build_tools_jar: "BuildTools.jar" -# Liste des répertoires à créer -minecraft_dirs: - - "{{ minecraft_base_dir }}" - - "{{ minecraft_server_dir }}" - - "{{ minecraft_sources_dir }}" - - "{{ minecraft_tools_dir }}" - - "{{ 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" +# Plugins par défaut +default_plugins: + - name: "WorldEdit" + url: "https://dev.bukkit.org/projects/worldedit/files/latest" + - name: "Vault" + url: "https://dev.bukkit.org/projects/vault/files/latest" -# Packages requis pour la compilation -build_packages: - - git - - build-essential - - screen - - htop - - 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" \ No newline at end of file +# Configuration logs +logrotate_config: + rotate: 30 + size: "100M" + compress: true + delaycompress: true \ No newline at end of file diff --git a/roles/04-backups/defaults/main.yml b/roles/04-backups/defaults/main.yml deleted file mode 100644 index f525f21..0000000 --- a/roles/04-backups/defaults/main.yml +++ /dev/null @@ -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" \ No newline at end of file diff --git a/roles/04-backups/handlers/main.yml b/roles/04-backups/handlers/main.yml index 8afb668..719b956 100644 --- a/roles/04-backups/handlers/main.yml +++ b/roles/04-backups/handlers/main.yml @@ -2,5 +2,4 @@ - name: reload cron ansible.builtin.service: name: cron - state: reloaded - listen: reload cron service \ No newline at end of file + state: reloaded \ No newline at end of file diff --git a/roles/04-backups/tasks/01-create-backup-dirs.yml b/roles/04-backups/tasks/01-create-backup-dirs.yml deleted file mode 100644 index 683a432..0000000 --- a/roles/04-backups/tasks/01-create-backup-dirs.yml +++ /dev/null @@ -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 }}" \ No newline at end of file diff --git a/roles/04-backups/tasks/01-create-backup-structure.yml b/roles/04-backups/tasks/01-create-backup-structure.yml new file mode 100644 index 0000000..ff8f4f8 --- /dev/null +++ b/roles/04-backups/tasks/01-create-backup-structure.yml @@ -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 \ No newline at end of file diff --git a/roles/04-backups/tasks/02-install-rsync.yml b/roles/04-backups/tasks/02-install-rsync.yml deleted file mode 100644 index ef7112e..0000000 --- a/roles/04-backups/tasks/02-install-rsync.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -- name: Install rsync - ansible.builtin.apt: - name: rsync - state: present - when: ansible_os_family == "Debian" \ No newline at end of file diff --git a/roles/04-backups/tasks/02-setup-daily-backup.yml b/roles/04-backups/tasks/02-setup-daily-backup.yml new file mode 100644 index 0000000..00e75a9 --- /dev/null +++ b/roles/04-backups/tasks/02-setup-daily-backup.yml @@ -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 \ No newline at end of file diff --git a/roles/04-backups/tasks/03-configure-backup-script.yml b/roles/04-backups/tasks/03-configure-backup-script.yml deleted file mode 100644 index 1400481..0000000 --- a/roles/04-backups/tasks/03-configure-backup-script.yml +++ /dev/null @@ -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' \ No newline at end of file diff --git a/roles/04-backups/tasks/03-setup-weekly-backup.yml b/roles/04-backups/tasks/03-setup-weekly-backup.yml new file mode 100644 index 0000000..be84f3a --- /dev/null +++ b/roles/04-backups/tasks/03-setup-weekly-backup.yml @@ -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 \ No newline at end of file diff --git a/roles/04-backups/tasks/04-setup-cron.yml b/roles/04-backups/tasks/04-setup-cron.yml deleted file mode 100644 index de5fab8..0000000 --- a/roles/04-backups/tasks/04-setup-cron.yml +++ /dev/null @@ -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 \ No newline at end of file diff --git a/roles/04-backups/tasks/04-setup-monthly-backup.yml b/roles/04-backups/tasks/04-setup-monthly-backup.yml new file mode 100644 index 0000000..494c92b --- /dev/null +++ b/roles/04-backups/tasks/04-setup-monthly-backup.yml @@ -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 \ No newline at end of file diff --git a/roles/04-backups/tasks/05-restore-backup.ym b/roles/04-backups/tasks/05-restore-backup.ym deleted file mode 100644 index 177bdfe..0000000 --- a/roles/04-backups/tasks/05-restore-backup.ym +++ /dev/null @@ -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 \ No newline at end of file diff --git a/roles/04-backups/tasks/05-setup-restore-script.yml b/roles/04-backups/tasks/05-setup-restore-script.yml new file mode 100644 index 0000000..12ea415 --- /dev/null +++ b/roles/04-backups/tasks/05-setup-restore-script.yml @@ -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' \ No newline at end of file diff --git a/roles/04-backups/tasks/main.yml b/roles/04-backups/tasks/main.yml index 4e7dba6..4cc04a8 100644 --- a/roles/04-backups/tasks/main.yml +++ b/roles/04-backups/tasks/main.yml @@ -1,16 +1,16 @@ --- -- name: Include create backup directories tasks - ansible.builtin.include_tasks: 01-create-backup-dirs.yml +# Tâches principales sauvegardes +- import_tasks: 01-create-backup-structure.yml + tags: [backup, structure] -- name: Include install rsync tasks - ansible.builtin.include_tasks: 02-install-rsync.yml +- import_tasks: 02-setup-daily-backup.yml + tags: [backup, daily] -- name: Include configure backup script tasks - ansible.builtin.include_tasks: 03-configure-backup-script.yml +- import_tasks: 03-setup-weekly-backup.yml + tags: [backup, weekly] -- name: Include setup cron tasks - ansible.builtin.include_tasks: 04-setup-cron.yml +- import_tasks: 04-setup-monthly-backup.yml + tags: [backup, monthly] -- name: Include restore backup tasks - ansible.builtin.include_tasks: 05-restore-backup.yml - when: restore_backup | default(false) \ No newline at end of file +- import_tasks: 05-setup-restore-script.yml + tags: [backup, restore] \ No newline at end of file diff --git a/roles/04-backups/templates/backup-daily.sh.j2 b/roles/04-backups/templates/backup-daily.sh.j2 new file mode 100644 index 0000000..7139e24 --- /dev/null +++ b/roles/04-backups/templates/backup-daily.sh.j2 @@ -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}" \ No newline at end of file diff --git a/roles/04-backups/templates/backup-monthly.sh.j2 b/roles/04-backups/templates/backup-monthly.sh.j2 new file mode 100644 index 0000000..f11502c --- /dev/null +++ b/roles/04-backups/templates/backup-monthly.sh.j2 @@ -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}" \ No newline at end of file diff --git a/roles/04-backups/templates/backup-weekly.sh.j2 b/roles/04-backups/templates/backup-weekly.sh.j2 new file mode 100644 index 0000000..c14b2b2 --- /dev/null +++ b/roles/04-backups/templates/backup-weekly.sh.j2 @@ -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}" \ No newline at end of file diff --git a/roles/04-backups/templates/backup.sh.j2 b/roles/04-backups/templates/backup.sh.j2 deleted file mode 100644 index b0d127e..0000000 --- a/roles/04-backups/templates/backup.sh.j2 +++ /dev/null @@ -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 \ No newline at end of file diff --git a/roles/04-backups/templates/restore.sh.j2 b/roles/04-backups/templates/restore.sh.j2 index 887e175..d770090 100644 --- a/roles/04-backups/templates/restore.sh.j2 +++ b/roles/04-backups/templates/restore.sh.j2 @@ -1,61 +1,53 @@ #!/bin/bash -# {{ ansible_managed }} +# Script de restauration Minecraft -BACKUP_TYPE=$1 -BACKUP_DATE=$2 -BACKUP_BASE="{{ backup_base_dir }}" -SERVER_DIR="{{ minecraft_server_dir }}" +set -e -# Function to find backup file -find_backup() { - local type=$1 - local date=$2 - 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" +if [ $# -ne 2 ]; then + echo "Usage: $0 " + echo "Types: daily, weekly, monthly" + echo "Exemple: $0 daily minecraft-daily-20240127_020000" exit 1 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 -RESTORE_DIR="{{ minecraft_base_dir }}/restore_$(date +%Y%m%d_%H%M%S)" -mkdir -p "$RESTORE_DIR" +if [ ! -d "${BACKUP_DIR}/${BACKUP_NAME}" ]; then + echo "Erreur: Sauvegarde ${BACKUP_NAME} introuvable dans ${BACKUP_DIR}" + exit 1 +fi -# Extract backup -tar -xzf "$BACKUP_FILE" -C "$RESTORE_DIR" +echo "ATTENTION: Cette opération va remplacer les données actuelles du serveur." +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 -echo "Backing up current server state..." -tar -czf "{{ backup_base_dir }}/pre_restore_$(date +%Y%m%d_%H%M%S).tar.gz" \ - -C "{{ minecraft_base_dir }}" server/ +# Arrêt du serveur +echo "Arrêt du serveur Minecraft..." +systemctl stop minecraft || true +sleep 5 -# Restore files -echo "Restoring server files..." -rsync -av --delete "$RESTORE_DIR/server/" "$SERVER_DIR/" +# Sauvegarde du répertoire actuel +CURRENT_BACKUP="${TARGET_DIR}.backup-$(date +%Y%m%d_%H%M%S)" +echo "Sauvegarde du répertoire actuel vers ${CURRENT_BACKUP}" +cp -r "${TARGET_DIR}" "${CURRENT_BACKUP}" -# Set permissions -chown -R {{ minecraft_user }}:{{ minecraft_group }} "$SERVER_DIR" +# Restauration +echo "Restauration de ${BACKUP_NAME}..." +rsync {{ rsync_options }} "${BACKUP_DIR}/${BACKUP_NAME}/" "${TARGET_DIR}/" -# Clean up -rm -rf "$RESTORE_DIR" +# Correction des permissions +chown -R {{ minecraft_user }}:{{ minecraft_group }} "${TARGET_DIR}" -echo "Restore completed successfully!" \ No newline at end of file +# 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}" \ No newline at end of file diff --git a/roles/04-backups/vars/main.yml b/roles/04-backups/vars/main.yml index 35249c0..77bbc6e 100644 --- a/roles/04-backups/vars/main.yml +++ b/roles/04-backups/vars/main.yml @@ -1,11 +1,10 @@ --- -backup_dirs: - - "{{ backup_base_dir }}" - - "{{ backup_daily_dir }}" - - "{{ backup_weekly_dir }}" - - "{{ backup_monthly_dir }}" +# Variables sauvegardes +backup_script_path: /usr/local/bin +minecraft_backup_source: "{{ minecraft_server_dir }}" +minecraft_backup_dest: "{{ minecraft_backups_dir }}" -backup_source_dirs: - - "{{ minecraft_server_dir }}" - - "{{ minecraft_sources_dir }}" - - "{{ minecraft_tools_dir }}" \ No newline at end of file +backup_types: + - daily + - weekly + - monthly \ No newline at end of file diff --git a/roles/05-update/defaults/main.yml b/roles/05-update/defaults/main.yml index ffaf256..d9ac844 100644 --- a/roles/05-update/defaults/main.yml +++ b/roles/05-update/defaults/main.yml @@ -1,6 +1,6 @@ --- -update_check_ssh_keys: true -update_check_system: true -update_check_spigot: true -spigot_update_dir: "{{ minecraft_sources_dir }}/update" -spigot_previous_dir: "{{ minecraft_sources_dir }}/previous" \ No newline at end of file +# Configuration par défaut des mises à jour +update_check_enabled: true +update_system_packages: false +spigot_update_check_url: "https://hub.spigotmc.org/versions/" +update_backup_before: true \ No newline at end of file diff --git a/roles/05-update/handlers/main.yml b/roles/05-update/handlers/main.yml index a13444c..3382a42 100644 --- a/roles/05-update/handlers/main.yml +++ b/roles/05-update/handlers/main.yml @@ -1,13 +1,5 @@ --- -- name: restart services - ansible.builtin.systemd: - name: "{{ item }}" - 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 \ No newline at end of file +- name: restart minecraft + ansible.builtin.service: + name: minecraft + state: restarted \ No newline at end of file diff --git a/roles/05-update/meta/main.yml b/roles/05-update/meta/main.yml deleted file mode 100644 index 7cda289..0000000 --- a/roles/05-update/meta/main.yml +++ /dev/null @@ -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) \ No newline at end of file diff --git a/roles/05-update/tasks/01-check-ssh-keys.yml b/roles/05-update/tasks/01-check-ssh-keys.yml index 61429dc..d729fe8 100644 --- a/roles/05-update/tasks/01-check-ssh-keys.yml +++ b/roles/05-update/tasks/01-check-ssh-keys.yml @@ -1,21 +1,9 @@ --- -- name: Check for new SSH keys in repository - 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 +- name: Vérification des nouvelles clés SSH ansible.posix.authorized_key: - user: ansible + user: "{{ item.user }}" state: present key: "{{ item.key }}" - comment: "{{ item.name }}" - loop: "{{ ssh_keys_to_add }}" - when: - - ssh_keys_to_add | length > 0 - - item.key not in (current_keys.content | b64decode | default('')) \ No newline at end of file + comment: "{{ item.comment | default('Admin key') }}" + with_items: "{{ admin_ssh_keys | default([]) }}" + when: admin_ssh_keys is defined \ No newline at end of file diff --git a/roles/05-update/tasks/02-check-system-updates.yml b/roles/05-update/tasks/02-check-system-updates.yml index 2383751..284cd05 100644 --- a/roles/05-update/tasks/02-check-system-updates.yml +++ b/roles/05-update/tasks/02-check-system-updates.yml @@ -1,26 +1,23 @@ --- -- name: Update apt cache +- name: Vérification des mises à jour système disponibles ansible.builtin.apt: update_cache: yes cache_valid_time: 3600 when: ansible_os_family == "Debian" -- name: Check for available updates - ansible.builtin.command: apt list --upgradable - register: apt_updates - changed_when: false +- name: Liste des paquets à mettre à jour + ansible.builtin.apt: + upgrade: dist + dry_run: yes + register: system_updates_check when: ansible_os_family == "Debian" -- name: Display available updates - ansible.builtin.debug: - msg: "Available updates: {{ apt_updates.stdout_lines | length - 1 }} packages" - when: apt_updates is defined - -- name: Perform system update if requested +- name: Application des mises à jour système si nécessaire ansible.builtin.apt: - upgrade: safe + upgrade: dist autoremove: yes autoclean: yes when: - ansible_os_family == "Debian" - - perform_system_update | default(false) \ No newline at end of file + - update_system_packages | default(false) + - system_updates_check.changed \ No newline at end of file diff --git a/roles/05-update/tasks/03-check-spigot-version.yml b/roles/05-update/tasks/03-check-spigot-version.yml index ab44b9a..f206e64 100644 --- a/roles/05-update/tasks/03-check-spigot-version.yml +++ b/roles/05-update/tasks/03-check-spigot-version.yml @@ -1,30 +1,22 @@ --- -- name: Get current Spigot version +- name: Lecture de la version actuelle ansible.builtin.slurp: src: "{{ current_version_file }}" - register: current_version - ignore_errors: yes + register: current_version_content + failed_when: false -- name: Set current version fact - ansible.builtin.set_fact: - current_spigot_version: "{{ (current_version.content | b64decode).strip() if current_version is succeeded else 'unknown' }}" +- name: Définition de la version actuelle + set_fact: + 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: - url: "https://hub.spigotmc.org/versions/{{ minecraft_version }}.json" + url: "{{ spigot_update_check_url }}{{ minecraft_version }}.json" method: GET return_content: yes - register: latest_version_info - ignore_errors: yes + register: spigot_version_check + failed_when: false -- name: Compare versions - ansible.builtin.set_fact: - spigot_needs_update: "{{ current_spigot_version != minecraft_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) }}" \ No newline at end of file +- name: Détermination si une mise à jour est disponible + set_fact: + spigot_update_available: "{{ minecraft_version != current_spigot_version }}" \ No newline at end of file diff --git a/roles/05-update/tasks/04-download-new-spigot.yml b/roles/05-update/tasks/04-download-new-spigot.yml new file mode 100644 index 0000000..1451646 --- /dev/null +++ b/roles/05-update/tasks/04-download-new-spigot.yml @@ -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' \ No newline at end of file diff --git a/roles/05-update/tasks/04-download-new-version.yml b/roles/05-update/tasks/04-download-new-version.yml deleted file mode 100644 index e3e798d..0000000 --- a/roles/05-update/tasks/04-download-new-version.yml +++ /dev/null @@ -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 \ No newline at end of file diff --git a/roles/05-update/tasks/05-compile-new-spigot.yml b/roles/05-update/tasks/05-compile-new-spigot.yml new file mode 100644 index 0000000..77bb33f --- /dev/null +++ b/roles/05-update/tasks/05-compile-new-spigot.yml @@ -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 }}" \ No newline at end of file diff --git a/roles/05-update/tasks/05-compile-new-version.yml b/roles/05-update/tasks/05-compile-new-version.yml deleted file mode 100644 index ef466dc..0000000 --- a/roles/05-update/tasks/05-compile-new-version.yml +++ /dev/null @@ -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 \ No newline at end of file diff --git a/roles/05-update/tasks/06-configure-new-version.yml b/roles/05-update/tasks/06-configure-new-version.yml deleted file mode 100644 index d9d785b..0000000 --- a/roles/05-update/tasks/06-configure-new-version.yml +++ /dev/null @@ -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 \ No newline at end of file diff --git a/roles/05-update/tasks/06-switch-versions.yml b/roles/05-update/tasks/06-switch-versions.yml new file mode 100644 index 0000000..f883f06 --- /dev/null +++ b/roles/05-update/tasks/06-switch-versions.yml @@ -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 \ No newline at end of file diff --git a/roles/05-update/tasks/07-switch-versions.yml b/roles/05-update/tasks/07-switch-versions.yml deleted file mode 100644 index f4d349e..0000000 --- a/roles/05-update/tasks/07-switch-versions.yml +++ /dev/null @@ -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 }}" \ No newline at end of file diff --git a/roles/05-update/tasks/main.yml b/roles/05-update/tasks/main.yml index 7a7c61c..e1f1e0c 100644 --- a/roles/05-update/tasks/main.yml +++ b/roles/05-update/tasks/main.yml @@ -1,28 +1,23 @@ --- -- name: Include check SSH keys tasks - ansible.builtin.include_tasks: 01-check-ssh-keys.yml - when: update_check_ssh_keys +# Tâches principales mises à jour +- import_tasks: 01-check-ssh-keys.yml + tags: [update, ssh-keys] -- name: Include check system updates tasks - ansible.builtin.include_tasks: 02-check-system-updates.yml - when: update_check_system +- import_tasks: 02-check-system-updates.yml + tags: [update, system] + when: update_system_packages | default(false) -- name: Include check Spigot version tasks - ansible.builtin.include_tasks: 03-check-spigot-version.yml - when: update_check_spigot +- import_tasks: 03-check-spigot-version.yml + tags: [update, spigot-version] -- name: Include download new version tasks - ansible.builtin.include_tasks: 04-download-new-version.yml - when: spigot_needs_update | default(false) +- import_tasks: 04-download-new-spigot.yml + tags: [update, spigot-download] + when: spigot_update_available | default(false) -- name: Include compile new version tasks - ansible.builtin.include_tasks: 05-compile-new-version.yml - when: spigot_needs_update | default(false) +- import_tasks: 05-compile-new-spigot.yml + tags: [update, spigot-compile] + when: spigot_update_available | default(false) -- name: Include configure new version tasks - ansible.builtin.include_tasks: 06-configure-new-version.yml - when: spigot_needs_update | default(false) - -- name: Include switch versions tasks - ansible.builtin.include_tasks: 07-switch-versions.yml - when: spigot_update_ready | default(false) \ No newline at end of file +- import_tasks: 06-switch-versions.yml + tags: [update, spigot-switch] + when: spigot_update_available | default(false) and spigot_compilation_success | default(false) \ No newline at end of file diff --git a/roles/05-update/templates/version-switch.sh.j2 b/roles/05-update/templates/version-switch.sh.j2 index 554c48f..ba8e228 100644 --- a/roles/05-update/templates/version-switch.sh.j2 +++ b/roles/05-update/templates/version-switch.sh.j2 @@ -1,36 +1,55 @@ #!/bin/bash -# {{ ansible_managed }} +# Script de changement de version Minecraft -STAGING_DIR="{{ update_staging_dir }}" -SERVER_DIR="{{ minecraft_server_dir }}" -PREVIOUS_DIR="{{ spigot_previous_dir }}" -DATE=$(date +%Y%m%d_%H%M%S) +set -e -# Create previous directory if not exists -mkdir -p "$PREVIOUS_DIR" +if [ $# -ne 1 ]; then + echo "Usage: $0 " + exit 1 +fi -# Backup current server -echo "Backing up current server..." -tar -czf "$PREVIOUS_DIR/server_before_update_$DATE.tar.gz" \ - -C "$SERVER_DIR" \ - --exclude='world*' \ - --exclude='logs' \ - --exclude='crash-reports' \ - . +NEW_VERSION=$1 +MINECRAFT_DIR="{{ minecraft_server_dir }}" +TEMP_BUILD_DIR="{{ temp_build_dir }}" +BACKUP_DIR="${MINECRAFT_DIR}/backup-$(date +%Y%m%d_%H%M%S)" -# Sync new version to server directory -echo "Switching to new version..." -rsync -av --delete \ - --exclude='world*' \ - --exclude='logs' \ - --exclude='crash-reports' \ - --exclude='plugins/*.yml' \ - --exclude='ops.json' \ - --exclude='whitelist.json' \ - --exclude='banned-*.json' \ - "$STAGING_DIR/" "$SERVER_DIR/" +echo "Changement vers la version ${NEW_VERSION}" -# Set permissions -chown -R {{ minecraft_user }}:{{ minecraft_group }} "$SERVER_DIR" +# Vérification que le nouveau JAR existe +if [ ! -f "${TEMP_BUILD_DIR}/spigot-${NEW_VERSION}.jar" ]; then + echo "Erreur: Fichier spigot-${NEW_VERSION}.jar introuvable" + exit 1 +fi -echo "Version switch completed!" \ No newline at end of file +# Arrêt du serveur +echo "Arrêt du serveur Minecraft..." +systemctl stop minecraft || true +sleep 10 + +# Sauvegarde de l'ancienne version +echo "Sauvegarde de l'ancienne version..." +mkdir -p "${BACKUP_DIR}" +cp "${MINECRAFT_DIR}/spigot.jar" "${BACKUP_DIR}/spigot-old.jar" 2>/dev/null || true + +# Copie de la nouvelle version +echo "Installation de la nouvelle version..." +cp "${TEMP_BUILD_DIR}/spigot-${NEW_VERSION}.jar" "${MINECRAFT_DIR}/spigot.jar" +chown {{ minecraft_user }}:{{ minecraft_group }} "${MINECRAFT_DIR}/spigot.jar" + +# Test de démarrage +echo "Test de la nouvelle version..." +systemctl start minecraft + +# Vérification que le serveur démarre correctement +sleep 30 +if systemctl is-active --quiet minecraft; then + echo "Mise à jour réussie vers la version ${NEW_VERSION}" + echo "Ancienne version sauvegardée dans: ${BACKUP_DIR}" +else + echo "Erreur: La nouvelle version ne démarre pas correctement" + echo "Restauration de l'ancienne version..." + systemctl stop minecraft || true + cp "${BACKUP_DIR}/spigot-old.jar" "${MINECRAFT_DIR}/spigot.jar" 2>/dev/null || true + systemctl start minecraft + exit 1 +fi \ No newline at end of file diff --git a/roles/05-update/vars/main.yml b/roles/05-update/vars/main.yml index 8336936..5ba73cd 100644 --- a/roles/05-update/vars/main.yml +++ b/roles/05-update/vars/main.yml @@ -1,4 +1,5 @@ --- -spigot_version_url: "https://hub.spigotmc.org/versions/latest.json" -current_version_file: "{{ minecraft_server_dir }}/.version" -update_staging_dir: "{{ minecraft_sources_dir }}/staging" \ No newline at end of file +# Variables mises à jour +update_script_path: /usr/local/bin +temp_build_dir: "/tmp/minecraft-build" +current_version_file: "{{ minecraft_server_dir }}/.version" \ No newline at end of file diff --git a/secrets.example b/secrets.example index a74c32b..cee687c 100644 --- a/secrets.example +++ b/secrets.example @@ -1,27 +1,21 @@ -# Variables secrètes à créer dans Gitea Secrets -# NE PAS COMMITER CE FICHIER +# Fichier des secrets à configurer dans Gitea +# Copier ces variables dans les secrets de votre repository Gitea -# SSH Keys pour les administrateurs -admin_ssh_keys: - - name: admin1 - key: "SSH_KEY_ADMIN1" - - name: admin2 - key: "SSH_KEY_ADMIN2" +# Variables SSH +ANSIBLE_SSH_PRIVATE_KEY= +ANSIBLE_SSH_PUBLIC_KEY= -# Mot de passe pour la base de données (si nécessaire) -db_password: "DB_PASSWORD_SECRET" +# Variables serveur +MINECRAFT_ADMIN_PASSWORD= +BACKUP_SSH_KEY= -# Token API pour les mises à jour -spigot_api_token: "SPIGOT_API_TOKEN" +# Variables réseau +ALLOWED_SSH_IPS= +MINECRAFT_RCON_PASSWORD= -# Clés pour les backups distants -backup_ssh_key: "BACKUP_SSH_KEY" -backup_remote_host: "backup.example.com" -backup_remote_user: "backup" -backup_remote_path: "/backups/minecraft" +# Variables base de données (si nécessaire) +DB_PASSWORD= -# RCON Password -rcon_password: "RCON_PASSWORD_SECRET" - -# Minecraft server properties secrets -server_rcon_password: "SERVER_RCON_PASSWORD" \ No newline at end of file +# Variables notification +DISCORD_WEBHOOK= +SLACK_TOKEN= \ No newline at end of file diff --git a/site.yml b/site.yml index 12ae2b4..6494865 100644 --- a/site.yml +++ b/site.yml @@ -1,40 +1,16 @@ --- -- name: Installation complète du serveur Minecraft +- name: Installation complète serveur Minecraft Spigot hosts: minecraft_servers - become: true - gather_facts: true - - pre_tasks: - - name: Vérification de la connectivité - ansible.builtin.ping: - - - name: Collecte des facts si nécessaire - ansible.builtin.setup: - when: ansible_facts == {} + remote_user: ansible + become: yes + gather_facts: yes roles: - - role: 01-server_hardening - tags: - - hardening - - security - - - role: 02-installation-java - tags: - - java - - prerequisites - - - role: 03-installation-Minecraft - tags: - - minecraft - - installation - - - role: 04-backups - tags: - - backup - - maintenance - - - role: 05-Update - tags: - - update - - maintenance - when: update_check | default(false) \ No newline at end of file + - 01-server_hardening + - 02-installation-java + - 03-Installation-minecraft + - 04-backups + - 05-Update + + vars_files: + - "inventories/{{ inventory_dir | basename }}/group_vars/all.yml" \ No newline at end of file