在CLI和CloudFormation中使用最新AMI

一、背景

在CloudFormation中,如果采用hardcode方式嵌入了当前的AMI ID,那么在未来一段时间AMI版本升级后,旧的版本就会过期,导致新创建的环境都必须再次运行yum update进行版本升级。同时,当AMI版本达到一定时间后,因为版本较旧存在安全隐患,可能会下架无法调用,这时候CloudFormation就失效了不能在运行。由此,需要一个在CloudFormation中能使用调用到最新AMI的办法。

本文将分别介绍在AWS CLI下调用最新AMI ID和在CloudFormation中调用System Manager查询的方法。

二、在AWS CLI中获取最新的AMI ID

首先安装并配置AWS CLI,设置了正确的Region和Access Key后,可以开始操作。以查询Amazon Linux 2系统为例。

执行如下命令显示所有AMI(注意区分当前CLI调用的Region):

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

返回结果部分节选如下:

    "amzn2-ami-hvm-2.0.20210525.0-arm64-gp2",
  "amzn2-ami-hvm-2.0.20210525.0-x86_64-ebs",
  "amzn2-ami-hvm-2.0.20210525.0-x86_64-gp2",
  "amzn2-ami-hvm-2.0.20210617.0-arm64-gp2",
  "amzn2-ami-hvm-2.0.20210617.0-x86_64-ebs",
  "amzn2-ami-hvm-2.0.20210617.0-x86_64-gp2",
  "amzn2-ami-hvm-2.0.20210701.0-arm64-gp2",
  "amzn2-ami-hvm-2.0.20210701.0-x86_64-ebs",
  "amzn2-ami-hvm-2.0.20210701.0-x86_64-gp2",
  "amzn2-ami-hvm-2.0.20210721.2-arm64-gp2",
  "amzn2-ami-hvm-2.0.20210721.2-x86_64-ebs",
  "amzn2-ami-hvm-2.0.20210721.2-x86_64-gp2",
  "amzn2-ami-hvm-2.0.20210813.1-arm64-gp2",
  "amzn2-ami-hvm-2.0.20210813.1-x86_64-ebs",
  "amzn2-ami-hvm-2.0.20210813.1-x86_64-gp2"

从中可以看到,名为x86_64的是基于Intel Xeon处理器的EC2 AMI,名称带有arm64的是适合Graviton2的AMI。以当前为例,我们将使用 amzn2-ami-hvm-2.0.20210813.1-arm64-gp2 创建EC2。

接下来执行如下命令查询完整的AMI信息。

aws ec2 describe-images --owners amazon --filters "Name=name,Values=amzn2-ami-hvm-2.0.20210813.1-arm64-gp2"

由此将输入完整的AMI信息如下。

{
  "Images": [
      {
          "Architecture": "arm64",
          "CreationDate": "2021-08-25T23:13:09.000Z",
          "ImageId": "ami-0fabc2ef286ed7b51",
          "ImageLocation": "amazon/amzn2-ami-hvm-2.0.20210813.1-arm64-gp2",
          "ImageType": "machine",
          "Public": true,
          "OwnerId": "141808717104",
          "PlatformDetails": "Linux/UNIX",
          "UsageOperation": "RunInstances",
          "State": "available",
          "BlockDeviceMappings": [
              {
                  "DeviceName": "/dev/xvda",
                  "Ebs": {
                      "DeleteOnTermination": true,
                      "SnapshotId": "snap-0d752eb6fbcae0cab",
                      "VolumeSize": 8,
                      "VolumeType": "gp2",
                      "Encrypted": false
                  }
              }
          ],
          "Description": "Amazon Linux 2 LTS Arm64 AMI 2.0.20210813.1 arm64 HVM gp2",
          "EnaSupport": true,
          "Hypervisor": "xen",
          "ImageOwnerAlias": "amazon",
          "Name": "amzn2-ami-hvm-2.0.20210813.1-arm64-gp2",
          "RootDeviceName": "/dev/xvda",
          "RootDeviceType": "ebs",
          "SriovNetSupport": "simple",
          "VirtualizationType": "hvm"
      }
  ]
}

在以上返回信息中,ImageId": "ami-0fabc2ef286ed7b51" 就是在本Region开通Graviton2处理器的EC2所需要的AMI ID。

三、在CloudFormation中调用System Manager获取最新AMI ID

1、查询SSM Path

首先在命令行下获取所有AMI清单。

aws ssm get-parameters-by-path --path "/aws/service/ami-amazon-linux-latest" --query 'Parameters[*].Name' | sort

输出结果如下:

[
  "/aws/service/ami-amazon-linux-latest/amzn-ami-hvm-x86_64-ebs",
  "/aws/service/ami-amazon-linux-latest/amzn-ami-hvm-x86_64-gp2",
  "/aws/service/ami-amazon-linux-latest/amzn-ami-hvm-x86_64-s3",
  "/aws/service/ami-amazon-linux-latest/amzn-ami-minimal-hvm-x86_64-s3",
  "/aws/service/ami-amazon-linux-latest/amzn-ami-pv-x86_64-s3",
  "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-arm64-gp2",
  "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-ebs",
  "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2",
  "/aws/service/ami-amazon-linux-latest/amzn2-ami-kernel-5.10-hvm-x86_64-ebs",
  "/aws/service/ami-amazon-linux-latest/amzn2-ami-minimal-hvm-arm64-ebs",
  "/aws/service/ami-amazon-linux-latest/amzn-ami-minimal-hvm-x86_64-ebs",
  "/aws/service/ami-amazon-linux-latest/amzn-ami-minimal-pv-x86_64-ebs",
  "/aws/service/ami-amazon-linux-latest/amzn-ami-minimal-pv-x86_64-s3",
  "/aws/service/ami-amazon-linux-latest/amzn-ami-pv-x86_64-ebs",
  "/aws/service/ami-amazon-linux-latest/amzn2-ami-kernel-5.10-hvm-arm64-gp2",
  "/aws/service/ami-amazon-linux-latest/amzn2-ami-kernel-5.10-hvm-x86_64-gp2",
  "/aws/service/ami-amazon-linux-latest/amzn2-ami-minimal-hvm-x86_64-ebs"
]

在这个清单中,选择/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-arm64-gp2作为使用Graviton2处理器的EC2的AMI ID。在这个AMI名称中可以看到带有gp2的字样,用这个AMI创建基于gp3的也是可以成功的。

如果需要查询Windows的AMI,命令如下:

aws ssm describe-parameters --parameter-filters "Key=Name, Option=BeginsWith, Values=/aws/service/ami-windows-latest/Windows_Server-2019" --query 'Parameters[*].Name' | sort

返回结果如下:

    "/aws/service/ami-windows-latest/Windows_Server-2019-Chinese_Simplified-Full-Base",
    "/aws/service/ami-windows-latest/Windows_Server-2019-Chinese_Traditional-Full-Base",
    "/aws/service/ami-windows-latest/Windows_Server-2019-Czech-Full-Base",
    "/aws/service/ami-windows-latest/Windows_Server-2019-Dutch-Full-Base",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-Base",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-ContainersLatest",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-ECS_Optimized",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-ECS_Optimized/image_id",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-EKS_Optimized-1.14/image_id",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-EKS_Optimized-1.15/image_id",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-EKS_Optimized-1.16",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-EKS_Optimized-1.16/image_id",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-EKS_Optimized-1.17",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-EKS_Optimized-1.17/image_id",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-EKS_Optimized-1.18",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-EKS_Optimized-1.18/image_id",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-EKS_Optimized-1.19",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-EKS_Optimized-1.19/image_id",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-EKS_Optimized-1.20",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-EKS_Optimized-1.20/image_id",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-EKS_Optimized-1.21",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-EKS_Optimized-1.21/image_id",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Deep-Learning",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-Base",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-ContainersLatest",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-ECS_Optimized",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-ECS_Optimized/image_id",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-EKS_Optimized-1.14/image_id",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-EKS_Optimized-1.15/image_id",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-EKS_Optimized-1.16",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-EKS_Optimized-1.16/image_id",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-EKS_Optimized-1.17",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-EKS_Optimized-1.17/image_id",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-EKS_Optimized-1.18",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-EKS_Optimized-1.18/image_id",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-EKS_Optimized-1.19",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-EKS_Optimized-1.19/image_id",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-EKS_Optimized-1.20",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-EKS_Optimized-1.20/image_id",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-EKS_Optimized-1.21",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-EKS_Optimized-1.21/image_id"
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-HyperV",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-SQL_2016_SP2_Enterprise",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-SQL_2016_SP2_Express",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-SQL_2016_SP2_Standard",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-SQL_2016_SP2_Web",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-SQL_2017_Enterprise",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-SQL_2017_Express",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-SQL_2017_Standard",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-SQL_2017_Web",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-SQL_2019_Enterprise",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-SQL_2019_Express",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-SQL_2019_Standard",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-SQL_2019_Web",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-STIG-Core",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-STIG-Full",
    "/aws/service/ami-windows-latest/Windows_Server-2019-English-Tesla",
    "/aws/service/ami-windows-latest/Windows_Server-2019-French-Full-Base",
    "/aws/service/ami-windows-latest/Windows_Server-2019-German-Full-Base",
    "/aws/service/ami-windows-latest/Windows_Server-2019-Hungarian-Full-Base",
    "/aws/service/ami-windows-latest/Windows_Server-2019-Italian-Full-Base",
    "/aws/service/ami-windows-latest/Windows_Server-2019-Japanese-Full-Base",
    "/aws/service/ami-windows-latest/Windows_Server-2019-Japanese-Full-SQL_2017_Enterprise",
    "/aws/service/ami-windows-latest/Windows_Server-2019-Japanese-Full-SQL_2017_Standard",
    "/aws/service/ami-windows-latest/Windows_Server-2019-Japanese-Full-SQL_2017_Web",
    "/aws/service/ami-windows-latest/Windows_Server-2019-Japanese-Full-SQL_2019_Enterprise",
    "/aws/service/ami-windows-latest/Windows_Server-2019-Japanese-Full-SQL_2019_Standard",
    "/aws/service/ami-windows-latest/Windows_Server-2019-Japanese-Full-SQL_2019_Web",
    "/aws/service/ami-windows-latest/Windows_Server-2019-Korean-Full-Base",
    "/aws/service/ami-windows-latest/Windows_Server-2019-Polish-Full-Base",
    "/aws/service/ami-windows-latest/Windows_Server-2019-Portuguese_Brazil-Full-Base",
    "/aws/service/ami-windows-latest/Windows_Server-2019-Portuguese_Portugal-Full-Base",
    "/aws/service/ami-windows-latest/Windows_Server-2019-Russian-Full-Base",
    "/aws/service/ami-windows-latest/Windows_Server-2019-Spanish-Full-Base",
    "/aws/service/ami-windows-latest/Windows_Server-2019-Swedish-Full-Base",
    "/aws/service/ami-windows-latest/Windows_Server-2019-Turkish-Full-Base",
[
]

在这个Windows清单中,选择“/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-Base”就可以了。

现在可以开始编写CloudFormation了。

2、编写CloudFormation

编写如下一个最小化的CloudFormation用于测试。下文使用gp3为例创建系统盘。

# 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-arm64-gp2'

Resources:
EC2Instance01:
  Type: 'AWS::EC2::Instance'
  Properties:
    ImageId: !Ref LatestAmiId
    InstanceType: t4g.micro
    Monitoring: true
    BlockDeviceMappings: # Use gp3 as root disk
      - DeviceName: /dev/xvda
        Ebs:
          VolumeType: gp3
          VolumeSize: 10
          DeleteOnTermination: true

Outputs:
LatestAMI:
  Value: !Ref LatestAmiId
EC2PrivateIP:
  Value: !GetAtt EC2Instance01.PrivateIp

使用这个CloudFormation创建环境,可以看到EC2创建成功。

使用SSM的好处:

  • 始终使用最新的AMI创建EC2,不需要在维护AMI ID版本
  • 不区分区域,不需要在逐个针对Region嵌入AMI ID清单

四、参考资料

参考文档(英文):

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