Для того, чтобы обеспечить автоматическое резервное сохранение серверов в 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.
