Created
October 28, 2025 08:42
-
-
Save rhowe/18f7370f7427bd32c6447f68d67f4825 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package terraform.is_secure | |
| import data.terraform.resources | |
| deny contains msg if { | |
| some resource in securable_resources | |
| resource.values.input.secure != true | |
| msg := sprintf("Resources should have secure=true. Resource in violation: %v", [resource.address]) | |
| } | |
| # Resources which can be flagged 'secure' | |
| # In this case, our example is a "terraform_data" resource whose input object contains a 'secure' boolean key | |
| securable_resources contains r if { | |
| some r in resources.resources | |
| "terraform_data" == r.type | |
| # This is a way to test for the existence of a key in an object. | |
| # "Can we retrieve any value by looking up the key?" | |
| _ = r.values.input.secure | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package terraform.resources | |
| import data.terraform.library | |
| resources contains r if { | |
| some path, value | |
| # Walk over the JSON tree and check if the node we are | |
| # currently on is a module (either root or child) resources | |
| # value. | |
| walk(input.planned_values, [path, value]) | |
| # Look for resources in the current value based on path | |
| some r in module_resources(path, value) | |
| } | |
| # Variant to match root_module resources | |
| module_resources(path, value) := value if { | |
| # Expect something like: | |
| # | |
| # { | |
| # "root_module": { | |
| # "resources": [...], | |
| # ... | |
| # } | |
| # ... | |
| # } | |
| # | |
| # Where the path is [..., "root_module", "resources"] | |
| reverse_index(path, 1) == "resources" | |
| reverse_index(path, 2) == "root_module" | |
| } | |
| # Variant to match child_modules resources | |
| module_resources(path, value) := value if { | |
| # Expect something like: | |
| # | |
| # { | |
| # ... | |
| # "child_modules": [ | |
| # { | |
| # "resources": [...], | |
| # ... | |
| # }, | |
| # ... | |
| # ] | |
| # ... | |
| # } | |
| # | |
| # Where the path is [..., "child_modules", 0, "resources"] | |
| # Note that there will always be an index int between `child_modules` | |
| # and `resources`. We know that walk will only visit each one once, | |
| # so we shouldn't need to keep track of what the index is. | |
| reverse_index(path, 1) == "resources" | |
| reverse_index(path, 3) == "child_modules" | |
| } | |
| reverse_index(path, idx) := path[count(path) - idx] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment