hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.
https://www.terraform.io/
Other
42.68k stars 9.55k forks source link

Dynamically enable/disable check blocks #35081

Open tomhaynes opened 6 months ago

tomhaynes commented 6 months ago

Terraform Version

Terraform v1.7.4

Use Cases

We are currently looking at rolling out automated integration testing, hopefully involving the use of check blocks. To ease roll-out and adoption across our shared modules it would be very useful to support flagging these on/off via count/for_each.

We also see use-cases whereby our modules provide a set of default checks that can be tailored or extended by specific implementation - again this would naturally fit the use of for_each

Attempted Solutions

We're currently trying to use just external data sources, but as these are smoke tests they would be better implemented with the check blocks.

Proposal

No response

References

No response

crw commented 6 months ago

Thanks for this feature request! If you are viewing this issue and would like to indicate your interest, please use the 👍 reaction on the issue description to upvote this issue. We also welcome additional use case descriptions. Thanks again!

apparentlymart commented 6 months ago

Hi @tomhaynes,

I don't mean the following as any statement about specifically what you requested -- it's still an open feature request ready for consideration -- but I wanted to share a way you could approximate this in today's Terraform.

One current possibility is to place the entire check block in a separate module and then use a module call whose number of instances is decided dynamically:

module "checks" {
  count = /* whatever rule you have to choose whether to check or not */ ? 1 : 0

  # (and then any arguments needed to pass data into
  # the nested check blocks.)
}

Terraform Core treats check blocks in a similar way as it treats variable, output, and locals, which don't support multi-instances within a particular module but still get multi-instanced when their containing module is multi-instanced. Therefore if you declare a child module containing a check blocks with count = 0 then there are effectively zero instances of the check block, and therefore there are effectively no checks under that module call.


The feature request in this issue would avoid the need for that extra level of indirection, but I think it would otherwise be treated in just the same way by Terraform Core, just with some more complicated logic for deciding which instances of the check block are declared.

One potential implementation complexity is that check blocks allow nested data blocks, and so if the check blocks they were in also supported multi-instances then this would create an extra level of dynamic instance "fan-out": the containing module, the check block, and the data block. I expect that the handling of that situation will be the most complex design problem to solve if this is accepted. (Today module calls are the only kind of object that is both multi-instance itself and can contain another kind of object that is multi-instanced, and so the internal API treats modules in a special way compared to other object types.)

tomhaynes commented 6 months ago

Many thanks for your quick reply @apparentlymart, that does sound like it would work - though as you say slightly more cumbersome. Is it possible to link to the existing feature request for the meta-arguments? In the meantime we'll have a go with wrapping in a submodule. Thanks again!

tomhaynes commented 6 months ago

@apparentlymart confirm your suggestion works well thanks! It might be worth adding that as an option to the docs here - as that's what led me to raising the request.

I think I misread you're initial reply in thinking there is a separate open request for the meta-argument support. I'm happy to leave this open if its useful, we'll carry on with the submodule for now.

apparentlymart commented 6 months ago

Indeed, as far as I know this is the only issue discussing the idea of check blocks alone being dynamically disabled, so I think leaving it open makes sense. My reply was only intended as a possible alternative you could use immediately, so you wouldn't be completely blocked.

apparentlymart commented 6 months ago

A correction on what I said in an earlier comment:

Currently data blocks nested inside check blocks are not allowed to use either count or for_each arguments, and so adding support for multiple instances of a check block would not necessarily require an extra level of nesting, but it would still require a different kind of nesting than exists anywhere else in the language today.

In particular, the absolute address of a data block inside a check block does not actually mention the check block at all, and so introducing multi-instance check blocks would require some way to distinguish the different nested data block instances from one another even though the item being repeated is not currently part of the address.

PavelSlepushkin commented 3 weeks ago

Another scenario - we want to use checks to verify change of k8s configuration and ensure that after apply all deployments have spec.replicas == .status.readyReplicas To do this we need to iterate over all namespaces and check it in every namespace.(that's how terraform k8s provider works) It would be good to have a for_each for a check or for a nested data block.(to iterate over namespaces) Right now we're using global data source, so it is not a blocker, but nice to have.