Commit e3c2c853 authored by kawsark's avatar kawsark

updaed to second generation sentinel policy file

parent 2f16f5cc
Pipeline #91088274 passed with stages
in 33 seconds
# This policy uses the Sentinel tfplan import to require that
# all Google compute instances have machine types from an allowed list
##### Imports #####
import "tfplan"
import "strings"
##### Functions #####
# Find all resources of a specific type from all modules using the tfplan import
find_resources_from_plan = func(type) {
resources = {}
# Iterate over all modules in the tfplan import
for tfplan.module_paths as path {
# Iterate over the named resources of desired type in the module
for tfplan.module(path).resources[type] else {} as name, instances {
# Iterate over resource instances
for instances as index, r {
# Get the address of the instance
if length(path) == 0 {
# root module
address = type + "." + name + "[" + string(index) + "]"
} else {
# non-root module
address = "module." + strings.join(path, ".module.") + "." +
type + "." + name + "[" + string(index) + "]"
}
# Add the instance to resources map, setting the key to the address
resources[address] = r
}
}
}
return resources
}
# Validate that all instances of a specified resource type being modified have
# a specified top-level attribute in a given list
validate_attribute_in_list = func(type, attribute, allowed_values) {
validated = true
# Get all resource instances of the specified type
resource_instances = find_resources_from_plan(type)
# Loop through the resource instances
for resource_instances as address, r {
# Skip resource instances that are being destroyed
# to avoid unnecessary policy violations.
# Used to be: if length(r.diff) == 0
if r.destroy and not r.requires_new {
print("Skipping resource", address, "that is being destroyed.")
continue
}
# Determine if the attribute is computed
if r.diff[attribute].computed else false is true {
print("Resource", address, "has attribute", attribute,
"that is computed.")
# If you want computed values to cause the policy to fail,
# uncomment the next line.
# validated = false
} else {
# Validate that each instance has allowed value
if (r.applied[attribute] else "") not in allowed_values {
print("Resource", address, "has attribute", attribute, "with value",
r.applied[attribute] else "",
"that is not in the allowed list:", allowed_values)
validated = false
}
}
}
return validated
}
##### Lists #####
# Allowed GCP Machine Types
# We don't include n1-standard-1 to illustrate overriding failed policy
allowed_types = [
"n1-standard-1",
]
##### Rules #####
# Main rule that calls the validation function and evaluates results
main = rule {
validate_attribute_in_list("google_compute_instance", "machine_type",
allowed_types)
}
\ No newline at end of file
import "tfplan"
get_vms = func() {
vms = []
for tfplan.module_paths as path {
vms += values(tfplan.module(path).resources.google_compute_instance) else []
}
return vms
}
allowed_machine_types = [
"n1-standard-1",
]
vms = get_vms()
machine_type_allowed = rule {
all vms as _, instances {
all instances as index, r {
r.applied.machine_type in allowed_machine_types
}
}
}
main = rule {
(machine_type_allowed) else true
}
\ No newline at end of file
policy "restrict-machine-type" {
policy "restrict-gce-machine-type" {
enforcement_level = "soft-mandatory"
}
\ No newline at end of file
......@@ -22,7 +22,8 @@ then
fi
# Create policy set
sed "s/my-workspace-id/${workspace_id}/" < ../api_templates/policysets.json.template > policysets.json
d=$(date "+%H%M%S")
sed -e "s/gcp-policies/gcp-policies-$d/" -e "s/my-workspace-id/${workspace_id}/" < ../api_templates/policysets.json.template > policysets.json
curl --header "Authorization: Bearer ${TFC_TOKEN}" \
--header "Content-Type: application/vnd.api+json" \
--request POST --data @policysets.json \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment