Skip to content

Commit c34c2cf

Browse files
added aws example
Signed-off-by: ivan katliarchuk <[email protected]>
1 parent f08b3e4 commit c34c2cf

24 files changed

+2614
-0
lines changed

.editorconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,9 @@ indent_size = 2
4343
[Makefile]
4444
indent_style = tab
4545
indent_size = 2
46+
47+
[*.rego]
48+
indent_style = space
49+
indent_size = 4
50+
trim_trailing_whitespace = true
51+

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
- [K8s security best practices: opa policies](https://github.com/ik-infrastructure-testing/k8s-security-policies)
2020
- [Terraform policies: opa policies](https://github.com/ik-infrastructure-testing/confectionery)
2121
- [Styra labs: opa policies](https://github.com/ik-infrastructure-testing/academy-samples)
22+
- [Rego examples](https://github.com/ik-infrastructure-testing/RegoCheatSheetExamples-rego-fork)
23+
- [AWS Policy as code OPA](https://github.com/ik-infrastructure-testing/aws-infra-policy-as-code-with-terraform-fork)
24+
- [Teraform rego](https://developer.hashicorp.com/terraform/cloud-docs/policy-enforcement/define-policies/opa)
2225

2326
---
2427

playground/ex10/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@
99
# Exercise 10
1010

1111
From [here](https://github.com/nyalavarthi/opa-policies-s3-rds/blob/master/rds-validate.rego)
12+
- [fork](https://github.com/ik-infrastructure-testing/opa-policies-s3-rds-fork)
13+
- [article](http://i-cloudconsulting.com/open-policy-agent-opa-terraform-example/)

playground/ex20/assert.rego

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# https://play.openpolicyagent.org/p/QUNnPpZU44
2+
package play
3+
4+
permit[permission] {
5+
is_workforce
6+
input.role == "admin"
7+
permission = getPermission(input.role)
8+
}
9+
10+
permit[permission] {
11+
not is_workforce
12+
input.role == "expert"
13+
permission = getPermission(input.role)
14+
}
15+
16+
is_workforce {
17+
input.nsId == "50000000"
18+
}
19+
20+
getPermission(role) = permission {
21+
permission := data.permissionList[role]
22+
}
23+
24+
permissionList := {
25+
"admin": "allPermission",
26+
"expert": "reviewPermission",
27+
}
28+
29+
test_Permit {
30+
count(permit) == 1 with input as {
31+
"nsId": "50000000",
32+
"role": "admin",
33+
}
34+
}
35+
36+
test_Not_Permit {
37+
count(permit) == 0 with input as {
38+
"nsId": "50000000",
39+
"role": "developer",
40+
}
41+
}
42+
43+
test_Permissions {
44+
permit == {"reviewPermission"} with input as {"role": "expert"}
45+
}
46+
47+
test_Permit_developer {
48+
count(getPermission("developer")) > 0 with data.permissionList as {"developer": "test"}
49+
}
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
package utils
2+
3+
# Checks if action is create or update
4+
# Common path: resource.change.actions
5+
is_create_or_update(change_actions) {
6+
change_actions[count(change_actions) - 1] == ["create", "update"][_]
7+
}
8+
9+
# Checks of resource is being created or updated
10+
is_resource_create_or_update(resource) {
11+
is_create_or_update(resource.change.actions)
12+
}
13+
14+
# Creates an array with all falsey values removed.
15+
# The values false, null, 0, "", {} and [] are considered falsey.
16+
compact(array) = output {
17+
output := [value |
18+
value := array[_]
19+
not is_null(value)
20+
not value == false
21+
not value == ""
22+
not value == 0
23+
not value == []
24+
not value == {}
25+
]
26+
}
27+
28+
# Checks if `match` value matches to all items in array.
29+
every(array, match) {
30+
count([value |
31+
value := array[_]
32+
value == match
33+
]) == count(array)
34+
} else = false {
35+
true
36+
}
37+
38+
# Gets the value at path of object.
39+
get(object, path) = output {
40+
[obj_path, value] = walk(object)
41+
path_array := to_path(path)
42+
obj_path == path_array
43+
output := value
44+
}
45+
46+
# Gets the value at path of object.
47+
# If the resolved value is undefined,
48+
# the default_value is returned in its place.
49+
get_or_default(object, path, default_value) = output {
50+
output := get(object, path)
51+
} else = output {
52+
output := default_value
53+
}
54+
55+
# Checks if path exists on object
56+
has(object, path) {
57+
[obj_path, value] = walk(object)
58+
obj_path == to_path(path)
59+
} else = false {
60+
true
61+
}
62+
63+
# Checks if value exists in array
64+
includes(array, value) {
65+
value == array[_]
66+
} else = false {
67+
true
68+
}
69+
70+
# Gets index of object in array that matches provided fraction object
71+
index_by(array, fraction) = output {
72+
some i
73+
item = array[i]
74+
is_fraction(item, fraction)
75+
output := i
76+
} else = output {
77+
output := -1
78+
}
79+
80+
# Gets index of value in array
81+
index_of(array, value) = output {
82+
some i
83+
item = array[i]
84+
item == value
85+
output := i
86+
} else = output {
87+
output := -1
88+
}
89+
90+
# Checks if value is null or false
91+
is_null_or_false(value) {
92+
is_null(value)
93+
} else {
94+
value == false
95+
} else = false {
96+
true
97+
}
98+
99+
# Checks if object matches fraction
100+
is_fraction(object, fraction) {
101+
search_keys = keys(fraction)
102+
count({key |
103+
key = search_keys[_]
104+
object[key] == fraction[key]
105+
}) == count(search_keys)
106+
} else = false {
107+
true
108+
}
109+
110+
# Gets the keys of object
111+
keys(object) = output {
112+
output := {key |
113+
[path, value] = walk(object)
114+
key := path[0]
115+
}
116+
}
117+
118+
# Gets the size of collection
119+
size(collection) = output {
120+
is_string(collection)
121+
output := count(collection)
122+
} else = output {
123+
output := count(keys(collection))
124+
}
125+
126+
# Converts set to an array
127+
to_array(set) = output {
128+
output := [value |
129+
value := set[_]
130+
]
131+
}
132+
133+
# Converts array to a set
134+
to_set(array) = output {
135+
output := {value |
136+
value := array[_]
137+
}
138+
}
139+
140+
_parse_array_index(value) = output {
141+
contains(value, "[")
142+
number_string := substring(value, 1, count(value) - 2)
143+
output = try_to_number(number_string)
144+
} else = output {
145+
output = value
146+
}
147+
148+
# Converts string path to a path array
149+
to_path(path) = output_array {
150+
output_array := [value |
151+
part := split(path, ".")[_]
152+
value := _parse_array_index(part)
153+
]
154+
}
155+
156+
# Attempts to converts string to a number
157+
try_to_number(string) = out {
158+
out := to_number(string)
159+
} else = out {
160+
out := string
161+
}
162+
163+
is_resource_of_type(resource, service) {
164+
resource.mode == "managed"
165+
contains(resource.type, service)
166+
resource.change.actions[count(resource.change.actions) - 1] != "delete"
167+
}
168+
169+
# Checks if service resource exists in the plan
170+
find_service_resource(plan, service) = result {
171+
result := [ x.address | x := plan.resource_changes[_]; is_resource_of_type(x, service)]
172+
}
173+
174+
# Checks if arrays is null or empty
175+
is_array_null_or_empty(value) {
176+
is_null(value)
177+
} else {
178+
size(value) = 0
179+
} else = false {
180+
true
181+
}
182+
183+
# Check if an array contains specified value
184+
contains_element(array, value) {
185+
array[_] = value
186+
} else = false {
187+
true
188+
}
189+
190+
# find configuration entries for resource
191+
find_configuration_resource(plan, resource) = cfgresource{
192+
# case where there is no module
193+
not resource.module_address
194+
some ssm_resource
195+
plan.configuration.root_module.resources[ssm_resource].address == resource.address
196+
cfgresource := plan.configuration.root_module.resources[ssm_resource]
197+
} else = cfgresource{
198+
some ssm_resource
199+
# case with module (or nested modules)
200+
base_path := "configuration.root_module"
201+
# get module_address and split with "."
202+
module_address_list := split(resource.module_address, ".")
203+
# list comprehention to keep only modules names not "module." entries
204+
nested_module_path := [ path | module_address_list[i] != "module"; path := module_address_list[i] ]
205+
# rebuild path for configuration section
206+
temp_path := concat(".", [ path2 | nested_module_path[i] ; path2 := sprintf("module_calls.%s.module",[nested_module_path[i]])])
207+
temp_path2 := concat(".", [base_path, temp_path])
208+
209+
# search input object starting at root_module
210+
myobj := data.utils.get(plan, temp_path2)
211+
concat(".", [resource.module_address, myobj.resources[ssm_resource].address]) == resource.address
212+
cfgresource := myobj.resources[ssm_resource]
213+
}

0 commit comments

Comments
 (0)