I think there is a similar code if you google, but I keep it as a memorandum.
I've often seen code that uses AWS Instance Scheduler or sets a time for a tag and stops when Lambda runs regularly, but I also wanted to reduce the number of Lambda runs to maximize costs. Therefore, I assumed that the time was fixed.
I want to execute automatic stop of the instance set as below in the tag of EC2 instance at 21:00 on weekdays.
auto-stoptrueCreate an IAM role with this kind of policy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "ec2:StopInstances",
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}
I want to shut down automatically at 21:00 every night
cron(0 12 ? * MON-FRI *)
And set. Note that the time is UTC, so convert JST to UTC and set it.
Create Lambda by specifying the above IAM role / CloudWatch Events. The default execution time is 3 seconds, but it is not enough, so set it to about 1 minute. The runtime is Python 3.8.
import json
def lambda_handler(event, context):
    import boto3
    ec2 = boto3.client('ec2')
    #Get the target EC2 instance IDs
    instances = targetInstances(ec2,'auto-stop', 'true')
    if len(instances) != 0:
        print("--- stop instances ---")
        print(instances)
        #Stop
        ec2.stop_instances(InstanceIds=instances)
#Get the target EC2 instance IDs
def targetInstances(ec2, tag_name, tag_value):
    query = [
        {"Name": "instance-state-name", "Values": ["running"]},
        {'Name': 'tag-key', "Values": [tag_name]},
    ]
    fetch_instances = ec2.describe_instances(Filters=query)['Reservations']
    instances = []
    for i in fetch_instances:
        for tags in i['Instances'][0]['Tags']:
            if tag_name in tags['Key']:
                if tags['Value'] == tag_value:
                    instanceId = i['Instances'][0]["InstanceId"]
                    instances.append(i['Instances'][0]["InstanceId"])
    return(instances)
Let's save the instance fee by dropping EC2 instances for the development environment frequently.
If you also want to do automatic startup, add ʻec2: StartInstances` to the policy, create Cloudwatch Events with a new start time, create Lambda, and rewrite the above code for startup.
Recommended Posts