|
| 1 | +# Sentinel HTTP Import and Parameters Examples |
| 2 | +This directory contains examples of using the [HTTP import](https://docs.hashicorp.com/sentinel/imports/http) and [policy parameters](https://docs.hashicorp.com/sentinel/language/parameters) that were added in the Sentinel 0.13.0 runtime. Policy parameters allow you to specify API credentials without storing them in your policies which would be undesirable since policies are stored in VCS repositories. |
| 3 | + |
| 4 | +Be sure to use Sentinel 0.15.2 or higher with these policies. |
| 5 | + |
| 6 | +These policies are essentially the same as the second-generation versions in this [directory](../../../second-generation/cloud-agnostic/http-examples), but the [use-latest-module-versions.sentinel](./use-latest-module-versions.sentinel) in this directory uses the [tfconfig/v2](https://www.terraform.io/docs/cloud/sentinel/import/tfconfig-v2.html) import instead of the older [tfconfig](https://www.terraform.io/docs/cloud/sentinel/import/tfconfig.html) import. It uses that import indirectly by calling some functions from the [tfconfig-functions](../../common-functions/tfconfig-functions) Sentinel module. |
| 7 | + |
| 8 | +## Policies |
| 9 | +There are currently three example policies in this directory: |
| 10 | +* [check-external-http-api.sentinel](./check-external-http-api.sentinel) |
| 11 | +* [use-latest-module-versions.sentinel](./use-latest-module-versions.sentinel) |
| 12 | +* [asteroids.sentinel](./asteroids.sentinel) |
| 13 | + |
| 14 | +The first policy simply uses the HTTP import to call an external API, https://yesno.wtf/api that randomly returns "yes" or "no" (but sometimes returns "maybe"). It also uses the recently added [case statement](https://docs.hashicorp.com/sentinel/language/spec/#case-statements) that provides a selection control mechanism to conditionally execute different logic based on the value of an argument. |
| 15 | + |
| 16 | +You can test the first policy from this directory (after forking or cloning the repository and [installing the Sentinel CLI](https://docs.hashicorp.com/sentinel/intro/getting-started/install/)) with this command: |
| 17 | +``` |
| 18 | +sentinel test -run=check -verbose |
| 19 | +``` |
| 20 | + |
| 21 | +The second policy uses the HTTP import to call the Terraform Registry [List Modules API](https://www.terraform.io/docs/registry/api.html#list-modules) against a Terraform Cloud or Terraform Enterprise server in order to determine the most recent version of each module in the [Private Module Registry](https://www.terraform.io/docs/cloud/registry/index.html) (PMR) of an organization on that server or in the [public Terraform registry](https://registry.terraform.io). This policy also uses parameters as described below. |
| 22 | + |
| 23 | +The third policy uses the HTTP import to call a [NASA API](https://api.nasa.gov/) that retrieves a list of Near Earth Objects and warns if any of them are too close for comfort. This is based on an example from this HashiCorp [blog](https://www.hashicorp.com/blog/announcing-business-aware-policies-for-terraform-cloud-and-enterprise/) that announced the HTTP import and "Business-aware Policies". This policy also uses parameters as described below. |
| 24 | + |
| 25 | +## Use of Parameters in use-latest-module-versions.sentinel |
| 26 | +The [use-latest-module-versions.sentinel](./use-latest-module-versions.sentinel) policy uses four parameters: |
| 27 | +* `public_registry` indicates whether the public Terraform registry is being used. This is `false` by default, but could be set to `true`. |
| 28 | +* `address` gives the address of the Terraform Cloud or Terraform Enterprise server. It defaults to `app.terraform.io` which is the address of the multi-tenant Terraform Cloud server that HashiCorp runs. You must specify a value for this if using a Terraform Enterprise server. |
| 29 | +* `organization` gives the name of an [organization](https://www.terraform.io/docs/cloud/users-teams-organizations/organizations.html) on the Terraform Cloud or Terraform Enterprise server specified by `address`. You must always specify a valid organization. |
| 30 | +* `token` gives a valid Terraform Cloud API token which can be a user, team, or organization token. See the [API tokens](https://www.terraform.io/docs/cloud/users-teams-organizations/api-tokens.html) document for more information. |
| 31 | + |
| 32 | +## Use of Parameters in asteroids.sentinel |
| 33 | +The [asteroids.sentinel](./asteroids.sentinel) policy uses two parameters: |
| 34 | +* `api_token` must be set to a NASA API token. (See below.) |
| 35 | +* `danger_distance` specifies a distance in miles such that any Near Earth Object that would come within that many miles of Earth will generate a Sentinel violation. |
| 36 | + |
| 37 | +Before you can test asteroids.sentinel with the provided test cases and mocks, you must obtain a NASA API token from https://api.nasa.gov and then add it to the `api_token` field of the pass.json and fail.json test cases under the test/asteroids directory. |
| 38 | + |
| 39 | +## Using Parameters with the Sentinel CLI |
| 40 | +While parameters can currently be set with environment variables when using the `sentinel apply` command, they cannot be set with environment variables when using the `sentinel test` command. |
| 41 | + |
| 42 | +Consequently, you **cannot** test the use-latest-module-versions.sentinel policy with the `sentinel test` command using the provided test cases and mocks since you will not have a token allowed to call the API against the specified Cloud-Operations organization. |
| 43 | + |
| 44 | +You could test the policy with the `sentinel test` command if you edited the mocks to reference modules contained in a PMR in an organization on your own TFC or TFE organization or contained in the public registry and added your own valid API token to the test cases. |
| 45 | + |
| 46 | +Since many readers won't have modules in their own TFC/TFE organization, we have provided a [sentinel.json](./sentinel.json) configuration file and an additional mock file [mocks/mock-tfconfig-fail.sentinel](./mocks/mock-tfconfig-fail.sentinel) that references modules from the [public Terraform registry](https://registry.terraform.io). These allow you to run the `sentinel apply` command to use the use-latest-module-versions.sentinel policy. |
| 47 | + |
| 48 | +Specifically, you can run this command to test that the versions of the Azure modules from the public module registry are the latest: |
| 49 | +``` |
| 50 | +sentinel apply use-latest-module-versions.sentinel -trace |
| 51 | +``` |
| 52 | +You do not need a token when talking to the public registry, so the sentinel.json file sets `token` to an empty string. |
| 53 | + |
| 54 | +The policy should fail since the mock does not use the most recent versions of the two modules. If you would like to see the policy pass, change the versions of the modules in mocks/mock-tfconfig-fail.sentinel to the most recent versions listed under https://registry.terraform.io/modules/Azure/network/azurerm and https://registry.terraform.io/modules/Azure/compute/azurerm. Currently, those are "3.0.1" and "3.2.0" respectively. |
| 55 | + |
| 56 | +Note that the `sentinel test` and `sentinel apply` commands for testing/applying the use-latest-module-versions.sentinel policy **really** are making HTTP calls to the API endpoints to retrieve the list of matching modules in the registries. However, the mocks simulate which modules would actually be used by Terraform code. |
| 57 | + |
| 58 | +You should **not** edit sentinel.json unless you also edit mocks/mock-tfconfig-fail.sentinel to reference actual modules in the registry and organization that sentinel.json refers to. |
| 59 | + |
| 60 | +## Using Parameters with Terraform Cloud/Enterprise |
| 61 | +If you wish to use the [use-latest-module-versions.sentinel](./use-latest-module-versions.sentinel) policy on a Terraform Cloud (TFC) or Terraform Enterprise (TFE) server, you need to specify values for the `organization` and `token` parameters when registering the policy set that contains this policy. Only do this if you have actually created some modules in the Private Module Registry (PMR) in an organization on your server and have Terraform code that uses them. |
| 62 | + |
| 63 | +You can do this as follows: |
| 64 | +1. Copy the files [check-external-http-api.sentinel](./check-external-http-api.sentinel), [use-latest-module-versions.sentinel](./use-latest-module-versions.sentinel), and [sentinel.hcl](./sentinel.hcl) into a VCS repository. (Don't copy the file sentinel.json which is only for use with the Sentinel CLI.) |
| 65 | +1. Optionally edit the copy of sentinel.hcl to set the enforcement_level for the use-latest-module-versions policy to `soft-mandatory`. |
| 66 | +1. Commit the files to your VCS repository. |
| 67 | +1. Instead of doing the above 3 steps, you could fork the [test-http-policies-and-parameters](https://github.com/rberlind/test-http-policies-and-parameters) repository and use that fork. |
| 68 | +1. [Register a new policy set](https://www.terraform.io/docs/cloud/sentinel/manage-policies.html#managing-policy-sets) on your Terraform Cloud or Terraform Enterprise server. |
| 69 | +1. Edit the registered policy sets to specify values for the `organization` and `token` parameters making sure you pick an organization that actually has some modules in its PMR and that the token you give is a valid API token with permission in that organization. (You cannot specify parameters until after creating the policy set.) Parameters are added at the bottom of the Policy Set screen. |
| 70 | +1. Be sure to mark your `token` parameter as sensitive so that nobody else can see it in the Terraform Cloud UI. |
| 71 | +1. If using a Terraform Enterprise server, also specify a value for the `address` parameter, using a value like "tfe.example.com". |
| 72 | +1. Save the policy set. |
| 73 | +1. Add a workspace to the policy set that uses Terraform code that references modules in the PMR in the organization you specified. |
| 74 | +1. Queue a plan against that workspace in the Terraform Cloud UI. |
0 commit comments