terraform: how do you make a resource idempotent - i.e. create if not exists but do nothing if it does exist

时间:2018-07-24 10:11:44

标签: terraform

I have a bit of sample code that:

  1. creates an EC2 instance
  2. creates and adds my public key

but I'd like it to be idempotent. i.e. if the key exists then it will still run and not fail with an error.

Not sure how to do that. Any suggestions?

Sample code:

provider "aws" {
  region = "eu-west-1"
}

module ec2 {
  source = "./ec2_instance"
  name = "EC2 Instance"
} 

resource "aws_key_pair" "my_key" {
  key_name   = "my_key"
  public_key = "<string>"
}

and it's aws_key_pair.my_key that I'm trying to make idempotent.

At the moment I get errors like:

Error: Error applying plan:

1 error(s) occurred:

* aws_key_pair.my_key: 1 error(s) occurred:

* aws_key_pair.my_key: Error import KeyPair: InvalidKeyPair.Duplicate: The keypair 'my_key' already exists.
    status code: 400, request id: <request id>

2 个答案:

答案 0 :(得分:2)

只要提供者中的所有资源均由Terraform创建或由Terraform管理,这就是Terraform的行为。

如果您有一个空白的AWS账户,并针对问题中的代码应用Terraform,则它将创建一个AWS密钥对以及您的ec2模块中包含的任何内容。

如果之后再运行计划,则该计划不会显示任何更改。

在这种情况下,AWS API仅允许通过可配置的方式允许资源的单个版本,并且该资源已经存在于Terraform所知范围之外。这适用于AWS密钥对,其中每个AWS账户/区域组合只能有一个由相同名称命名的密钥对。

此时,您有两个选择:您可以让Terraform直接管理AWS密钥对,也可以简单地使用数据源引用它,而不用尝试创建一个新的密钥对。

要使Terraform管理AWS密钥对,您可以运行以下命令import it

terraform import aws_key_pair.my_key my_key

相反,如果您只想引用它,通常可以使用data source,但是在这种情况下,您只需引用它就没有必要了(因此没有aws_key_pair数据源)。密钥对的名称,例如本例:

resource "aws_instance" "web" {
  ami           = "am-123456"
  instance_type = "t2.micro"
  key_pair      = "my_key"
}

答案 1 :(得分:0)

看起来您需要将现有的my_key密钥对导入到terraform状态。导入资源后,terraform将不会尝试创建存在的密钥对。

terraform import aws_key_pair.my_key my_key

https://www.terraform.io/docs/import/index.html