initial commit

This commit is contained in:
worm 2023-11-25 20:28:18 -08:00
commit 6b69bbf7df
3 changed files with 33 additions and 0 deletions

11
README.md Normal file
View file

@ -0,0 +1,11 @@
The goal of this product is to evaluate the contents of a Terraform (or OpenTofu) run and permit/deny it taking place.
It will use the JSON `plan` representation as outlined here:
https://developer.hashicorp.com/terraform/internals/json-format#plan-representation
Chiefly the `resource_changes` collection.
The simple goal of at this stage is to allow someone to write very simple rules for Terraform compliance.
For instance, "aws_instance must be of type t3.micro"
Initially, examples will be simple and static.

1
example-plan.json Normal file
View file

@ -0,0 +1 @@
{"format_version":"1.1","terraform_version":"1.3.7","variables":{"foo":{"value":"bar"}},"planned_values":{"root_module":{"resources":[{"address":"aws_ebs_volume.example","mode":"managed","type":"aws_ebs_volume","name":"example","provider_name":"registry.terraform.io/hashicorp/aws","schema_version":0,"values":{"availability_zone":"us-west-2a","final_snapshot":false,"multi_attach_enabled":null,"outpost_arn":null,"size":4,"tags":null,"tags_all":{"bazz":"Qux","foo":"bar","region":"us-west-2"},"timeouts":null},"sensitive_values":{"tags_all":{}}}]}},"resource_changes":[{"address":"aws_ebs_volume.example","mode":"managed","type":"aws_ebs_volume","name":"example","provider_name":"registry.terraform.io/hashicorp/aws","change":{"actions":["create"],"before":null,"after":{"availability_zone":"us-west-2a","final_snapshot":false,"multi_attach_enabled":null,"outpost_arn":null,"size":4,"tags":null,"tags_all":{"bazz":"Qux","foo":"bar","region":"us-west-2"},"timeouts":null},"after_unknown":{"arn":true,"encrypted":true,"id":true,"iops":true,"kms_key_id":true,"snapshot_id":true,"tags_all":{},"throughput":true,"type":true},"before_sensitive":false,"after_sensitive":{"tags_all":{}}}}],"configuration":{"provider_config":{"aws":{"name":"aws","full_name":"registry.terraform.io/hashicorp/aws","version_constraint":"4.53.0","expressions":{"default_tags":[{"tags":{"references":["var.foo"]}}]}}},"root_module":{"resources":[{"address":"aws_ebs_volume.example","mode":"managed","type":"aws_ebs_volume","name":"example","provider_config_key":"aws","expressions":{"availability_zone":{"constant_value":"us-west-2a"},"size":{"constant_value":4}},"schema_version":0}],"variables":{"foo":{"default":"bar"}}}}}

21
main.raku Normal file
View file

@ -0,0 +1,21 @@
use JSON::Fast;
my $plan = from-json "example-plan.json".IO.slurp;
my $resource-changes = $plan<resource_changes>;
my %required-tags = "foo" => ["bar", "buzz"];
# There's no reason to expect that non-managed resources will be needed.
# However, Sentinel policies often have this as a parameter
# .grep is Raku's 'filter' method: https://docs.raku.org/routine/grep
sub get-resource-type (@resource-list, Str $resource-type, Str $mode="managed") {
@resource-list.grep: { $_<mode> eq $mode && $_<type> eq $resource-type }
}
sub check-tags ($resource, %required_tags) {
return True if %required_tags.grep($resource<change><after><tags_all><foo>); # or $resource.change.after.tags<foo> eq "bar";
}
my @aws-ebs-volumes = get-resource-type($resource-changes, "aws_ebs_volume");
say @aws-ebs-volumes.grep: { check-tags($_, %required-tags) };