Terraform 中用于 aws 安全组的变量值
Variable values in Terraform for aws security groups
我是 terraform 的新手,正在尝试创建一个具有入口和出口规则的 AWS 安全组。我没有对值进行硬编码并创建多个入口和出口块,而是尝试使用 terraform lookup
函数。
main.tf
文件如下所示:
provider "aws" {
version = "~> 2.0"
region = var.region
profile = var.profile
}
resource "aws_security_group" "this" {
name = "test-sg"
description = "test security group"
dynamic "ingress" {
for_each = var.ingress_rules
content {
description = lookup(ingress.value, "description", null)
from_port = lookup(ingress.value, "from_port", null)
to_port = lookup(ingress.value, "to_port", null)
protocol = lookup(ingress.value, "protocol", null)
cidr_blocks = lookup(ingress.value, "cidr_blocks", null)
}
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "test-sg"
}
}
variables.tf
文件看起来像这样
variable "ingress_rules" {
default = {
"description" = ["For HTTP", "For SSH"]
"from_port" = ["80", "22"]
"to_port" = ["80", "22"]
"protocol" = ["tcp", "tcp"]
"cidr_blocks" = ["0.0.0.0/0", "0.0.0.0/0"]
}
type = map(list(string))
description = "Security group rules"
}
当我运行terraform validate
时显示配置有效,当我运行terraform plan
时显示如下错误:
ingress.value is list of string with 2 elements
Invalid value for "inputMap" parameter: lookup() requires a map as the first
argument.
花了很长时间,我还是想不出如何解决这个错误。将查找值传递到 variables.tf
文件的正确方法是什么。
您已将变量的默认值构建为五个映射,其中包含一个字符串键和一个字符串列表值。您可能想要一个包含一系列与入口规则的各种属性关联的键和值的映射。您可以相应地更新变量值,例如:
variable "ingress_rules" {
default = {
"my ingress rule" = {
"description" = "For HTTP"
"from_port" = "80"
"to_port" = "80"
"protocol" = "tcp"
"cidr_blocks" = ["0.0.0.0/0"]
},
"my other ingress rule" = {
"description" = "For SSH"
"from_port" = "22"
"to_port" = "22"
"protocol" = "tcp"
"cidr_blocks" = ["0.0.0.0/0"]
}
}
type = map(any)
description = "Security group rules"
}
现在,在您的 for_each
迭代器中,第一个 ingress.key
的值将是 my ingress rule
,而第一个 ingress.value
的值将是您的整个地图键和字符串。以前,第一个 ingress.key
是 description
,第一个值是 ["For HTTP", "For SSH"]
。这就是您收到该错误的原因:您无法从 ["For HTTP", "For SSH"]
列表中使用键 description
查找值。进行此变量值更新后,您应该会有预期的行为。
请注意,您可以使用对象进一步优化类型:
default = {
"my ingress rule" = {
description = "For HTTP"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
},
"my other ingress rule" = {
description = "For SSH"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
type = map(object({
description = string
from_port = number
to_port = number
protocol = string
cidr_blocks = list(string)
}))
我会按如下方式实现它:
resource "aws_security_group" "test_security_group" {
name = "test-sg"
description = "test security group"
dynamic "ingress" {
for_each = var.sg_ingress_rules
content {
from_port = ingress.value.from_port
to_port = ingress.value.to_port
protocol = ingress.value.protocol
cidr_blocks = ingress.value.cidr_blocks
description = ingress.value.description
}
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "test security group"
}
}
variables.tf
variable "sg_ingress_rules" {
description = "Ingress security group rules"
type = map
}
my_vars.tfvars
sg_ingress_rules = {
"1" = {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
description = "HTTP"
},
"2" = {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["<my_private_ip>/32"]
description = "SSH"
}
}
希望对理解有帮助!
我是 terraform 的新手,正在尝试创建一个具有入口和出口规则的 AWS 安全组。我没有对值进行硬编码并创建多个入口和出口块,而是尝试使用 terraform lookup
函数。
main.tf
文件如下所示:
provider "aws" {
version = "~> 2.0"
region = var.region
profile = var.profile
}
resource "aws_security_group" "this" {
name = "test-sg"
description = "test security group"
dynamic "ingress" {
for_each = var.ingress_rules
content {
description = lookup(ingress.value, "description", null)
from_port = lookup(ingress.value, "from_port", null)
to_port = lookup(ingress.value, "to_port", null)
protocol = lookup(ingress.value, "protocol", null)
cidr_blocks = lookup(ingress.value, "cidr_blocks", null)
}
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "test-sg"
}
}
variables.tf
文件看起来像这样
variable "ingress_rules" {
default = {
"description" = ["For HTTP", "For SSH"]
"from_port" = ["80", "22"]
"to_port" = ["80", "22"]
"protocol" = ["tcp", "tcp"]
"cidr_blocks" = ["0.0.0.0/0", "0.0.0.0/0"]
}
type = map(list(string))
description = "Security group rules"
}
当我运行terraform validate
时显示配置有效,当我运行terraform plan
时显示如下错误:
ingress.value is list of string with 2 elements
Invalid value for "inputMap" parameter: lookup() requires a map as the first
argument.
花了很长时间,我还是想不出如何解决这个错误。将查找值传递到 variables.tf
文件的正确方法是什么。
您已将变量的默认值构建为五个映射,其中包含一个字符串键和一个字符串列表值。您可能想要一个包含一系列与入口规则的各种属性关联的键和值的映射。您可以相应地更新变量值,例如:
variable "ingress_rules" {
default = {
"my ingress rule" = {
"description" = "For HTTP"
"from_port" = "80"
"to_port" = "80"
"protocol" = "tcp"
"cidr_blocks" = ["0.0.0.0/0"]
},
"my other ingress rule" = {
"description" = "For SSH"
"from_port" = "22"
"to_port" = "22"
"protocol" = "tcp"
"cidr_blocks" = ["0.0.0.0/0"]
}
}
type = map(any)
description = "Security group rules"
}
现在,在您的 for_each
迭代器中,第一个 ingress.key
的值将是 my ingress rule
,而第一个 ingress.value
的值将是您的整个地图键和字符串。以前,第一个 ingress.key
是 description
,第一个值是 ["For HTTP", "For SSH"]
。这就是您收到该错误的原因:您无法从 ["For HTTP", "For SSH"]
列表中使用键 description
查找值。进行此变量值更新后,您应该会有预期的行为。
请注意,您可以使用对象进一步优化类型:
default = {
"my ingress rule" = {
description = "For HTTP"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
},
"my other ingress rule" = {
description = "For SSH"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
type = map(object({
description = string
from_port = number
to_port = number
protocol = string
cidr_blocks = list(string)
}))
我会按如下方式实现它:
resource "aws_security_group" "test_security_group" {
name = "test-sg"
description = "test security group"
dynamic "ingress" {
for_each = var.sg_ingress_rules
content {
from_port = ingress.value.from_port
to_port = ingress.value.to_port
protocol = ingress.value.protocol
cidr_blocks = ingress.value.cidr_blocks
description = ingress.value.description
}
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "test security group"
}
}
variables.tf
variable "sg_ingress_rules" {
description = "Ingress security group rules"
type = map
}
my_vars.tfvars
sg_ingress_rules = {
"1" = {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
description = "HTTP"
},
"2" = {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["<my_private_ip>/32"]
description = "SSH"
}
}
希望对理解有帮助!