Skip to content

How to stop all EC2 in all AWS regions at the same time?

How to stop all EC2 in all AWS regions at the same time 2022 cloud.jpg

Hello everyone, today I will describe how I dealt with stopping EC2 machines on AWS cloud test accounts in all regions simultaneously. I will provide a simple step-by-step tutorial on how to build such a solution.

I have different AWS accounts and the problem for me was that I was forgetting to turn off EC2 when I finished testing. Of course, I received notifications that I was about to go over budget, so I didn’t lose too much money. You can learn about how you can set a budget and receive such notifications in this article How to control costs in the AWS cloud ?? – blog with step by step tutorial (lepczynski.it)

An additional problem was that I was creating EC2 machines in different regions. Sometimes I forgot where, and even if I remembered, it was tiring to go into each region and turn off machines in each one.

I came up with a simple script that checks all regions for EC2 machines. If it finds an EC2 machine, it stops it. The script, of course, runs itself every day at a certain time, in my case at 1am.

Below you will find a complete solution that you too can implement and stop paying for machines that are unnecessarily turned on. The solution is perfect even if you don’t know how many machines you have and where they are. Just like me 😀

Action plan – what you will need:

  1. IAM policy that only allows to find and stop EC2
  2. IAM role with minimal privileges
  3. Lambda function
  4. CloudWatch Event

1) IAM policy that only allows to find and stop EC2

Go to IAM, select Policies and create a new IAM Policy, click on Create policy.

create aws policy 2022
AWS Create policy

Now you can create your own policy or use the one I created stop_ec2. Just switch to JSON and paste the code below.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "ec2:DescribeInstanceAttribute",
                "ec2:DescribeRegions",
                "ec2:StopInstances",
                "ec2:DescribeInstanceStatus"
            ],
            "Resource": "*"
        }
    ]
}

2) IAM role with minimal privileges

Now you can create an IAM Role. Go to IAM, select Roles. Create a new IAM Role, click Create roles, and then select Lambda.

aws create IAM role 2022
AWS Service – Lambda

Add the policy you created earlier and move on. Now, you can add a name such as stop_ec2, a description to the role and click Create role.

add policy ro aws role 2022 stop ec2
AWS Roles – add permissions

3) Lambda function

Now we move on to create Lambda Functions. From the services, select Lambda and click Create function.

lambda aws create function
AWS Lambda – functions

I create a lambda function using Python 3.9 and name it stop_ec2.

Very important! Remember to change the Execution role to the role you created in the previous section. In my case it is stop_ec2. You add the policy to the role, and you add the role to the function, it’s so simple 🙂

create function aws lambda python
AWS Lambda from scratch

The function is very simple, it is supposed to find all EC2s in a given account, in all regions. If it finds an EC2 it prints out their id and state. All machines that have a state equal to running will be automatically stopped.

import boto3 
ec2_client = boto3.client('ec2')
regions = [region['RegionName'] for region in ec2_client.describe_regions()['Regions']]

def lambda_handler(event, context):
    for region in regions:
        ec2_client = boto3.client('ec2', region)
        all_instances = ec2_client.describe_instances()
        if all_instances:
            print("List all instances:")
            for reservation in all_instances['Reservations']:
                for instance in reservation['Instances']:
                    print(instance['InstanceId'] + "-" + instance['State']['Name'])
                    
                    if instance['State']['Name'] == 'running':
                        print("Stopping ec2: " + instance['InstanceId'])
                        ec2_client.stop_instances(InstanceIds=[instance['InstanceId']])

TEST

function stop ec2
Logs from function stop_ec2

Of course, you can extend the lambda function so that, for example, it works only in a certain region. Then it is enough to add one variable and if.

You can also create an identical function just running EC2 machines. This way you can have one function responsible for shutting down machines and another for turning them on. To do that, you add a Cloud Watch Event to make the function run automatically and that’s it.

4) Cloud Watch Event

Once you’ve created your function and verified that it works properly, then you can automate its triggering, for example, by adding a CloudWatch Event. This allows you to run the function at a specific time. If you are interested in this topic, I wrote about it in the article How to automate S3 | Lambda + CloudWatch Events | 2022 (lepczynski.it)

All you have to do is click Add Trigger, select CloudWatch Events from the list, add a name and description. I like to use cron expressions, but you don’t have to. My function will run every day at one o’clock in the morning.

cloudwatch event stop ec2 2022
AWS Lambda – add trigger

Summary

As you can see, it is very easy to make a simple lambda function that will make life easier and save money. Even though I’m not a developer, I like to use Lambda functions in AWS because they have a wide range of uses and are really powerful.

If you are interested in the article, try to create a function like me yourself, and then expand and adapt it to your needs. The best way to learn is through practice.

2 thoughts on “How to stop all EC2 in all AWS regions at the same time?”

  1. This does not list all instances from all regions just EC2 instances in which region is created Lambda function

  2. It worked when I checked, but you can check each region separately to be sure. When you add:

    regions = [region['RegionName'] for region in ec2_client.describe_regions()['Regions']]

    and

    for region in regions:
    ec2_client = boto3.client('ec2', region)

    I will update the article soon. With this code, the function will check what regions are available and check each region separately.

    Thank you very much for your comment, it allowed me to improve the code.

Comments are closed.