【问题标题】:Terraform fails to import key pair with Amazon EC2Terraform 无法使用 Amazon EC2 导入密钥对
【发布时间】:2017-02-28 10:12:19
【问题描述】:

使用 Terraform 0.7.7。

我有一个简单的 Terraform 文件,其中包含以下内容:

provider "aws" {
  access_key = "${var.access_key}"
  secret_key = "${var.secret_key}"
  region     = "${var.region}"
}

resource "aws_instance" "personal" {
  ami           = "${lookup(var.amis, var.region)}"
  instance_type = "t2.micro"
}

resource "aws_eip" "ip" {
  instance = "${aws_instance.personal.id}"
}

resource "aws_key_pair" "personal" {
  key_name = "mschuchard-us-east"
  public_key = "${var.public_key}"
}

Terraform apply 产生以下错误:

aws_key_pair.personal: Creating...
  fingerprint: "" => "<computed>"
  key_name:    "" => "mschuchard-us-east"
  public_key:  "" => "ssh-rsa pubkey hash mschuchard-us-east"
aws_instance.personal: Creating...
  ami:                      "" => "ami-c481fad3"
  availability_zone:        "" => "<computed>"
  ebs_block_device.#:       "" => "<computed>"
  ephemeral_block_device.#: "" => "<computed>"
  instance_state:           "" => "<computed>"
  instance_type:            "" => "t2.micro"
  key_name:                 "" => "<computed>"
  network_interface_id:     "" => "<computed>"
  placement_group:          "" => "<computed>"
  private_dns:              "" => "<computed>"
  private_ip:               "" => "<computed>"
  public_dns:               "" => "<computed>"
  public_ip:                "" => "<computed>"
  root_block_device.#:      "" => "<computed>"
  security_groups.#:        "" => "<computed>"
  source_dest_check:        "" => "true"
  subnet_id:                "" => "<computed>"
  tenancy:                  "" => "<computed>"
  vpc_security_group_ids.#: "" => "<computed>"
aws_instance.personal: Creation complete
aws_eip.ip: Creating...
  allocation_id:     "" => "<computed>"
  association_id:    "" => "<computed>"
  domain:            "" => "<computed>"
  instance:          "" => "i-0ab94b58b0089697d"
  network_interface: "" => "<computed>"
  private_ip:        "" => "<computed>"
  public_ip:         "" => "<computed>"
  vpc:               "" => "<computed>"
aws_eip.ip: Creation complete
Error applying plan:

1 error(s) occurred:

* aws_key_pair.personal: Error import KeyPair: InvalidKeyPair.Duplicate: The keypair 'mschuchard-us-east' already exists.
status code: 400, request id: 51950b9a-55e8-4901-bf35-4d2be234abbf

我在谷歌上找到的唯一帮助是删除 *.tfstate 文件,我尝试过但没有帮助。我可以使用带有这个密钥对的 gui 启动一个 EC2 实例并轻松地通过 ssh 进入它,但是当尝试使用相同的全功能密钥对时,Terraform 会出错。

【问题讨论】:

    标签: amazon-ec2 terraform


    【解决方案1】:

    使用 ${uuid()} 函数在生成时总是获取密钥对的随机 id,选择/生成的 UUID 会使其进入状态文件,因此您仍然可以删除,但不会更新可能的。每次应用 terraform 文件时,都会生成一个新的密钥对...

    虽然您确实无法使用 AWS 提供商从头开始生成密钥对,但您可以使用 TLS 提供商生成的 RSA 私钥在 AWS 中生成新的密钥对对象。

    resource "aws_key_pair" "test" {
        key_name   = "${uuid()}"
        public_key = "${tls_private_key.t.public_key_openssh}"
    }
    provider "tls" {}
    resource "tls_private_key" "t" {
        algorithm = "RSA"
    }
    provider "local" {}
    resource "local_file" "key" {
        content  = "${tls_private_key.t.private_key_pem}"
        filename = "id_rsa"
        provisioner "local-exec" {
            command = "chmod 600 id_rsa"
        }
    }
    

    使用 tls 提供程序生成密钥,并每次将其作为新对象导入。 然后导出私钥,以便稍后访问服务器。

    值得注意的是,这打破了 Terraform 尝试使用的范式之一(基础架构即代码),但从实际开发的角度来看,这可能有点过于理想化...... Terraform 构建在中途失败并指出失效。更好的解决方案可能是 AWS 插件收到自动导入的“已经存在”错误,或者这是可以设置的可选行为。

    【讨论】:

      【解决方案2】:

      错误告诉您密钥对已存在于您的 AWS 账户中,但 Terraform 在其状态文件中不知道它,因此每次都尝试创建它。

      这里有两种选择。首先,您可以简单地将其从 AWS 账户中删除并允许 Terraform 上传它,从而使其由 Terraform 管理并处于其状态文件中。

      或者,您可以使用 Terraform import 命令将预先存在的资源导入您的状态文件:

      terraform import aws_key_pair.personal mschuchard-us-east
      

      【讨论】:

      • 在我的情况下,导入是aws_key_pair.personal。无论如何,在与凭据斗争了一段时间并放弃让 Terraform 使用凭据文件之后,我成功导入并运行了terraform apply。然后我意识到资源实际上在做什么以及如何将key_name 与实例相关联。 Terraform 对用户非常不友好,确实需要更高级的教程。对导入命令进行编辑,我会接受这个答案。
      • 同时盯着 EC2 实例仪表板让我意识到我还需要 vpc_security_group_ids。现在我实际上可以成功 ssh 到由 Terraform 创建的 EC2 实例,但是来自 ${aws_instance.personal.public_dns} 的输出完全不准确,所以我面前还有一个 bang-head-against-wall 会话。
      【解决方案3】:

      错误说AWS中已经存在密钥对,并没有说明它是使用Terraform还是使用控制台创建的。

      您应该在 AWS 控制台 EC2 -&gt; Key Pairs 中看到它以获取正确的区域。在使用 Terraform 重试导入之前,您应该使用控制台将其删除。

      【讨论】:

      • 等等,根据terraform.io/docs/providers/aws/r/key_pair.html,我无法使用 Terraform 创建密钥对。另外,如果我从控制台中删除密钥对,我怎么知道在 Terraform 中指定它的公钥?
      • 正确,您不能使用 Terraform 创建 EC2 密钥对,但您可以在本地创建它(保密)并从中获取公钥(ssh-keygen -y -f myssh.key &gt; myssh.pub),您可以将其放入资源aws_key_pair .
      • 删除密钥不是解决方案。如果这只是您配置中的一个资源,并且您有依赖于此的 EC2,则需要有一个解决方案而不删除它
      • 它确实对我有用。从 EC2 中删除密钥对后,-> 密钥对,我能够启动实例。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-21
      • 2020-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-13
      • 2015-02-23
      相关资源
      最近更新 更多