tflint
tflint copied to clipboard
feature: Add tfenv support
If tfenv is installed (and/or a tfenv compatibility flag is somehow passed), parse the output of the .terraform-version file in current working directory or (if none present), the current output of terraform --version to determine what version of tflint to install. Rather than installing in the usual path, when tfenv is present, install in /opt/ alongside each version of terraform installed by tfenv. Coordinate with tfenv maintainers to ensure that the same shims that adjust the $PATH of terraform also adjust the $PATH of tflint appropriately.
I dropped an issue for the tfenv maintainers as well to request support for tflint version handling in tfenv: https://github.com/tfutils/tfenv/issues/256
If you're both willing to add this feature set, might make sense to reach out to one another and coordinate activities.
This doesn't seem viable to me. TFLint uses Terraform as a library. Strictly speaking, it is only compatible with the version of Terraform it was built with, though many configurations are forwards compatible. Config written for 0.13 will almost always work fine with 0.15, for example.
There is no systematic way to go from a given Terraform version to the latest compatible TFLint version. Short of manually maintaining those mappings, I don't see how we could produce that. You mention in one of the linked issues that the changelog specifies that, but the changelog is meant for humans and can't be treated as machine readable.
Maintaining a mapping in the linux install file was my first thought. This could be automated of course as part of the CI/CD pipeline. With that map, it would make it relatively easy on the tfenv side.
The changelog parsing is a less than stellar alternative to that. The changelog output appeared to be automated, which is the only reason I suggested it.
Hmm, I guess as part of the release process we could find the Terraform version with go list and update a JSON file where the keys are TF versions and the values are TFLint. If you wanted to try a PR I can have a look.
@bendrucker, I wrote a little thingy that creates a metadata file in a few different formats: https://gist.github.com/codrcodz/4508473b3bcf3aa5e10ea58791e5ecff#file-metadata_parser-sh
Here is some sample output: https://gist.github.com/codrcodz/4508473b3bcf3aa5e10ea58791e5ecff#file-output-txt
Let me know if that is something you would be even remotely interested in merging in. If so, I'll drop it in a PR.
Note: The terraform version parsing via go list only works a certain amount of releases back. I see you guys were using glide for dependency management early on, but unfortunately, some of the glide.lock files are missing the terraform repo commit hash so I opted just to mark any terraform versions from releases from that "glide-era" as "unknown" rather than have a mix of hashes, version tags, and "unknown" strings listed in the metadata.
Whoa, impressive! I think it'd be fine to just do this going forward and perhaps manually backfill a TFLint version or two for 0.13 and 0.14. It'd be nice to manage the JSON file with a Go program in anticipation of the logic changing. Per #937, Terraform will move its packages to internal/ sometime soon and the direct coupling between TFLint and Terraform versions will be broken.
Ah, okay. Well, I don't really know golang well enough to write something similar to this in it, so if that is the route that makes the most sense because of those upcoming changes from the Hashicorp folks, have fun!
Looking though #937, I think I understand the issue. If the team opts for relying on https://github.com/hashicorp/hcl-lang +
https://github.com/hashicorp/terraform-schema or makes their own libterraform, either way, this parser should be able to handle that with a few minor tweaks.
Regarding how far back to keep versioning, I designed the parser to run in the pipeline somewhere in the release stage, and to build the JSON, YAML, and Bash file from scratch each time. This will account for edgey things like tags being moved and other oddities that are likely rare, but could occur. Right now, it looks like the team switched over to using go modules and moved away from glide right around version 0.12.0 of terraform, which is great because I think that's as far back as tfenv goes anyway. I don't think it supports installing anything older than that. The cutover from glide happened at v0.8.1 of tflint according to the output snippet from the parser:
{
"tflint_version": "0.8.0",
"terraform_version": "unknown"
},
{
"tflint_version": "0.8.1",
"terraform_version": "v0.12.0"
},
With some pretty minor tweaks, instead of just grabbing the metadata for https://github.com/hashicorp/terraform, I could grab it for https://github.com/hashicorp/* or any other org that is pertinent and drop that into the metadata files as a *_version variable alongside tflint_version and terraform_version. The tricky part, like you mentioned, will be figuring out which terraform version matches the non-terraform hashicorp repos that tflint eventually imports as libraries. If it's decided to go the libterraform route, this should be pretty trivial. Otherwise, if hcl-lang, terraform-schema, etc are only supporting one version per release, and not listing which version of terraform they support, it could be much trickier. After just a cursory glance at terraform-schema, it looks like they might be striving for at least some amount of backwards compatibility and support for multiple versions simultaneously, but for how many versions back, they don't say.
The whole intent of consolidating and presenting this metadata is so that folks that aren't always on the cutting edge, (like most enterprises with more work than they have SREs), will not have to constantly update their terraform configurations. They'll still be able to easily enjoy the benefits of tools like tflint in a workflow that supports multiple versions of terraform running multiple generations of their infrastructure-as-code, orchestrated by the same toolbox node or CI/CD orchestrator. As a result, the metadata consolidation and presentation mechanism (whatever that ends up being) needs to be flexible enough to handle a wide range of versions, especially as we approach terraform v1.0.
@bendrucker, tweaked it a bit to support adding in arbitrary go modules from sources other than https://github.com/hashicorp/terraform. For proof of concept, now parsing metadata for github.com/hashicorp/hcl/v2 as well and adding that to the metadata files.
Here is the new version of the script: https://gist.github.com/codrcodz/ad6b0a287ba4cd02fdc4cbd072ce6ec4#file-metadata_parser-sh
I separated out the global vars from the script too, for tidiness: https://gist.github.com/codrcodz/ad6b0a287ba4cd02fdc4cbd072ce6ec4#file-metadata_parser-vars-sh
Here is the sample output that includes the github.com/hashicorp/hcl/v2 metadata:
https://gist.github.com/codrcodz/ad6b0a287ba4cd02fdc4cbd072ce6ec4#file-output-txt
Want me to submit a PR?
Let's hold for now, really appreciate you sharing these scripts.
I want to try to focus on the future of both TFLint and Terraform. It's also worth pointing out that TFLint is also plugin oriented and most plugins implicitly depend on a provider schema/version. Plugins also don't currently support having multiple versions in the way that Terraform provider plugins do. There's a complicated story to getting this right. I understand the pain of trying to use Terraform locally with multiple disparate versions but I'm not sure we should be taking on this burden given its complexity and our limited time to maintain TFLint.
If TFLint no longer depends on Terraform as a library, it should be increasingly possible to use to use the latest version of TFLint even if your Terraform configuration is somewhat behind. We can revisit this issue as part of that effort.
https://github.com/hashicorp/terraform-schema#why-a-separate-repository-from-terraform-core
Thank you for working on this.
Currently, TFLint is Terraform version-agnostic and follows the Terraform v1.x compatibility promise. As a result, you can use TFLint almost without worrying about Terraform versions.
Closing this issue based on the above. If you want to continue discussing this issue, please open a discussion instead of an issue. Thanks.