[PYTHON] Run Systems Manager from Lambda to get a backup of EC2

Introduction

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)

What i did

--Create a Windows server --Get backup from Systems Manager --Run Systems Manager documents from Lambda

Windows server creation and IAM role settings

Create one EC2 to get a backup. image.png

The security group is set to the minimum. image.png

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. image.png

A few minutes after creating EC2, you can see the target instance from the managed instance of Systems Manager. image.png

Get backup from 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. image.png

This time, I will use the "AWS EC2-CreateVssSnapshot" document created by AWS. image.png

From the target items, select the server you just mentioned and run the document. image.png

Check that the status of the executed command is successful from the command history. image.png

I was able to take a snapshot successfully. image.png

Run Systems Manager documents from Lambda

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. image.png

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. image.png

Since snapshots have also been created, there seems to be no problem. image.png

Supplement to conclusions and findings

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

Run Systems Manager from Lambda to get a backup of EC2
How to get a list of links from a page from wikipedia
How to get a value from a parameter store in lambda (using python)
Run BigQuery from Lambda
[Command] Command to get a list of files containing double-byte characters
I want to start a lot of processes from python
How to get a list of built-in exceptions in python
A quick explanation from creating AWS Lambda Layers to linking
Send a request from AWS Lambda to Amazon Elasticsearch Service
How to get a quadratic array of squares in a spiral!
I tried to get a database of horse racing using Pandas
Try to get a list of breaking news threads in Python.
Things to note when running Python on EC2 from AWS Lambda
How to get a string from a command line argument in python
TensorFlow To learn from a large number of images ... ~ (almost) solution ~
[Python] How to get & change rows / columns / values from a table.
Here's a brief summary of how to get started with Django
How to use Visual Recognition to get LINE ID from a girl
[Python] Get the update date of a news article from HTML
Simple code to call a python program from Javascript on EC2
I tried to get a list of AMI Names using Boto3
How to get the vertex coordinates of a feature in ArcPy
Call dlm from python to run a time-varying coefficient regression model
How to get a job as an engineer from your 30s
Create a function to get the contents of the database in Go
DataFrame of pandas From creating a DataFrame from two lists to writing a file
Preparing to run Flask on EC2
[Lambda] [Python] Post to Twitter from Lambda!
[EC2] How to run selenium webdriver
[EC2] How to take a screen capture of your smartphone with selenium
[Python memo] I want to get a 2-digit hexadecimal number from a decimal number
When running a Python shell from Electron, pass multiple arguments to run Python.
[Linux] Command to get a list of commands executed in the past
How to get a namespaced view name from a URL (path_info) in Django
How to get a sample report from a hash value using VirusTotal's API
Get the song name from the title of the video you tried to sing
Get the average salary of a job with specified conditions from indeed.com
TensorFlow To learn from a large number of images ... (Unsolved problem) → 12/18 Solved
Let Code Day6 Starting from Zero "1342. Number of Steps to Reduce a Number to Zero"