AWS Lambda – Stop Instances Outside Office Hours (Python / AWS)

I previously wrote about using some Python to stop AWS EC2 instances that had the tag “office_hours” and indicated that this could be automatically run via AWS Lambda.

This blog post is a brief follow up with some notes on creating the Lambda function, using the Python from the previous blog post. Using AWS Lambda with the previous Python requires an AWS Lambda function is created and possibly requires an AWS Role and a AWS Policy to be created (depending if your have already defined these in your AWS account).

Open AWS Lambda from the AWS web console and choose “Create Function”.

Give the function a meaningful name and copy/paste the Python code from the previous blog post. This code searches for any EC2 instances in the specified region that have the tag office_hours set to a value of true, and attempts to stop them.

Choose “Add Trigger” and choose “EventBridge (CloudWatch Events)” as the event source. Then create a CloudWatch event that runs on a schedule expression using cron. The following expression:

00 18 ? * MON-FRI *

Causes the event to run at 18:00 (6pm) Monday, Tuesday, Wednesday, Thursday and Friday, the working week. This event triggers the Lambda, which would search and stop any EC2 instances with the office_hours:true tag. To give the Lambda function the ability to do this though we also need to give it some permissions. Please try to limit the permissions that the function has, as too high permissions can see dangerous consequences if the function is changed or maliciously edited (e.g. to terminate instances instead of stopping them).

I recommend creating a new AWS role with an appropriate name (e.g. EC2_Lambda_Stop_Office_Hours) and giving that role a policy (similar name) with permissions to describe EC2 instances (needed to read the tag) and stop EC2 instances (to stop the instances). The policy will also need to.include permissions to create a log group, create a log stream and put log events, so that it can log issues with function. The AWS policy code would look similar to:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    

        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "ec2:StopInstances"
            ],
            "Resource": "*"
        }
    ]
}

With a recommendation to limit the resource if possible.

Posted in AWS