Terraform - 无法将字符串变量传递给子模块
Terraform - Unable to pass string variable to child module
我有一些嵌套模块的 terraform 设置。简化后看起来像这样
├── modules
│ ├── sec-groups
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ ├── variables.tf
│ │ └── versions.tf
├── dev
│ ├── env.dev.tfvars
│ ├── main.tf
│ ├── versions.tf
│ └── variables.tf
└── prod
├── env.prod.tfvars
├── main.tf
├── versions.tf
└── variables.tf
开发中的位置:
main.tf
module "aws_dev_sec-groups" {
source = "../modules/sec-groups"
vpc_name = aws_vpc.dev_bp_vpc
vpc_id = aws_vpc.dev_bp_vpc.id
localip = var.localip
}
variables.tf
variable "localip" {
type = string
}
env.dev.tfvars
localip = "1.1.1.1/32"
并且在 sec-groups 模块中:
main.tf
resource "aws_security_group" "servers_sg" {
name = "servers_sg"
description = "Traffic allowed to and from Servers"
vpc_id = var.vpc_id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = [var.localip]
}
}
variables.tf
variable vpc_id {}
variable localip {
type = string
}
--
'terraform init' 产生了预期的结果。但是,'terraform plan' 会产生以下错误。对我来说,这意味着一个空的 localip 变量,这意味着我没有正确声明变量,是这样吗?
Error: "" is not a valid CIDR block: invalid CIDR address:
on ../modules/sec-groups/main.tf line 63, in resource "aws_security_group" "servers_sg":
63: resource "aws_security_group" "servers_sg" {
}
提前致谢
--
% terraform -v
Terraform v0.13.0
+ provider registry.terraform.io/hashicorp/aws v3.2.0
+ provider registry.terraform.io/hashicorp/random v2.3.0
来自 .tfvars
文件的变量被分配给根模块。
如果您发布的代码实际上是在根级别,当您指定 -var-file
.
时,它将起作用
如果它实际上不在根级别,您很可能没有正确传递 localip
变量。您看到 Error: "" is not a valid CIDR block: invalid CIDR address:
的事实表明您在某处传递了一个空字符串。如果你没有正确加载 .tfvars
而上面的代码实际上是在根级别,你会得到一个不同的错误(缺少变量),因为你没有为 localip
变量提供默认值。
事实证明我完全miss-understood 模块是如何工作的。我假设子模块需要通过在子模块中指定多个模块块来使用来自父模块或其他子模块的变量。我发现我正在将变量从多个子模块传递到每个子模块,事后看来这似乎很奇怪但当时并没有。
这意味着一些子模块在循环中尝试 re-instantiate 多次,因此出现错误消息。我现在意识到野兽方法是让父模块调用子模块的输出值传递给其他子模块,子模块不应该使用与父模块中相同的变量相互引用。
感谢所有与此相关的指点,对于 red-herring 引用 localip 变量表示歉意。
我有一些嵌套模块的 terraform 设置。简化后看起来像这样
├── modules
│ ├── sec-groups
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ ├── variables.tf
│ │ └── versions.tf
├── dev
│ ├── env.dev.tfvars
│ ├── main.tf
│ ├── versions.tf
│ └── variables.tf
└── prod
├── env.prod.tfvars
├── main.tf
├── versions.tf
└── variables.tf
开发中的位置:
main.tf
module "aws_dev_sec-groups" {
source = "../modules/sec-groups"
vpc_name = aws_vpc.dev_bp_vpc
vpc_id = aws_vpc.dev_bp_vpc.id
localip = var.localip
}
variables.tf
variable "localip" {
type = string
}
env.dev.tfvars
localip = "1.1.1.1/32"
并且在 sec-groups 模块中:
main.tf
resource "aws_security_group" "servers_sg" {
name = "servers_sg"
description = "Traffic allowed to and from Servers"
vpc_id = var.vpc_id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = [var.localip]
}
}
variables.tf
variable vpc_id {}
variable localip {
type = string
}
--
'terraform init' 产生了预期的结果。但是,'terraform plan' 会产生以下错误。对我来说,这意味着一个空的 localip 变量,这意味着我没有正确声明变量,是这样吗?
Error: "" is not a valid CIDR block: invalid CIDR address:
on ../modules/sec-groups/main.tf line 63, in resource "aws_security_group" "servers_sg":
63: resource "aws_security_group" "servers_sg" {
}
提前致谢
--
% terraform -v
Terraform v0.13.0
+ provider registry.terraform.io/hashicorp/aws v3.2.0
+ provider registry.terraform.io/hashicorp/random v2.3.0
来自 .tfvars
文件的变量被分配给根模块。
如果您发布的代码实际上是在根级别,当您指定 -var-file
.
如果它实际上不在根级别,您很可能没有正确传递 localip
变量。您看到 Error: "" is not a valid CIDR block: invalid CIDR address:
的事实表明您在某处传递了一个空字符串。如果你没有正确加载 .tfvars
而上面的代码实际上是在根级别,你会得到一个不同的错误(缺少变量),因为你没有为 localip
变量提供默认值。
事实证明我完全miss-understood 模块是如何工作的。我假设子模块需要通过在子模块中指定多个模块块来使用来自父模块或其他子模块的变量。我发现我正在将变量从多个子模块传递到每个子模块,事后看来这似乎很奇怪但当时并没有。
这意味着一些子模块在循环中尝试 re-instantiate 多次,因此出现错误消息。我现在意识到野兽方法是让父模块调用子模块的输出值传递给其他子模块,子模块不应该使用与父模块中相同的变量相互引用。
感谢所有与此相关的指点,对于 red-herring 引用 localip 变量表示歉意。