Имеем windows сервер в AWS и задача настроить резервное копирование. Можно использовать снапшоты, но тогда возникнет проблема с целостностью данных. Ещё хочется хранить недельные и месячные снапшоты, а lifecycle в снапшотах этого не предлагает. Новый сервисе AWS Backup тоже не умеет ещё делать целостные снапшоты или я не нашёл как. Ну и хочется что бы всё это работало максимально без моего участия.
Для достижения поставленой задачи нам потребуется
Для начала нам нужна роль для сервера. Роль должна разрешать AWS SSM и создание EBS снапшотов.
Заходим в IAM > Policies > Create policy.
Переходим в закладку JSON и вставляем
Жмём Review policy в Имя пишем что то типа VssSnapshotPolicy. Сохраняем
Теперь создаём роль.
IAM > Roles > Create Role
Выбираем AWS Service > EC2 и идём в Permissions.
Здесь добавляем AmazonSSMManagedInstanceCore для SMM и нашу полиси которую мы создали ранне VssSnapshotPolicy. При желании присваем таг для нашей роли и даём ей имя допустим VssSnapshotRole.
Затем идём и присваиваем эту роль для желаемых серверов.
Всё теперь ssm может “управлять” этими серверами.
Теперь нам надо на сервера поставить AWSVssComponents. для этого выбираем Run command и жмём Run command ищем AWS-ConfigureAWSPackage.
В Command parameters выбираем Install, Name – AwsVssComponents, Версия последняя.
В Target выбираем системы которые будем бекапить.
Жмём RUN.
После окончания мы можем можем сделать бекап из консоли SSM.
Выбираем Run command, ищем AWSEC2-CreateVssSnapshot. В Target ставим наши сервера. Выбираем параметры как Exclude Boot Volume, Copy Only и No Writers.
Жмём RUN. У нас должны создаться снапшоты.
Для уведомлений о бекапах создадим SNS Topic. И подпишемся на него. Я использую уведомление на почту.
Создаём политику, которая разрешает слать сообщения в нашу очередь
И создаём роль с этой политикой.
Для автоматизации процесса воспользуемся SSM maintenance window.
Жмём Create maintenance window. Заполняем Name, заполняем Schedule какой душе угодно.
Заходим в созданный maintenance window и добавляем Register RUN command task. Заполняем параметры. В Tag я прописываю тип бекапа (TAG Key=SnapshotType,Value=). У меня это три возможных параметра Day, Week, Month и соответственно три maintenance window. Ставим Enable SNS notifications и указываем нашу роль для sns и topic.
Всё теперь снапшоты будут создаваться по расписанию.
И через некоторое время снапшотов у нас станет слишком много – их надо чистить. Для этого воспользуемся другим сервисом AWS – Lambda.
Для начала создадим роль которая умеет читать и удалять снапшоты.
Для этого в IAM создаём policy
И эту policy вешаем на новую роль.
Идём в lambda и создаём новую python функцию.
Роль используем созданную выше. В качестве триггера используем CloudWatch Event.
эта функция проходит по всем volume, ищет для всех volumes снапшоты которые completed, тегом SnapshotType и удаляет все снапшоты которые больше snapshot retentions. У меня храится 5 последних дневных, 3 недельных и 2 месячных снапшота.
Для достижения поставленой задачи нам потребуется
- Windows Server 2008 R2 или новее работающий в AWS
- SSM Agent version 2.2.58.0 или новее
- AWS Tools for Windows PowerShell 3.3.48.0 или новее
- AWS System manager
- IAM
- SNS
- Lambda
Для начала нам нужна роль для сервера. Роль должна разрешать AWS SSM и создание EBS снапшотов.
Заходим в IAM > Policies > Create policy.
Переходим в закладку JSON и вставляем
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:CreateTags",
"Resource": "arn:aws:ec2:*::snapshot/*"
},
{
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances",
"ec2:CreateSnapshot"
],
"Resource": "*"
}
]
}
Жмём Review policy в Имя пишем что то типа VssSnapshotPolicy. Сохраняем
Теперь создаём роль.
IAM > Roles > Create Role
Выбираем AWS Service > EC2 и идём в Permissions.
Здесь добавляем AmazonSSMManagedInstanceCore для SMM и нашу полиси которую мы создали ранне VssSnapshotPolicy. При желании присваем таг для нашей роли и даём ей имя допустим VssSnapshotRole.
Затем идём и присваиваем эту роль для желаемых серверов.
Всё теперь ssm может “управлять” этими серверами.
Теперь нам надо на сервера поставить AWSVssComponents. для этого выбираем Run command и жмём Run command ищем AWS-ConfigureAWSPackage.
В Command parameters выбираем Install, Name – AwsVssComponents, Версия последняя.
В Target выбираем системы которые будем бекапить.
Жмём RUN.
После окончания мы можем можем сделать бекап из консоли SSM.
Выбираем Run command, ищем AWSEC2-CreateVssSnapshot. В Target ставим наши сервера. Выбираем параметры как Exclude Boot Volume, Copy Only и No Writers.
Жмём RUN. У нас должны создаться снапшоты.
Для уведомлений о бекапах создадим SNS Topic. И подпишемся на него. Я использую уведомление на почту.
Создаём политику, которая разрешает слать сообщения в нашу очередь
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "sns:Publish",
"Resource": "arn:aws:sns:ap-northeast-1:Account ID:Topic Name"
}
]
}
И создаём роль с этой политикой.
Для автоматизации процесса воспользуемся SSM maintenance window.
Жмём Create maintenance window. Заполняем Name, заполняем Schedule какой душе угодно.
Заходим в созданный maintenance window и добавляем Register RUN command task. Заполняем параметры. В Tag я прописываю тип бекапа (TAG Key=SnapshotType,Value=). У меня это три возможных параметра Day, Week, Month и соответственно три maintenance window. Ставим Enable SNS notifications и указываем нашу роль для sns и topic.
Всё теперь снапшоты будут создаваться по расписанию.
И через некоторое время снапшотов у нас станет слишком много – их надо чистить. Для этого воспользуемся другим сервисом AWS – Lambda.
Для начала создадим роль которая умеет читать и удалять снапшоты.
Для этого в IAM создаём policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"logs:DeleteSubscriptionFilter",
"ec2:DeleteSnapshot",
"ec2:DescribeSnapshots",
"logs:DeleteLogStream",
"logs:CreateExportTask",
"logs:DeleteResourcePolicy",
"logs:CreateLogStream",
"logs:DeleteMetricFilter",
"logs:TagLogGroup",
"logs:CancelExportTask",
"ec2:DescribeVolumes",
"logs:DeleteRetentionPolicy",
"logs:DeleteLogDelivery",
"logs:AssociateKmsKey",
"logs:PutDestination",
"logs:DisassociateKmsKey",
"logs:UntagLogGroup",
"logs:DeleteLogGroup",
"logs:PutDestinationPolicy",
"ec2:DescribeSnapshotAttribute",
"logs:DeleteDestination",
"logs:PutLogEvents",
"logs:CreateLogGroup",
"logs:PutMetricFilter",
"logs:CreateLogDelivery",
"logs:PutResourcePolicy",
"logs:UpdateLogDelivery",
"logs:PutSubscriptionFilter",
"logs:PutRetentionPolicy"
],
"Resource": "*"
}
]
}
И эту policy вешаем на новую роль.
Идём в lambda и создаём новую python функцию.
import datetime
import sys
import boto3
def get_volume_snapshots(client, volume_id, SnapshotType):
args = {
"Filters": [
{ "Name": "volume-id", "Values": [volume_id] },
{ "Name": "status", "Values": ["completed"] },
{ "Name": "tag-key", "Values": ["SnapshotType"]},
{ "Name": "tag-value", "Values": [SnapshotType]},
],
"OwnerIds": ["self"]
}
snapshots = []
while True:
resp = client.describe_snapshots(**args)
snapshots += resp.get("Snapshots", [])
if "NextToken" in resp:
args["NextToken"] = resp["NextToken"]
else:
break
return snapshots
def delete_snapshot(client, snapshot_id):
wait_period = 5
retries = 5
while True:
try:
client.delete_snapshot(SnapshotId=snapshot_id)
return True
except Exception as ex:
# As the list of snapshot is eventually consistent old snapshots might appear in listed snapshots
if getattr(ex, "response", {}).get("Error", {}).get("Code", "") == "'InvalidSnapshot.NotFound":
return False
# Throttling might occur when deleting snapshots too fast
if "throttling" in ex.message.lower():
retries -= 1
if retries == 0:
raise ex
time.sleep(wait_period)
wait_period = min(wait_period + 10 , 30)
continue
raise ex
def lambda_handler(event, context):
retentions = {"Day": 5, "Week": 3, "Month": 2}
client = boto3.client("ec2")
vols = client.describe_volumes()
snapshots_deleted = []
for vol in vols['Volumes']:
vol_id = vol['VolumeId']
for SnapshotType, retention_count in retentions.items():
snapshots_for_volume = sorted(get_volume_snapshots(client, vol_id, SnapshotType), key=lambda s: s["StartTime"], reverse=True)
snapshots_to_delete = []
if retention_count > 0:
snapshots_to_delete = [b["SnapshotId"] for b in snapshots_for_volume[retention_count:]]
for snapshot_id in snapshots_to_delete:
if delete_snapshot(client, snapshot_id):
snapshots_deleted.append(snapshot_id)
return {
"DeletedSnapshots": snapshots_deleted
}
Роль используем созданную выше. В качестве триггера используем CloudWatch Event.
эта функция проходит по всем volume, ищет для всех volumes снапшоты которые completed, тегом SnapshotType и удаляет все снапшоты которые больше snapshot retentions. У меня храится 5 последних дневных, 3 недельных и 2 месячных снапшота.
Комментарии (6)
ustas33
07.08.2019 16:38Меня мучает вопрос, не проще ли на S3 бакапить? А потом life policy на S3 Glacier переносить.
ufoton Автор
07.08.2019 17:05Ну ebs снапшоты хранятся на S3.
Если вопрос об бекапе чисто данных… то да можно бекапить на s3 и в случае падения поднимать новую машину и настраивать её и потом восстанавливать данные но сколько времени это займёт?
el_kex
Интересный подход. По поводу целостности: были ли реальные прецеденты нарушения целостности при бэкапе volume?
Мне кажется, с Lambda тут небольшой оверхед вышел. Ведь можно использовать AWS API, который довольно много умеет. Например, то же создание снэпшотов или бэкапирование виртуалки целиком как AMI вместе с состоянием, что по идее должно сохранять состояние и обеспечивать целостность (но это неточно). Через него же можно ротировать бэкапы.
Вот тут тоже на тему бэкапов довольно интересно.
ufoton Автор
Я меньше всего хочу в самый нужный момент понять, что бекап не консистентный.
Снапшот не гарантирует консистентность. AMI гарантирует, но машина рестартится в этот момент. Можно использовать и API, но в моём подходе всё проще на мой взгляд, да и powershell и windows я так хорошо не знаю
Я читал эту статью
el_kex
Кстати, ещё есть занятная вещь — EC2 Lifecycle Manager. Он позволяет работать с аналогичным Вашему подходом.
Я не уверен, создаёт ли он Maintenance Window на это время. Но что мешает создать его параллельно?
Основная плюшка — у него есть параметр Retention, который снимает необходимость создания лямбды для удаления старых бэкапов.
ufoton Автор
Lifecycle Manager не умеет хранить отдельно месячные и недельные бекапы. И он не делает консистентный бекап.