繁体   English   中英

terraform 中的三元条件运算符

[英]ternary conditional operators in terraform

我与 terraform 合作了很多,希望建立一个内部解决方案来支持基础设施。 到目前为止,我已经编写了大部分 terraform 代码,并且正在构建 Ansible 代码,用于对已建立的实例进行后处理。 I am shuttling over the dynamic inventory from terraform to Ansible using this little Go app that can be found here, https://github.com/adammck/terraform-inventory . 所有这些都运作良好。

随着我对 terraform 代码的深入了解,我正在尝试在 Linux 实例的 ssh 键上使用三元条件运算符。 目标是在多个实例上“重用”该资源。

我的资源看起来像这样..

resource "aws_key_pair" "key" {
  key_name = var.ssh_key
  count = var.create_ssh_key ? 1 : 0
  public_key = file("~/.ssh/${var.ssh_key}")
}

我在这里的关键参数中包含了 [count.index] ...

resource "aws_instance" "linux" {
  ami           = var.linux_ami
  instance_type = var.linux_instance_type
  count         = var.linux_instance_number
  subnet_id     = data.aws_subnet.itops_subnet.id
  key_name      = aws_key_pair.key[count.index].key_name
  ...

$ terraform validate返回干净。

$ terraform plan -var-file response-file.tfvars -var "create_ssh_key=false"没有。

标准错误如下...

$ terraform plan -var-file response-file.tfvars -var "create_ssh_key=false"
╷
│ Error: Invalid index
│
│   on instances.tf line 16, in resource "aws_instance" "linux":
│   16:   key_name      = aws_key_pair.key[count.index].key_name
│     ├────────────────
│     │ aws_key_pair.key is empty tuple
│     │ count.index is 0
│
│ The given key does not identify an element in this collection value.

我错过了什么?

感谢您的反馈!

如果aws_key_pair中的count为 0,则以后根本没有要引用的密钥。

所以你必须检查并使用null在这种情况下消除key_name

resource "aws_instance" "linux" {
  ami           = var.linux_ami
  instance_type = var.linux_instance_type
  count         = var.linux_instance_number
  subnet_id     = data.aws_subnet.itops_subnet.id
  key_name      = var.create_ssh_key ? aws_key_pair.key[0].key_name : null

我认为您的示例中的根本问题是您的resource "aws_key_pair" "key"块和resource "aws_instance" "linux"块的count值都不同,因此使用count.index第二个的count.index以访问第一个的实例。

在您的情况下,您似乎有零个密钥对(它说aws_key_pair.key is empty tuple )但您至少有一个 EC2 实例,因此您的表达式正在尝试访问密钥对资源的第零个实例,然后失败因为它没有第零个实例。

如果您使用的是 Terraform v0.15 或更高版本,则可以使用one function简洁地处理密钥对资源的零实例和一实例情况,如下所示:

resource "aws_instance" "linux" {
  # ...
  key_name = one(aws_key_pair.key[*].key_name)
  # ...
}

把它分解成更小的部分:

  • aws_key_pair.key[*].key_name是一个splat 表达式,它通过访问每个对象上的.key_name从对象列表aws_key_pair.key到仅包含键名的字符串列表中。 在您的情况下,因为您的资源只能有计数 0 或 1,所以这将是键名的零或一元素列表。
  • 然后接受one两种可能的结果,如下所示:
    • 如果它是一个单元素列表,它将只返回不再包含在列表中的单个元素。
    • 如果它是一个零元素列表,它将返回null在资源参数中,这与根本不指定该参数的含义相同。

然后,效果将是,如果您有一个密钥对,那么它将关联该密钥对,但如果您没有密钥对,那么它将保留该参数未设置,从而创建一个没有密钥的实例完全配对。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM