-
Notifications
You must be signed in to change notification settings - Fork 0
/
terraform.rego
90 lines (76 loc) · 2.44 KB
/
terraform.rego
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package terraform.analysis
import input as tfplan
########################
# Parameters for Policy
########################
# acceptable score for automated authorization
blast_radius = 30
# weights assigned for each operation on each resource-type
weights = {
"aws_autoscaling_group": {"delete": 100, "create": 10, "modify": 1},
"aws_instance": {"delete": 10, "create": 1, "modify": 1}
}
# Consider exactly these resource types in calculations
resource_types = {"aws_autoscaling_group", "aws_instance", "aws_iam", "aws_launch_configuration"}
#########
# Policy
#########
# Authorization holds if score for the plan is acceptable and no changes are made to IAM
default authz = false
authz {
score < blast_radius
not touches_iam
}
# Compute the score for a Terraform plan as the weighted sum of deletions, creations, modifications
score = s {
all := [ x |
some resource_type
crud := weights[resource_type];
del := crud["delete"] * num_deletes[resource_type];
new := crud["create"] * num_creates[resource_type];
mod := crud["modify"] * num_modifies[resource_type];
x := del + new + mod
]
s := sum(all)
}
# Whether there is any change to IAM
touches_iam {
all := instance_names["aws_iam"]
count(all) > 0
}
####################
# Terraform Library
####################
# list of all resources of a given type
instance_names[resource_type] = all {
some resource_type
resource_types[resource_type]
all := [name |
tfplan[name] = _
startswith(name, resource_type)
]
}
# number of deletions of resources of a given type
num_deletes[resource_type] = num {
some resource_type
resource_types[resource_type]
all := instance_names[resource_type]
deletions := [name | name := all[_]; tfplan[name]["destroy"] == true]
num := count(deletions)
}
# number of creations of resources of a given type
num_creates[resource_type] = num {
some resource_type
resource_types[resource_type]
all := instance_names[resource_type]
creates := [name | all[_] = name; tfplan[name]["id"] == ""]
num := count(creates)
}
# number of modifications to resources of a given type
num_modifies[resource_type] = num {
some resource_type
resource_types[resource_type]
all := instance_names[resource_type]
modifies := [name | name := all[_]; obj := tfplan[name]; obj["destroy"] == false; not obj["id"]]
num := count(modifies)
}