Azure Security

Maximize your code consistency with Megalinter

Maximize your code consistency with Megalinter

TL;DR

Lint your code with megalinter for more consistent, secure, and cleaner looking projects!

Jump to recipe

The problem

Without any kind of linting your code can become quite messy and not good looking. Indentations can be inconsistent, trailing whitespaces, array listing, ++. The list goes on and on. You can use terraform fmt to format terraform code. You can use prettier extension in VSCode to format many kinds of code. But both these methods require some sort of manual intervention from the developer. Linting is not something absolutely everyone does, and so you might end up with messy code.

The solution

The solution is linting your code with a linter. A linter is a machine for removing the short fibres from cotton seeds after ginning. At least that is the explanation I can find when searching the internet. More precisely when talking about development a Linter is a static code analysis tool used to find bugs, programming errors, style errors, and suspicious constructs. I mentioned tflint briefly when writing about pre-commit for Terraform.

There are several different linters one can use for validating code:

You can lint locally in VSCode with extensions, use pre-commit hooks like I mentioned in the post above, or just simply run manual linting commands on your client (not very practical). Best of all I think would be to use some form of linting in your CI/CD. That way you can force the linting as part of deploying software/infrastructure.

Enter megalinter!

Megalinter is a collection of linters “powered by OX Security”:

MegaLinter is an Open-Source tool for CI/CD workflows that analyzes the consistency of your code, IAC, configuration, and scripts in your repository sources, to ensure all your projects sources are clean and formatted whatever IDE/toolbox is used by their developers, powered by OX Security.

It supports 55 languages, 24 formats, and 20 tooling formats.

You can use it as a GitHub action or in any CI system. It is highly configurable and free for all uses.

Run locally

Running locally is an option, but it requires npm and some installed dependencies. This is impractical to keep up with, and will require some form of increased upkeep on your client. You could run it with npx, but still it is impractical to run manually for each change to code. The other option for running locally is with pre-commit hooks. This will work best when running on Linux-based operating systems, but still requires the megalinter dependencies to be installed.

I can’t imagine there is a need to run this locally, as long as you run it in your pipeline.

Common configuration options

Apply fixes

  • APPLY_FIXES apply fixes on your code automatically. This means your files will be updated with the correct style/indentation/coding standards
  • APPLY_FIXES_EVENT to specify the event on which to fix: all, push, pull_request, none (Only for GitHub Action usage!)
  • APPLY_FIXES_MODE to specify mode: commit to create a new commit and push it on the same branch, or pull_request to create a new PR targeting the branch

You can choose to You can either apply fixes on all code, or just choose a subset like JSON, MARKDOWN, TERRAFORM.

Activation/Deactivation of tools

  • ENABLE / ENABLE_LINTERS setting lets you enable some tools, and automatically disables the ones not explicitly mentioned.
  • DISABLE / DISABLE_LINTERS setting lets you disable tools, and automatically enables the ones not explicitly mentioned.
  • DISABLE_ERROR_LINTERS settings lets you enable a linter, but any errors are considered non blocking.

Pre and Post commands

  • PRE_COMMANDS enables you to run custom commands before running megalinter. This could be for removing some temp-files or similar tasks.
  • POST_COMMANDS enables you to run custom commands after running megalinter. This could be for writing some report to wherever.

You can read more about them: PRE_COMMANDS, POST_COMMANDS

GitHub settings

  • GITHUB_STATUS_REPORTER updates any Pull Requests with status for each linter. Very nifty for visualization of tests in a PR.
  • GITHUB_COMMENT_REPORTER updates any Pull request with a comment containing a linter test table for easy access to detailed logs.

An example config file

There are many other settings you can configure. Please have a look at them here.

Use in GitHub workflow

Usage in a GitHub workflow is easy if you just use the one provided from OX Security. This workflow file, if placed in your .github/workflows folder, will run on any push to any branch, and on PRs to master or main.

  • You can see an example of how the workflow runs when a push to master is performed here
  • This is a push to a branch other than master.

  • Pull Request example here.

  • Pull Request comment example here.

Please be aware that this is just testing for fun and demo purposes. None of this is fit for use in production without some TLC.

Other included tools

Please note that Trivy, Checkov, and some other security scanning tools are also included in Megalinter. If you are scanning with these already, you can disable them inside Megalinter. Alternatively you can disable your other scan and do all the scanning in megalinter.

Config for either environment variables or the .mega-linter.yml file:

# Disable the tools
DISABLE_LINTERS:
  - REPOSITORY_CHECKOV
  - REPOSITORY_TRIVY
  - TERRAFORM_TERRASCAN

# Run the tools but don't stop execution
DISABLE_ERRORS_LINTERS:
  - REPOSITORY_CHECKOV
  - REPOSITORY_TRIVY
  - TERRAFORM_TERRASCAN

It is ultimately up to you!

Slow image pull

The pulling of oxsecurity/megalinter did take quite some time, so I would recommend docker-cache or similar actions. Over three minutes for pulling the image can be somewhat annoying if you run this often, and are waiting on the result. I haven’t tested caching myself, but it should reduce the time considerably.

In summary

Linting is important, and more importantly quite easy, when you can use collections of linters like megalinter. Including all these linters in your workflow would require way more configuration and more steps without megalinter.

Lint your code, there is no excuse! 😉