一、背景
在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清单
四、参考资料
参考文档(英文):