learner
learner

Reputation: 2840

terraform plan returns the Error: Unsupported argument

I have the following three files as below: main.tf, variables.tf and dev.auto.tfvars

Snippet from main.tf

module "sql_vms" {
  source                  = "git::[email protected]:xxxxxxxxxxxx/terraform-modules//azure/"
  rg_name                 = var.resource_group_name
  location                = module.resource_group.external_rg_location
  vnet_name               = var.virtual_network_name
  subnet_name             = var.sql_subnet_name
  app_nsg                 = var.application_nsg
  vm_count                = var.count_vm
  base_hostname           = var.sql_host_basename
  sto_acc_suffix          = var.storage_account_suffix
  vm_size                 = var.virtual_machine_size
  vm_publisher            = var.virtual_machine_image_publisher
  vm_offer                = var.virtual_machine_image_offer
  vm_sku                  = var.virtual_machine_image_sku
  vm_img_version          = var.virtual_machine_image_version
  username                = var.username
  password                = var.password
}

Snippet from variables.tf

variable "app_subnet_name" {
  type    = string
}

variable "sql_subnet_name" {
  type    = string
}

Snippet from dev.auto.tfvars

app_subnet_name = "subnet_1"

sql_subnet_name = "subnet_2"

application_nsg = "test_nsg"

However, I'm getting error like below

Error: Unsupported argument

  on main.tf line 7, in module "sql_vms":
   7:   subnet_name    = var.sql_subnet_name

An argument named "subnet_name" is not expected here.


Error: Unsupported argument

  on main.tf line 8, in module "sql_vms":
   8:   app_nsg        = var.application_nsg

An argument named "app_nsg" is not expected here.

My modules directory structure looks like below

$ ls -R terraform-modules/
terraform-modules/:
aws  azure  gcp

terraform-modules/aws:
alb  ec2-instance-rhel

terraform-modules/aws/alb:

terraform-modules/aws/ec2-instance-rhel:
main.tf

terraform-modules/azure:
compute  resourcegroup  sqlserver

terraform-modules/azure/compute:
main.tf  README.md  variable.tf

terraform-modules/azure/resourcegroup:
data.tf  outputs.tf  variables.tf

terraform-modules/azure/sqlserver:
main.tf  README.md  variables.tf

terraform-modules/gcp:
compute

terraform-modules/gcp/compute:
main.tf

Any idea what is going wrong here?

Upvotes: 11

Views: 66028

Answers (7)

FG_online555
FG_online555

Reputation: 9

When I had this error in my case, the answer actually was that I had the dev.auto.tfvars named dev.auto.tf.

So always check for wrong file naming.

Upvotes: 0

Promise Preston
Promise Preston

Reputation: 28900

I had a similar issue when working with AWS Eventbridge and Terraform.

When I run terraform plan I get the error below:

Error: Unsupported argument
│ 
│   on ../../modules/aws/eventbridge/main.tf line 37, in resource "aws_cloudwatch_event_target" "ecs_cloudwatch_event_target":
│   37:     maximum_age_in_seconds = var.maximum_age_in_seconds
│ 
│ An argument named "maximum_age_in_seconds" is not expected here.

Here's how I solved it:

The issue was that I was not using the correct attribute for the AWS Eventbridge resource block.

The attribute should have been maximum_event_age_in_seconds and not maximum_age_in_seconds.

Another issue that could this is not defining a variable in your terraform script that is already defined in a module.

That's all

Upvotes: 1

CyclingDave
CyclingDave

Reputation: 1476

If you are starting out with Terraform, you will get that error message ("An argument named "example" is not expected here") if your module arguments refer to the resource properties and not to variable names, see below for an example:

Example of a Terraform module "example_mod.tf" you want to call from your module:

variable "sg_name" { }   # Usually in a separate file
variable "sg_desc" { }   # called variables.tf

resource "example_resource" "example_name" {
  name        = var.sg_name
  description = var.sg_desc
...
}

CORRECT WAY:

module "my_module" {
  source = "./modules/example_mod.tf"

  sg_name = "whatever"  # NOTE the left hand side "sg_name" is the variable name
  sg_desc = "whatever"    
...
}

INCORRECT WAY: (Gives the error "An argument named "name" is not expected here" )

module "my_module" {
  source = "./modules/example_mod.tf"

  name   = "whatever" # WRONG because the left hand side "name" is a resource property
  description = "whatever" # WRONG for the same reason   
...
}

Upvotes: 18

Rotem jackoby
Rotem jackoby

Reputation: 22128

I'll share my pain as well.

Writing block configuration like this

  vpc_config = {
    subnet_ids = [aws_subnet.example1.id, aws_subnet.example2.id]
  }

Instead of (Notice the = Equal Sign):

  vpc_config {
    subnet_ids = [aws_subnet.example1.id, aws_subnet.example2.id]
  }

Will give an error of An argument named "vpc_config" is not expected here and will waste you a few good hours.

Upvotes: 2

Charles Xu
Charles Xu

Reputation: 31414

I think the issue is that you do not refer to the exact module with the source. I see you have three modules in the source:

source = "git::[email protected]:xxxxxxxxxxxx/terraform-modules//azure/"

They are compute, resourcegroup and sqlserver. But you want to load them in one module. So it cannot find the related variables for the modules. I also don't think it's the right way to load all the modules like that. I would recommend you load the modules one by one like below:

module "compute" {
  source = "git::[email protected]:xxxxxxxxxxxx/terraform-modules//azure/compute"
  ...
}

module "resourcegroup" {
  source = "git::[email protected]:xxxxxxxxxxxx/terraform-modules//azure/resourcegroup"
  ...
}

module "sqlserver" {
  source = "git::[email protected]:xxxxxxxxxxxx/terraform-modules//azure/sqlserver"
  ...
}

Upvotes: 3

Marko E
Marko E

Reputation: 18138

Without knowing the details about the module it is usually hard to say what's the reason for an error, but in this particular case it seems that there isn't a requirement in the module you're importing to use those two arguments (subnet_name and app_nsg), or rather that you are using a version of the module that doesn't require them to be present. What helps with that type of error is to check if there is a version of the module that does have such a requirement. The syntax for using a particular module version from Github is explained in Terraform Module Sources documentation, Selecting a Revision section:

module "vpc" {
  source = "git::https://example.com/vpc.git?ref=v1.2.0"
}

You are probably using SSH to fetch the module, so the recommended way to do that is:

When using Git over SSH, we recommend using the ssh://-prefixed URL form for consistency with all of the other URL-like git address forms.

In your example, this translates to:

module "sql_vms" {
  source = "git::ssh://[email protected]/org/terraform-modules-repo.git//azure/module-name?ref=v1.2.0"

where org is your organisation's (or your private) Github account, terraform-modules-repo is the repo where modules reside, module-name is the module you are using and ref=v1.2.0 represents the module revision number.

The error An argument named "example" is not expected here. means that the module doesn't expect to see an input argument with that name. Think about Terraform modules as functions in a programming language: in order to have a function provide a result, you pass the function a set of required arguments. If you provide more (or less) input arguments than required by that function call, you will get an error. (There are special cases but it is out of the scope of this question.)


Another similarity between modules and functions is that Terraform modules can also provide output values, besides creating resources that are specified. That can be handy in cases where output can be used as input in other modules or resources. The line module.resource_group.external_rg_location is doing exactly that: getting the output value from another module and using it to assign a value to an argument location.

Upvotes: 1

It could be happening due to plenty of reasons. I'd suggest some verification:


  1. Check if you are using the correct source URL, path or revision branch/tag.

I'm not sure about your implementation, but you probably want to double check the revision you are referencing contains theses variable declarations.

GitHub Modules addressing allows ref argument.

Refer to the GitHub Module Addressing for Terraform Documentation and how to specify a revision.

  1. Check if all necessary variables are declared on every module, including the root module.

Did you declare those variables both in a variables.tf file on your root directory and on the module context/path?

I know that's exhausting and repetitive, but every module should be designed as an "independent project". Each module **MUST have its own declared variables.tf**, which work as inputs for that module, and it is also desirable that it has its own mapped outputs.tf, provider.tf, backend.tf, etc., though these last ones are not required.


FYI: Doing so you guarantee scalability, reusability, as well as reliability to work with different tfstate files and even different repositories for each module in order to guarantee atomicity and minimum permissions, hence preventing your infrastructure from being destroyed by undesired code changes.

I highly recommend this read to understand the importance of independent modularization design.

Furthermore, tools like Terragrunt, Terratest can make this job less painful by keeping your code DRY ( Don't Repeat Yourself ).

  1. Check if the **type constraints of the related variables match.**

If that's not your case, try looking if the type constraints match between all declarations of the variables used both as arguments ( on your root variables.tf ) and inputs ( on your module level variables.tf ).

Upvotes: 0

Related Questions