I have a massive terraform state I maintain for work. After learning about reusing resources using modules I adopted the same rule for terraform I have for other PLs “only call functions in the main func”. Meaning I’m only allowed to declare modules that reference resources at the top level.

My problem is that I have modules calling modules all over the place, the average length of any of my resources is 8 names. I have values I want to share across multiple different kinds of modules that do different things. Currently I have a top level module called “constants” with output blocks to store every constant I need. It works to an extent.

The thing is that I had a similar problem when web developing in React. Prop drilling is a coding style in React where a component receives a prop just for the purpose of passing the prop to a child component, the receiving component doesn’t actually need that prop for itself. React solves this by the context api which lets one component pass a value to any child component of any depth. How can we have something similar in Terraform? Even though every resource I have is defined once in code, it declares the same resources hundreds of times with different appropriate values.

I wish I could pass things like the dockerSecret to a kubernetes deployment 6 modules deep in such a way that that dependant component of a module waits for the docker secret to be created while other resources that don’t depend on it can be scheduled to be created later. Prop drilling doesn’t work all that well and it forces you to copy alot of code. Maybe modules aren’t the best way to reuse resources.

I feel like HCL doesn’t have syntax that would support such a thing idomatically. Maybe something like decorator syntax or a special type of block where you write a proper data, resource, or module block?

What do you guys think?

  • dbx12
    link
    fedilink
    English
    arrow-up
    1
    ·
    9 months ago

    I’m not sure I follow the “only functions in the main function” rule. Does that mean you only have module blocks and no resource blocks at the top level? If yes, then I don’t see the benefit of that rule in context of Terraform.

    Regarding the huge state, that’s something I usually try to avoid, just to avoid several minutes of “refreshing state” of the full thing. Separate projects have their own folder in Terraform, each containing the relevant resources (container, task definition etc). If I need to access info of a different project, I use terraform_remote_state and access its outputs.