Terraform连接现有EC2实例:替代remote-exec的安全方案咨询
关于Terraform在现有EC2实例使用remote-exec的疑问
我当前通过SSH连接Ubuntu EC2实例执行脚本,示例代码如下:
resource "null_resource" "cwa_setup_on_existing_ec2" { for_each = toset(local.cw_existing_instance_watchlist) connection { type = "ssh" user = "ubuntu" private_key = "${file("priv_key")}" host = each.value.instance_info.public_ip timeout = "4m" } provisioner "file"{ source = "user_data.sh" destination = "/tmp/user_data.sh" } provisioner "remote-exec" { inline = [ "echo '----- Executing cwa-setup script on already initialized ec2 ------- '", "chmod +x /tmp/user_data.sh", "cd /tmp", "./user_data.sh >> cwa-setup.log" ] } }
我先通过file provisioner将脚本复制到EC2实例,再执行它。使用自己的私钥连接时执行成功且安全,但需要连接根账号下多用户创建的一组现有实例,从磁盘加载其他用户私钥既不安全也不可行。我的疑问如下:
- 通过Terraform连接现有EC2实例的更佳方式有哪些?
- Terraform文档建议将Provisioners作为最后手段,那么在不影响安全访问的前提下,远程执行脚本的替代方案有哪些?
解决方案
一、连接现有EC2实例的更优方式
- 使用EC2 Instance Connect:无需管理SSH密钥,通过AWS API临时推送SSH公钥到实例,有效期最长60秒。Terraform中可通过
aws_ec2_instance_connect资源生成临时连接凭证,配合remote-exec时无需指定private_key,改用临时生成的密钥对即可完成连接。 - IAM角色+Session Manager:给目标EC2实例附加具备SSM权限的IAM角色,通过AWS Systems Manager Session Manager连接实例,无需开放SSH端口。Terraform中可将连接类型设为
ssm(type = "ssm"),无需配置私钥,完全依赖IAM权限控制访问范围。 - 集中托管SSH密钥:预先将统一的SSH公钥注入所有目标实例(比如通过IAM Instance Profile的用户数据拉取、或存储在AWS Systems Manager Parameter Store中),Terraform从AWS Secrets Manager安全读取对应的私钥,避免本地磁盘存储敏感密钥。
二、替代Provisioners的远程执行方案
- AWS Systems Manager Run Command:直接通过SSM向目标实例批量发送命令,无需建立SSH连接。Terraform中可定义
aws_ssm_document封装脚本逻辑,再通过aws_ssm_command触发一次性执行,或用aws_ssm_association关联实例实现周期性执行,权限由IAM严格管控。 - 配置管理工具集成:用Terraform输出实例标签、IP等信息,再通过
local-exec调用Ansible、Chef等工具批量执行脚本。这类工具自带成熟的安全访问机制,比如基于IAM的认证、密钥托管,无需Terraform直接处理连接逻辑。 - 自定义Lambda触发执行:编写Lambda函数,通过SSM API触发目标实例执行脚本,Terraform负责部署Lambda并配置触发规则(比如按实例标签筛选目标)。全程通过IAM权限控制,无需直接连接实例,安全性更高。
- 幂等性用户数据补充执行:如果脚本具备幂等性,可通过SSM触发实例重新执行用户数据脚本,适合对现有实例补做初始化操作,避免重复执行带来的异常。
内容的提问来源于stack exchange,提问作者mkRuby009
相关产品推荐
相关产品推荐

