I've created a module which does port-forwarding for VM's and theres a variable inside of type list(object) which I am having trouble referring to.
There's a main.tf file inside proxmox-instance (tree included below) with our variable inside of it. It has a for_each loop and I am trying to use the objects inside the variable loop of./proxmox-instance/main.tf on a different directry - the. directory inside./main.tf.
.
├── main.tf
├── output.tf
└── proxmox-instance
├── main.tf
├── output.tf
├── providers.tf
└── variables.tf
I do not fully understand how the syntax works when referring variables from a different folder.
Here's the code snippet
variable "forwarded_ports" {
description = "Your Template name - Will be cloned from this template"
type = list(object({
host_port = number
guest_port = number
}))
default = [{
"host_port" = 2222,
"guest_port" = 22
}]
}
The./proxmox-instance/main.tf looks like this
resource "iptables_nat" "dnat-front" {
# Creates an entry for each template specified
for_each = [for k in forwarded_ports : k]
name = "iptable-${var.vm_name}-${each.value.host_port}-to-${each.value.guest_port}"
on_cidr_blocks = ["195.201.172.34"] # Proxmox network device IP here
dnat {
iface = "enp7s0"
protocol = "tcp"
to_port = each.value.host_port # Custom Port for ingress connections
nat_ip = "${proxmox_vm_qemu.vm.default_ipv4_address}:${each.value.guest_port}" # VM Internal IP here
}
}
forwarded_ports.host_port
forwarded_ports.guest_port
module "instance" {
source = "./proxmox-instance"
vm_name = "Terraform"
template_name = "ubuntu-20.04"
# cloud-init settings
ipconfig0 = "ip=dhcp"
cloud_init_user = "ubuntu"
cloud_init_password = "password"
forwarded_ports.host_port = 2222
forwarded_ports.guest_port = 22
}
I've tried playing with the syntax for host / guest port but couldn't fully understand it and so and kept receving errors..
Output 1/2
forwarded_ports.host_port = 2222
forwarded_ports.guest_port = 22
Error: Argument or block definition required
│
│ on main.tf line 17, in module "instance":
│ 17: forwarded_ports.guest_port = 22
│
│ An argument or block definition is required here. To set an argument, use the equals sign "=" to introduce the argument value.
Output 2/2
forwarded_ports = [{
host_port = 2222
guest_port = 22
}]
│ Error: Missing required argument
│
│ on main.tf line 5, in module "instance":
│ 5: module "instance" {
│
│ The argument "host_port" is required, but no definition was found.
│ Error: Missing required argument
│
│ on main.tf line 5, in module "instance":
│ 5: module "instance" {
│
│ The argument "guest_port" is required, but no definition was found.
In my opinion, at least two things are wrong [could be more because of missing code I can not commit]
1: In your ./proxmox-instance/main.tf
the for_each = [for k in forwarded_ports: k]
needs to refer to a variable defined in terraform.
Correct Reference:
resource "iptables_nat" "dnat-front" {
# Creates an entry for each template specified
for_each = [for k in var.forwarded_ports : k] ## change is ** var.forwarded_ports **
name = "iptable-${var.vm_name}-${each.value.host_port}-to-${each.value.guest_port}"
on_cidr_blocks = ["195.201.172.34"] # Proxmox network device IP here
dnat {
iface = "enp7s0"
protocol = "tcp"
to_port = each.value.host_port # Custom Port for ingress connections
nat_ip = "${proxmox_vm_qemu.vm.default_ipv4_address}:${each.value.guest_port}" # VM Internal IP here
}
}
[for k in var.forwarded_ports: k]
will give you following tuple on which you have work in your module interface call.
[
{
"guest_port" = 22
"host_port" = 2222
},
]
you can verify this in terraform console. More Details on Terraform Console at here
2: Your module interface call is also wrong, the error message An argument or block definition is required here. To set an argument, use the equals sign "=" to introduce the argument value.
An argument or block definition is required here. To set an argument, use the equals sign "=" to introduce the argument value.
is complaining about the forwarded_ports.host_port = 2222
and forwarded_ports.guest_port = 22
.
As the code snippet pasted is not complete here, seems like a few other variables and resources are missing. Please try to use something like
module "instance" {
source = "./proxmox-instance"
vm_name = "Terraform"
template_name = "ubuntu-20.04"
# cloud-init settings
ipconfig0 = "ip=dhcp"
cloud_init_user = "ubuntu"
cloud_init_password = "password"
## module will refer to the variables and then pass them in the correct type.
forwarded_ports = [
{
host_port = 2222
guest_port = 22
},
{
host_port = another_value
guest_port = another_value
},
]
}
I hope this helps.
When using an object in a variable, you have to define it in much the same way that your default is used within the module.
The first error you get explains it best:
Error: Argument or block definition required
│
│ on main.tf line 17, in module "instance":
│ 17: forwarded_ports.guest_port = 22
│
│ An argument or block definition is required here. To set an argument, use the equals sign "=" to introduce the argument value.
To reference the forwarded_ports
variable in your module, you should pass it as an argument to the module.
Here is the correct syntax:
module "instance" {
source = "./proxmox-instance"
vm_name = "Terraform"
template_name = "ubuntu-20.04"
# cloud-init settings
ipconfig0 = "ip=dhcp"
cloud_init_user = "ubuntu"
cloud_init_password = "password"
forwarded_ports = [{
host_port = 2222
guest_port = 22
}]
}
variables
inside of modules are inputs in the module block. Any variable that does NOT contain a default is required, and those that contain a default are optional.
The second error from Output 2/2 :
│ Error: Missing required argument
│
│ on main.tf line 5, in module "instance":
│ 5: module "instance" {
│
│ The argument "host_port" is required, but no definition was found.
Indicates that there are additional variables named host_port
and guest_port
that are unrelated to the forwarded_ports
variable and are apparently required. Your code isn't showing this, but I suspect you'll find both of these in your module variables.tf
file. The likely reason you're seeing this error is because you're correctly defining forwarded_ports
in that example, but missing other unrelated arguments with names that are confusing you.
To understand more about module inputs, see Terraform's documentation on Input Variables .
./proxmox-instance/main.tf
resource "iptables_nat" "dnat-front" {
# Creates an entry for each template specified
for_each = [for k in forwarded_ports : k]
...
This should be var.forwarded_ports
and should look something like this:
resource "iptables_nat" "dnat-front" {
for_each = [for k in var.forwarded_ports : k]
name = "iptable-${var.vm_name}-${each.value.host_port}-to-${each.value.guest_port}"
on_cidr_blocks = ["195.201.172.34"] # Proxmox network device IP here
dnat {
iface = "enp7s0"
protocol = "tcp"
to_port = each.value.host_port
nat_ip = "${proxmox_vm_qemu.vm.default_ipv4_address}:${each.value.guest_port}" # VM Internal IP here
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.