備份 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