diff --git a/inventory_template/group_vars/backup.yml b/inventory_template/group_vars/backup_server.yml similarity index 59% rename from inventory_template/group_vars/backup.yml rename to inventory_template/group_vars/backup_server.yml index 52b1eba..f565f02 100644 --- a/inventory_template/group_vars/backup.yml +++ b/inventory_template/group_vars/backup_server.yml @@ -2,10 +2,7 @@ private_key_backup_user_host: "{{ vault_private_key_backup_user_host }}" public_key_backup_user_host: "{{ vault_public_key_backup_user_host }}" -# All GIT repositories to backup -git_repo_to_backup: - - ansible-base - -# Ports allowed by iptables -tcp_authorized_ports: - - 22 +# GIT repositories to backup +git_repositories: + - https://git.example.org/user/template-repository.git + - git@git.example.org:user/template-repository.git diff --git a/inventory_template/inventory.yml b/inventory_template/inventory.yml index f629ff9..7aa1ad2 100644 --- a/inventory_template/inventory.yml +++ b/inventory_template/inventory.yml @@ -6,6 +6,9 @@ all: children: function: children: + backup_server: + hosts: + myFirstDebianHost.example.org: munin_server: hosts: myFirstGentooHost.example.org: diff --git a/playbook_backup_server_deploy.yml b/playbook_backup_server_deploy.yml new file mode 100644 index 0000000..e8f0095 --- /dev/null +++ b/playbook_backup_server_deploy.yml @@ -0,0 +1,4 @@ +--- +- hosts: backup_server + roles: + - backup_server diff --git a/roles/backup_server/README.md b/roles/backup_server/README.md new file mode 100644 index 0000000..360236c --- /dev/null +++ b/roles/backup_server/README.md @@ -0,0 +1,81 @@ +Ansible Role: backup_server +========= + +This role set up a GNU/Linux backup server. + +Requirements +------------ + +You need private/public SSH keys to access GIT repositories to backup. + +Role Variables +-------------- + +All variables and default values are defined in `defaults/main.yml` : + + # Private/public SSH keys for the backup user on the backup server to access GIT repositories to backup + private_key_backup_user_host: "" + public_key_backup_user_host: "" + + # GIT repositories to backup + git_repositories: [] + + # Name of the cron service and cron package (depends on your OS, can be cron, cronie, crond...) + cron_client_service_name: cron + cron_client_package: cron + + # Name of the GIT package + git_package: git + + # Name of the Borkbackup package + borgbackup_package: borgbackup + + # Backup folder + backup_folder: "/data" + + # Folder to deploy backup scripts + backup_scripts_folder: "/usr/local/sbin" + + # GIT backup user + backup_user_git: "backup-git" + + # Crontask GIT backup scheduling + backup_git_cron_weekday: "*" + backup_git_cron_hour: "1" + backup_git_cron_minute: "30" + + # Crontask GIT archive backup scheduling + backup_git_archive_cron_weekday: "*" + backup_git_archive_cron_hour: "2" + backup_git_archive_cron_minute: "30" + + # Alias config file + aliases_config_file: "/etc/aliases" + + # User or email to send GIT backup scripts report + backup_git_mail_target: "root" + +**WARNING :** you need to define all of these variables, else you may have errors (use ansible-vault). + +Dependencies +------------ + +None. + +Example Playbook +---------------- + + - hosts: backup_server + roles: + - backup_server + +License +------- + +BSD + +Author Information +------------------ + +This role was created in 2020 by Nemo. + diff --git a/roles/backup_server/defaults/main.yml b/roles/backup_server/defaults/main.yml new file mode 100644 index 0000000..3ce1e34 --- /dev/null +++ b/roles/backup_server/defaults/main.yml @@ -0,0 +1,44 @@ +--- +# defaults file for backup_server + +# Private/public SSH keys for the backup user on the backup server to access GIT repositories to backup +private_key_backup_user_host: "" +public_key_backup_user_host: "" + +# GIT repositories to backup +git_repositories: [] + +# Name of the Cron service and cron package (depends on your OS, can be cron, cronie, crond...) +cron_client_service_name: cron +cron_client_package: cron + +# Name of the GIT package +git_package: git + +# Name of the Borkbackup package +borgbackup_package: borgbackup + +# Backup folder +backup_folder: "/data" + +# Folder to deploy backup scripts +backup_scripts_folder: "/usr/local/sbin" + +# GIT backup user +backup_user_git: "backup-git" + +# Crontask GIT backup scheduling +backup_git_cron_weekday: "*" +backup_git_cron_hour: "1" +backup_git_cron_minute: "30" + +# Crontask GIT archive backup scheduling +backup_git_archive_cron_weekday: "*" +backup_git_archive_cron_hour: "2" +backup_git_archive_cron_minute: "30" + +# Alias config file +aliases_config_file: "/etc/aliases" + +# User or email to send GIT backup scripts report +backup_git_mail_target: "root" diff --git a/roles/backup_server/handlers/main.yml b/roles/backup_server/handlers/main.yml new file mode 100644 index 0000000..c2c1a58 --- /dev/null +++ b/roles/backup_server/handlers/main.yml @@ -0,0 +1,11 @@ +--- +# handlers file for backup_server + +- name: "restart cron" + service: + name: "{{ cron_service_name }}" + enabled: yes + state: restarted + +- name: update aliases + command: postalias {{ aliases_config_file }} diff --git a/roles/backup_server/meta/main.yml b/roles/backup_server/meta/main.yml new file mode 100644 index 0000000..85fc37b --- /dev/null +++ b/roles/backup_server/meta/main.yml @@ -0,0 +1,26 @@ +galaxy_info: + author: nemo + description: Set up backup server for GNU/Linux. + company: Wirebrass + + license: license (BSD) + + min_ansible_version: 2.4 + + platforms: + - name: Debian + versions: + - stretch + - buster + - name: Gentoo + versions: + - all + + galaxy_tags: + - backup + - git + - system + - server + - auto + +dependencies: [] diff --git a/roles/backup_server/tasks/aliases.yml b/roles/backup_server/tasks/aliases.yml new file mode 100644 index 0000000..50460fa --- /dev/null +++ b/roles/backup_server/tasks/aliases.yml @@ -0,0 +1,7 @@ +--- +- name: Update mail aliases. + lineinfile: + dest: "{{ aliases_config_file }}" + line: "{{ backup_user_git }}: {{ backup_git_mail_target }}" + regexp: "^{{ backup_user_git }}:" + notify: update aliases diff --git a/roles/backup_server/tasks/crontasks.yml b/roles/backup_server/tasks/crontasks.yml new file mode 100644 index 0000000..eec09d6 --- /dev/null +++ b/roles/backup_server/tasks/crontasks.yml @@ -0,0 +1,20 @@ +--- +- name: GIT backup crontask configured + cron: + name: "GIT backup" + user: "{{ backup_user_git }}" + weekday: "{{ backup_git_cron_weekday }}" + hour: "{{ backup_git_cron_hour }}" + minute: "{{ backup_git_cron_minute }}" + job: "{{ backup_scripts_folder }}/backup_git.sh" + notify: restart cron + +- name: GIT archives backup crontask configured + cron: + name: "GIT Archive Backup" + user: "{{ backup_user_git }}" + weekday: "{{ backup_git_archive_cron_weekday }}" + hour: "{{ backup_git_archive_cron_hour }}" + minute: "{{ backup_git_archive_cron_minute }}" + job: "{{ backup_scripts_folder }}/backup_git_archive.sh" + notify: restart cron diff --git a/roles/backup_server/tasks/folders.yml b/roles/backup_server/tasks/folders.yml new file mode 100644 index 0000000..4a453ad --- /dev/null +++ b/roles/backup_server/tasks/folders.yml @@ -0,0 +1,24 @@ +--- +- name: Backup folder created + file: + path: "{{ backup_folder }}" + state: directory + owner: root + group: root + mode: '0755' + +- name: GIT backup folder created + file: + path: "{{ backup_folder }}/{{ backup_user_git }}" + state: directory + owner: "{{ backup_user_git }}" + group: "{{ backup_user_git }}" + mode: '0700' + +- name: GIT archives backup folder created + file: + path: "{{ backup_folder }}/{{ backup_user_git }}-archives" + state: directory + owner: "{{ backup_user_git }}" + group: "{{ backup_user_git }}" + mode: '0700' diff --git a/roles/backup_server/tasks/main.yml b/roles/backup_server/tasks/main.yml new file mode 100644 index 0000000..151526d --- /dev/null +++ b/roles/backup_server/tasks/main.yml @@ -0,0 +1,12 @@ +--- +# Main tasks file for backup_server + +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- import_tasks: user_git.yml +- import_tasks: package.yml +- import_tasks: folders.yml +- import_tasks: scripts.yml +- import_tasks: crontasks.yml +- import_tasks: aliases.yml diff --git a/roles/backup_server/tasks/package.yml b/roles/backup_server/tasks/package.yml new file mode 100644 index 0000000..c654b84 --- /dev/null +++ b/roles/backup_server/tasks/package.yml @@ -0,0 +1,16 @@ +--- +- name: Cron installed + package: + name: "{{ cron_package }}" + state: present + notify: restart cron + +- name: GIT installed + package: + name: "{{ git_package }}" + state: present + +- name: BorgBackup installed + package: + name: "{{ borgbackup_package }}" + state: present diff --git a/roles/backup_server/tasks/scripts.yml b/roles/backup_server/tasks/scripts.yml new file mode 100644 index 0000000..85fb33b --- /dev/null +++ b/roles/backup_server/tasks/scripts.yml @@ -0,0 +1,16 @@ +--- +- name: Deploy GIT backup script + template: + src: backup_git.sh.j2 + dest: "{{ backup_scripts_folder }}/backup_git.sh" + owner: "{{ backup_user_git }}" + group: "{{ backup_user_git }}" + mode: '0740' + +- name: Deploy Archive backup script + template: + src: backup_git_archive.sh.j2 + dest: "{{ backup_scripts_folder }}/backup_git_archive.sh" + owner: "{{ backup_user_git }}" + group: "{{ backup_user_git }}" + mode: '0740' diff --git a/roles/backup_server/tasks/user_git.yml b/roles/backup_server/tasks/user_git.yml new file mode 100644 index 0000000..e020cef --- /dev/null +++ b/roles/backup_server/tasks/user_git.yml @@ -0,0 +1,29 @@ +--- +- name: "Backup user GIT created" + user: + name: "{{ backup_user_git }}" + password: "!" + +- name: GIT backup SSH folder created + file: + path: "/home/{{ backup_user_git }}/.ssh" + state: directory + owner: "{{ backup_user_git }}" + group: "{{ backup_user_git }}" + mode: '0755' + +- name: Private key to access GIT repository in RO deployed + copy: + dest: "/home/{{ backup_user_git }}/.ssh/id_rsa" + owner: "{{ backup_user_git }}" + group: "{{ backup_user_git }}" + mode: '0600' + content: "{{ private_key_backup_user_host }}" + +- name: Public key to access GIT repository in RO deployed + copy: + dest: "/home/{{ backup_user_git }}/.ssh/id_rsa.pub" + owner: "{{ backup_user_git }}" + group: "{{ backup_user_git }}" + mode: '0644' + content: "{{ public_key_backup_user_host + '\n' }}" diff --git a/roles/backup_server/templates/backup_git.sh.j2 b/roles/backup_server/templates/backup_git.sh.j2 new file mode 100644 index 0000000..92dc035 --- /dev/null +++ b/roles/backup_server/templates/backup_git.sh.j2 @@ -0,0 +1,21 @@ +#!/bin/bash + +{% for git_repo in git_repositories %} +if [ ! -d {{ backup_folder }}/{{ backup_user_git }}/{{ git_repo | basename }} ]; then + cd {{ backup_folder }}/{{ backup_user_git }} + GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" git clone --mirror {{ git_repo }} +fi + +cd {{ backup_folder }}/{{ backup_user_git }}/{{ git_repo | basename }} +GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" git remote update + +if [ ! -d {{ backup_folder }}/{{ backup_user_git }}/{{ (git_repo | basename | splitext)[0] }} ]; then + cd {{ backup_folder }}/{{ backup_user_git }} + GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" git clone {{ git_repo }} +fi + +cd {{ backup_folder }}/{{ backup_user_git }}/{{ (git_repo | basename | splitext)[0] }} +GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" git fetch --all + +{% endfor %} + diff --git a/roles/backup_server/templates/backup_git_archive.sh.j2 b/roles/backup_server/templates/backup_git_archive.sh.j2 new file mode 100644 index 0000000..8e87bf6 --- /dev/null +++ b/roles/backup_server/templates/backup_git_archive.sh.j2 @@ -0,0 +1,13 @@ +#!/bin/bash + +borg list {{ backup_folder }}/{{ backup_user_git }}-archives &>/dev/null + +if [ $? -ne 0 ] +then + mkdir -p {{ backup_folder }}/{{ backup_user_git }}-archives -m 0740 + export BORG_PASSPHRASE="" + borg init --encryption=repokey {{ backup_folder }}/{{ backup_user_git }}-archives +fi + +borg prune -v {{ backup_folder }}/{{ backup_user_git }}-achives --keep-daily=7 --keep-weekly=4 --keep-monthly=1 +borg create --info --stats {{ backup_folder }}/{{ backup_user_git }}-archives::$(date +%F) $(find {{ backup_folder }}/{{ backup_user_git }}/ -maxdepth 1 -type d | tr '\n' ' ') diff --git a/roles/backup_server/vars/Debian.yml b/roles/backup_server/vars/Debian.yml new file mode 100644 index 0000000..0a7e0cf --- /dev/null +++ b/roles/backup_server/vars/Debian.yml @@ -0,0 +1,4 @@ +--- +cron_service_name: cron +cron_package: cron +aliases_config_file: /etc/aliases diff --git a/roles/backup_server/vars/Gentoo.yml b/roles/backup_server/vars/Gentoo.yml new file mode 100644 index 0000000..dffe71e --- /dev/null +++ b/roles/backup_server/vars/Gentoo.yml @@ -0,0 +1,4 @@ +--- +cron_service_name: cronie +cron_package: cronie +aliases_config_file: /etc/mail/aliases diff --git a/roles/backup_server/vars/RedHat.yml b/roles/backup_server/vars/RedHat.yml new file mode 100644 index 0000000..0c6e1bc --- /dev/null +++ b/roles/backup_server/vars/RedHat.yml @@ -0,0 +1,4 @@ +--- +cron_service_name: crond +cron_package: cronie +aliases_config_file: /etc/aliases