Reputation: 19422
Here is my dir structure:
├── main.tf
├── modules
│ ├── subnets
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ ├── variables.tf
│ └── vpc
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
├── outputs.tf
└── variables.tf
and my modules/vpc/main.tf
resource "aws_vpc" "env_vpc" {
cidr_block = "${var.vpc_cidr_block}"
enable_dns_support = "${var.vpc_enable_dns_support}"
enable_dns_hostnames = "${var.vpc_enable_dns_hostnames}"
tags = {
Name = "${var.env_name}-vpc"
Provisioner = "Terraform"
}
lifecycle {
create_before_destroy = true
}
}
and my modules/vpc/variables.tf
variable "env_name" {
description = "The name of the env the VPC will belong to"
# no default provided
}
When I perform terraform plan
➢ terraform plan
Error: Missing required argument
on main.tf line 1, in module "vpc":
1: module "vpc" {
The argument "env_name" is required, but no definition was found.
When I pass the var in the cmd:
➢ terraform plan -var 'env_name=ffff'
Error: Value for undeclared variable
A variable named "env_name" was assigned on the command line, but the root
module does not declare a variable of that name. To use this value, add a
"variable" block to the configuration.
The problem does not go away even when I declare the variable in root variables.tf
as in
➢ cat variables.tf
variable "env_name" {}
any suggestions?
edit: When I provided a default
value for that variable, the plan
worked. It did ask me interactively for an env_name
value but the plan
output was with the default
value. Why is that?
edit2: Clarification about the contents of the variables.tf
files:
➢ ls
main.tf modules outputs.tf variables.tf
➢ cat variables.tf
variable "env_name" {}
In the modules/vpc
directory:
➢ ls
main.tf outputs.tf variables.tf
aws_vpc/modules/vpc stand_alone_vpc ✗
➢ cat variables.tf
variable "env_name" {
description = "The name of the environment/microservice the VPC will belong to"
default = "wbl"
}
It asks me to input the env_name
value, but it ignores it and makes use of the default
, as set in modules/vpc/variables.tf
. Here is the plan
:
➢ terraform plan
var.env_name
Enter a value: foo
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# module.vpc.aws_internet_gateway.env_igw will be created
+ resource "aws_internet_gateway" "env_igw" {
+ id = (known after apply)
+ owner_id = (known after apply)
+ tags = {
+ "Name" = "wbl-igw"
+ "Provisioner" = "Terraform"
}
+ vpc_id = (known after apply)
}
# module.vpc.aws_vpc.env_vpc will be created
+ resource "aws_vpc" "env_vpc" {
+ arn = (known after apply)
+ assign_generated_ipv6_cidr_block = false
+ cidr_block = "10.0.0.0/16"
+ default_network_acl_id = (known after apply)
+ default_route_table_id = (known after apply)
+ default_security_group_id = (known after apply)
+ dhcp_options_id = (known after apply)
+ enable_classiclink = (known after apply)
+ enable_classiclink_dns_support = (known after apply)
+ enable_dns_hostnames = true
+ enable_dns_support = true
+ id = (known after apply)
+ instance_tenancy = "default"
+ ipv6_association_id = (known after apply)
+ ipv6_cidr_block = (known after apply)
+ main_route_table_id = (known after apply)
+ owner_id = (known after apply)
+ tags = {
+ "Name" = "wbl-vpc"
+ "Provisioner" = "Terraform"
}
}
Plan: 2 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
Upvotes: 1
Views: 10297
Reputation: 19422
It seems that the way around this (i.e. to be able to override the default
value set in the submodule's variable.tf
) is the following:
1) declare the variable in the top (root) level variables.tf
, as in
> $ cat variables.tf
variable "env_name" {
default = "top-level"
}
2) set the variable value in the section of root's module main.tf
that calls the submodule, as in:
module "vpc" {
source = "./modules/vpc"
# variables
env_name = "${var.env_name}"
}
This way, the variable that will end up being passed to the submodule, is the one declared in the parent module's variables.tf
Upvotes: 4