skip to Main Content

I am trying to create multiple ec2 instance using terraform modules. As every instance will have different user data, I want to do this but it’s giving error

data "local_file" "user_data" {
  for_each = { for ec2 in var.ec2_instances : ec2.name => ec2 }
  filename = "${path.cwd}/${each.value.user_data}"
}

resource "aws_instance" "instances" {
  for_each = { for instance in var.ec2_instances : instance.name => instance }

  ami                    = each.value.ami
  instance_type          = each.value.type
  cpu_core_count         = each.value.cpu_core
  user_data_base64  = base64encode(data.local_file.user_data[each.value.name].rendered)
}

module.tf

module "ec2_app_demo" {
  source = "./aws-ec2-application/"

  ec2_instances     = var.ec2_instances
}

In the tfvars file

ec2_instances= [
{
name = test1
user_data = ec2_1.sh
},
{
name = test2
user_data = ec2_2.sh
}
]

Error:

Error: Invalid function argumentnn on main.tf line 76, in data "local_file" "linux-vm-cloud-init":n 76: filename = file("${each.value.user_data}")n

Please let me know if the file name can be used a variable.

The folder structure is below:
enter image description here

3

Answers


  1. Chosen as BEST ANSWER

    I was able to do this by doing below. I didn't need data source. Just added below:

    user_data = each.value.user_data != "" ? file("${path.module}/../${each.value.user_data}") : null
    

  2. You do not need file. Just the path is enough:

    filename = "${path.module}/${each.value.user_data}"
    
    Login or Signup to reply.
  3. Since the shell files are in the same directory, it should be easy to achieve what you want. Additionally, the variable has to use quoted values:

    ec2_instances= [
      {
        name = "test1"
        user_data = "ec2_1.sh"
      },
      {
        name = "test2"
        user_data = "ec2_2.sh"
      }
    ]
    

    The file built-in function expect you to provide a path to the file [1], it has no knowledge if the file is in the same directory or not:

    file reads the contents of a file at the given path and returns them as a string.

    As per the comments (h/t: @Marcin) in order for the code to work, the data source should be changed to this (the file is not required):

    data "local_file" "user_data" {
      for_each = { for ec2 in var.ec2_instances : ec2.name => ec2 }
      filename = "${path.module}/../${each.value.user_data}"
    }
    

    EDIT: Based on the comments, the shell script is named differently compared to what was originally posted in the question for the variable value. For this to work, the variable value has to change to:

    ec2_instances= [
      {
        name = "test1"
        user_data = "tmosquid02.sh"
      }
    ]
    

    [1] https://developer.hashicorp.com/terraform/language/functions/file

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search