tflint icon indicating copy to clipboard operation
tflint copied to clipboard

Linting repo with multiple folders

Open emahnovets opened this issue 5 years ago • 9 comments

HI guys.

I have a repo with similar structure:

.
├── .tflint.hcl
├── development
│   ├── script1.tf
│   ├── script2.tf
│   └── script3.tf
└── modules
    ├── module1
    │   ├── script1.1.tf
    │   └── script1.2.tf
    ├── module2
    │   └── script2.1.tf
    └── module3
        ├── script3.1.tf
        ├── script3.2.tf
        └── script3.3.tf

Is it possible to use just one .tflint.hcl and run lint for all modules and environments by one command from repo root? Maybe someone has some ideas?

emahnovets avatar Nov 21 '19 11:11 emahnovets

Unfortunately, to do that, you need to run the tflint command under all directories. I agree that it is redundant, but I'm not sure how to properly lint for all environments.

wata727 avatar Nov 23 '19 12:11 wata727

@emahnovets I use a bash script that walks submodule directories and runs tflint in each of them. Feel free to adapt it to your needs:

#!/usr/bin/env bash

set -eo pipefail

config_file="$(git rev-parse --show-toplevel)/.tflint.hcl"

echo "Scanning the modules"
readarray -t module_dirs < <(find . -name .terraform -prune , -type f -name '*.tf' -printf '%h\n' | sort | uniq)
for module_dir in "${module_dirs[@]}"; do
  echo
  echo "======================================================================"
  echo "Checking ${module_dir}"
  echo "======================================================================"
  echo
  (
    cd "${module_dir}"
    terraform init -backend=false
    profiles=()
    readarray -O ${#profiles[@]} -t profiles < <(find . -maxdepth 1 -type f -name 'terraform.tfvars.*' -printf '%f\n')
    readarray -O ${#profiles[@]} -t profiles < <(find . -maxdepth 1 -type f -name '*.tfvars' -printf '%f\n')
    if [[ ${#profiles[@]} -gt 0 ]]; then
      for profile in "${profiles[@]}"; do
        echo
        echo "Using variable values from: ${profile}"
        echo
        tflint --config="${config_file}" --var-file="${profile}"
      done
    else
      echo
      echo "Using default variable values"
      echo
      tflint --config="${config_file}"
    fi
  )
done

sergei-ivanov avatar Apr 14 '20 11:04 sergei-ivanov

@sergei-ivanov I did almost the same :)

emahnovets avatar Apr 14 '20 14:04 emahnovets

Hey guys,

this would be awsome for me. In larger projects, code will be structured into little submodules like java packages. Currently tflint isn't working for me, because no code live on the root.

djakielski avatar Jul 14 '20 19:07 djakielski

This works for me find <root_dir> -type d | xargs -I {} tflint {}.

mujx avatar Aug 04 '20 09:08 mujx

Ressurecting this issue because I bumped in the same problem today.

I have a pretty simple folder structure (check screenshot). When I run tflint from the root of the git repository it shows an error telling me to terraform init, but I already did. CDing into the terraform folder and running it again shows no lint error.

image

We probably need an --recursive, --root-folder, --change-directory,-chdir or related environment variable kinda option. I think that would be really beneficial for monorepos, git hooks and CI/CD pipelines.

EDIT: Tflint needs to be in the same directory as the .terraform root directory to inspect modules and provider configurations. You need to cd into the directory that has the .terraform folder to be able to lint your terraform files.

As I stated above, I think any of the options this would be a great feature to the tool.

Also, Terraform has an environment variable TF_DATA_DIR (see here) that you can point to another .terraform data dir folder.

1mamute avatar Jun 07 '21 02:06 1mamute

With Terraform replacement of a directory argument with -chdir, we'll probably look to do the same as part of a breaking release for Terraform 1.0 (#937).

This should also pave the way for multiple TFLint sub-commands, i.e. tflint init && tflint inspect.

See comments in #841 around --recursive. I expect us to stick to Terraform parity and continue to leave that to users. For GitHub Actions, I'm working on an Action to find all modules in a monorepo which can then provide input to a matrix job or be looped over by a single job. Something like this, but specific to Terraform:

https://github.com/marketplace/actions/collect-directory-names-by-file

Will add examples of how to integrate that with TFLint to the docs here or in the setup-tflint repo when it's ready. Finding all Terraform module directories is equally necessary if you're running terraform validate or any other static analysis tool so we want to defer it to another tool.

bendrucker avatar Jun 22 '21 16:06 bendrucker

I would love to see the recursive feature!

steveoh avatar Jul 28 '21 23:07 steveoh

I've published and will continue to work on https://github.com/bendrucker/find-terraform-modules which handles this for GitHub Actions in a way that's compatible with any CLI for analyzing Terraform modules. I'm considering evolving this from a JS action to a CLI that could be used in other CIs. At this time, there's no active plan for TFLint to take on its own --recursive flag. Because this continues to get bump and +1 comments, I'm locking the thread here.

bendrucker avatar Jul 29 '21 00:07 bendrucker