You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows下用Terraform创建AWS密钥对并生成.pem文件问题求助

Windows环境下Terraform无法生成.pem密钥文件的解决办法

问题描述

我尝试用Terraform创建EC2服务器,待服务器创建完成后执行代码安装Nginx。流程是先创建密钥对并保存为.pem文件,再通过remote-exec provisioner访问远程服务器。但目前.pem文件无法生成,出现提示:
aws_key_pair.generated_key (local-exec): (output suppressed due to sensitive value in config)

原代码如下:

provider "aws" {
    region = "us-east-1"
}

variable "key_name" {
    default = "terraform"
}

resource "tls_private_key" "example" {
  algorithm = "RSA"
  rsa_bits  = 4096
}

resource "aws_key_pair" "generated_key" {
  key_name   = var.key_name
  public_key = tls_private_key.example.public_key_openssh

  provisioner "local-exec" { # Create a "terraform.pem" to your computer!!
    command = "echo '${tls_private_key.example.private_key_pem}' > ./${aws_key_pair.generated_key.key_name}.pem"
  }

}

data "aws_ami" "app_ami" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm*"]
  }
}

resource "aws_instance" "myec2" {
    ami = data.aws_ami.app_ami.id
    instance_type = "t2.micro"
    key_name = aws_key_pair.generated_key.key_name

    connection {
        type = "ssh"
        user = "ec2-user"
        #password = var.root_password
        private_key = file("./${aws_key_pair.generated_key.key_name}.pem")
        host = self.public_ip
    }

    provisioner "remote-exec" {
        inline = [
            "sudo amazon-linux-extras install -y nginx1",
            "sudo systemctl start nginx"
        ]
    }

}

output "private_key" {
        value     = tls_private_key.example.private_key_pem
        sensitive = true
}

解决办法

问题出在Windows的echo命令无法正确处理包含特殊字符的私钥内容,加上Terraform对敏感值的输出抑制,导致local-exec无法生成有效文件。改用Terraform的local_file资源替代local-exec,同时优化EC2连接配置:

修改后的代码:

provider "aws" {
    region = "us-east-1"
}

variable "key_name" {
    default = "terraform"
}

resource "tls_private_key" "example" {
  algorithm = "RSA"
  rsa_bits  = 4096
}

resource "aws_key_pair" "generated_key" {
  key_name   = var.key_name
  public_key = tls_private_key.example.public_key_openssh
}

# 用local_file生成.pem文件,替代local-exec
resource "local_file" "private_key" {
  content         = tls_private_key.example.private_key_pem
  filename        = "./${var.key_name}.pem"
  file_permission = "0600" # 保持密钥文件权限安全,Windows下兼容
}

data "aws_ami" "app_ami" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm*"]
  }
}

resource "aws_instance" "myec2" {
    ami = data.aws_ami.app_ami.id
    instance_type = "t2.micro"
    key_name = aws_key_pair.generated_key.key_name

    connection {
        type = "ssh"
        user = "ec2-user"
        # 直接引用tls私钥,无需读取本地文件,避免时序问题
        private_key = tls_private_key.example.private_key_pem
        host = self.public_ip
    }

    provisioner "remote-exec" {
        inline = [
            "sudo amazon-linux-extras install -y nginx1",
            "sudo systemctl start nginx"
        ]
    }

    # 确保密钥文件生成后再创建EC2实例(可选,增强可靠性)
    depends_on = [local_file.private_key]
}

output "private_key" {
        value     = tls_private_key.example.private_key_pem
        sensitive = true
}

关键修改说明

  • 移除aws_key_pair中的local-exec,改用local_file资源生成.pem文件,它能直接处理Terraform的敏感值,避免Windows命令行的转义问题。
  • EC2的connection部分直接使用tls_private_key.example.private_key_pem,不需要读取本地文件,既避免了文件生成和读取的时序问题,也更安全。
  • 添加depends_on确保密钥文件生成完成后再创建EC2实例,增强流程可靠性。
  • 给生成的.pem文件设置0600权限,符合密钥文件的安全规范,同时兼容Windows环境。

内容的提问来源于stack exchange,提问作者Rga91

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 06:22:47