This is a custom ruleset for tflint.
We use this publicly available ruleset to enforce our best practices and conventions in our Terraform code.
It is enabled in .tflint.hcl
files, which are present in the repositories for terraform-infra
and terraform-module
.
For example like so:
plugin "terraform" {
enabled = true
preset = "recommended"
}
plugin "google" {
enabled = true
version = "0.29.0"
source = "github.com/terraform-linters/tflint-ruleset-google"
}
plugin "kramp" {
enabled = true
version = "1.0.0"
source = "github.com/kramphub/tflint-ruleset-kramp"
}
config {
call_module_type = "all"
}
tflint --init
will then download the ruleset from GitHub and make it available for use.
Using goreleaser to build the binaries and deploy then to GitHub. Installation instructions can be found here.
An example for MacOS:
brew install goreleaser
To try it out, simply only building the binaries without actual releasing:
goreleaser build --clean --snapshot
To do a 'dry-run' release (thus not actually releasing):
goreleaser release --clean --skip=publish --skip=validate
The actual release is done by this CloudBuild script: cloudbuild-release.yaml.
Which responds on a tag that is created by: cloudbuild-tag.yaml.
If the commit message starts with, for example, feat: ...
or fix: ...
(see semantic-release).
This repository is based on this template: tflint-ruleset-template. There you can also find some example rules.
And for reference, you can also find all the standard rules here:
The rules are written in Go, and are located in the rules directory.
It is also possible to write rules in OPA/Rego (as we tried during our efforts to use trivy
).
But Go gives more flexibility and allows for easy unit-testing, thus being more powerful.
make test && make install
It will be copied to the tflint plugins directory (~/.tflint.d/plugins
).
You can use this environment variable: TFLINT_LOG=debug
cd manual_tests/verify
TFLINT_LOG=debug tflint --enable-plugin=kramp
Then you could use the GoLang Docker image to run the tests etc:
docker run -it --rm \
--name "tflint-ruleset-kramp" \
--volume "$(pwd):/workspace" \
--workdir="/workspace" \
--env "USERID=$(id -u):$(id -g)" \
--entrypoint=bash \
golang:1.22.3 \
-c "go mod tidy && make build && make test"
If you want to build a binary for Apple Silicon you could do something like this:
docker run -it --rm \
--name "tflint-ruleset-kramp" \
--volume "$(pwd):/workspace" \
--workdir="/workspace" \
--env "USERID=$(id -u):$(id -g)" \
--env "GOOS=darwin" \
--env "GOARCH=arm64" \
--entrypoint=bash \
arm64v8/golang:1.22.3 \
-c "go mod tidy && go build"
Please do this only as a last resort!
If you think a rule is wrong, please contact Team Cloud-Platform, so we can modify it accordingly.
To ignore a rule (the white space after the colon is important):
# !!! Add here a clear description of the reason why you disable this rule !!!
# tflint-ignore: authoritative_iam_policy_on_folder_level
resource "google_folder_iam_policy" "folder_admin_policy" {
folder = google_folder.department1.name
policy_data = data.google_iam_policy.admin.policy_data
}
It is possible, when you check on attribute level, to report as range the location of that attribute.
For 'range' you can thus use attribute.Expr.Range()
.
But then an 'ignore' comment on block level is not respected (it should then be on attribute level).
See iam_policy_on_project_level_rule.go for an example.