archil patel
archil patel

Reputation: 27

Merge more than 2 tfvars file contents

I have usecase where I have 3 tfvars files

1.tfvars
api_stages=[
  {
      api_id= "xxxx"
      stage="play"
  }
]

2.tfvars
api_stages=[
  {
      api_id= "yyy"
      stage="play"
  }
]

3.tfvars    
api_stages=[
  {
      api_id= "zzz"
      stage="play"
  }
]

and I am creating 1 single usage plan using this

resource "aws_api_gateway_usage_plan" "usage_plan" {
  name         = var.usage_plan_name     
   throttle_settings {
    burst_limit = var.burst_limit
    rate_limit  = var.rate_limit
  }  
   
  dynamic "api_stages" {
      for_each = var.api_stages
      content {
        api_id     = api_stages.value.api_id
        stage = api_stages.value.stage      
      }
    }
}

And this tfvars files will be created by different users.

Question: How can I merge this different tfvars file and attach all api_id and stages to single usage plan?

right now when I am doing plan, it's only taking last file's value.

Upvotes: 1

Views: 4624

Answers (1)

Martin Atkins
Martin Atkins

Reputation: 74169

.tfvars file processing happens before any configuration expressions are evaluated, so there is no way to do exactly what you asked about here: the rule for .tfvars files is always that the last definition of a particular variable "wins", as you've seen.

The some options that are close to what you want here would be:

  • Define three different variables, perhaps named to indicate the three different sources that are providing these values, and then concatenate the three of them together in a local value:

    locals {
      all_api_stages = concat(
        var.a_api_stages,
        var.b_api_stages,
        var.c_api_stages,
      )
    }
    

    This approach would be appropriate only if there being exactly three sets of variables is a meaningful constraint for your system.

  • Declare the actual stage objects inside your configuration and make the variable instead be a list of keys for them:

    variable "api_stages" {
      type = set(string)
    }
    
    locals {
      api_stages = {
        x = {
          api_id = "xxxx"
          stage  = "play"
        }
        y = {
          api_id = "yyyy"
          stage  = "play"
        }
        z = {
          api_id = "zzzz"
          stage  = "play"
        }
      }
    }
    

    You can then use -var when running Terraform to choose the appropriate settings, instead of using -var-file:

    terraform apply -var='api_stages=["x", "y"]'
    

Upvotes: 1

Related Questions