Для того, чтобы обеспечить автоматическое резервное сохранение серверов в Amazon Web Services EC2 я предлагаю воспользоваться скриптом Python, который запускается через сервис AWS Lambda.
Логика скрипта:
- Проверить все работающие серверы на наличие метки Backup со значением Yes.
- Создать снимок со всех дисков сервера, где указана метка резервного копирования.
- Проверить старые автоматические снимки дисков (имя снимка начинается с autosnapshot) на предмет устаревания (более 2 дней).
- Удалить старые снимки дисков, найденные на предыдущем шаге.
Код скрипта:
import boto3 import json, datetime from datetime import tzinfo, timedelta, datetime print('Loading function') def lambda_handler(event, context): regions = [context.invoked_function_arn.split(':')[3]] if 'regions' in event: regions = event['regions'] retention_days = 2 if 'retention_days' in event: retention_days = event['retention_days'] print("AWS snapshot backups stated at %s...\n" % datetime.now()) for region in regions: print("Region: %s" % region) create_region_snapshots(region, retention_days) print("\nAWS snapshot backups completed at %s\n" % datetime.now()) # create snapshot for region def create_region_snapshots(region, retention_days): ec2 = boto3.resource('ec2', region_name=region) instances = ec2.instances.filter( Filters=[ {'Name': 'instance-state-name', 'Values': ['running']}, {'Name': 'tag:Backup', 'Values':['yes','Yes']} ]) for i in instances: instance_name = filter(lambda tag: tag['Key'] == 'Name', i.tags)[0]['Value'] print("\tInstance: %s - %s" % (instance_name, i.id)) volumes = ec2.volumes.filter(Filters=[{'Name': 'attachment.instance-id', \ 'Values': [i.id]}]) snapshot_volumes(instance_name, retention_days, volumes) # create and prune snapshots for volume def snapshot_volumes(instance_name, retention_days, volumes): for v in volumes: print("\t\tVolume found: \t%s" % v.volume_id) create_volume_snapshot(instance_name, v) prune_volume_snapshots(retention_days, v) # create snapshot for volume def create_volume_snapshot(instance_name, volume): snapname = '%s-%s' % (instance_name, datetime.now().strftime("%Y.%m.%d") ) description = 'autosnapshot %s %s %s' % (instance_name, volume.volume_id, datetime.now().strftime("%Y.%m.%d %H:%M:%S") ) snapshot = volume.create_snapshot(Description=description) if snapshot: snapshot.create_tags(Tags=[{'Key': 'Name', 'Value': snapname}]) print("\t\tSnapshot created with description [%s]" % description) # find and delete snapshots older than retention_days def prune_volume_snapshots(retention_days, volume): for s in volume.snapshots.all(): now = datetime.now(s.start_time.tzinfo) old_snapshot = ( now - s.start_time ) > timedelta(days=retention_days) if not old_snapshot or not s.description.startswith('autosnapshot '): continue print("\t\tDeleting snapshot [%s - %s] created [%s]" % ( s.snapshot_id, \ s.description, str( s.start_time ))) try: s.delete() except: print("\t\tError: snapshot [%s - %s] is blocked and can't be deleted" % ( \ s.snapshot_id, s.description))
Настройка Lambda функции:
- Перейти в AWS Lambda через Services --> Lambda.
- Создать новую функцию через Create a Lambda Function.
- Выбрать пустую функцию Blank function.
- Выбрать триггер CloudWatch Events и создать новое правило для событий:
Имя: cwr-BackupService.
Описание: Backup schedule for Lambda.
Тип: Schedule expression.
Расписание: rate(1 day).
Включено: Yes. - Создать саму функцию:
Имя: lam-BackupService.
Описание: Backup service for EC2.
Обработчик: Python 2.7.
Тип кода: Edit code inline.
Код: вставить код скрипта.
Обработчик: lambda_function.lambda_handler.
Роль: Create custom role (после создания роли будет Choose existing role).
Имя роли: LAM-BackupService (откроется новое окно, где надо ввести имя роли и нажать Allow). - В дополнительных настройках функции установить:
Память: 128 MB.
Время выполнения: 5 minutes (чем больше серверов и их размер, тем дольше будет выполняться функция).
VPC: no VPC. - Проверить все параметры и создать функцию.
Использование функции в EC2:
- Перейти в AWS EC2 через Services --> EC2.
- Выбрать любой работающий сервер.
- На вкладке Tags нажать Add/Edit Tags.
- Создать метку Backup со значением Yes.
- Вернуться в AWS Lambda через Services --> Lambda.
- Выбрать функцию lam-BackupService.
- Нажать кнопку Test - функция запустится, а под ней будет отображен лог работы.
START RequestId: 0f1ec135-6ac3-11e7-a2f9-79390a179184 Version: $LATEST AWS snapshot backups stated at 2017-07-17 07:39:26.504412... Region: eu-west-1 MyTestServer - i-09c37a1234565c80b Volume found: vol-09b7f123456f1bb2b Snapshot created with description [autosnapshot MyTestServer vol-09b7f123456f1bb2b ...] AWS snapshot backups completed at 2017-07-17 07:39:31.038931 END RequestId: 0f1ec135-6ac3-11e7-a2f9-79390a179184 REPORT RequestId: 0f1ec135-6ac3-11e7-a2f9-79390a179184 Duration: 4534.80 ms Billed Duration: 4600 ms
- Вернуться в AWS EC2 через Services --> EC2.
- Перейти на вкладку снимков томов Snapshots - здесь можно найти только что сделанный снимок с диска сервера.
- Перейти в AWS CloudWatch через Services --> CloudWatch.
- Перейти на вкладку журналов Logs и выбрать журнал /aws/lambda/lam-BackupService.
- Выбрав поток вывода функции от нужной даты, можно посмотреть ход выполнения операции резервного копирования за любой день.
Функция резервного копирования готова к работе.
Примечание. Длительность хранения снимков томов можно отрегулировать параметром retention_days в теле функции или указать этот параметр во входящих параметрах к функции в триггере cwr-BackupService.