I was wondering if there was a good way to get a regular backup of EC2, but I found out that SSM can take snapshots, so I ran it from Lambda. I'll skip creating the server, but since I'm using Systems Manager, I'm using Windows Server 2019, which has the SSM agent installed by default.
reference Install and configure the SSM agent on your Windows instance (https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/sysman-install-ssm-win.html)
--Create a Windows server --Get backup from Systems Manager --Run Systems Manager documents from Lambda
Create one EC2 to get a backup.
The security group is set to the minimum.
Once you've created EC2, attach an IAM role so that Systems Manager can run on your instance. This time, for verification, only EC2FullAccess (for snapshot acquisition) and SSMManagedInstanceCore (for SSM execution) are set.
A few minutes after creating EC2, you can see the target instance from the managed instance of Systems Manager.
I'd like to get a backup with Lambda at once, but first I will confirm that I can get a backup from Systems Manager.
Press the command execution button.
This time, I will use the "AWS EC2-CreateVssSnapshot" document created by AWS.
From the target items, select the server you just mentioned and run the document.
Check that the status of the executed command is successful from the command history.
I was able to take a snapshot successfully.
Now that you have a backup from Systems Manager, let's run Systems Manager from Lambda.
First, create an IAM role for running Lambda. Start with only Lambda execute permission and proceed while eliminating errors.
By the way, the Lambda code looks like this (written in Python)
lambda_function.py
import json
import traceback
import boto3
import logging
from datetime import datetime
logger = logging.getLogger()
logger.setLevel(logging.INFO)
instance_id = 'i-0bec94e365078de8c'
document_name = 'AWSEC2-CreateVssSnapshot'
exec_date = datetime.now().strftime("%Y/%m/%d_%H:%M:%S")
snapshot_name = 'testserver-snapshot-' + exec_date
def lambda_execute_ssm(event):
ssm = boto3.client('ssm')
logger.info("Start Get Snapshot")
ssm_result = ssm.send_command(
InstanceIds = [ instance_id ],
DocumentName = document_name,
Parameters = {
'ExcludeBootVolume': [
'False',
],
'description': [
'Ssm Execute Document',
],
'tags': [
'Key=Name,Value={}'.format(snapshot_name),
]
}
)
logger.info("exec lambda result -> {}".format(ssm_result))
logger.info("Completed!")
def lambda_handler(event, context):
try:
lambda_execute_ssm(event)
except Exception:
logger.error('Exception -> {}'.format(traceback.format_exc()))
When I try to run Lambda in this state, the following error occurs
botocore.exceptions.ClientError: An error occurred (AccessDeniedException) when calling the SendCommand operation: User: arn:aws:sts::XXXXXXXXXXXX:assumed-role/lambda-ssm-handler/ssm-execution is not authorized to perform: ssm:SendCommand on resource: arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:instance/i-0bec94e365078de8c
As far as I read the error content, I am trying to execute SendCommand of SSM, but it seems that it is because Lambda does not have that authority?
When I attached a policy (AmazonSSMMaintenanceWindowRole) that allows SSM SendCommand privileges to the Lambda role and ran Lambda again, it ended successfully.
Since snapshots have also been created, there seems to be no problem.
Since I was able to get a backup from Lambda, it seems that I can get a regular backup if I execute it on a schedule with CloudEvent etc.
With this method, it is necessary to create Lambda for deletion, so life cycle manager may be better in that respect, but life cycle manager has a time lag in acquisition and flexibility to do with CloudWatch Event cron It is not possible to set a schedule, so if you need it, you should run Lambda.
Actually, I wanted to make a place to notify SNS when the SSM command fails, but since errors occurred frequently when passing the role for SNS notification, I decided to take a snapshot once. I can't understand the IAM roll. ..
Recommended Posts