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.tfAny idea what is going wrong here?
7 Answers
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
...
} 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" ...
} 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::"
}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/"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.
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.
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
It could be happening due to plenty of reasons. I'd suggest some verification:
- 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.
- 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 ).
- 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 ).
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.