资讯动态

AWS CloudFormation 实战:通过 UserData 自动为 EC2 根卷打标签(Windows 与 Linux 双系统方案)

发布时间:2026/10/15 2:58:39 来源:尧图企业网站定制
【免费下载链接】aws-cloudformation-templatesA collection of useful CloudFormation templates项目地址https://gitcode.com/gh_mirrors/aw/aws-cloudformation-templates点击查看免费下载本文基于开源仓库 aws-cloudformation-templates 中的 TaggingRootVolumesInEC2 解决方案 展开。该方案提供了一份完整的 CloudFormation 模板它同时创建一台 Linux 实例和一台 Windows 实例并借助实例资源自身的UserData属性在系统启动阶段自动为各自的 EBS 根卷打上MyRootTag: MyRootVolumesValue标签。读完本文你将掌握根卷自动标记的完整架构、双系统下的脚本实现差异、最小权限 IAM 设计以及通过 CLI 与控制台两种方式部署该模板的完整操作流程。一、为什么要给 EC2 根卷自动打标签在真实的生产环境中EBS 卷尤其是实例根卷的标签管理往往容易被忽略。根卷由 AWS 在创建实例时隐式创建默认不会携带业务维度的标签这给后续的成本分摊、资源审计、自动化运维如按标签触发备份、清理、巡检带来很大不便。本模板的核心思路是让实例在首次启动时“自己”给自己的根卷打标签。整个流程不需要人工登录服务器、不需要额外的编排系统只需在创建实例时注入一段启动脚本并通过 IAM 角色授予必要的 API 权限即可。模板同时覆盖了 Linux 与 Windows 两种最常见的操作系统展示了两种完全不同的脚本实现路径。二、模板资源总览与整体工作流程模板包含 4 个资源全部定义在 Tagging_Root_volume.yamlJSON 版本见 Tagging_Root_volume.json资源逻辑名类型作用WindowsInstanceAWS::EC2::InstanceWindows 2016 实例启动时通过 PowerShell 脚本标记根卷LinuxInstanceAWS::EC2::InstanceAmazon Linux 2 实例启动时通过 AWS CLI 命令标记根卷InstanceRoleAWS::IAM::Role赋予 EC2 描述实例与创建标签权限的 IAM 角色InstanceProfileAWS::IAM::InstanceProfile将角色挂载到两台实例的实例配置文件整体工作流程如下CloudFormation 创建两台实例并将InstanceProfile注入到两台实例中实例首次启动时执行UserData脚本Linux 为 Shell 脚本Windows 为 PowerShell脚本通过实例元数据服务IMDS地址169.254.169.254获取可用区、实例 ID 等自身信息脚本根据实例 ID 查询该实例的块设备映射定位根卷Linux 下为第一个块设备Windows 下匹配/dev/sda1的VolumeId调用aws ec2 create-tagsLinux或New-EC2TagWindows为该卷写入标签标签写入成功后即可在 EC2 控制台或通过aws ec2 describe-tags看到根卷上的MyRootTag。三、模板参数详解模板定义了 6 个参数部署时需要根据实际环境填写参数类型默认值说明KeyNameAWS::EC2::KeyPair::KeyName无已有的 EC2 密钥对名称用于 SSH/RDP 登录实例InstanceTypeStringt2.micro实例类型模板通过AllowedValues限定了 t2、m3、m4、c4、c3、r3、i2 系列共 31 种可选值默认t2.microInstanceAZAWS::EC2::AvailabilityZone::Name无实例所在的可用区AZWindowsAMIIDAWS::SSM::Parameter::ValueAWS::EC2::Image::Id/aws/service/ami-windows-latest/Windows_Server-2016-English-Full-BaseWindows AMI ID从 Systems Manager 参数库动态获取LinuxAMIIDAWS::SSM::Parameter::ValueAWS::EC2::Image::Id/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2Linux AMI ID同样从 SSM 参数库动态获取SubnetIdAWS::EC2::Subnet::Id无实例所在的子网值得注意的是两个 AMI 参数的写法AWS::SSM::Parameter::ValueAWS::EC2::Image::Id属于 CloudFormation 的动态引用Dynamic Reference模板不会在创建栈时写死某个 AMI而是从 SSM 公共参数库中读取“最新”的 AMI ID。默认值分别指向 Windows Server 2016 英文全功能版与 Amazon Linux 2 的公共参数路径因此无需在参数中手工维护 AMI ID注意这些默认参数对应的镜像适用于 eu-west-1 等常见区域跨区域使用时请以目标区域实际存在的公共参数为准。四、Linux 实例的根卷标记实现Linux 实例的UserData是理解整个方案的关键源码见 Tagging_Root_volume.yaml 中LinuxInstance资源AWS_AVAIL_ZONE$(curl http://169.254.169.254/latest/meta-data/placement/availability-zone) AWS_REGIONecho \$AWS_AVAIL_ZONE\ | sed s/[a-z]$// AWS_INSTANCE_ID$(curl http://169.254.169.254/latest/meta-data/instance-id) ROOT_VOLUME_IDS$(aws ec2 describe-instances --region $AWS_REGION --instance-id $AWS_INSTANCE_ID --output text --query Reservations[0].Instances[0].BlockDeviceMappings[0].Ebs.VolumeId) aws ec2 create-tags --resources $ROOT_VOLUME_IDS --region $AWS_REGION --tags KeyMyRootTag,ValueMyRootVolumesValue逐行拆解获取可用区通过实例元数据服务IMDS的placement/availability-zone路径取得可用区例如eu-west-1a推导区域可用区去掉最后一个字母即得到区域名例如eu-west-1a→eu-west-1。这里用sed s/[a-z]$//去掉末尾小写字母获取实例 ID通过元数据服务的instance-id路径取得当前实例 ID定位根卷调用aws ec2 describe-instances用--query取出BlockDeviceMappings[0].Ebs.VolumeIdLinux 实例中第一个块设备即根卷作为目标卷 ID打标签调用aws ec2 create-tags写入KeyMyRootTag,ValueMyRootVolumesValue。UserData通过!Base64内建函数编码注入JSON 版本使用Fn::Base64。由于 Amazon Linux 2 默认预装了 AWS CLI因此无需额外安装工具即可执行aws ec2命令脚本执行所需的权限来自实例所挂载的 IAM 角色见下文第六节。五、Windows 实例的根卷标记实现Windows 实例使用 PowerShell 实现同一目标这也是原文档中强调的“Windows AMI 未预装 AWS CLI 时可退化为纯 Windows 命令”的路径源码见同一 yaml 文件中WindowsInstance资源$AWS_AVAIL_ZONE(curl http://169.254.169.254/latest/meta-data/placement/availability-zone).Content $AWS_REGION$AWS_AVAIL_ZONE.Substring(0,$AWS_AVAIL_ZONE.length-1) $AWS_INSTANCE_ID(curl http://169.254.169.254/latest/meta-data/instance-id).Content $ROOT_VOLUME_IDS((Get-EC2Instance -Region $AWS_REGION -InstanceId $AWS_INSTANCE_ID).Instances.BlockDeviceMappings | where-object DeviceName -match /dev/sda1).Ebs.VolumeId $tag New-Object Amazon.EC2.Model.Tag $tag.key MyRootTag $tag.value MyRootVolumesValue New-EC2Tag -Resource $ROOT_VOLUME_IDS -Region $AWS_REGION -Tag $tag实现要点通过curlPowerShell 中实际调用的是 Web 请求读取元数据服务取.Content获得可用区与实例 ID用Substring去掉可用区末位字母得到区域名Get-EC2Instance是 AWS Tools for PowerShellAWSPowerShell 模块的 cmdlet返回实例的BlockDeviceMappings通过where-object DeviceName -match /dev/sda1精确匹配 Windows 根卷设备名取出其Ebs.VolumeId构造Amazon.EC2.Model.Tag对象key MyRootTag、value MyRootVolumesValue调用New-EC2Tagcmdlet 完成打标签。该路径不依赖 AWS CLI只依赖 PowerShell 与 AWS Tools for PowerShell 模块——这正是模板对 Windows 镜像兼容性考虑的具体体现Windows Server 2016 默认预装了 EC2Config / EC2Launch 及 PowerShell即使目标 AMI 未安装 AWS CLI模板中的这段脚本依然可以独立完成任务。六、最小权限 IAM 角色设计两台实例能够打标签前提是获得了 IAM 角色授予的权限。模板中的InstanceRole遵循最小权限原则策略内容如下信任策略AssumeRolePolicyDocumentPrincipal.Service为ec2.amazonaws.comAction为sts:AssumeRole即仅允许 EC2 服务代入该角色权限策略taginstancepolicyEffect: AllowAction包含ec2:Describe*与ec2:CreateTagsResource为*。其中ec2:Describe*用于支撑describe-instances/Get-EC2Instance查询根卷 IDec2:CreateTags用于写入标签两个权限恰好覆盖脚本全部 API 调用没有授予多余的高危权限如ec2:DeleteTags、ec2:RunInstances。InstanceProfile资源将InstanceRole绑定为实例配置文件两台实例通过IamInstanceProfile: !Ref InstanceProfile引用它。模板同时为两台实例配置了附加块设备映射BlockDeviceMappings/dev/sdm上的 10 GiB io1 卷200 IOPSDeleteOnTermination: true用于演示实例与数据卷的关系注意根卷标签逻辑只作用于根卷不受该附加映射影响。七、部署方式一通过 AWS CLI 创建栈原文档给出了完整的 CLI 命令部署前请按实际环境替换密钥对、实例类型、可用区与 AMI 参数aws cloudformation create-stack \ --stack-name TaggingVolumes \ --template-body file://Tagging_Root_volume.json \ --parameters \ ParameterKeyKeyName,ParameterValueTestKey \ ParameterKeyInstanceType,ParameterValuet2.micro \ ParameterKeyInstanceAZ,ParameterValueeu-west-1 \ ParameterKeyWindowsAMIID,ParameterValueami-0d138b26f46625e2f \ ParameterKeyLinuxAMIID,ParameterValueami-0fad7378adf284ce0命令要点--stack-name TaggingVolumes栈名可自定义--template-body file://Tagging_Root_volume.json指向本地模板文件仓库同时提供 Tagging_Root_volume.json 与 Tagging_Root_volume.yaml 两种格式file://路径指向哪个均可--parameters中的KeyName、InstanceAZ、SubnetId为必填项模板未设默认值InstanceType、WindowsAMIID、LinuxAMIID可省略分别回落到t2.micro与 SSM 参数默认值。八、部署方式二通过 CloudFormation 控制台创建栈如果不使用 CLI也可以按原文档的 8 步流程在控制台完成部署打开 CloudFormation 控制台https://console.aws.amazon.com/cloudformation/home选择Create Stack然后选择Design template设计模板在页面底部的Template标签页中粘贴模板内容Tagging_Root_volume.json 或 YAML 均可说明模板中需要根据操作系统与标签需求调整的“核心业务部分”正是UserData属性——修改其中MyRootTag/MyRootVolumesValue的值即可改变写入根卷的标签键值对选择Create stack图标点击Next为栈输入名称在Parameters页面填写参数SSH 密钥对名称KeyName、实例类型InstanceType以及最重要的 AMIWindowsAMIID/LinuxAMIID注意模板默认值面向 eu-west-1 区域点击Next再点击Next进入审核页在最终创建前必须勾选确认框声明 CloudFormation 有权创建 IAM 资源本模板会创建InstanceRole与InstanceProfile这两个 IAM 资源否则创建栈会被拒绝。九、验证结果与使用提醒栈创建并等实例完成初始化后可通过以下任一方式验证根卷标签是否写入控制台EC2 控制台 → Volumes找到实例根卷查看 Tags 列是否出现MyRootTag: MyRootVolumesValueCLI执行aws ec2 describe-tags --filters Nameresource-id,ValuesVolumeId或直接aws ec2 describe-volumes --volume-ids VolumeId查看标签。使用提醒会产生费用模板会创建两台 EC2 实例和一个 IAM 角色按 AWS 标准计费验证完毕后记得删除栈aws cloudformation delete-stack --stack-name TaggingVolumes以避免持续扣费AMI 区域差异模板的 AMI 参数默认值对应 eu-west-1 区域可用的公共参数其他区域请以目标区域实际的 SSM 参数路径为准UserData 只在首次启动执行标签写入依赖首次启动注入的脚本实例重启不会重复执行若根卷在实例启动后才被替换需要重新触发标记逻辑标签权限若自定义镜像未安装 AWS CLI 或 AWS Tools for PowerShellLinux 路径需要预装 AWS CLIWindows 路径则按模板中保留的“纯 Windows 命令”写法即未注释的Get-EC2Instance/New-EC2Tag方案执行即可。十、小结本模板是“实例自我标记”模式的一个典型示范用UserData IAM 实例配置文件替代人工运维在实例生命周期的最早期完成根卷标签初始化让后续基于标签的成本分析与自动化治理拥有可靠的数据基础。仓库中的 README 概述了整体思路与部署步骤YAML 与 JSON 双格式模板则为两种操作系统分别给出了可直接复用的脚本与权限配置读者可按需选取其一部署到自己的账号中。赞分享【免费下载链接】aws-cloudformation-templatesA collection of useful CloudFormation templates项目地址https://gitcode.com/gh_mirrors/aw/aws-cloudformation-templates点击查看免费下载相关推荐ToolJet 在 AWS EC2 上的部署实战指南基于 AMI 与 CloudFormation 的完整方案ToolJet 在 AWS EC2 上的部署实战指南基于 AMI 与 CloudFormation 的完整方案 本指南完整讲解如何在 AWS EC2 上部署低代码后端前端AI 应用MCP 服务Telegraf aws_ec2 处理器插件完全指南为指标自动附加 AWS EC2 元数据标签Telegraf aws_ec2 处理器插件完全指南为指标自动附加 AWS EC2 元数据标签 导读 aws_ec2 是 Telegraf 内置的流式处理器可观测性指标监控运维从装好到收到第一声广播SDR 软件定义无线电接收上手指南从装好到收到第一声广播SDR 软件定义无线电接收上手指南 SDR 是一款跨平台的开源软件定义无线电SDR接收软件支持 Windows、Linux桌面应用通信上一篇如何彻底解决HTML转Word的格式丢失问题html-to-docx实战指南下一篇如何通过MegSpot提升你的视觉分析效率5个实用技巧揭秘创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑