【问题标题】:Terraform: module outputs not being recognised as variablesTerraform:模块输出未被识别为变量
【发布时间】:2019-04-29 08:00:17
【问题描述】:

我想只是一个快速的理智检查,也许我的眼睛变得混乱了。我正在将一个单一的 terraform 文件分解为模块。

我的main.tf 只调用两个模块,gke 用于 google kubernetes 引擎,storage 在之前创建的集群上创建一个持久卷。

模块gke 有一个outputs.tf,它输出以下内容:

output "client_certificate" {
  value     = "${google_container_cluster.kube-cluster.master_auth.0.client_certificate}"
 sensitive = true
}
output "client_key" {
  value     = "${google_container_cluster.kube-cluster.master_auth.0.client_key}"
 sensitive = true
}
output "cluster_ca_certificate" {
  value     = "${google_container_cluster.kube-cluster.master_auth.0.cluster_ca_certificate}"
 sensitive = true
}
output "host" {
  value     = "${google_container_cluster.kube-cluster.endpoint}"
 sensitive = true
}

那么在存储模块的main.tf中,我有:

client_certificate     = "${base64decode(var.client_certificate)}"
client_key             = "${base64decode(var.client_key)}"
cluster_ca_certificate = "${base64decode(var.cluster_ca_certificate)}"
host     = "${var.host}"

然后在根 main.tf 我有以下内容:

client_certificate = "${module.gke.client_certificate}"
client_key = "${module.gke.client_key}"
cluster_ca_certificate = "${module.gke.cluster_ca_certificate}"
host = "${module.gke.host}"

在我看来,它看起来是正确的。 certs、key和host变量的值应该由outputs.tfgke模块输出,由root的main.tf拾取,然后作为常规变量传递给storage

我是不是弄错了?还是我快疯了,似乎有些不对劲。

当我运行一个计划时,我被问到变量没有被填充。

编辑:

添加一些附加信息,包括我的代码。

如果我为它要求的变量手动添加虚拟条目,我会收到以下错误:

Macbook: $ terraform plan
var.client_certificate
  Enter a value: 1

var.client_key
  Enter a value: 2

var.cluster_ca_certificate
  Enter a value: 3

var.host
  Enter a value: 4
...
(filtered out usual text)
...
 * module.storage.data.google_container_cluster.kube-cluster: 1 error(s) occurred:

* module.storage.data.google_container_cluster.kube-cluster: data.google_container_cluster.kube-cluster: project: required field is not set

它似乎在抱怨 data.google_container_cluster 资源需要项目属性。但它不是一个有效的资源。是给提供者的,但它是为提供者填写的。

代码如下:

文件夹结构:

root-folder/
├── gke/
│   ├── main.tf
│   ├── outputs.tf
│   ├── variables.tf
├── storage/
│   ├── main.tf
│   └── variables.tf
├── main.tf
├── staging.json
├── terraform.tfvars
└── variables.tf

根文件夹/gke/main.tf:

provider "google" {
  credentials = "${file("staging.json")}"
  project     = "${var.project}"
  region      = "${var.region}"
  zone        = "${var.zone}"
}

resource "google_container_cluster" "kube-cluster" {
  name               = "kube-cluster"
  description        = "kube-cluster"
  zone               = "europe-west2-a"
  initial_node_count = "2"
  enable_kubernetes_alpha = "false"
  enable_legacy_abac = "true"

  master_auth {
    username = "${var.username}"
    password = "${var.password}"
  }

  node_config {
    machine_type = "n1-standard-2"
    disk_size_gb = "20"
    oauth_scopes = [
      "https://www.googleapis.com/auth/compute",
      "https://www.googleapis.com/auth/devstorage.read_only",
      "https://www.googleapis.com/auth/logging.write",
      "https://www.googleapis.com/auth/monitoring"
    ]
  }
}

根文件夹/gke/outputs.tf:

output "client_certificate" {
  value     = "${google_container_cluster.kube-cluster.master_auth.0.client_certificate}"
 sensitive = true
}
output "client_key" {
  value     = "${google_container_cluster.kube-cluster.master_auth.0.client_key}"
 sensitive = true
}
output "cluster_ca_certificate" {
  value     = "${google_container_cluster.kube-cluster.master_auth.0.cluster_ca_certificate}"
 sensitive = true
}
output "host" {
  value     = "${google_container_cluster.kube-cluster.endpoint}"
 sensitive = true
}

根文件夹/gke/variables.tf:

variable "region" {
  description = "GCP region, e.g. europe-west2"
  default = "europe-west2"
}
variable "zone" {
  description = "GCP zone, e.g. europe-west2-a (which must be in gcp_region)"
  default = "europe-west2-a"
}
variable "project" {
  description = "GCP project name"
}
variable "username" {
  description = "Default admin username"
}
variable "password" {
  description = "Default admin password"
}

/root-folder/storage/main.cf:

provider "kubernetes" {
  host     = "${var.host}"
  username = "${var.username}"
  password = "${var.password}"
  client_certificate     = "${base64decode(var.client_certificate)}"
  client_key             = "${base64decode(var.client_key)}"
  cluster_ca_certificate = "${base64decode(var.cluster_ca_certificate)}"
}
data "google_container_cluster" "kube-cluster" {
  name   = "${var.cluster_name}"
  zone   = "${var.zone}"
}
resource "kubernetes_storage_class" "kube-storage-class" {
  metadata {
    name = "kube-storage-class"
  }
  storage_provisioner = "kubernetes.io/gce-pd"
  parameters {
    type = "pd-standard"
  }
}
resource "kubernetes_persistent_volume_claim" "kube-claim" {
  metadata {
    name      = "kube-claim"
  }
  spec {
    access_modes       = ["ReadWriteOnce"]
    storage_class_name = "kube-storage-class"
    resources {
      requests {
        storage = "10Gi"
      }
    }
  }
}

/root/storage/variables.tf:

variable "username" {
  description = "Default admin username."
}
variable "password" {
  description = "Default admin password."
}
variable "client_certificate" {
  description = "Client certificate, output from the GKE/Provider module."
}
variable "client_key" {
  description = "Client key, output from the GKE/Provider module."
}
variable "cluster_ca_certificate" {
  description = "Cluster CA Certificate, output from the GKE/Provider module."
}
variable "cluster_name" {
  description = "Cluster name."
}
variable "zone" {
  description = "GCP Zone"
}
variable "host" {
  description = "Host endpoint, output from the GKE/Provider module."
}

/根文件夹/main.tf:

module "gke" {
  source = "./gke"
  project = "${var.project}"
  region = "${var.region}"
  username = "${var.username}"
  password = "${var.password}"
}
module "storage" {
  source = "./storage"
  host = "${module.gke.host}"
  username = "${var.username}"
  password = "${var.password}"
  client_certificate = "${module.gke.client_certificate}"
  client_key = "${module.gke.client_key}"
  cluster_ca_certificate = "${module.gke.cluster_ca_certificate}"
  cluster_name = "${var.cluster_name}"
  zone = "${var.zone}"
}

/根文件夹/variables.tf:

variable "project" {}
variable "region" {}
variable "username" {}
variable "password" {}
variable "gc_disk_size" {}
variable "kpv_vol_size" {}
variable "host" {}
variable "client_certificate" {}
variable "client_key" {}
variable "cluster_ca_certificate" {}
variable "cluster_name" {}
variable "zone" {}

出于显而易见的原因,我不会粘贴 staging.jsonterraform.tfvars 的内容 :)

【问题讨论】:

  • 在你的状态和“terraform output”中你有价值观吗?
  • 无法分辨两者,因为它没有走那么远。一旦我运行一个计划,它就会询问变量的值。我已经输入了虚拟值,但是我还有其他需要解决的错误。我在输出中看不到任何内容,并且 tfstate 永远不会填充。
  • 更多的是进行健全性检查,以确保一切正常。也许是其他问题造成的?
  • 从您的解释来看,我认为这是有道理的,但是由于没有看到所有代码和所有错误消息,我们缺少一些东西。
  • 抱歉,我发现很难用有限的信息提供帮助。我已经用我现在得到的错误以及所有代码和文件夹结构更新了原始帖子。希望这会有所帮助。感谢收看,非常感谢。

标签: kubernetes terraform devops terraform-provider-gcp


【解决方案1】:

在您的/root-folder/variables.tf 中,删除以下条目:

variable "host" {}
variable "client_certificate" {}
variable "client_key" {}
variable "cluster_ca_certificate" {}

这些不是根级别的 Terraform 代码需要的变量。相反,它们被作为 1 个模块的输出 --> 输入到第 2 个模块。

【讨论】:

  • 非常好,感谢您的理解和回答。就这样搞定了。
猜你喜欢
  • 2021-01-11
  • 2021-07-13
  • 2021-05-06
  • 2017-01-19
  • 1970-01-01
  • 2019-10-06
  • 2020-12-08
  • 2017-03-05
  • 1970-01-01
相关资源
最近更新 更多