如何从 Terraform 输出中传递值而不将其放入 tfvars 文件中

Posted

技术标签:

【中文标题】如何从 Terraform 输出中传递值而不将其放入 tfvars 文件中【英文标题】:How to pass values from the Terraform output without putting it in the tfvars file 【发布时间】:2021-11-22 16:08:08 【问题描述】:

一切都好吗?

我正在研究如何使用 terraform 进行 eks 部署,作为一种好习惯,我将其分成模块以使其可重用,但是当我在 testcluster-vpc 中运行计划时,生成的输出是公共子网和私有子网以及vpc_id ,我如何使用这些参数而不需要将这些值放在terraform.tfvars 中的testcluster 文件夹中?

我考虑过使用 Data Sources ,但它不起作用,它仍然要求在计划期间传递值

我把结构弄明白了

├── testclusters
│   ├── config.tf
│   ├── main.tf
│   ├── output.tf
│   ├── terraform.tfvars
│   └── variables.tf
├── testclusters-vpc
│   ├── config.tf
│   ├── main.tf
│   ├── outputs.tf
│   ├── terraform.tfvars
│   └── variables.tf
├── modules
│   ├── cluster
│   │   ├── eks_control_plane.tf
│   │   ├── eks_workers.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   ├── eks-control-plane
│   │   ├── iam.tf
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   ├── security-groups.tf
│   │   └── variables.tf
│   ├── eks-vpc
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   └── eks-workers
│       ├── authconfig.tf
│       ├── iam.tf
│       ├── main.tf
│       ├── outputs.tf
│       ├── security-groups.tf
│       ├── user-data.tf
│       └── variables.tf
└── terraform-state
    ├── config.tf
    ├── terraform-state-dynamodb.tf
    ├── terraform-state-s3.tf
    ├── terraform.tfstate
    ├── terraform.tfstate.backup
    ├── terraform.tfvars
    └── variables.tf
module "testcluster" 
  source                = "../modules/cluster"
  vpc_id                = data.aws_vpc.vpc.id # var.vpc_id
  public_subnets        = data.aws_subnet_ids.public.ids # var.public_subnet_ids
  private_subnets       = data.aws_subnet_ids.private.ids # var.private_subnet_ids
  cluster_full_name     = "$var.clusters_name_prefix-$terraform.workspace"
  cluster_version       = var.cluster_version
  workers_instance_type = var.workers_instance_type
  workers_ami_id        = data.aws_ssm_parameter.workers_ami_id.value
  workers_number_min    = var.workers_number_min
  workers_number_max    = var.workers_number_max
  workers_storage_size  = var.workers_storage_size
  commom_tags           = local.commom_tags
  aws_region            = var.aws_region


locals 
  commom_tags = 
    ManagedBy   = "terraform"
    ClusterName = "$var.clusters_name_prefix-$terraform.workspace"
  

这是生成 VPC 参数以创建集群的输出文件

output "vpc_id" 
  value = module.vpc.eks_cluster_vpc_id


output "private_subnet_ids" 
  value = module.vpc.eks_private_subnet_ids


output "public_subnets_ids" 
  value = module.vpc.eks_public_subnet_ids


【问题讨论】:

“我考虑过使用数据源,但它没有工作它仍然要求在计划期间传递值”你能分享你在这里尝试的内容以及运行时的输出吗?这应该可以正常工作,但要告诉您当前哪里出了问题并不容易。 @ydaetskcoR 您好,感谢您的回答,我尝试使用 terraform state 方法,但正如我所说这不是一个好习惯,我需要知道的是如何获取输出值​​​从 testcluster-vpc 文件夹中并在 testcluster 文件夹内的 main.tf 文件中使用它,因此您不需要将这些值传递给 Tfvars 【参考方案1】:

正如我所不知道的,您想使用从一个 terraform 文件夹到另一个文件夹的输出变量。使用terraform_remote_state 实现此目的的一种方法

EX : 在testcluster-vpc 文件夹中,在地图中公开输出

output "testclusters_vpc_net" 
  value = 
    "vpc_id"             = module.vpc.eks_cluster_vpc_id
    "private_subnet_ids" = module.vpc.eks_private_subnet_ids
    "public_subnets_ids" = module.vpc.eks_public_subnet_ids
    
  

testcluster 文件夹中引用testcluster-vpc 文件夹中的 terraform 状态文件,例如

data "terraform_remote_state" "testcluster-vpc" 
  backend = "s3"

  config = 
    bucket = "<bucket-name>"
    key    = "<path-to-tfstate-file>"
    region = "<region>"
  

现在您可以访问这些值

vpc_id = data.terraform_remote_state.testcluster-vpc.outputs.testclusters_vpc_net.vpc_id

注意:要实现此testclusters_vpc_net 应始终在testcluster 文件夹之前运行以访问更新的远程状态及其输出

【讨论】:

对于拥有原生数据源的事物,请停止推荐使用远程状态数据源。相比之下,它过于复杂并且配置起来很痛苦。它也没有解决这个特定问题,因为 OP 尝试使用正确的本机数据源,但仍然有一个变量提示,所以看起来他们配置错误。 你能解释一下为什么使用远程状态过于复杂和痛苦吗?其简单的配置,以及使用本地日期源的替代方案并解决了目的。我不明白它是如何解决的。 @SuryaPrakashPatel 查看官方文档,似乎 Hashicorp 支持这种使用状态的方式,我在文档+ subnets = data.terraform_remote_state.vpc.outputs.public_subnet_ids 中看到了此摘录,但现在出现此错误Error: Unsupported attribute on main.tf line 4, in module "testcluster": 4: public_subnets = data.terraform_remote_state.vpc.outputs.public_subnet_ids data.terraform_remote_state.vpc.outputs is object with 3 attributes This object does not have an attribute named "public_subnet_ids". 确保您已应用计划并应用,并确保输出及其格式存在于您所引用的状态文件中。您可以通过转储状态文件进行检查或使用 terraform 输出命令进行检查 @SuryaPrakashPatel 你好,我在这里做了测试,现在成功了,非常感谢! ,上一次运行的错误是 private_subnet_ids 缺少 (.)

以上是关于如何从 Terraform 输出中传递值而不将其放入 tfvars 文件中的主要内容,如果未能解决你的问题,请参考以下文章

如何访问对象而不将其作为参数传递?

jQuery:如何在事件处理函数中获取事件对象而不将其作为参数传递?

如何将一些信息传递给视图而不将其包含在 URL 中(django 新手)

如何发布数据而不将其传递给模型.Net Core

如何将 package.json 导入 Typescript 文件而不将其包含在编译输出中?

如何自动将用户信息传递给 Bot Framework 对话实例,而不将其作为显式消息发布在聊天窗口中?