I am new to terraform, I am learning modules. I am stuck in a problem.
I have modules folder as root which contain two folders EC2
and IAM
and they have terraform code in them. In the same modules folder I have main.tf
file which is a module file for calling EC2 instance terraform code.
For your information, EC2 instance folder contain two files one for instance resource and second is for defining variables.
My EC2 file looks like this.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}
# Configure the AWS Provider
provider "aws" {
region = "us-east-1"
}
resource "aws_instance" "web" {
count = "${var.ec2_count}"
ami = "${var.ami}"
instance_type = "${var.instance_type}"
tags = {
Name = "App_Instance"
}
}
My Variable.tf
file looks like this.
variable "ec2_count" {
type = number
default = 1
}
variable "ami" {
type = string
}
variable "instance_type" {
type = string
}
My main.tf
file looks like this.
module "EC2" {
source = "./EC2"
}
Now I want that when I type terraform plan
command, it should take input at the command prompt but it is showing me below error.
PS: I don't want to pass the value of the variable in the module.
C:\Users\PC\Desktop\AWS_Modules\Modules>terraform plan
╷
│ Error: Missing required argument
│
│ on main.tf line 1, in module "EC2":
│ 1: module "EC2" {
│
│ The argument "ami" is required, but no definition was found.
╵
╷
│ Error: Missing required argument
│
│ on main.tf line 1, in module "EC2":
│ 1: module "EC2" {
│
│ The argument "instance_type" is required, but no definition was found.
CodePudding user response:
Since you are new to modules, there are a few things to consider:
- Where are you defining the variables
- How are you passing the values to variables required by the module
Ideally, you would pass the values to variables when calling the module:
module "EC2" {
source = "./EC2"
ami = "ami-gafadfafa"
instance_type = "t3.micro"
}
However, since you said you do not want to do that, then you need to assign the default values to variables on the module level. This can be achieved with:
variable "ec2_count" {
type = number
default = 1
}
variable "ami" {
type = string
default = "ami-gafadfafa"
}
variable "instance_type" {
type = string
default = "t3.micro"
}
This way, if you do not provide values when calling the module, the instance will be created and you are still leaving the option to provide the values if someone else were to use your module.
The third option is to have a separate variables.tf
file in the root module (i.e., the same directory where you are calling the module from) and not define the values for variables. It would be basically a copy paste of the file you have on the module level without defining any default values. Here is an example:
# variables.tf on the root module level
variable "ec2_count" {
type = number
}
variable "ami" {
type = string
}
variable "instance_type" {
type = string
}
However, in this case, it is impossible not to use the input variable names when calling the module. For this to work with providing the values on the CLI, the code would have to change to:
module "EC2" {
source = "./EC2"
ec2_count = var.ec2_count
ami = var.ami
instance_type = var.instance_type
}
There is no other way the module can know how to map the values you want it to consume without actually setting those variables to a certain value when calling the module.