是否可以在资源本身内部引用资源名称

syl*_*ylr 5 terraform

我想在资源本身内部使用资源名称以避免字符串重复和复制/粘贴错误。

resource "aws_instance" "bastion-euw3-infra-01" {
  ami           = "ami-078db6d55a16afc82"
  instance_type = "t2.micro"
  key_name      = "sylvain"

  user_data = templatefile("./scripts/cloudinit.yaml", {
    hostname          = "bastion-euw3-infra-01"
    tailscale_authkey = var.tailscale_authkey
  })

  network_interface {
    device_index         = 0
    network_interface_id = aws_network_interface.bastion-euw3-infra-01.id
  }

  tags = {
    Name        = "bastion-euw3-infra-01"
    Environment = "infra"
  }

  lifecycle {
    ignore_changes = [user_data]
  }
}
Run Code Online (Sandbox Code Playgroud)

基本上我想"bastion-euw3-infra-01"用某种 var 替换资源内部,例如:

resource "aws_instance" "bastion-euw3-infra-01" {
  ...

  user_data = templatefile("./scripts/cloudinit.yaml", {
    hostname          = ___name___
    tailscale_authkey = var.tailscale_authkey
  })

  ...

  tags = {
    Name        = ___name___
    Environment = "infra"
  }

  ...
}
Run Code Online (Sandbox Code Playgroud)

terraform 是否提供了一种方法来做到这一点?

Kar*_*are 2

就像评论中已经提到的那样,没有直接支持。但很容易解决;-)

\n

我将展示gitlab的示例,您可以自己将其转换为您的 aws 资源。

\n

更新:在答案的最后,我发布了您问题的伪代码!

\n

我的示例将处理avatar和 ,avatar_hash它们都属于相同的值(文件名),这里是 gitlab 组的文档

\n

在以下步骤中我将省略 gitlab 的提供者声明

\n
terraform {\n  required_providers {\n    gitlab = {\n      source  = "gitlabhq/gitlab"\n      version = "16.3.0"\n    }\n  }\n  backend "http" {\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

复制并粘贴 -> 不好,以及你的问题的原因

\n

复制和粘贴解决方案将使用两倍的图像路径。坏的。

\n
resource "gitlab_group" "playground" {\n  name        = "Playground"\n  path        = "playground"\n  description = "Try your ideas! Space for spikes! "\n  avatar      = "${path.root}/../img/playground.png"\n  avatar_hash = filesha256("${path.root}/../img/playground.png")\n}\n
Run Code Online (Sandbox Code Playgroud)\n

解决方案

\n

第一个解决方案 - 局部变量

\n

在 terraform 文件中使用局部变量,src/main.tf例如.

\n
locals {\n  playground_avatar = "${path.root}/../img/playground.png"\n}\n\nresource "gitlab_group" "playground" {\n  name        = "Playground"\n  path        = "playground"\n  description = "Try your ideas! Space for spikes! "\n  avatar      = local.playground_avatar\n  avatar_hash = filesha256(local.playground_avatar)\n}\n
Run Code Online (Sandbox Code Playgroud)\n

第二种解决方案 - 创建一个模块

\n

使用模块并重用模块变量。

\n

创建一个文件modules/group/main.tf

\n
resource "gitlab_group" "default_group" {\n  name        = var.name\n  path        = var.path\n  description = var.description\n  avatar      = var.avatar\n  avatar_hash = var.avatar != "" ? filesha256(var.avatar) : ""\n}\n
Run Code Online (Sandbox Code Playgroud)\n

创建文件modules/group/var.tf

\n
variable "name" {\n  type = string\n}\n\nvariable "path" {\n  type    = string\n  default = ""\n}\n\nvariable "description" {\n  type    = string\n  default = ""\n}\n\nvariable "avatar" {\n  description = "A local path to the avatar image to upload."\n  type        = string\n  default     = ""\n}\n
Run Code Online (Sandbox Code Playgroud)\n

在您的 terraform 文件中使用src/main.tf模块source = "../modules/group"

\n
module "gitlab_group_playground" {\n  source      = "../modules/group"\n  path        = "Playground"\n  name        = "playground"\n  description = "Try your ideas! Space for spikes! "\n  avatar      = "${path.root}/../img/playground.png"\n}\n
Run Code Online (Sandbox Code Playgroud)\n

行不通的方法

\n

不起作用 - 引用自身

\n
resource "gitlab_group" "playground" {\n  name        = "Playground"\n  path        = "playground"\n  description = "Try your ideas! Space for spikes! "\n  avatar      = "${path.root}/../img/playground.png"\n  avatar_hash = filesha256(resource.gitlab_group.playground.avatar)\n}\n
Run Code Online (Sandbox Code Playgroud)\n

错误 \xe2\x9d\x97\xe2\x9d\x97\xe2\x9d\x97:Configuration for gitlab_group.playground may not refer to itself.

\n

不起作用 - 使用self

\n
resource "gitlab_group" "playground" {\n  name        = "Playground"\n  path        = "playground"\n  description = "Try your ideas! Space for spikes! "\n  avatar      = "${path.root}/../img/playground.png"\n  avatar_hash =  filesha256(self.avatar)\n}\n
Run Code Online (Sandbox Code Playgroud)\n

错误 \xe2\x9d\x97\xe2\x9d\x97\xe2\x9d\x97:The "self" object is not available in this context. This object can be used only in resource provisioner, connection, and postcondition blocks.

\n

回答你的伪代码

\n
locals {\n  my_aws_hostname = "bastion-euw3-infra-01"\n}\n\nresource "aws_instance" "bastion-euw3-infra-01" {\n  ...\n\n  user_data = templatefile("./scripts/cloudinit.yaml", {\n    hostname          = local.my_aws_hostname\n    tailscale_authkey = var.tailscale_authkey\n  })\n\n  ...\n\n  tags = {\n    Name        = local.my_aws_hostname\n    Environment = "infra"\n  }\n\n  ...\n}\n
Run Code Online (Sandbox Code Playgroud)\n