Reading json objects from files

Hello,

What is the suggested way to read json strings from a file in a sentinel policy file?

Also, do json.unmarshal( ) support nested json objects? I got an error; wasn’t sure if there is an issue with the code or there is a limitation w.r.t nested elements

Hi @rpointer

How static is the JSON data that you would like to read? Will it change for each policy evaluation or is it a set-and-forget string value? I can list a couple of different options that are available but before I do, can you confirm if you are writing a policy for Terraform, Vault, Consul, or Nomad?

@hcrhall

Thanks. I’m writing policies for Terraform.

Looking to parse the plan output to identify policy violations, i.e.,
terraform show -json plan.out
So, the json won’t be static and will/might change for each policy invocation.

Thanks for confirming. Currently, there’s no elegant way of doing so. Assuming that you want to run this on the command line, you could try the following:

$ terraform show -json plan.out
$ sentinel apply -config ./policy/sentinel.hcl -global plan="$(cat ./plan.out)" -trace

You should then be able to evaluate the global data as follows using print:

main = print(plan.terraform_version)

Let me know how you get on with the above :smile:

Passing plan.json through the command line doesn’t seem to work,

`rajeev@rajeev:~/code/terraform/sentinel$ ./sentinel apply -global "myplan="$(cat ./plan.json)""  policy4.sentinel

invalid value "myplan={\"format_version\":\"1.1\", ...`

When I use the global block in sentinel.hcl (pasting the json as the value), it does work,

global "myplan" {
    value = {"format_version":"1.1",
                   ...
                   ...
                   }

and I’m able to access keys further levels down (rule - Pass),

main = rule { length(myplan.planned_values.root_module.child_modules[0].resources) == 2 }

On a quick check, I notice that the following passes,

sentinel apply -param 'myobj={"k1": "v1"}'  policy5.sentinel -trace
param myobj
main = rule { myobj.k1 == "v1" }

The following is a pass as well,

sentinel apply -global 'myobj={"k1": {"k11": "v11"}'  policy5.sentinel -trace
main = rule { myobj.k1.k11 == "v11" }

Not sure the issue with plan json. I guess I can use a Python helper to construct the sentinel.hcl by adding in a global block with plan.json as the value. But I guess then I might as well do the whole policy evaluation in Python :slightly_smiling_face:

@rpointer try and remove the quotes that wrap the value for the global data:

./sentinel apply -global myplan="$(cat ./plan.json)" policy4.sentinel

@hcrhall yes, that worked :+1:

rajeev@rajeev:~/code/terraform/sentinel$ ./sentinel apply -global "myplan=$(cat ./plan.json)"  policy4.sentinel
Pass - policy4.sentinel

Don’t know how I missed the enclosed double quotes.

Thank you. You’ve been very helpful