Для достижения поставленой задачи нам потребуется
1) Windows Server 2008 R2 или новее работающий в AWS
2) SSM Agent version 2.2.58.0 или новее
3) AWS Tools for Windows PowerShell 3.3.48.0 или новее
4) AWS System manager
5) IAM
6) SNS
7) 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 месячных снапшота.
ссылка на оригинал статьи https://habr.com/ru/post/462601/
Добавить комментарий