Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Azure Support #67

Closed
wants to merge 29 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 57 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,16 @@ Available variables:

| Name | Required | Description |
| ----------------------- |:--------:| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `location` | yes | The location of the Backend. Currently, [Local](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#local), [SFTP](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#sftp), [S3](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#amazon-s3) and [B2](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#backblaze-b2) are supported |
| `location` | yes | The location of the Backend. Currently, [Local](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#local), [SFTP](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#sftp), [S3](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#amazon-s3), [B2](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#backblaze-b2) and [Azure](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#microsoft-azure-blob-storage) are supported |
| `password` | yes | The password used to secure this repository |
| `init` | no | Describes if the repository should be initialized or not. Use `false` if you are backuping to an already existing repo. |
| `aws_access_key` | no | The access key for the S3 backend |
| `aws_secret_access_key` | no | The secret access key for the S3 backend |
| `aws_default_region` | no | The desired region for the S3 backend |
| `b2_account_id` | no | The account ID for Backblaze B2 backend |
| `b2_account_key` | no | The account key for Backblaze B2 backend |
| `azure_account_name` | no | The account Name for Azure Storage backend |
| `azure_account_key` | no | The account key for Azure Storage backend |

Example:
```yaml
Expand All @@ -123,10 +125,13 @@ Available variables:
| ------------------ |:-----------------------------:| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name` | yes | The name of this backup. Used together with pruning and scheduling and needs to be unique. |
| `repo` | yes | The name of the repository to backup to. |
| `src` | yes | The source directory or file |
| `src` | yes | List of the source directories or files |
| `stdin` | no | Is this backup created from a [stdin](https://restic.readthedocs.io/en/stable/040_backup.html#reading-data-from-stdin)? |
| `stdin_cmd` | no (yes if `stdin` == `true`) | The command to produce the stdin. |
| `stdin_filename` | no | The filename used in the repository. |
| `before_script` | no | Content for a script, that will be executed before the backup command. |
| `notify_script` | no | Content for a notify, that will be executed after the backup and forget command command. |
| `notify_zabbix` | no | Details to notify an Zabbix Server after each backup run. |
| `tags` | no | Array of default tags |
| `keep_last` | no | If set, only keeps the last n snapshots. |
| `keep_hourly` | no | If set, only keeps the last n hourly snapshots. |
Expand All @@ -142,6 +147,8 @@ Available variables:
| `schedule_hour` | no (`*`) | Hour when the job is run. ( 0-23, *, */2, etc ) |
| `schedule_weekday` | no (`*`) | Weekday when the job is run. ( 0-6 for Sunday-Saturday, *, etc ) |
| `schedule_month` | no (`*`) | Month when the job is run. ( 1-12, *, */2, etc ) |
| `disable_logging` | no (`false`) | Allows you to enable/disable the logging. |
| `max_result_log_size` | no (`500000`) | Allows you to specify max result log file size. Default deletes the result log file if it is bigger than 500 KB. |
| `exclude` | no (`{}`) | Allows you to specify files to exclude. See [Exclude](#exclude) for reference. |

Example:
Expand All @@ -150,7 +157,10 @@ restic_backups:
data:
name: data
repo: remote
src: /path/to/data
src:
- /path/to/data
before_script: "{{ lookup('file', 'before-script.sh') }}"
notify_script: "{{ lookup('file', 'notify-cript.sh') }}"
scheduled: true
schedule_hour: 3
```
Expand All @@ -177,6 +187,50 @@ exclude:
Please refer to the use of the specific keys to the
[documentation](https://restic.readthedocs.io/en/latest/040_backup.html#excluding-files).

#### Before Script
The `before_script` key on a backup allows you to specify content for an script which will executed before all backup commands.
The content can be specified in an extra file an loaded like that:
`before_script: "{{ lookup('file', 'before_script.sh') }}"`

This script can be used for example to create an db-dump before the backup.

#### Notify Script
The `notifiy_script` key on a backup allows you to specify content for an script which will executed after all backup commands.
The content can be specified in an extra file an loaded like that:
`notifiy_script: "{{ lookup('file', 'notifiy_script.sh') }}"`

The noify_script will be executed with an parameter which shows the status of the backup process.

| Code | Description |
| ---- | ----------- |
| "NO_ERROR" | all good |
| "BEFORE_SCRIPT_FAILED" | before scirpt has failed, so backup and forget will not be executed |
| "BACKUP_FAILED" | restic backup command has failed, so forget will not be executed |
| "FORGET_FAILED" | restic forget command has failed |

The passed status parameter can be handled like this:
```bash
#!/bin/sh
echo "afterScript"

if [[ "$1" = "NO_ERROR" ]]
then
echo "No Error!"
else
echo "Errors:" $1
fi
```

#### Notify Zabbix
The `notify_zabix` key on a backup allows you to specify details to notify an Zabbix Server after each backup run. You can specify the follwing keys:
```yaml
notify_zabbix:
serverHost: 192.168.1.5
serverPort: 10051
host: fooBar
key: fooBarBackupState
```

## Dependencies
none
## Example Playbook
Expand Down
2 changes: 2 additions & 0 deletions tasks/configure.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
AWS_DEFAULT_REGION: '{{ item.value.aws_default_region | default("") }}'
B2_ACCOUNT_ID: '{{ item.value.b2_account_id | default("") }}'
B2_ACCOUNT_KEY: '{{ item.value.b2_account_key | default("") }}'
AZURE_ACCOUNT_NAME: '{{ item.value.azure_account_name | default("") }}'
AZURE_ACCOUNT_KEY: '{{ item.value.azure_account_key | default("") }}'
no_log: true
register: restic_init
changed_when: "'created restic repository' in restic_init.stdout"
Expand Down
58 changes: 49 additions & 9 deletions tasks/distribution/Linux.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
---
# tasks file for skeleton

- name: reformat dict if necessary
set_fact:
restic_backups: "{{ restic_backups|dict2items|json_query('[*].value') }}"
when:
- restic_backups | type_debug == "dict"

- name: Create backup credentials
template:
src: restic_access_Linux.j2
dest: '{{ restic_script_dir }}/access-{{ item.name }}.sh'
dest: '{{ restic_script_dir }}/access-{{ item.repo }}.sh'
mode: '0700'
owner: '{{ restic_dir_owner }}'
group: '{{ restic_dir_group }}'
Expand All @@ -25,10 +19,12 @@
- name: Create backup script
template:
src: restic_script_Linux.j2
dest: '{{ restic_script_dir }}/backup-{{ item.name }}.sh'
dest: '{{ restic_script_dir }}/{{ item.name }}-backup/backup.sh'
mode: '0700'
owner: '{{ restic_dir_owner }}'
group: '{{ restic_dir_group }}'
lstrip_blocks: yes
trim_blocks: yes
no_log: true
with_items: '{{ restic_backups }}'
when:
Expand All @@ -37,10 +33,54 @@
- item.src is defined or item.stdin and item.stdin_cmd is defined
- item.repo in restic_repos

- name: create before script
copy:
content: "{{ item.before_script }}"
dest: '{{ restic_script_dir }}/{{ item.name }}-backup/before.sh'
mode: '0700'
owner: '{{ restic_dir_owner }}'
group: '{{ restic_dir_group }}'
no_log: true
with_items: '{{ restic_backups }}'
when:
- item.name is defined
- item.before_script is defined
- item.repo in restic_repos

- name: create notify script
copy:
content: "{{ item.notify_script }}"
dest: '{{ restic_script_dir }}/{{ item.name }}-backup/notify.sh'
mode: '0700'
owner: '{{ restic_dir_owner }}'
group: '{{ restic_dir_group }}'
no_log: true
with_items: '{{ restic_backups }}'
when:
- item.name is defined
- item.notify_script is defined
- item.repo in restic_repos

- name: zabbix notification
include: '../zabbix.yml'
with_items: '{{ restic_backups }}'
no_log: true
when:
- item.notify_zabbix is defined
- item.repo in restic_repos

- name: zabbix passive check
include: '../zabbix-passive.yml'
with_items: '{{ restic_backups }}'
no_log: true
when:
- item.passive_zabbix_check is defined
- item.repo in restic_repos

- name: Setup CRON jobs
cron:
name: 'arillso.restic backup {{ item.name }}'
job: 'CRON=true {{ restic_script_dir }}/backup-{{ item.name }}.sh'
job: 'CRON=true {{ restic_script_dir }}/{{ item.name }}-backup/backup.sh'
minute: '{{ item.schedule_minute | default("*") }}'
hour: '{{ item.schedule_hour | default("*") }}'
weekday: '{{ item.schedule_weekday | default("*") }}'
Expand Down
16 changes: 16 additions & 0 deletions tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
---
# tasks file for skeleton

- name: reformat dict if necessary
set_fact:
restic_backups: "{{ restic_backups|dict2items|json_query('[*].value') }}"
when:
- restic_backups | type_debug == "dict"

- name: add OS specific variables
include_vars: '{{ loop_vars }}'
with_first_found:
Expand Down Expand Up @@ -32,6 +38,16 @@
group: '{{ restic_dir_group }}'
with_items: '{{ restic_create_paths }}'

- name: Ensure backup script directories exist
file:
state: 'directory'
path: '{{ restic_script_dir }}/{{ item.name }}-backup'
mode: '0755'
owner: '{{ restic_dir_owner }}'
group: '{{ restic_dir_group }}'
no_log: true
with_items: '{{ restic_backups }}'

- name: Check if downloaded binary is present
stat:
path: '{{ restic_download_path }}/bin/restic-{{ restic_version }}'
Expand Down
10 changes: 10 additions & 0 deletions tasks/zabbix-passive.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---

- name: create zabbix backups JSON
template:
src: zabbix_backups_Linux.j2
dest: '{{ restic_script_dir }}/backups.json'
mode: '0704'
owner: '{{ restic_dir_owner }}'
group: '{{ restic_dir_group }}'
no_log: true
15 changes: 15 additions & 0 deletions tasks/zabbix.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---

- name: create zabbix-sender script
copy:
src: "templates/zabbix-sender.sh"
dest: '{{ restic_script_dir }}/zabbix-sender.sh'
mode: '0700'
owner: '{{ restic_dir_owner }}'
group: '{{ restic_dir_group }}'
no_log: true

- name: install netcat
package:
name: netcat
state: present
8 changes: 5 additions & 3 deletions templates/restic_access_Linux.j2
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ export B2_ACCOUNT_ID={{ restic_repos[item.repo].b2_account_id }}
{% if restic_repos[item.repo].b2_account_key is defined %}
export B2_ACCOUNT_KEY={{ restic_repos[item.repo].b2_account_key }}
{% endif %}
BACKUP_NAME={{ item.name }}
{% if item.src is defined %}
BACKUP_SOURCE={{ item.src }}
{% if restic_repos[item.repo].azure_account_name is defined %}
export AZURE_ACCOUNT_NAME={{ restic_repos[item.repo].azure_account_name }}
{% endif %}
{% if restic_repos[item.repo].azure_account_key is defined %}
export AZURE_ACCOUNT_KEY={{ restic_repos[item.repo].azure_account_key }}
{% endif %}
Loading