From 93321b220efd4b5a54079d57ccb4d2af1d4bbfec Mon Sep 17 00:00:00 2001 From: Charlie Egan Date: Thu, 6 Mar 2025 17:57:16 +0100 Subject: [PATCH] Revert "docs: Update terraform examples" (#7428) This reverts commit d506db305c8bd26d9357ddf7fb7d0c423ad677a4. This was committed to main in error and should be merged via PR instead. Signed-off-by: Charlie Egan --- docs/content/terraform.md | 133 +++++++++++++++++--------------------- 1 file changed, 58 insertions(+), 75 deletions(-) diff --git a/docs/content/terraform.md b/docs/content/terraform.md index 5e3950d59f..036d9e00e6 100644 --- a/docs/content/terraform.md +++ b/docs/content/terraform.md @@ -12,7 +12,8 @@ Terraform is about to make before it makes them. Such tests help in different wa * tests can auto-approve run-of-the-mill infrastructure changes and reduce the burden of peer-review * tests can help catch problems that arise when applying Terraform to production after applying it to staging -Terraform is a popular integration case for OPA and there are already a number of popular tools for + +Terraform is a popular integration case for OPA and there are already a number of popular tools for running policy on HCL and plan JSONs. {{< ecosystem_feature_link @@ -37,9 +38,8 @@ This tutorial requires * [Terraform 0.12.6](https://releases.hashicorp.com/terraform/0.12.6/) * [OPA](https://github.com/open-policy-agent/opa/releases) -(This tutorial _should_ also work with the -[latest version of Terraform](https://www.terraform.io/downloads.html), but -it is untested. Contributions welcome!) +(This tutorial *should* also work with the [latest version of Terraform](https://www.terraform.io/downloads.html), but +it is untested. Contributions welcome!) # Getting Started @@ -48,8 +48,8 @@ it is untested. Contributions welcome!) ### 1. Create and save a Terraform plan Create a [Terraform](https://www.terraform.io/docs/index.html) file that includes an -auto-scaling group and a server on AWS. -(You will need to modify the `shared_credentials_file` to point to your AWS credentials.) +auto-scaling group and a server on AWS. (You will need to modify the `shared_credentials_file` +to point to your AWS credentials.) ```shell cat >main.tf < tfplan.json Here is the expected contents of `tfplan.json`. -```json +```live:terraform:input { "format_version": "0.1", "terraform_version": "0.12.6", @@ -467,7 +467,7 @@ practice you would vary the threshold depending on the user.) **policy/terraform.rego**: -```rego +```live:terraform:module:openable package terraform.analysis import input as tfplan @@ -502,21 +502,21 @@ authz if { # Compute the score for a Terraform plan as the weighted sum of deletions, creations, modifications score := s if { - all_resources := [x | - some resource_type, crud in weights - - del := crud.delete * num_deletes[resource_type] - new := crud.create * num_creates[resource_type] - mod := crud.modify * num_modifies[resource_type] + 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_resources) + s := sum(all) } # Whether there is any change to IAM touches_iam if { - all_resources := resources.aws_iam - count(all_resources) > 0 + all := resources.aws_iam + count(all) > 0 } #################### @@ -524,50 +524,39 @@ touches_iam if { #################### # list of all resources of a given type -resources[resource_type] := all_resources if { - some resource_type, _ in resource_types - - all_resources := [name | - some name in tfplan.resource_changes +resources[resource_type] := all if { + some resource_type + resource_types[resource_type] + all := [name | + name := tfplan.resource_changes[_] name.type == resource_type ] } # number of creations of resources of a given type num_creates[resource_type] := num if { - some resource_type, _ in resource_types - - all_resources := resources[resource_type] - creates := [res | - some res in all_resources - "create" in res.change.actions - ] + some resource_type + resource_types[resource_type] + all := resources[resource_type] + creates := [res | res := all[_]; res.change.actions[_] == "create"] num := count(creates) } # number of deletions of resources of a given type num_deletes[resource_type] := num if { - some resource_type, _ in resource_types - - all_resources := resources[resource_type] - - deletions := [res | - some res in all_resources - "delete" in res.change.actions - ] + some resource_type + resource_types[resource_type] + all := resources[resource_type] + deletions := [res | res := all[_]; res.change.actions[_] == "delete"] num := count(deletions) } # number of modifications to resources of a given type num_modifies[resource_type] := num if { - some resource_type, _ in resource_types - - all_resources := resources[resource_type] - - modifies := [res | - some res in all_resources - "update" in res.change.actions - ] + some resource_type + resource_types[resource_type] + all := resources[resource_type] + modifies := [res | res := all[_]; res.change.actions[_] == "update"] num := count(modifies) } ``` @@ -580,17 +569,12 @@ ask it to evaluate `terraform/analysis/authz`. ```shell opa exec --decision terraform/analysis/authz --bundle policy/ tfplan.json ``` - -```json -{ - "result": [ - { - "path": "tfplan.json", - "result": true - } - ] -} +```live:terraform/authz:query:hidden +data.terraform.analysis.authz ``` +```live:terraform/authz:output +``` + If you're curious, you can ask for the score that the policy used to make the authorization decision. In our example, it is 11 (10 for the creation of the auto-scaling group and 1 for the creation of the server). @@ -599,21 +583,16 @@ In our example, it is 11 (10 for the creation of the auto-scaling group and 1 fo opa exec --decision terraform/analysis/score --bundle policy/ tfplan.json ``` -```json -{ - "result": [ - { - "path": "tfplan.json", - "result": 11 - } - ] -} +```live:terraform/score:query:hidden +data.terraform.analysis.score +``` +```live:terraform/score:output ``` If as suggested in the previous step, you want to modify your policy to make an authorization decision based on both the user and the Terraform plan, the input you would give to OPA would take the form `{"user": , "plan": }`, and your policy would reference the user with `input.user` and -the plan with `input.plan`. You could even go so far as to provide the Terraform state file and the AWS +the plan with `input.plan`. You could even go so far as to provide the Terraform state file and the AWS EC2 data to OPA and write policy using all of that context. ### 5. Create a Large Terraform plan and Evaluate it @@ -718,7 +697,7 @@ You learned a number of things about Terraform Testing with OPA: * OPA gives you fine-grained policy control over Terraform plans. * You can use data other than the plan itself (e.g. the user) when writing authorization policies. -Keep in mind that it's up to you to decide how to use OPA's Terraform tests and authorization decision. Here are some ideas. +Keep in mind that it's up to you to decide how to use OPA's Terraform tests and authorization decision. Here are some ideas. * Add it as part of your Terraform wrapper to implement unit tests on Terraform plans * Use it to automatically approve run-of-the-mill Terraform changes to reduce the burden of peer-review @@ -733,9 +712,7 @@ If you'd like to explore an additional example that uses terraform modules pleas ### 1. Create and save Terraform module plan Create a new Terraform file that includes a -security group and security group from a module. -(This example uses the module from -[terraform-aws-modules](https://github.com/terraform-aws-modules/terraform-aws-security-group)) +security group and security group from a module. (This example uses the module from https://github.com/terraform-aws-modules/terraform-aws-security-group) ```shell cat >main.tf <