Sean Goldfarb
Sean Goldfarb

Reputation: 400

How to get free-tier AMI in AWS using python with boto3

I'm trying to build a function in python that creates a new ec2 instance in a specific region. For the function to work I need to specify the AMI of this new instance. The problem is that the same AMI (for example Amazon Linux) has a different id in different regions and I can't use an image of one region in another region instance.

and I can't understand how do I get this AMI id in this specific region

def create_instance(region):
        ec2 = boto3.resource('ec2', region)
        instances = ec2.create_instances(InstanceType='t2.micro',
                                         MinCount=1, MaxCount=1,
                                         ImageId='AMI-id') # What do I put here?

For now, it's not really important what the AMI is besides the fact that it is Linux and free-tier, So maybe searching a specific known free-tier Linux AMI will work.

I know you can get all AMI using describe_images() function but how do I filter only those that are Linux (Could be a specific version) and free-tier

boto3.client('ec2').describe_images(Filters["""What do I write here to get only linux free-tier AMI"""])

Upvotes: 1

Views: 1738

Answers (3)

adriaanbd
adriaanbd

Reputation: 357

Here's the script I came up with:

import boto3
from typing import Optional, List


def get_ami_ids(names: Optional[List[str]]=None) -> List[str]:
    if names is None:
        names = [
            '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
        ]
    ssm = boto3.client('ssm')
    response = ssm.get_parameters(Names=names)
    metadata: dict = response['ResponseMetadata']
    if metadata['HTTPStatusCode'] == 200:
        params: List[dict] = response['Parameters']
        amis: List[str] = [p.get('Value') for p in params]

    return amis

print(get_ami_ids())

This should give you a list of AMI id's if there are any in the response. However, I don't see where to specify the AWS Region like the AWS CLI equivalent in the answer provided by anton.

Upvotes: 0

r0ck
r0ck

Reputation: 192

Sean, Try this...

ec2_client= session.client('ec2', region_name=region_name)
print(f'***region_name: {region_name}')
response= ec2_client.describe_instance_types(  
#InstanceTypes=['t2.micro']
Filters=[
    {
        'Name': 'free-tier-eligible',
        'Values': ['true']
        }
    ]
) 
#pprint(response['InstanceTypes'][0]['InstanceType'])

instance_type= response['InstanceTypes'][0]['InstanceType']
response= ec2_client.describe_images(
   Filters=[{'Name': 'name', 'Values': [instance_type]},]   
)
#pprint(response)

for image in response['Images']:
     print(image['ImageId'])

 Result:**************************************
 ***region_name: ap-south-1
 ami-0e84c461
 ami-1154187e
 ami-2f0e7540
 ami-4d8aca22
 ami-50aeed3f
 ami-77a4e718
 ami-cce794a3

Hope it helps...
r0ck

Upvotes: 1

Anton
Anton

Reputation: 4052

AWS System Manager maintains the curated list of AWS Linux 2 AMIs at /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

Here is the CLI call:

$ aws ssm get-parameters --names /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 --region us-east-1

{
    "Parameters": [
        {
            "Name": "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2",
            "Type": "String",
            "Value": "ami-0323c3dd2da7fb37d",
            "Version": 27,
            "LastModifiedDate": 1586395100.713,
            "ARN": "arn:aws:ssm:us-east-1::parameter/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
        }
    ],
    "InvalidParameters": []
}

You should be able to do the same in Python with SSM BOTO3 API.

Upvotes: 3

Related Questions