Как стать автором
Обновить

Резервное копирование windows серверов в AWS

Время на прочтение4 мин
Количество просмотров2.8K
Имеем windows сервер в AWS и задача настроить резервное копирование. Можно использовать снапшоты, но тогда возникнет проблема с целостностью данных. Ещё хочется хранить недельные и месячные снапшоты, а lifecycle в снапшотах этого не предлагает. Новый сервисе AWS Backup тоже не умеет ещё делать целостные снапшоты или я не нашёл как. Ну и хочется что бы всё это работало максимально без моего участия.

Для достижения поставленой задачи нам потребуется

  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 месячных снапшота.
Теги:
Хабы:
+7
Комментарии6

Публикации

Изменить настройки темы

Истории

Ближайшие события

PG Bootcamp 2024
Дата16 апреля
Время09:30 – 21:00
Место
МинскОнлайн
EvaConf 2024
Дата16 апреля
Время11:00 – 16:00
Место
МоскваОнлайн
Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн