Search code examples
jsonamazon-web-servicesterraformterraform-provider-aws

loop through multiple json files as inputs in Terraform


Description: I have multiple json files that I want to pass into Terraform as inputs. All the json files would have the following format:

i.e input.json

{
    "one": {
        "instance_type": "t2.micro"

    },
    "two": {
        "instance_type": "t2.micro"
    }
}

locals.tf

locals {
    json_files = fileset("${path.module}/inputs/", "*.json")   
    json_data  = [ for f in local.json_files : jsondecode(file("${path.module}/inputs/${f}")) ]
}

main.tf

module "ec2-instance" {
  source  = "terraform-aws-modules/ec2-instance/aws"
  version = "4.1.4"

  for_each                    = { for f in local.json_data : f.instance_type => f }
  name                        = "instance-${each.key}"
  ami                         = "ami-ebd02392"
  instance_type               = each.value.instance_type
  subnet_id                   = aws_subnet.subnet[0].id
  associate_public_ip_address = true
  vpc_security_group_ids      = [aws_security_group.ec2.id] #defined in security.tf
  key_name                    = aws_key_pair.kp.key_name #defined in providers.tf
  tags = {
    Name = "instance-test"
  }
}

Goal: So what I should expect TFE to do is to provision 2 servers by providing the key/values in the json files using the module above with both the instance types being t2.micros.

Issue: But I am getting the error below

│ Error: Unsupported attribute
│
│   on ec2.tf line 7, in module "ec2-instance":
│    7:   for_each                    = { for f in local.json_data : f.instance_type => f }
│
│ This object does not have an attribute named "instance_type".

Sorry if my question and/or format is/are poor.


Solution

  • You can flatten your json_data:

    locals {
        json_files = fileset("${path.module}/input/", "*.json")   
        json_data  = merge([ for f in local.json_files : jsondecode(file("${path.module}/input/${f}")) ]...)
        
    }
    

    then

    module "ec2-instance" {
      source  = "terraform-aws-modules/ec2-instance/aws"
      version = "4.1.4"
    
      for_each                    = local.json_data 
      name                        = "instance-${each.key}"
      ami                         = "ami-ebd02392"
      instance_type               = each.value.instance_type
      subnet_id                   = aws_subnet.subnet[0].id
      associate_public_ip_address = true
      vpc_security_group_ids      = [aws_security_group.ec2.id] #defined in security.tf
      key_name                    = aws_key_pair.kp.key_name #defined in providers.tf
      tags = {
        Name = "instance-test"
      }
    }