Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Linters which are not language-specific:
| Go | [gofmt] or [gofumpt] | |
| Gherkin | [prettier-plugin-gherkin] | |
| GraphQL | [Prettier] | |
| HCL (Hashicorp Config) | [terraform] fmt | |
| HCL (Hashicorp Config) | [terraform] fmt | [tflint] |
| HTML | [Prettier] | |
| JSON | [Prettier] | |
| Java | [google-java-format] | [pmd] , [Checkstyle], [Spotbugs] |
Expand Down Expand Up @@ -76,6 +76,7 @@ Linters which are not language-specific:
[eslint]: https://eslint.org/
[swiftformat]: https://github.com/nicklockwood/SwiftFormat
[terraform]: https://github.com/hashicorp/terraform
[tflint]: https://github.com/terraform-linters/tflint
[buf]: https://docs.buf.build/format/usage
[keep-sorted]: https://github.com/google/keep-sorted
[ktfmt]: https://github.com/facebook/ktfmt
Expand Down
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Each example is self-contained and shows:
- `proto/` - Protocol Buffer formatting and linting with Buf
- `starlark/` - Starlark formatting with Buildifier; linting with Buildifier
- `qml/` - QML formatting with qmlformat; linting with qmllint
- `terraform/` - Terraform formatting with terraform fmt; linting with tflint

## Multi-language Example

Expand Down
1 change: 1 addition & 0 deletions examples/terraform/.bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build:lint --aspects=//tools/lint:linters.bzl%tflint
12 changes: 12 additions & 0 deletions examples/terraform/.tflint.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Plugins are pre-fetched by the tflint_plugin repository rule and placed
# in TFLINT_PLUGIN_DIR. source/version are omitted here so tflint discovers
# plugins by name without needing --init or network access.

plugin "terraform" {
enabled = true
preset = "recommended"
}

plugin "google" {
enabled = true
}
3 changes: 3 additions & 0 deletions examples/terraform/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package(default_visibility = ["//visibility:public"])

exports_files([".tflint.hcl"])
9 changes: 9 additions & 0 deletions examples/terraform/MODULE.aspect
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Aspect Extension setup for CLI "lint" and "format" commands
# This example is in rules_lint, so we use a local dependency.
# See https://github.com/bazel-starters/terraform/blob/main/MODULE.aspect
# for a real-world example.
axl_local_dep(
name = "rules_lint",
path = "../..",
auto_use_tasks = True,
)
20 changes: 19 additions & 1 deletion examples/terraform/MODULE.bazel
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
"Bazel dependencies for Terraform formatting example"
"Bazel dependencies for Terraform formatting and linting example"

bazel_dep(name = "aspect_rules_lint")
bazel_dep(name = "jq.bzl", version = "0.6.0")

local_path_override(
module_name = "aspect_rules_lint",
path = "../..",
)

# Demonstrate fetching a tflint plugin via the tflint_plugin repository rule.
# The google plugin validates Google Cloud-specific Terraform resources.
tflint_ext = use_extension("@aspect_rules_lint//lint:tflint_plugins.bzl", "tflint_ext")
tflint_ext.plugin(
name = "tflint_plugin_google",
ruleset_name = "google",
sha256s = {
"linux_amd64": "e5034d2c25c2ed94b131897904614ea8b575fb1fc7a0619b14a874d8cb9adec1",
"linux_arm64": "e7e387b7ed4ee02c81efaaab87c47af69377a2a1809e579e357d0965fb524299",
"darwin_amd64": "2d393ac529b285c29d5818272ab9df9a9af3c6d1173ab642bd42d0a8b7cfe606",
"darwin_arm64": "96fb99f49b25b54000729da9f396b14ef885c2204e3db2e0414a7f21578fd6fc",
},
url_template = "https://github.com/terraform-linters/tflint-ruleset-google/releases/download/v0.39.0/tflint-ruleset-google_{platform}.zip",
)
use_repo(tflint_ext, "tflint_plugin_google")
20 changes: 15 additions & 5 deletions examples/terraform/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
# Terraform Formatting Example
# Terraform Example

This example demonstrates how to set up formatting for Terraform (HCL) code using `rules_lint`.
This example demonstrates how to set up formatting and linting for Terraform (HCL) code using `rules_lint`.

## Supported Tools

### Formatters

- **terraform** - Official Terraform formatter

Note: No Terraform linter is currently available in rules_lint.
### Linters

- **tflint** - Pluggable Terraform linter

## Usage

Expand All @@ -20,8 +22,16 @@ Format all Terraform files:
bazel run //tools/format:format
```

Format specific files:
### Lint Code

Lint Terraform files via the aspect:

```bash
bazel lint //src:example
```

Or using vanilla Bazel:

```bash
bazel run //tools/format:format -- hello.tf
bazel build //src:example --aspects=//tools/lint:linters.bzl%tflint --output_groups=rules_lint_human
```
7 changes: 7 additions & 0 deletions examples/terraform/src/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package(default_visibility = ["//visibility:public"])

filegroup(
name = "example",
srcs = ["main.tf"],
tags = ["lint-with-tflint"],
)
24 changes: 24 additions & 0 deletions examples/terraform/src/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# This file intentionally contains lint violations:
# - The google provider is missing a version constraint (terraform_required_providers).
# - A required_version attribute is missing (terraform_required_version).
# - The machine_type "invalid-machine-type" does not exist
# (google_compute_instance_invalid_machine_type, from the google plugin).
terraform {
required_providers {
google = {
source = "hashicorp/google"
}
}
}

resource "google_compute_instance" "example" {
name = "example"
machine_type = "invalid-machine-type"
zone = "us-central1-a"

boot_disk {
initialize_params {
image = "debian-cloud/debian-11"
}
}
}
37 changes: 37 additions & 0 deletions examples/terraform/test/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# buildifier: disable=bzl-visibility
load("@aspect_rules_lint//lint/private:machine_report_testing.bzl", "PHYSICAL_ARTIFACT_LOCATION_URI_FILTER")
load("@jq.bzl//jq:jq.bzl", "jq_test")
load("//test:machine_output.bzl", "machine_tflint_report")
load("//tools/lint:linters.bzl", "tflint_test")

package(default_visibility = ["//visibility:public"])

tflint_test(
name = "tflint",
srcs = ["//src:example"],
expected_exit_code = 2,
)

machine_tflint_report(
name = "machine_tflint_report",
src = "//src:example",
)

# tflint's native SARIF includes multiple runs (one per ruleset plus a
# "tflint-errors" run for internal errors), so we check .runs[0] rather
# than .runs[] for the tool name.
jq_test(
name = "tflint_machine_output_test",
file1 = "machine_tflint_report",
file2 = "machine_tflint_report",
filter1 = ".runs[0].tool.driver.name",
filter2 = "\"tflint\"",
)

jq_test(
name = "tflint_machine_output_test_uri",
file1 = "machine_tflint_report",
file2 = "machine_tflint_report",
filter1 = PHYSICAL_ARTIFACT_LOCATION_URI_FILTER,
filter2 = "\"src/main.tf\"",
)
11 changes: 11 additions & 0 deletions examples/terraform/test/lint_test.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
bats_load_library "bats-support"
bats_load_library "bats-assert"

@test "should produce reports" {
run aspect lint //src:example
assert_success
# The terraform plugin's recommended preset flags missing version constraints
assert_output --partial "terraform_required_providers"
# The google plugin flags the invalid machine type
assert_output --partial "google_compute_instance_invalid_machine_type"
}
7 changes: 7 additions & 0 deletions examples/terraform/test/machine_output.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"Terraform-specific machine report rules for testing."

# buildifier: disable=bzl-visibility
load("@aspect_rules_lint//lint/private:machine_report_testing.bzl", "machine_report_rule")
load("//tools/lint:linters.bzl", "tflint")

machine_tflint_report = machine_report_rule(tflint)
6 changes: 6 additions & 0 deletions examples/terraform/tools/lint/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
"""Linter binary definitions for Terraform.

tflint is provided via rules_multitool; no additional BUILD targets needed here.
"""

package(default_visibility = ["//:__subpackages__"])
14 changes: 14 additions & 0 deletions examples/terraform/tools/lint/linters.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"Define Terraform linter aspects"

load("@aspect_rules_lint//lint:lint_test.bzl", "lint_test")
load("@aspect_rules_lint//lint:tflint.bzl", "lint_tflint_aspect")

tflint = lint_tflint_aspect(
binary = "@aspect_rules_lint//lint:tflint_bin",
config = Label("//:.tflint.hcl"),
plugins = [
Label("@tflint_plugin_google//:plugin"),
],
)

tflint_test = lint_test(aspect = tflint)
16 changes: 16 additions & 0 deletions lint/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ alias(
actual = "@multitool//tools/shellcheck",
)

alias(
name = "tflint_bin",
actual = "@multitool//tools/tflint",
)

alias(
name = "ty_bin",
actual = "@multitool//tools/ty",
Expand Down Expand Up @@ -274,6 +279,17 @@ bzl_library(
],
)

bzl_library(
name = "tflint",
srcs = ["tflint.bzl"],
deps = ["//lint/private:lint_aspect"],
)

bzl_library(
name = "tflint_plugins",
srcs = ["tflint_plugins.bzl"],
)

bzl_library(
name = "yamllint",
srcs = ["yamllint.bzl"],
Expand Down
36 changes: 36 additions & 0 deletions lint/multitool.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,42 @@
}
]
},
"tflint": {
"binaries": [
{
"kind": "archive",
"url": "https://github.com/terraform-linters/tflint/releases/download/v0.61.0/tflint_linux_arm64.zip",
"file": "tflint",
"sha256": "999c25cfdb5208fe1133dec6b219e666a39fc2a7a0786a781dc9924ea5945ebf",
"os": "linux",
"cpu": "arm64"
},
{
"kind": "archive",
"url": "https://github.com/terraform-linters/tflint/releases/download/v0.61.0/tflint_linux_amd64.zip",
"file": "tflint",
"sha256": "ca4e4e8cb7cc3436f2b6979e9c4fd4e2623a66fcca1ad1fe12f8669967636ae2",
"os": "linux",
"cpu": "x86_64"
},
{
"kind": "archive",
"url": "https://github.com/terraform-linters/tflint/releases/download/v0.61.0/tflint_darwin_arm64.zip",
"file": "tflint",
"sha256": "6593fa24cb6e14d2d0cf7af7fd02a271242f1038af6ecb5384f6738e105a0fea",
"os": "macos",
"cpu": "arm64"
},
{
"kind": "archive",
"url": "https://github.com/terraform-linters/tflint/releases/download/v0.61.0/tflint_darwin_amd64.zip",
"file": "tflint",
"sha256": "9cd3106c7b74f83cbcd90e0593dfaa1ce14dc5260fe32d946915fd0004aec2f4",
"os": "macos",
"cpu": "x86_64"
}
]
},
"ty": {
"binaries": [
{
Expand Down
Loading
Loading