获取 AWS 实例的最新 AMI ID

Get latest AMI ID for AWS instance

我想在为自动缩放架构创建 ec2 实例时获取 AWS Linux 机器的最新 ami id。

我正在尝试 aws cli 来获取图像类型,但是如果我使用 describe-images 命令,它会打印出很多信息。

我的要求是只获取图像 ID,以便我可以使用它来创建启动配置或启动具有最新 ami-id 的实例。

AWS CLI

一种过滤输出并仅获取所需属性的方法是使用过滤器的组合,在 aws describe-images 命令上查询,如下所示:

aws ec2 describe-images \ 
--owners 'amazon' \
--filters 'Name=description,Values=Amazon Linux AMI*' \
--query 'sort_by(Images, &CreationDate)[-1].[ImageId]' \
--output 'text'

命令说明:

  • 所有者:对于亚马逊的图片,请使用 'amazon'。要查询您自己的图像,请使用 'self'
  • 过滤器:您可以使用过滤器列表来过滤出您要查找的实例。我更喜欢 description,因为我发现某些图像缺少 name 过滤器。 支持通配符。 More on filters
  • 查询:查询可用于仅过滤输出中需要的内容。您还可以对输出中出现的字段进行排序。我对图像和创建日期进行了排序以获取最后创建的图像并过滤了 ImageId
  • 输出:输出可以是 jsontext,具体取决于您计划使用它的方式。

使用Python

您可以使用以下 python 脚本执行相同的操作:

import boto3
from operator import itemgetter

client = boto3.client('ec2')
response = client.describe_images(
    Filters=[
        {
            'Name': 'description',
            'Values': [
                'Amazon Linux AMI*',
            ]
        },
    ],
    Owners=[
        'amazon'
    ]
)
# Sort on Creation date Desc
image_details = sorted(response['Images'],key=itemgetter('CreationDate'),reverse=True)
ami_id = image_details[0]['ImageId']

更新:

您可以使用细粒度过滤器来获得更快的响应。 @Jack 的回答中提到的过滤器有效。

filters = [ {
    'Name': 'name',
    'Values': ['amzn-ami-hvm-*']
},{
    'Name': 'description',
    'Values': ['Amazon Linux AMI*']
},{
    'Name': 'architecture',
    'Values': ['x86_64']
},{
    'Name': 'owner-alias',
    'Values': ['amazon']
},{
    'Name': 'owner-id',
    'Values': ['137112412989']
},{
    'Name': 'state',
    'Values': ['available']
},{
    'Name': 'root-device-type',
    'Values': ['ebs']
},{
    'Name': 'virtualization-type',
    'Values': ['hvm']
},{
    'Name': 'hypervisor',
    'Values': ['xen']
},{
    'Name': 'image-type',
    'Values': ['machine']
} ]

# Use above filters 
response = client.describe_images(
  Filters=filters,
  Owners=[
      'amazon'
  ]
)

最近一个鲜为人知的功能是 Query for the latest Amazon Linux AMI IDs using AWS Systems Manager Parameter Store | AWS Compute Blog

命名空间由两部分组成:

  • 参数存储前缀(树):/aws/service/ami-amazon-linux-latest/
  • AMI 名称别名:(示例)amzn-ami-hvm-x86_64-gp2

这些:

aws ec2 describe-images --owners amazon --filters "Name=name,Values=amzn*" --query 'sort_by(Images, &CreationDate)[].Name'

Get-EC2ImageByName -Name amzn* | Sort-Object CreationDate | Select-Object Name

可以改成:

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

Get-SSMParameter -Name /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 -region us-east-1

另外,它可以用于 CloudFormation 模板:

# Use public Systems Manager Parameter
 Parameters :
 LatestAmiId :
 Type : 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
 Default: ‘/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2’

Resources :
 Instance :
 Type : 'AWS::EC2::Instance'
 Properties :
 ImageId : !Ref LatestAmiId

我在这里看到了类似的脚本

https://github.com/bwood/latest-ami/blob/master/latest-ami.py

但是由于某些原因,当 运行 时,我收到错误

来自参考:

https://aws.amazon.com/blogs/compute/query-for-the-latest-amazon-linux-ami-ids-using-aws-systems-manager-parameter-store/

具体针对 AWS CloudFormation:

# Use public Systems Manager Parameter
Parameters:
  LatestAmiId:
    Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
    Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'

Resources:
 Instance:
    Type: 'AWS::EC2::Instance'
    Properties:
      ImageId: !Ref LatestAmiId

来自 AWS CLI:

aws ssm get-parameters-by-path --path "/aws/service/ami-amazon-linux-latest" --region us-east-1

Powershell:

Get-SSMParametersByPath -Path "/aws/service/ami-amazon-linux-latest" -region us-east-1

Vaulstein 和 John Rotenstein 的回答帮助我理解了这个解决方案。谢谢!

就我而言,我们有很多由不同所有者发布的私有 AMI(有 2-3 个),并且混合使用 CentOS 或 AmazonLinux2 创建的自定义私有 AMI 作为根据。任务是找到在 x86 架构上运行并基于 AmazonLinux2.

的最新 AMI

请注意,我没有使用 --owner,因为在我的例子中,AMI 由不同的团队发布并且具有不同的所有者 ID。但是,如果您有一个发布这些内容的 owner/team,则建议包含此选项以过滤掉您不想要的所有其他 AMI。

这对我们有用:

aws ec2 describe-images \
--query 'sort_by(Images, &CreationDate)[-1].Name' \
--region eu-west-1 \
--no-include-deprecated \
--executable-users self \
--output text \
--filters "Name=name,Values=here-ami-amzn2-*" \
    "Name=architecture,Values=x86_64" \
    "Name=image-type,Values=machine" \
    "Name=state,Values=available" \
    "Name=virtualization-type,Values=hvm" \
    "Name=root-device-type,Values=ebs" 

解释: 我们在这里做的是:

这会得到按 CreationDate 排序的结果。我们正在从结果中获取 -1 (last/latest) 项的名称。

--query 'sort_by(Images, &CreationDate)[-1].Name'

请注意,可用的 AMI 可能因地区而异,因此请务必指定您打算实例化它的地区。

--region eu-west-1 \

避免弃用 AMI(如果有)。我们没有,但决定未来安全。

--no-include-deprecated \

确保获取的 AMI 确实可供您使用。

--executable-users self \

这是可选的。如果是文本,则返回不带双引号的 AMI 名称

--output text \

过滤器用于缩小结果范围并排除不需要的结果。幸运的是,我们的组织以一种易于区分 AMI 名称中的 wither amzn2 或 CentOS 的方式命名了 AMI。我们想要亚马逊 Linux 2 AMI

--filters "Name=name,Values=org-name-ami-amzn2-*" \

我们有 ARM 和 x86_64 版本的 AMI,我团队的代码只在 X86_64 上测试过。所以选择那个:

"Name=architecture,Values=x86_64" \

这可能有不同的值,我认为对于大多数人来说这将是机器

"Name=image-type,Values=machine" \

仅选择处于可用状态的 AMI:

"Name=state,Values=available" \

这就是虚拟化的实现方式。大多数人可以放心选择hvm:

"Name=virtualization-type,Values=hvm" \

选择根卷为 EBS 的 AMI

"Name=root-device-type,Values=ebs"