Working with EC2 Instances using Boto3 in Python

Kelvin Galabuzi

Kelvin Galabuzi

5
(1)

The Amazon EC2 is a cloud service within Amazon Web Services cloud platform that allows building and managing virtual machines to support various application workloads. With Amazon EC2, you can create, resize or decommission instances at any time depending on the business requirements. As a Cloud Automation Engineer, you’ll be dealing with a lot of tasks around this topic. So, this article is providing code snippets that will help you create, start, stop, list, filter, delete, tag, and modify Amazon EC2 Instances using the AWS Software Development Kit (SDK) for Python – Boto3 library.

Table of contents

Prerequisites

How to manage EC2 Instances using Boto3?

This section of the article will cover the basic operations with EC2 instances using the Boto3 library.

Creating EC2 instance

To create one or more EC2 instances, you need to use the create_instances() method of the EC2 resource. The simplest EC2 instance configuration might include the following arguments:

  • MinCount – minimum number of EC2 instances to launch
  • MaxCount – maximum number of EC2 instances to launch
  • ImageId – the Amazon Machine Image which is used to launch your EC2 instance (Working with Snapshots and AMIs using Boto3 in Python)
  • InstanceType – Instance Type specifies how much CPU and RAM resources your EC2 instance should have
  • KeyName – SSH key name, which you’re going to use to get remote access to the EC2 instance

Such configuration will launch an EC2 instance in the default VPC:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
KEY_PAIR_NAME = 'my-ssh-key-pair'
AMI_ID = 'ami-0cc00ed857256d2b4'

instances = EC2_RESOURCE.create_instances(
    MinCount = 1,
    MaxCount = 1,
    ImageId=AMI_ID,
    InstanceType='t2.micro',
    KeyName=KEY_PAIR_NAME,
    TagSpecifications=[
        {
            'ResourceType': 'instance',
            'Tags': [
                {
                    'Key': 'Name',
                    'Value': 'my-ec2-instance'
                },
            ]
        },
    ]
)

for instance in instances:
    print(f'EC2 instance "{instance.id}" has been launched')
    
    instance.wait_until_running()
    print(f'EC2 instance "{instance.id}" has been started')

The create_instances() method returns a list of launched instances. You can use the fol-loop to walk through the instances and wait till every instance is up and running if you need to (the wait_until_running() method).

Here’s an execution output:

6. Working with EC2 Instances using Boto3 in Python - Creating EC2 instance

Listing EC2 Instances

The best way to list all EC2 instances is to use the all() method from the instances collection of the EC2 resource.

Then you can use for-loop to iterate through the returned list of instances to get the information about Instance ID (id), Platform (platform), Instance Type (instance_type), Public IP (public_ip_address), Image (image.id) and many others by accessing instance object attributes.

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)

instances = EC2_RESOURCE.instances.all()

for instance in instances:
    print(f'EC2 instance {instance.id}" information:')
    print(f'Instance state: {instance.state["Name"]}')
    print(f'Instance AMI: {instance.image.id}')
    print(f'Instance platform: {instance.platform}')
    print(f'Instance type: "{instance.instance_type}')
    print(f'Piblic IPv4 address: {instance.public_ip_address}')
    print('-'*60)

The screenshot below shows the resulting sample output from running the script.

7. Working with EC2 Instances using Boto3 in Python - Listing all EC2 instances

Filtering EC2 instances

Filtering EC2 allows you to get a list of EC2 instances based on specified conditions. For example, you can get specific instance information by instance type, a list of instances based on Tags, instance state, and many other conditions.

Filtering EC2 instances by state

To filter by state, you can use the filter() method in the instances collection of the EC2 resource.

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
INSTANCE_STATE = 'running'

instances = EC2_RESOURCE.instances.filter(
    Filters=[
        {
            'Name': 'instance-state-name',
            'Values': [
                INSTANCE_STATE
            ]
        }
    ]
)

print(f'Instances in state "{INSTANCE_STATE}":')

for instance in instances:
    print(f'  - Instance ID: {instance.id}')

Here’s an execution output:

8. Working with EC2 Instances using Boto3 in Python - Filtering EC2 instances by state

Filtering EC2 instances by type

To filter EC2 instances by type, you can use the filter() method in the instances collection of the EC2 resource:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
INSTANCE_TYPE = 't2.micro'

instances = EC2_RESOURCE.instances.filter(
    Filters=[
        {
            'Name': 'instance-type',
            'Values': [
                INSTANCE_TYPE
            ]
        }
    ]
)

print(f'Instances of type "{INSTANCE_TYPE}":')

for instance in instances:
    print(f'  - Instance ID: {instance.id}')

Here’s an execution output:

9. Working with EC2 Instances using Boto3 in Python - Filtering EC2 instances by type

Filtering EC2 instances by Tag

To filter EC2 instances by type, you can use the filter() method in the instances collection of the EC2 resource:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
INSTANCE_NAME_TAG_VALUE = 'my-ec2-instance'

instances = EC2_RESOURCE.instances.filter(
    Filters=[
        {
            'Name': 'tag:Name',
            'Values': [
                INSTANCE_NAME_TAG_VALUE
            ]
        }
    ]
)

print(f'Instances with Tag "Name={INSTANCE_NAME_TAG_VALUE}":')

for instance in instances:
    print(f'  - Instance ID: {instance.id}')

Here’s an execution output:

10. Working with EC2 Instances using Boto3 in Python - Filtering EC2 instances by Tag

Filtering EC2 instances by instance ID

To filter EC2 instances by Instance ID, you can use the filter() method in the instances collection of the EC2 resource:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
INSTANCE_ID = 'i-020b3f1914105320d'

instances = EC2_RESOURCE.instances.filter(
    InstanceIds=[
        INSTANCE_ID,
    ],
)

for instance in instances:
    print(f'Instance {instance.id} state is {instance.state["Name"]}')

Here’s an execution output:

11. Working with EC2 Instances using Boto3 in Python - Filtering EC2 instances by Instance ID

Describing EC2 instance properties

To access the EC2 instance properties, you can use the describe_instances() method of the EC2 client (gets all properties in the Python dictionary format), or you can use the EC2.Instance class’ attributes (provides access to a specific attribute) of the EC2 resource.

Describing all EC2 instance properties

The describe_instances() method accepts the Filters and InstanceIds attributes that allow you to find specific instances.

#!/usr/bin/env python3

import json
from datetime import date, datetime
import boto3

AWS_REGION = "us-east-2"
EC2_CLIENT = boto3.client('ec2', region_name=AWS_REGION)
INSTANCE_ID = 'i-020b3f1914105320d'


# Helper method to serialize datetime fields
def json_datetime_serializer(obj):
    if isinstance(obj, (datetime, date)):
        return obj.isoformat()
    raise TypeError ("Type %s not serializable" % type(obj))


response = EC2_CLIENT.describe_instances(
    InstanceIds=[
        INSTANCE_ID,
    ],
)

print(f'Instance {INSTANCE_ID} attributes:')

for reservation in response['Reservations']:
    print(json.dumps(
            reservation,
            indent=4,
            default=json_datetime_serializer
        )
    )

Here’s an execution output:

12. Working with EC2 Instances using Boto3 in Python - Describing all EC2 instance properties

Listing EC2 instance EBS volumes

To get EC2 instance EBS volumes, you can use the block_device_mappings list of the EC2.Instance resource:

#!/usr/bin/env python3

import boto3

AWS_REGION = 'us-east-2'
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
INSTANCE_ID = 'i-020b3f1914105320d'

instance = EC2_RESOURCE.Instance(INSTANCE_ID)

device_mappings = instance.block_device_mappings

print(f'Volumes attached to the EC2 instance "{INSTANCE_ID}":')

for device in device_mappings:
    print(f"  - Volume {device['Ebs']['VolumeId']} attached as {device['DeviceName']}")

For additional information on working with EBS volumes, check out the Working with EBS volumes in Python using the Boto3 article.

Here’s an execution output:

13. Working with EC2 Instances using Boto3 in Python - Listing EC2 instance EBS volumes

Getting EC2 instance state

To get the EC2 instance state, you can use the state list of the EC2.Instance resource:

#!/usr/bin/env python3

import boto3

AWS_REGION = 'us-east-2'
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
INSTANCE_ID = 'i-020b3f1914105320d'

instance = EC2_RESOURCE.Instance(INSTANCE_ID)

print(f'EC2 instance "{INSTANCE_ID}" state: {instance.state["Name"]}')

If you’d like to get a state of multiple EC2 instances, here’s an example of using the filter() method.

14. Working with EC2 Instances using Boto3 in Python - Getting EC2 instance state

Managing EC2 instance Tags

Tags allow you to group your resources according to your organization and project structure, and they usually help organize resources in groups for management or billing reporting purposes.

Adding Tags to EC2 instance

To add Tags to EC2 instances, you can use the create_tags() method of the EC2.Instance resource:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
INSTANCE_ID = 'i-020b3f1914105320d'

TAGS = [
    {
        'Key': 'Environment',
        'Value': 'dev'
    }
]

instances = EC2_RESOURCE.instances.filter(
    InstanceIds=[
        INSTANCE_ID,
    ],
)

for instance in instances:
    instance.create_tags(Tags=TAGS)
    print(f'Tags successfully added to the instance {instance.id}')

Here’s an execution output:

15. Working with EC2 Instances using Boto3 in Python - Adding Tags to EC2 instance

Listing EC2 instance Tags

To list all tags that are associated with the EC2 instances, you can use a for loop to iterate through the list of instance.tags (EC2 resource):

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
INSTANCE_ID = 'i-020b3f1914105320d'

instances = EC2_RESOURCE.instances.filter(
    InstanceIds=[
        INSTANCE_ID,
    ],
)

for instance in instances:
    print(f'EC2 instance {instance.id} tags:')

    if len(instance.tags) > 0:
        for tag in instance.tags:
            print(f'  - Tag: {tag["Key"]}={tag["Value"]}')
    else:
        print(f'  - No Tags')

    print('-'*60)

Here’s an execution output:

16. Working with EC2 Instances using Boto3 in Python - Listing EC2 instance Tags

Updating EC2 instance Tags

To update Tags of EC2 instances, you can use the create_tags() method of the EC2.Instance resource that not only creates but also overrides Tags (previous example)

Deleting EC2 instance Tags

To delete Tags from EC2 instances, you can use the delete_tags() method of the EC2.Instance resource.

Note: you can delete the EC2 instance Tag based on its Key (required) and optional Value. If you specify a Tag Key without a Tag Value, the delete_tags() method will delete any Tag with the specified Key regardless of its value. If you specify a Tag Key with the Value that equals an empty string, the delete_tags() method will delete the Tag only if its value is an empty string.

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
INSTANCE_ID = 'i-020b3f1914105320d'

TAGS = [
    {
        'Key': 'Environment',
        'Value': 'dev'
    }
]

instances = EC2_RESOURCE.instances.filter(
    InstanceIds=[
        INSTANCE_ID,
    ],
)

for instance in instances:
    instance.delete_tags(Tags=TAGS)
    print(f'Tags successfully deleted from the instance {instance.id}')

Here’s an execution output:

17. Working with EC2 Instances using Boto3 in Python - Deleting EC2 instance Tags

EC2 instance advanced monitoring

To enable advanced monitoring for the EC2 Instance, use the monitor() method to turn the monitoring on and the unmonitor() method to turn the monitoring off (EC2 resource):

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
INSTANCE_ID = 'i-020b3f1914105320d'

instances = EC2_RESOURCE.instances.filter(
    InstanceIds=[
        INSTANCE_ID,
    ],
)

for instance in instances:
    monitoring_state = instance.monitoring['State']

    if monitoring_state == 'enabled':
        instance.unmonitor()
    else:
        instance.monitor()

    print(f'Instance monitoring: {monitoring_state}')

Here’s an execution output:

18. Working with EC2 Instances using Boto3 in Python - Enable and disable Advanced monitoring

Managing EC2 instance state

In this section of the article, we’ll cover the basic method allowing to manage EC2 instance state: start(), stop(), reboot(), and terminate().

Starting EC2 instance

To start up instances, you can use the start() method of the EC2.Instance object:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
INSTANCE_ID = 'i-020b3f1914105320d'

instance = EC2_RESOURCE.Instance(INSTANCE_ID)

instance.start()

print(f'Starting EC2 instance: {instance.id}')
    
instance.wait_until_running()

print(f'EC2 instance "{instance.id}" has been started')

The wait_until_running() waiter method allows you to wait till the EC2 instance is up and running.

20. Working with EC2 Instances using Boto3 in Python - Start EC2 instance

Stopping EC2 instance

To stop instances, you can use the stop() method of the EC2.Instance object:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
INSTANCE_ID = 'i-020b3f1914105320d'

instance = EC2_RESOURCE.Instance(INSTANCE_ID)

instance.stop()

print(f'Stopping EC2 instance: {instance.id}')
    
instance.wait_until_stopped()

print(f'EC2 instance "{instance.id}" has been stopped')

The wait_until_stopped() waiter method allows you to wait till the EC2 instance is completely stopped.

19. Working with EC2 Instances using Boto3 in Python - Stop EC2 instance

Rebooting EC2 instance

To stop instances, you can use the reboot() method of the EC2.Instance object:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
INSTANCE_ID = 'i-020b3f1914105320d'

instance = EC2_RESOURCE.Instance(INSTANCE_ID)

instance.reboot()

print(f'EC2 instance "{instance.id}" has been rebooted')

Here’s an execution output:

21. Working with EC2 Instances using Boto3 in Python - Reboot EC2 instance

Terminating EC2 instance

To terminate the EC2 instance, you can use the terminate() method of the EC2.Instance object:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
INSTANCE_ID = 'i-020b3f1914105320d'

instance = EC2_RESOURCE.Instance(INSTANCE_ID)

instance.terminate()

print(f'Terminating EC2 instance: {instance.id}')
    
instance.wait_until_terminated()

print(f'EC2 instance "{instance.id}" has been terminated')

The wait_until_terminated() waiter method allows you to wait till the EC2 instance is completely terminated.

22. Working with EC2 Instances using Boto3 in Python - Terminate EC2 instance

Modifying EC2 instance attributes using Boto3

To change EC2 instance attributes, you can use the modify_attribute() method of the EC2 resource.

Note: You can specify only one attribute at a time. In addition, some attribute changes require the instance to be in a stopped state at the time of the change.

Changing EC2 instance type

To modify the EC2 instance type, you can use the modify_attribute() method of the EC2 client:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
INSTANCE_ID = 'i-04091b10d2cdc86aa'

instance = EC2_RESOURCE.Instance(INSTANCE_ID)

instance.stop()
instance.wait_until_stopped()

instance.modify_attribute(
    InstanceType={
        'Value': 't2.small'
    }
)

instance.start()
instance.wait_until_running()

print(f'Instance type has been successfully changed')

Here’s an execution output:

23. Working with EC2 Instances using Boto3 in Python - Changing EC2 instance type

How to manage SSH keys using Boto3?

Before creating an EC2 instance using Boto3, you have to set up an SSH key in your account. You must have an SSH key during the EC2 instance launch if you’re not using AWS Systems Manager and are willing to have remote access to your EC2 instance. In addition to that, you’ll need an SSH key to get the Windows EC2 instance password.

You can create an SSH key manually using AWS Web Console or automatically by using the Boto3 library. This section of the article will describe how to use the Boto3 library to manage SSH keys.

For more information about SSH keys, we recommend you look at the Top 10 SSH Features You MUST Know To Be More Productive article.

Creating SSH key

To create an SSH key pair, you have to use the create_key_pair() method of the EC2 resource. This method will generate a new SSH key pair and let you save the private SSH key.

Note: please, pay attention that if you don’t save your private SSH key returned by the create_key_pair() method, you’ll have to generate a new SSH key because AWS does not store your private SSH key.

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)

key_pair = EC2_RESOURCE.create_key_pair(
    KeyName='my-ssh-key-pair',
    TagSpecifications=[
        {
            'ResourceType': 'key-pair',
            'Tags': [
                {
                    'Key': 'Name',
                    'Value': 'my-ssh-key-pair'
                },
            ]
        },
    ]
)

print(f'SSH key fingerprint: {key_pair.key_fingerprint}')
print(f'Private SSH key: {key_pair.key_material}')

Here’s an execution output:

1. Working with EC2 Instances using Boto3 in Python - Generating SSH Key pair using Boto3 client

Listing SSH keys

To list all SSH keys using Boto3, you need to use the all() method of the key_pairs collection of the EC2 resource and the for-loop. The most useful properties of the returned KeyPairInfo object are:

  • key_name
  • key_fingerprint
  • tags
#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)

key_pairs = EC2_RESOURCE.key_pairs.all()

for key in key_pairs:
    print(f'SSH key "{key.key_name}" fingerprint: {key.key_fingerprint}')

Here’s an example output:

2. Working with EC2 Instances using Boto3 in Python - Listing SSH keys

Searching for SSH keys

The key_pairs collection of the EC2 resource allows you to use the filter() method to search for specific SSH keys by key id, name, or tag.

Searching for SSH key by name

Here’s an example of filtering SSH key by its name:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)

key_pairs = EC2_RESOURCE.key_pairs.filter(
    KeyNames=[
        'my-ssh-key-pair',
    ],
)

for key in key_pairs:
    print(f'SSH key "{key.key_name}" fingerprint: {key.key_fingerprint}')

Here’s an execution output:

3. Working with EC2 Instances using Boto3 in Python - Searching for SSH key by name

Searching for SSH key by tag

Here’s an example of filtering SSH key by the tag (you may specify as many tags as you’d like):

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)

key_pairs = EC2_RESOURCE.key_pairs.filter(
    Filters=[
        {
            'Name': 'tag:Name',
            'Values': [
                'my-ssh-key-pair',
            ]
        },
    ],
)

for key in key_pairs:
    print(f'SSH key "{key.key_name}" fingerprint: {key.key_fingerprint}')

Here’s an execution output:

4. Working with EC2 Instances using Boto3 in Python - Searching for SSH key by Tag

Deleting SSH key

To delete an SSH key pair, you have to use the delete() method of the KeyPair class of the EC2 resource:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
KEY_PAIR_NAME = 'my-ssh-key-pair'

key_pair = EC2_RESOURCE.KeyPair(KEY_PAIR_NAME)
key_pair.delete()

print(f'SSH key "{KEY_PAIR_NAME}" successfully deleted')

Here’s an execution output:

5. Working with EC2 Instances using Boto3 in Python - Deleting SSH key

Managing Security Groups using Boto3

Security groups control inbound and outbound traffic of the EC2 instance network interface. Each Security Group consists of one or many Security Group Rules. This section of the article will cover how to manage Security Groups and use them with EC2 instances.

Note: every EC2 instance must have at least one Security Group associated with it. If no Security Group has been specified during the EC2 instance launch, the default Security Group of the default VPC is associated with the instance.

Creating a Security Group

To define a Security Group, you can use the create_security_group() of the EC2 resource. To control inbound and outbound traffic, the authorize_ingress() and the authorize_egress() methods are used:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
VPC_ID = 'vpc-4b43de20'

security_group = EC2_RESOURCE.create_security_group(
    Description='Allow inbound SSH traffic',
    GroupName='allow-inbound-ssh',
    VpcId=VPC_ID,
    TagSpecifications=[
        {
            'ResourceType': 'security-group',
            'Tags': [
                {
                    'Key': 'Name',
                    'Value': 'allow-inbound-ssh'
                },
            ]
        },
    ],
)

security_group.authorize_ingress(
    CidrIp='0.0.0.0/0',
    FromPort=22,
    ToPort=22,
    IpProtocol='tcp',
)

print(f'Security Group {security_group.id} has been created')

Here’s an execution output:

24. Working with EC2 Instances using Boto3 in Python - Creating a Security Group

Listing all Security Groups

To list all Security Groups, you can use the all() method of the security_groups collection of the EC2 resource:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)

security_groups = EC2_RESOURCE.security_groups.all()

print('Security Groups:')
for security_group in security_groups:
    print(f'  - Security Group {security_group.id}')

Here’s an execution output:

25. Working with EC2 Instances using Boto3 in Python - Listing all Security Groups

Searching Security Groups

To find Security Groups by specified conditions, you can use the filter() method of the security_groups collection of the EC2 resource.

Searching Security Groups by ID

To find Security Groups by the Security Group ID, you can use the filter() method of the security_groups collection of the EC2 resource:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
SECURITY_GROUP_ID = 'sg-0e0fe09d642656bf3'

security_groups = EC2_RESOURCE.security_groups.filter(
    GroupIds=[
        SECURITY_GROUP_ID
    ]
)

for security_group in security_groups:
    print(f'Security Group {security_group.id} description: {security_group.description}')

Here’s an execution output:

26. Working with EC2 Instances using Boto3 in Python - Searching Security Groups by ID

Searching Security Groups by Tag

To find Security Groups by the Tag, you can use the filter() method of the security_groups collection of the EC2 resource:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
SECURITY_GROUP_ID = 'sg-0e0fe09d642656bf3'

security_groups = EC2_RESOURCE.security_groups.filter(
    Filters=[
        {
            'Name': 'tag:Name',
            'Values': [
                'allow-inbound-ssh',
            ]
        },
    ],
)

for security_group in security_groups:
    print(f'Security Group {security_group.id} description: {security_group.description}')

Here’s an execution output:

27. Working with EC2 Instances using Boto3 in Python - Searching Security Groups by Tag

Describing Security Groups

To list all Security Group’s properties, you can use the describe_security_groups() method that supports the same search attributes as the filter() method of the EC2 resource:

#!/usr/bin/env python3

import json
import boto3

AWS_REGION = "us-east-2"
EC2_CLIENT = boto3.client('ec2', region_name=AWS_REGION)
SECURITY_GROUP_ID = 'sg-0e0fe09d642656bf3'

response = EC2_CLIENT.describe_security_groups(
    GroupIds=[
        SECURITY_GROUP_ID,
    ],
)

print(f'Security Group {SECURITY_GROUP_ID} attributes:')

for security_group in response['SecurityGroups']:
    print(json.dumps(
            security_group,
            indent=4
        )
    )

Here’s an execution output:

28. Working with EC2 Instances using Boto3 in Python - Describing Security Groups

Deleting Security Groups

To delete a Security Group, you can use the delete() method of the SecurityGroup class of the EC2 resource:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
SECURITY_GROUP_ID = 'sg-0e0fe09d642656bf3'

security_group = EC2_RESOURCE.SecurityGroup(SECURITY_GROUP_ID)

security_group.delete()

print(f'Security Group {SECURITY_GROUP_ID} has been deleted')

Here’s an execution output:

29. Working with EC2 Instances using Boto3 in Python - Deleting Security Groups

Attaching Security Groups to the EC2 Instance

To attach Security Groups to the EC2 instance, you need to use the modify_attribute() method of the EC2.Instance class of the EC2 resource:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
SECURITY_GROUP_ID = 'sg-084dfa143cc85a5cf'
INSTANCE_ID = 'i-04091b10d2cdc86aa'

instance = EC2_RESOURCE.Instance(INSTANCE_ID)

instance.modify_attribute(
    Groups=[
        SECURITY_GROUP_ID
    ]
)

print(f'Security Group {SECURITY_GROUP_ID} has been attached to EC2 instance {INSTANCE_ID}')

Here’s an execution output:

30. Working with EC2 Instances using Boto3 in Python - Attaching Security Groups to EC2 instance

Listing EC2 instance Security Groups

To list EC2 instance Security Groups, you can use the security_groups attribute of the EC2.Instance class of the EC2 resource:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
INSTANCE_ID = 'i-04091b10d2cdc86aa'

instance = EC2_RESOURCE.Instance(INSTANCE_ID)

print(f'Instance {INSTANCE_ID} Security Groups:')

for security_group in instance.security_groups:
    print(f'  - Security Group {security_group["GroupId"]}')

Here’s an execution output:

31. Working with EC2 Instances using Boto3 in Python - List EC2 instance Security Groups

Detaching Security Group from the EC2 Instance

There’s no specific API call to detach the Security Group from the EC2 instance. To detach a Security Group from the EC2 Instance, you need to get all instance Security Groups as a list, remove the required Security Group from the list, and overrise the Groups EC2 instance attribute.

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
INSTANCE_ID = 'i-04091b10d2cdc86aa'
SECURITY_GROUP_ID = 'sg-6dbc5f1b'

instance = EC2_RESOURCE.Instance(INSTANCE_ID)

instance_sgs = [
    sg['GroupId'] for sg in instance.security_groups
]

if SECURITY_GROUP_ID in instance_sgs:
    instance_sgs.remove(SECURITY_GROUP_ID)

instance.modify_attribute(
    Groups=instance_sgs
)

print(f'Security Group {SECURITY_GROUP_ID} has been detached from the instance {INSTANCE_ID}')

Here’s an execution output:

32. Working with EC2 Instances using Boto3 in Python - Detach Security Group from the EC2 instance

How to manage Elastic IP addresses using Boto3?

The Elastic IP is a public IP address provided by AWS that doesn’t change when you start or stop the EC2 instance. In addition to that, the Elastic IP address can be attached or detached from the EC2 instance at any moment. By default, each AWS Account can allocate a maximum of five Elastic IP addresses.

Allocating Elastic IP address

To allocate an Elastic IP address for your AWS account, you can use the allocate_address() method of the EC2 client:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_CLIENT = boto3.client('ec2', region_name=AWS_REGION)

allocation = EC2_CLIENT.allocate_address(
    Domain='vpc',
    TagSpecifications=[
        {
            'ResourceType': 'elastic-ip',
            'Tags': [
                {
                    'Key': 'Name',
                    'Value': 'my-elastic-ip'
                },
            ]
        },
    ]
)

print(f'Allocation ID {allocation["AllocationId"]}')
print(f'  - Elastic IP {allocation["PublicIp"]} has been allocated')

Here’s an execution output:

33. Working with EC2 Instances using Boto3 in Python - Allocate EIP

Listing and describing Elastic IP addresses

To list and describe Elastic IP addresses, you can use the descibe_addresses() method of the EC2 client:

#!/usr/bin/env python3

import json
import boto3

AWS_REGION = "us-east-2"
EC2_CLIENT = boto3.client('ec2', region_name=AWS_REGION)

response = EC2_CLIENT.describe_addresses(
    Filters=[
        {
            'Name': 'tag:Name',
            'Values': ['my-elastic-ip']
        }
    ]
)

print('EIP attributes:')

for address in response['Addresses']:
    print(json.dumps(address, indent=4))

Here’s an execution output:

34. Working with EC2 Instances using Boto3 in Python - Describe EIP

Attaching an Elastic IP to an EC2 Instance

To associate an Elastic IP address with an EC2 Instance, you can use the associate_address() method of the EC2 client:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_CLIENT = boto3.client('ec2', region_name=AWS_REGION)
INSTANCE_ID = 'i-04091b10d2cdc86aa'

response = EC2_CLIENT.describe_addresses(
    Filters=[
        {
            'Name': 'tag:Name',
            'Values': ['my-elastic-ip']
        }
    ]
)

public_ip = response['Addresses'][0]['PublicIp']
allocation_id = response['Addresses'][0]['AllocationId']

response = EC2_CLIENT.associate_address(
    InstanceId=INSTANCE_ID,
    AllocationId=allocation_id
)

print(f'EIP {public_ip} associated with the instance {INSTANCE_ID}')

Here’s an execution output:

35. Working with EC2 Instances using Boto3 in Python - Associate EIP

Detaching an Elastic IP address from an EC2 instance

To disassociate (detach) an Elastic IP address from the EC2 instance, you need to use the disassociate_address() method of the EC2 client. The disassociate_address() method requires the AssociationId argument, which you can find by processing the list of the EC2 instance network interfaces:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_CLIENT = boto3.client('ec2', region_name=AWS_REGION)
EC2_RESOURCE = boto3.resource('ec2', region_name=AWS_REGION)
INSTANCE_ID = 'i-04091b10d2cdc86aa'

instance = EC2_RESOURCE.Instance(INSTANCE_ID)

response = EC2_CLIENT.describe_addresses(
    Filters=[
        {
            'Name': 'tag:Name',
            'Values': ['my-elastic-ip']
        }
    ]
)

public_ip = response['Addresses'][0]['PublicIp']

for interface in instance.network_interfaces:
    if interface.association:
        if public_ip == interface.association.public_ip:
            EC2_CLIENT.disassociate_address(
                AssociationId=interface.association.id
            )

print(f'EIP {public_ip} diassociated from the instance {INSTANCE_ID}')

Here’s an execution output:

36. Working with EC2 Instances using Boto3 in Python - Disassociate EIP

Releasing the Elastic IP address

To release an Elastic IP address, you can use the release_address() method of the EC2 client:

#!/usr/bin/env python3

import boto3

AWS_REGION = "us-east-2"
EC2_CLIENT = boto3.client('ec2', region_name=AWS_REGION)

response = EC2_CLIENT.describe_addresses(
    Filters=[
        {
            'Name': 'tag:Name',
            'Values': ['my-elastic-ip']
        }
    ]
)

public_ip = response['Addresses'][0]['PublicIp']
allocation_id = response['Addresses'][0]['AllocationId']

EC2_CLIENT.release_address(
    AllocationId=allocation_id
)

print(f'EIP {public_ip} has been released')

Here’s an execution output:

37. Working with EC2 Instances using Boto3 in Python - Release EIP

Summary

In this article, we’ve provided many Python code snippets for creating, starting, stopping, rebooting, filtering, deleting, tagging EC2 Instances using the Boto3. In addition to that, we’ve covered the management of SSH keys, Security Groups, and Elastic IP addresses.

How useful was this post?

Click on a star to rate it!

As you found this post useful...

Follow us on social media!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?

Top rated Udemy Courses to improve you career

Subscribe to our updates

Like this article?

Share on facebook
Share on Facebook
Share on twitter
Share on Twitter
Share on linkedin
Share on Linkdin
Share on pinterest
Share on Pinterest

Want to be an author of another post?

We’re looking for skilled technical authors for our blog!

Leave a comment

If you’d like to ask a question about the code or piece of configuration, feel free to use https://codeshare.io/ or a similar tool as Facebook comments are breaking code formatting.