Terraform部署无公网非sysprep AMI EC2时上传执行PowerShell问题
针对非sysprep无公网Windows Server 2012 EC2实例的配置执行方案
Windows Server 2012默认使用EC2Config服务处理用户数据,仅在首次从sysprep封装的AMI启动时默认执行用户数据,未做sysprep的AMI默认关闭了该执行开关,所以原有userdata配置无法生效,以下是3种可直接通过Terraform落地、无需公网支持的方案:
方案1:修改基础AMI的EC2Config配置(改动最小,推荐)
仅需要对原始非sysprep基础AMI做一次配置修改,后续所有实例都可直接复用原有userdata逻辑:
- 用原始非sysprep AMI启动一台临时实例
- 打开路径
C:\Program Files\Amazon\Ec2ConfigService\Settings\config.xml - 将
<Ec2HandleUserData>节点的属性值修改为Enabled - 保存配置后将该实例重新封装为自定义AMI,后续Terraform直接使用这个新AMI即可
- 原有
data "template_file" "userdata配置不需要做任何调整即可正常运行
方案2:通过AWS Systems Manager(SSM)实现(无需修改AMI)
实例在私有网络内无需公网,仅需要提前在VPC中部署3个SSM内网端点:
com.amazonaws.<区域编码>.ssmcom.amazonaws.<区域编码>.ssmmessagescom.amazonaws.<区域编码>.ec2messages
同时给EC2实例的IAM角色附加AmazonSSMManagedInstanceCore权限策略,之后直接用Terraform的aws_ssm_association资源完成文件上传、命令执行:
# 上传本地zip文件到实例 resource "aws_ssm_association" "upload_zip" { name = "AWS-RunPowerShellScript" targets { key = "InstanceIds" values = [aws_instance.example.id] } parameters = { commands = [ <<EOT $binData = [System.Convert]::FromBase64String("${base64encode(file("./本地文件路径/部署包.zip"))}") [System.IO.File]::WriteAllBytes("C:\部署路径\部署包.zip", $binData) EOT ] } wait_for_success_timeout_seconds = 300 } # 执行解压、安装等PowerShell命令 resource "aws_ssm_association" "run_setup" { name = "AWS-RunPowerShellScript" targets { key = "InstanceIds" values = [aws_instance.example.id] } parameters = { commands = [ "Expand-Archive C:\部署路径\部署包.zip -DestinationPath C:\部署路径\解压目录", "Start-Process C:\部署路径\解压目录\安装程序.exe -ArgumentList '/silent' -Wait", "powershell.exe -ExecutionPolicy Bypass -File C:\部署路径\解压目录\配置脚本.ps1" ] } depends_on = [aws_ssm_association.upload_zip] wait_for_success_timeout_seconds = 600 }
提示:如果上传的文件超过200KB,建议先将文件上传到同区域内网可访问的S3桶,给EC2实例角色加对应S3桶的读取权限,在SSM命令中用
Read-S3Object命令下载文件,避免base64编码后内容过大导致Terraform执行报错。
方案3:预配置启动任务到AMI
如果不想用SSM也不想修改EC2Config配置,可以提前把需要执行的逻辑写成PowerShell脚本,添加到AMI的Windows任务计划程序中,设置触发条件为「系统启动时、使用最高管理员权限执行」,Terraform创建实例时可通过自定义实例标签传递参数,脚本启动时主动读取实例标签调整执行逻辑即可。
内容的提问来源于stack exchange,提问作者Wanabee
相关产品推荐
相关产品推荐

