Skip to content

Commit 1c73e26

Browse files
authored
Add terraform.imports and terraform.checks functions (#69)
* Add `terraform.imports` function * Add `terraform.checks` function
1 parent ead86cc commit 1c73e26

File tree

16 files changed

+628
-0
lines changed

16 files changed

+628
-0
lines changed

docs/functions.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,111 @@ terraform.moved_blocks({"from": "any"}, {})
566566
]
567567
```
568568

569+
## `terraform.imports`
570+
571+
```rego
572+
blocks := terraform.imports(schema, options)
573+
```
574+
575+
Returns Terraform imports blocks.
576+
577+
- `schema` (schema): schema for attributes referenced in rules.
578+
- `options` (object[string: string]): options to change the retrieve/evaluate behavior.
579+
580+
Returns:
581+
582+
- `blocks` (array[object<config: body, decl_range: range>]): Terraform "import" blocks.
583+
584+
The `schema` and `options` are equivalent to the arguments of the `terraform.resources` function.
585+
586+
Examples:
587+
588+
```hcl
589+
import {
590+
to = aws_instance.example
591+
id = "i-abcd1234"
592+
}
593+
```
594+
595+
```rego
596+
terraform.imports({"id": "string"}, {})
597+
```
598+
599+
```json
600+
[
601+
{
602+
"config": {
603+
"id": {
604+
"value": "i-abcd1234",
605+
"unknown": false,
606+
"sensitive": false,
607+
"range": {...}
608+
}
609+
},
610+
"decl_range": {...}
611+
}
612+
]
613+
```
614+
615+
## `terraform.checks`
616+
617+
```rego
618+
blocks := terraform.checks(schema, options)
619+
```
620+
621+
Returns Terraform check blocks.
622+
623+
- `schema` (schema): schema for attributes referenced in rules.
624+
- `options` (object[string: string]): options to change the retrieve/evaluate behavior.
625+
626+
Returns:
627+
628+
- `blocks` (array[object<config: body, decl_range: range>]): Terraform "check" blocks.
629+
630+
The `schema` and `options` are equivalent to the arguments of the `terraform.resources` function.
631+
632+
Examples:
633+
634+
```hcl
635+
check "health_check" {
636+
data "http" "terraform_io" {
637+
url = "https://www.terraform.io"
638+
}
639+
640+
assert {
641+
condition = data.http.terraform_io.status_code == 200
642+
error_message = "${data.http.terraform_io.url} returned an unhealthy status code"
643+
}
644+
}
645+
```
646+
647+
```rego
648+
terraform.checks({"assert": {"condition": "bool"}}, {})
649+
```
650+
651+
```json
652+
[
653+
{
654+
"config": {
655+
"assert": [
656+
{
657+
"config": {
658+
"condition": {
659+
"unknown": true,
660+
"sensitive": false,
661+
"range": {...}
662+
}
663+
},
664+
"labels": null,
665+
"decl_range": {...}
666+
}
667+
]
668+
},
669+
"decl_range": {...}
670+
}
671+
]
672+
```
673+
569674
## `terraform.module_range`
570675

571676
```rego

integration/checks/.tflint.hcl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
plugin "terraform" {
2+
enabled = false
3+
}
4+
5+
plugin "opa" {
6+
enabled = true
7+
8+
policy_dir = "policies"
9+
}

integration/checks/main.tf

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
check "health_check" {
2+
data "http" "terraform_io" {
3+
url = "https://www.terraform.io"
4+
}
5+
6+
assert {
7+
condition = data.http.terraform_io.status_code == 200
8+
error_message = "${data.http.terraform_io.url} returned an unhealthy status code"
9+
}
10+
}
11+
12+
check "deterministic" {
13+
assert {
14+
condition = 200 == 200
15+
error_message = "condition should be true"
16+
}
17+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package tflint
2+
3+
deny_deterministic_check_condition[issue] {
4+
checks := terraform.checks({"assert": {"condition": "bool"}}, {})
5+
condition = checks[_].config.assert[_].config.condition
6+
condition.unknown == false
7+
8+
issue := tflint.issue("deterministic check condtion is not allowed", condition.range)
9+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package tflint
2+
import future.keywords
3+
4+
mock_checks(schema, options) := terraform.mock_checks(schema, options, {"main.tf": `
5+
check "deterministic" {
6+
assert {
7+
condition = 200 == 200
8+
error_message = "condition should be true"
9+
}
10+
}`})
11+
12+
test_deny_deterministic_check_condition_passed if {
13+
issues := deny_deterministic_check_condition with terraform.checks as mock_checks
14+
15+
count(issues) == 1
16+
issue := issues[_]
17+
issue.msg == "deterministic check condtion is not allowed"
18+
}
19+
20+
test_deny_deterministic_check_condition_failed if {
21+
issues := deny_deterministic_check_condition with terraform.checks as mock_checks
22+
23+
count(issues) == 0
24+
}

integration/checks/result.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"issues": [
3+
{
4+
"rule": {
5+
"name": "opa_deny_deterministic_check_condition",
6+
"severity": "error",
7+
"link": "policies/main.rego:3"
8+
},
9+
"message": "deterministic check condtion is not allowed",
10+
"range": {
11+
"filename": "main.tf",
12+
"start": {
13+
"line": 14,
14+
"column": 17
15+
},
16+
"end": {
17+
"line": 14,
18+
"column": 27
19+
}
20+
},
21+
"callers": []
22+
}
23+
],
24+
"errors": []
25+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"issues": [
3+
{
4+
"rule": {
5+
"name": "opa_test_deny_deterministic_check_condition_failed",
6+
"severity": "error",
7+
"link": "policies/main_test.rego:20"
8+
},
9+
"message": "test failed",
10+
"range": {
11+
"filename": "",
12+
"start": {
13+
"line": 0,
14+
"column": 0
15+
},
16+
"end": {
17+
"line": 0,
18+
"column": 0
19+
}
20+
},
21+
"callers": []
22+
}
23+
],
24+
"errors": []
25+
}

integration/imports/.tflint.hcl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
plugin "terraform" {
2+
enabled = false
3+
}
4+
5+
plugin "opa" {
6+
enabled = true
7+
8+
policy_dir = "policies"
9+
}

integration/imports/main.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import {
2+
to = aws_instance.example
3+
id = "i-abcd1234"
4+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package tflint
2+
3+
deny_import_blocks[issue] {
4+
imports := terraform.imports({}, {})
5+
count(imports) > 0
6+
7+
issue := tflint.issue("import blocks are not allowed", imports[0].decl_range)
8+
}

0 commit comments

Comments
 (0)