Terraform 无法使用 Amazon EC2 导入密钥对
Terraform fails to import key pair with Amazon EC2
使用 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 出错。
错误说密钥对已经存在于 AWS 中,但没有说明它是使用 Terraform 还是使用控制台创建的。
您应该在正确区域的 AWS 控制台 EC2 -> Key Pairs
中看到它。您应该先使用控制台删除它,然后再尝试使用 Terraform 导入它。
该错误告诉您该密钥对已存在于您的 AWS 帐户中,但 Terraform 在其状态文件中不知道它,因此每次都尝试创建它。
这里有两种选择。首先,您可以简单地将它从 AWS 帐户中删除并允许 Terraform 上传它,从而允许它由 Terraform 管理并保存在其状态文件中。
或者,您可以使用 Terraform import
命令将预先存在的资源导入您的状态文件:
terraform import aws_key_pair.personal mschuchard-us-east
使用 ${uuid()} 函数在生成时始终为密钥对获取随机 ID,selected/generated 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 provider生成一个key,每次导入一个新对象。
然后导出私钥,以便稍后访问服务器。
值得注意的是,这打破了 Terraform 尝试使用的范例之一(基础架构即代码),但从实际开发的角度来看,这可能有点过于理想化了……Terraform 构建中途失败并且状态无效。更好的解决方案可能是,如果 AWS 插件收到它自动导入的 "already exists" 错误,或者如果这是可以设置的可选行为。
使用 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 出错。
错误说密钥对已经存在于 AWS 中,但没有说明它是使用 Terraform 还是使用控制台创建的。
您应该在正确区域的 AWS 控制台 EC2 -> Key Pairs
中看到它。您应该先使用控制台删除它,然后再尝试使用 Terraform 导入它。
该错误告诉您该密钥对已存在于您的 AWS 帐户中,但 Terraform 在其状态文件中不知道它,因此每次都尝试创建它。
这里有两种选择。首先,您可以简单地将它从 AWS 帐户中删除并允许 Terraform 上传它,从而允许它由 Terraform 管理并保存在其状态文件中。
或者,您可以使用 Terraform import
命令将预先存在的资源导入您的状态文件:
terraform import aws_key_pair.personal mschuchard-us-east
使用 ${uuid()} 函数在生成时始终为密钥对获取随机 ID,selected/generated 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 provider生成一个key,每次导入一个新对象。 然后导出私钥,以便稍后访问服务器。
值得注意的是,这打破了 Terraform 尝试使用的范例之一(基础架构即代码),但从实际开发的角度来看,这可能有点过于理想化了……Terraform 构建中途失败并且状态无效。更好的解决方案可能是,如果 AWS 插件收到它自动导入的 "already exists" 错误,或者如果这是可以设置的可选行为。