获取 AWS 实例最新的 AMI ID

8

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

我尝试使用aws cli获取镜像类型,但如果我使用describe-images命令,它会打印出大量信息。

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


您希望通过AWS命令行界面(CLI)、编程语言或CloudFormation模板来完成吗?(答案将根据情况而异。) - John Rotenstein
@JohnRotenstein AWS cli或者使用Python是首选的方法。您能否在答案中添加如何从Cloudformation模板中执行此操作的说明? - Vaulstein
6个回答

24
最近推出的一个鲜为人知的功能是使用AWS Systems Manager参数存储库查询最新的Amazon Linux AMI ID | 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

同一图像类型的连续迭代中,AMI名称别名是否保持不变? - Vaulstein
1
对于参数存储,它是起作用的。对于 describe-images 方法,完整名称包括版本,因此使用通配符 * 来避免指定特定版本。 - John Rotenstein
1
@EricXinZhang 是的,gp2是Amazon EBS的一种卷类型。我认为它已经包含在AMI标识符中,以区分它与基于Instance Store支持的AMI,后者从临时Instance Store磁盘引导(这不是Amazon EBS)。 - John Rotenstein
@JohnRotenstein 鉴于这似乎是一个未记录的功能,我不清楚查询何时完成?在我的情况下,我有一个包含ASG和启动模板的CloudFormation模板,其中ImageId是一个查询路径,创建了几个月。而且启动模板具有特定的旧ami-0...镜像ID,因此每个新的EC2实例都将使用该固定AMI。更新CloudFormation模板可能什么也做不了,因为模板及其参数没有更改。那么如何触发基于最新AMI查询结果创建EC2实例的过程呢? - MarnixKlooster ReinstateMonica
@MarnixKloosterReinstateMonica 更新现有的堆栈可能无法正常工作,因为启动模板无法修改--相反,它们需要复制到新模板中,并修改ASG以使用该新模板。这可能超出了CloudFormation在“更新”操作期间的能力范围。此外,该值将在首次部署堆栈时提取,因此它可能不会随时间而改变。但是,对于新部署的堆栈,它确实可以完美地工作。 - John Rotenstein
显示剩余3条评论

11

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'

命令说明:

  • owners:对于Amazon的图像,请使用'Amazon'。要查询自己的图像,请使用“self”
  • filters:您可以使用一系列过滤器来过滤出所需查询的实例。我更喜欢描述,因为我发现有些图像缺少名称过滤器。 支持通配符。有关过滤器的更多信息
  • query:查询可用于仅过滤输出中所需的内容。您还可以按输出中存在的字段对其进行排序。我已对图像和创建日期进行了排序,以获取最近创建的图像并过滤掉ImageId
  • output:输出可以是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'
  ]
)

2

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

在我的情况下,我们有很多不同所有者(大约有2-3个)发布的私有AMI,其中混合了以CentOS或AmazonLinux2为基础创建的自定义私有AMI。任务是找到适用于x86架构且基于AmazonLinux2的最新AMI。

请注意,我没有使用--owner,因为在我的情况下,AMI由不同的团队发布,并且具有不同的Owner ID。但是,如果您有单个所有者/团队发布这些内容,则建议包括此选项以过滤掉所有其他不需要的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对结果进行排序。我们从结果中获取最后一个/最新的项目名称。

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

请注意,可用的 AMI 可能因地区而异,请务必指定您打算实例化它的区域。
--region eu-west-1 \

为避免使用过时的 AMI,我们决定采用更为安全的方法。虽然目前尚未出现此类情况,但我们仍希望未来能够更加稳妥。请保留 HTML 标签。
--no-include-deprecated \

为确保您获取的AMI实际可用,请执行以下操作。
--executable-users self \

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

--output text \

过滤器用于缩小结果范围和排除不需要的结果。幸运的是,我们的组织已经以易于区分amzn2或CentOS的方式命名了AMI名称。我们想要的是Amazon 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" 

2

来自Ref:

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

特别针对AWS CloudFormation:

该文章介绍了如何使用AWS Systems Manager Parameter Store查询最新的Amazon Linux AMI ID。在AWS CloudFormation中,可以使用该方法获取AMI ID并将其用于创建EC2实例。
# 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

1

是的,它的工作方式类似于我回答中的Python脚本。@Jack 在stackoverflow上,当您发布答案时,需要解释其中的操作。代码应该能够无错误运行。否则其他人会对您的答案进行负评。 - Vaulstein
抱歉,我已经为此创建了一个新的线程 https://stackoverflow.com/questions/51630229/latest-ami-id-in-a-given-region-using-a-set-of-filters - Jack
@Vaulstein,您能否请看一下latest-ami,并指导我可能出了什么问题? - Jack

0
您可以使用 Terraform 中的筛选选项获取最新的亚马逊 AMI 镜像2023年。
data "aws_ami" "base_ami" {
  most_recent      = true
  owners           = ["amazon"]

  filter {
    name   = "name"
    values = ["al2023-ami-2023.*-x86_64"]
  }

  filter {
    name   = "architecture"
    values = ["x86_64"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

}

*架构刚刚添加了额外的内容

resource "aws_instance" "ec2_instance" {

    ami = data.aws_ami.base_ami.id
    count = "1"
    subnet_id = "<your subnet>"
    instance_type = "<instance type>"
    key_name = "<private_key>"

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接