当前位置: 首页 > 知识库问答 >
问题:

如何在Terraform中创建SSH密钥?

许庆
2023-03-14

我需要为不同的用户旋转一堆EC2框。每个用户都应该从所有其他用户中沙盒化,所以每个EC2框都需要自己的SSH键。

在Terraform中实现这一点的最佳方法是什么?

我找到的几乎所有指令都希望我手动创建SSH密钥并将其粘贴到terraform脚本中。

(错误)示例:

  • https://github.com/hashicorp/terraform/issues/1243,
  • http://2ninjas1blog.com/terraform-assigning-an-aws-key-pair-to-your-ec2-instance-resource/
  • Terraform无法使用Amazon EC2导入密钥对)

由于我需要以编程方式为许多用户生成唯一的密钥,这是不切实际的。

这似乎不是一个困难的用例,但我在任何地方都找不到关于它的文档。

必要时,我可以使用Bash动态生成Terraform脚本并注入SSH密钥。但这似乎正是Terraform最初应该做的事情。

共有3个答案

杨凌
2023-03-14

前面答案的扩展,不适合评论:

要将生成的密钥写入具有正确权限的私有文件,请执行以下操作:

resource "local_file" "pem_file" {
  filename = pathexpand("~/.ssh/${local.ssh_key_name}.pem")
  file_permission = "600"
  directory_permission = "700"
  sensitive_content = tls_private_key.ssh.private_key_pem
}

然而,保存这样的文件的一个缺点是路径最终会处于terraform状态。如果只是CI/CD和/或一个人运行terraform应用程序,那没什么大不了的,但是如果有更多的“应用程序”,每当与上次应用程序不同的人运行应用程序时,tfstate就会更新。这会产生一些“更新”噪音。没什么大不了的,但需要注意的是。

另一种避免这种情况的方法是将pem文件保存在AWS Secrets Manager中,或在S3中进行加密,并提供一个获取该文件的命令

史骏祥
2023-03-14

下面的代码创建到AWS和myKey。pem到您的计算机以及创建的myKey和myKey。pem具有相同的私钥。(我使用了Terraform v0.15.4)

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

resource "aws_key_pair" "kp" {
  key_name   = "myKey"       # Create "myKey" to AWS!!
  public_key = tls_private_key.pk.public_key_openssh

  provisioner "local-exec" { # Create "myKey.pem" to your computer!!
    command = "echo '${tls_private_key.pk.private_key_pem}' > ./myKey.pem"
  }
}

别忘了做myKey。pem只有在ssh连接到ec2实例之前运行下面的代码才能读取。

chmod 400 myKey.pem

否则会出现以下错误。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0664 for 'myKey.pem' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "myKey.pem": bad permissions
ubuntu@35.72.30.251: Permission denied (publickey).
景哲
2023-03-14

Terraform可以使用tls_private_key资源生成SSL/SSH私钥。

因此,如果您想动态生成SSH密钥,可以执行以下操作:

variable "key_name" {}

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
}

data "aws_ami" "ubuntu" {
  most_recent = true

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["099720109477"] # Canonical
}

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

  tags {
    Name = "HelloWorld"
  }
}

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

这将创建一个处于Terraform状态的SSH密钥对(除了在不使用远程状态时可能对Terraform状态本身执行的操作之外,它不会写入磁盘),基于公钥创建一个AWS密钥对,然后创建一个Ubuntu 14.04实例,在该实例中,Ubuntu用户可以使用生成的私钥访问。

然后,您必须从状态文件中提取私钥并将其提供给用户。当应用Terraform时,您可以使用输出将其直接输出到标准输出。

从私钥获取输出是通过下面的命令:

terraform output -raw private_key

这里我应该指出,传递私钥通常是个坏主意,最好让开发人员创建自己的密钥对,并向您提供公钥,您(或他们)可以使用公钥生成AWS密钥对(可能使用上述示例中使用的AWS\U密钥对资源),然后在创建实例时指定。

一般来说,我只会使用类似上述的方法为您正在控制的非常临时的dev环境生成SSH密钥,这样您就不需要将私钥传递给任何人。如果您确实需要将私钥传递给他人,则需要确保在安全通道中执行此操作,并确保地形状态(包含纯文本私钥)也得到了适当的保护。

 类似资料:
  • 我成功地实现了在terraform中创建敏感资源的流程,在任何时候都不会透露敏感细节是什么,因此在我们的github repo中不会以纯文本存储。我让TF创建一个服务帐户,它与SA密钥相关,然后创建一个引用SA密钥输出的GCP密钥。 我现在想看看是否有任何方法可以对一些预定义的数据库密码执行相同的操作。流量会略有不同: 手动创建GCP secret(在secrets manager中),该密码的值

  • 我已经使用terraform tgw模块创建了一个中转网关,如下所示。 我使用terraform vpc模块创建了vpc。 当我运行上述terraform Iam时,出现错误“错误:创建EC2传输网关VPC附件时出错:重复子网Samezone:相同AZ的重复子网” 我在ap-south-1中有2个专用子网,在ap-south-1中有1个公用子网。

  • 问题内容: 我想给一些用户提供一百万个密码,例如: 必须至少包含6个字符 它必须包含数字和字母 我应该在这里使用吗?怎么样? 问题答案: Apache Commons Lang的RandomStringUtils提供了一些生成随机字符串的方法,该字符串可用作密码。 以下是8个字符的密码创建示例: 这将产生以下结果: 当然,您也可以使用一些方法来限制密码生成所允许的字符集: 将仅创建以下字符的密码:

  • 我使用下面的代码来存储我的应用程序中加密的一些信息。 由于Android中不推荐使用MasterKey类,所以我应该使用MasterKey类,但我无法找到正确的方法来定义相同的MasterKey。 有人能显示与可用的MasterKey和MasterKey. Builder类的精确匹配吗? 下面的解决方案是这样工作的:

  • > 我通过terraform创建了一个自签名tls证书和私钥。这些文件称为服务器。密钥和服务器。crt 我用这个证书和私钥创建了一个kubernetes tls机密:kubectl create secret tls dpaas secret-n dpaas prod-key server。密钥--cert server.crt 这工作正常,nginx入口ssl终止工作,以下kubectl命令:k

  • 问题内容: 可能是一个非常新手的问题,但我一直在阅读,发现在理解密码的创建和存储方面有些困难。从我读过的内容中,md5 / hash密码是将其存储在数据库中的最佳方法。但是,我将如何首先创建这些密码? 因此,说我有一个登录页面,其中包含用户bob和密码bob123-我将如何1.将bobs密码输入数据库(以哈希开头)2.如何获取并确认哈希密码? 谢谢 问题答案: 编辑2017/11/09:请务必查看