terraform-linters / tflint-ruleset-opa Goto Github PK
View Code? Open in Web Editor NEWExperimental: TFLint ruleset plugin for writing custom rules in Rego.
License: Mozilla Public License 2.0
Experimental: TFLint ruleset plugin for writing custom rules in Rego.
License: Mozilla Public License 2.0
Prematurely converted this to a discussion. Belongs as an issue in the opa
repo.
Originally posted by ericsaboia February 4, 2024
Hi, I'm using tflint-ruleset-opa
to set an issue when the resource signalfx_detector
is missing a notifications
attribute inside rule
.
The rule works fine when validating my detector, but if I include a main.tf
file that loads my defective detector, tflint fails with the error pasted in the output section. I even tried to exclude main.tf
with # tflint-ignore-file: all
, but it still fails.
My folder structure is:
.tflind.d/policies/
- tags.rego
detectors
- example.tf
.tflint.hcl
main.tf
main.tf:
module "detectors" {
source = "./detectors"
}
detectors/example.tf:
resource "signalfx_detector" "test" {
# Should fail as it's missing "notifications"
rule {
severity = "Warning"
}
}
.tflind.d/policies/tags.rego:
package tflint
import future.keywords.contains
import future.keywords.if
detectors := terraform.resources("signalfx_detector", {"rule": {"notifications": "any"}}, {})
detector_rule contains rule if {
rule := detectors[_].config.rule[_]
}
# Missing notifications declaration inside rule
deny_signalfx_detector_without_notification[issue] {
detector_rule[i].config == {}
issue := tflint.issue("Missing notifications declaration inside rule", detector_rule[i].decl_range)
}
TFLINT_OPA_POLICY_DIR="$(pwd)/.tflint.d/policies/" tflint --config "$(pwd)/.tflint.hcl" --recursive
none
plugin "opa" {
enabled = true
version = "0.5.0"
source = "github.com/terraform-linters/tflint-ruleset-opa"
}
plugin "terraform" {
enabled = false
}
panic: detectors/example.tf:3,3-7: Invalid reference; A reference to a resource type must be followed by at least one attribute access, specifying the resource name.
goroutine 88 [running]:
github.com/terraform-linters/tflint/tflint.listVarRefs({0x10342b058?, 0x140001349c0?})
github.com/terraform-linters/tflint/tflint/runner.go:326 +0x150
github.com/terraform-linters/tflint/tflint.(*Runner).listModuleVars(0x1400068f7a0, {0x10342b058?, 0x140001349c0?})
github.com/terraform-linters/tflint/tflint/runner.go:314 +0x34
github.com/terraform-linters/tflint/tflint.(*Runner).EmitIssue(0x1400068f7a0, {0x10ad35998?, 0x140001ec3c0}, {0x140001442a0, 0x2d}, {{0x1400012e600, 0x14}, {0x3, 0x3, 0x58}, ...}, ...)
github.com/terraform-linters/tflint/tflint/runner.go:240 +0x6c
github.com/terraform-linters/tflint/plugin.(*GRPCServer).EmitIssue.func1(...)
github.com/terraform-linters/tflint/plugin/server.go:202
github.com/terraform-linters/tflint/tflint.(*Runner).WithExpressionContext(...)
github.com/terraform-linters/tflint/tflint/runner.go:263
github.com/terraform-linters/tflint/plugin.(*GRPCServer).EmitIssue(0x140006082a0, {0x10342fd50?, 0x140001ec3c0}, {0x140001442a0, 0x2d}, {{0x1400012e600, 0x14}, {0x3, 0x3, 0x58}, ...}, ...)
github.com/terraform-linters/tflint/plugin/server.go:201 +0x11c
github.com/terraform-linters/tflint-plugin-sdk/plugin/internal/plugin2host.(*GRPCServer).EmitIssue(0x14000708ad0, {0x102dcb070?, 0x10?}, 0x140006517c0)
github.com/terraform-linters/[email protected]/plugin/internal/plugin2host/server.go:164 +0x1bc
github.com/terraform-linters/tflint-plugin-sdk/plugin/internal/proto._Runner_EmitIssue_Handler.func1({0x10342b4b8, 0x140000ddce0}, {0x103386d80?, 0x140006517c0})
github.com/terraform-linters/[email protected]/plugin/internal/proto/tflint_grpc.pb.go:722 +0x74
github.com/terraform-linters/tflint-plugin-sdk/plugin/internal/host2plugin.(*GRPCClient).Check.func1.RequestLogging.func1({0x10342b4b8, 0x140000ddce0}, {0x103386d80?, 0x140006517c0?}, 0x14000175f00, 0x14000800108)
github.com/terraform-linters/[email protected]/plugin/internal/interceptor/logging.go:16 +0x1a8
github.com/terraform-linters/tflint-plugin-sdk/plugin/internal/proto._Runner_EmitIssue_Handler({0x10339bb00?, 0x14000708ad0}, {0x10342b4b8, 0x140000ddce0}, 0x14000452500, 0x1400000f770)
github.com/terraform-linters/[email protected]/plugin/internal/proto/tflint_grpc.pb.go:724 +0x12c
google.golang.org/grpc.(*Server).processUnaryRPC(0x140001b8400, {0x10342b4b8, 0x140000dd650}, {0x103431088, 0x14000283860}, 0x1400061fe60, 0x14000413c20, 0x103c6d748, 0x0)
google.golang.org/[email protected]/server.go:1372 +0xb8c
google.golang.org/grpc.(*Server).handleStream(0x140001b8400, {0x103431088, 0x14000283860}, 0x1400061fe60)
google.golang.org/[email protected]/server.go:1783 +0xc4c
google.golang.org/grpc.(*Server).serveStreams.func2.1()
google.golang.org/[email protected]/server.go:1016 +0x5c
created by google.golang.org/grpc.(*Server).serveStreams.func2 in goroutine 74
google.golang.org/[email protected]/server.go:1027 +0x138
0.50.2
No response
This is a great tool for applying our own rules to our terraform code!!
But a question about this example (we don't want any aws_security_group_rule resources anymore):
package tflint
deny_aws_security_group_rule[issue] {
rules := terraform.resources("aws_security_group_rule", {"security_group_id": "string"}, {})
names := rules[_].config.security_group_id
count(rules) > 0
issue := tflint.issue(`aws_security_group_rule mag niet meer gebruikt worden, maar komt nog wel voor`, names.range)
}
This gives something like:
on terraform\rds.tf line 87:
87: security_group_id = "sg-123456"
How can I return the name of the resource, instead of a part of the config?
OPA v0.59 adds support for import rego.v1
to ensure compatibility with future OPA v1.0.
https://github.com/open-policy-agent/opa/releases/tag/v0.59.0
As far as I can see, the example policies in the official documentation seems to have switched to a syntax that uses import rego.v1
, so it would be a good idea to follow this in the example policies in this repository.
You have to write policies with many patterns in mind to cover all cases. For example:
count
meta-argumentfor_each
meta-argumentSee also https://github.com/terraform-linters/tflint-ruleset-opa/blob/v0.1.0/docs/handling_special_values.md
It can be frustrating to have to think about so much when writing a policy. Providing an option to fall back to the initial value of each type in the above cases might make it easier to write the policy.
The question is whether users prefer false positives or false negatives. The current design focuses to avoid false positives, but users who want to enforce policies prefer to avoid false negatives. We should think carefully about which one to default to.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.