使用 Lambda 建立自動備份機器人

備份 EBS 應該是很常見的事務性工作,所以我在網上找到了資料來使用 Lambda 機器人,為我的 EBS 自動建立備份快照(snapshot)。

只要按照這三個步驟就可以建立一個 EBS 自動備份機器人

Step 1 – 建立 Lambda backup 程式碼

此 Lambda function 的主要用途有

  • 尋找在指定 region 內的所有 Instances
  • 根據 Tags 過濾出需要備份的 Instances – 這裡的 Tag key 會是 “Backup” 或是 “backup”
  • 辨認出在對應 Instances 上的 EBS
  • 開始建立備份的 EBS snapshot
  • 將一些設定的 Tags 加在備份的 snapshots 上
  • 回報狀態

Step 2 – 使用 Cloudwatch Events 觸發 Lambda backup 動作

Step 3 – 在 EC2 Dashboard 裡確認 EBS sanpshots 有被建立


事前準備

  • EC2 Server(s) – 設定 Tag 為 “Key = Backup”,”Value = Yes” 注意大小寫需相符
  • IAM ROLE – Lambda Service Role 需要有 EC2FullAccess 的權限

Step 1 – 建立 Lambda backup 程式碼

建立 Lambda backup ,環境選擇 python 2.7。
在 # 全域變數 區塊設定為與自己相應的設定。

import boto3
import collections
import datetime

#全域變數
globalVars  = {}
globalVars['Owner']                 = "Your-Name"
globalVars['Environment']           = "Production"
globalVars['REGION_NAME']           = "ap-northeast-1"
globalVars['tagName']               = "Serverless-Automated-Backup"
globalVars['findNeedle']            = "BackUp"
globalVars['RetentionTag']          = "DeleteOn"
globalVars['RetentionInDays']       = "30"

# Region 名稱
ec = boto3.client('ec2', region_name='ap-northeast-1')

def backup_bot():

    snapsCreated = { 'Snapshots':[], }

    filters = [
        {'Name': 'tag-key', 'Values': [ globalVars['findNeedle'] ]},
        {'Name': 'tag-value', 'Values': ['Yes']},
    ]

    reservations = ec.describe_instances( Filters=filters ).get( 'Reservations', [] )

    instances = sum(
        [
            [i for i in r['Instances']]
            for r in reservations
        ], [])

    # 列出 Instances 的數量 : %d" % len(instances)
    snapsCreated['InstanceCount']=len(instances)

    to_tag = collections.defaultdict(list)

    # 遍歷該 Region 所有的 Instances
    for instance in instances:
        try:
            retention_days = [
                int(t.get('Value')) for t in instance['Tags']
                if t['Key'] == 'Retention'][0]
        except IndexError:
            retention_days = int(globalVars['RetentionInDays'])

        # 取得所有的 EBS
        for dev in instance['BlockDeviceMappings']:
            if dev.get('Ebs', None) is None:
                continue
            vol_id = dev['Ebs']['VolumeId']

            # 遍歷 Tags 來收集 Instances 的 name
            DescriptionTxt = ''
            for tag in instance['Tags']:
                if tag['Key'] == 'Name' :
                    DescriptionTxt = tag['Value']

            snap = ec.create_snapshot( VolumeId=vol_id, Description=DescriptionTxt )

            to_tag[retention_days].append(snap['SnapshotId'])

            # Tag 所有的剛建立的 snapshots 加上 Deletion Date
            # 以 "DeleteOn" 管理所有的 snapshots 何時該被移除
            for retention_days in to_tag.keys():
                delete_date = datetime.date.today() + datetime.timedelta(days=retention_days)
                # format 日期
                delete_fmt = delete_date.strftime('%Y-%m-%d')
                # 建立 Name, DeleteOn Tag 在 EBS sanpshots 上
                ec.create_tags(
                                Resources=to_tag[retention_days],
                                Tags=[
                                        {'Key': globalVars['RetentionTag'], 'Value': delete_fmt},
                                        {'Key': 'Name', 'Value': snap['Description'] },
                                    ]
                            )
                snapsCreated['Snapshots'].append({ 'SnapshotId':snap['SnapshotId'], 'VolumeId' : vol_id, 'InstanceId' : instance['InstanceId'], 'DeleteOn': delete_fmt })

        to_tag.clear()

    return snapsCreated


def lambda_handler(event, context):
    return backup_bot()

if __name__ == '__main__':
    lambda_handler(None, None)

Step 2 – 使用 Cloudwatch Events 觸發 Lambda backup 動作

使用 Cloudwatch Event 呼叫 Lambda 進行備份

# 每 5 分鐘備份一次.
rate(5 minutes)
or
# 每天備份一次.
rate(1 day)
or
# 每天 12:00pm UTC 進行備份.
cron(0 12 * * ? *)

更多 Scheduled 表達式的使用, 請參考: CloudWatch – Schedule Expressions for Rules

Step 3 – 在 EC2 Dashboard 裡確認 EBS sanpshots 有被建立


翻譯自:https://github.com/miztiik/serverless-backup