Skip to content

v1.156.0

Latest
Compare
Choose a tag to compare
@cloudposse-releaser cloudposse-releaser released this 27 Jan 18:55
255a05a
Validate Terraform input variables using OPA policies @aknysh (#977)

what

why

Use Open Policy Agent (OPA) policies to validate Terraform input variables.

Introduction

When executing atmos terraform <sub-command> commands, you can provide Terraform input variables on the command line using the -var flag. These variables will override the variables configured in Atmos stack manifests.

For example:

atmos terraform apply <component> -s <stack> -- -var name=api

atmos terraform apply <component> -s <stack> -- -var name=api -var 'tags={"Team":"api", "Group":"web"}'

NOTE: Terraform processes variables in the following order of precedence (from highest to lowest):

  • Explicit -var flags: these variables have the highest priority and will override any other variable values, including those specified in --var-file.

  • Variables in --var-file: values in a variable file override default values set in the Terraform configuration.
    Atmos generates varfiles from stack configurations and provides it to Terraform using the --var-file flag.

  • Environment variables: variables set as environment variables using the TF_VAR_ prefix.

  • Default values in the Terraform configuration files: these have the lowest priority.


When log level Trace is used, Atmos prints the Terraform variables specified on the command line in the "CLI variables" output.

For example:

ATMOS_LOGS_LEVEL=Trace /
atmos terraform apply my-component -s plat-ue2-dev -- -var name=api -var 'tags={"Team":"api", "Group":"web"}'

Variables for the component 'my-component' in the stack 'plat-ue2-dev':
environment: ue2
namespace: cp
region: us-east-2
stage: dev
tenant: plat

Writing the variables to file:
components/terraform/my-component/plat-ue2-dev-my-component.terraform.tfvars.json

CLI variables (will override the variables defined in the stack manifests):
name: api
tags:
    Team: api
    Group: web

Atmos exposes the Terraform variables passed on the command line in the tf_cli_vars section, which can be used in OPA policies for validation.

Terraform Variables Validation using OPA Policies

In atmos.yaml, configure the schemas.opa section:

# Validation schemas
schemas:
  # https://www.openpolicyagent.org
  opa:
    # Can also be set using `ATMOS_SCHEMAS_OPA_BASE_PATH` ENV var, or `--schemas-opa-dir` command-line arguments
    # Supports both absolute and relative paths
    base_path: "stacks/schemas/opa"

In the component manifest, add the settings.validation section to point to the OPA policy file:

components:
  terraform:
    my-component:
      settings:
        # All validation steps must succeed to allow the component to be provisioned
        validation:
          check-template-functions-test-component-with-opa-policy:
            schema_type: opa
            # 'schema_path' can be an absolute path or a path relative to 'schemas.opa.base_path' defined in `atmos.yaml`
            schema_path: "my-component/validate-my-component.rego"
            description: Check 'my-component' component using OPA policy
            # Validation timeout in seconds
            timeout: 5

Require a Terraform variable to be specified on the command line

If you need to enforce that a Terraform variable must be specified on the command line (and not in Atmos stack manifests),
add the following OPA policy in the file stacks/schemas/opa/my-component/validate-my-component.rego

# 'package atmos' is required in all `atmos` OPA policies
package atmos

# Atmos looks for the 'errors' (array of strings) output from all OPA policies.
# If the 'errors' output contains one or more error messages, Atmos considers the policy failed.

errors["for the 'my-component' component, the variable 'name' must be provided on the command line using the '-var' flag"] {
    not input.tf_cli_vars.name
}

When executing the following command (and not passing the name variable on the command line), Atmos will validate the component using the OPA policy, which will fail and prevent the component from being provisioned:

atmos terraform apply my-component -s plat-ue2-dev

Validating the component 'my-component' using OPA file 'my-component/validate-my-component.rego'

for the 'my-component' component, the variable 'name' must be provided on the command line using the '-var' flag

On the other hand, when passing the name variable on the command line using the -var name=api flag, the command will succeed:

atmos terraform apply my-component -s plat-ue2-dev -- -var name=api

Restrict a Terraform variable from being provided on the command line

If you need to prevent a Terraform variable from being passed (and overridden) on the command line, add the following OPA policy in the file stacks/schemas/opa/my-component/validate-my-component.rego

package atmos

errors["for the 'my-component' component, the variable 'name' cannot be overridden on the command line using the '-var' flag"] {
    input.tf_cli_vars.name
}

When executing the following command, Atmos will validate the component using the OPA policy, which will fail and prevent the component from being provisioned:

atmos terraform apply my-component -s plat-ue2-dev -- -var name=api

Validating the component 'my-component' using OPA file 'my-component/validate-my-component.rego'

for the 'my-component' component, the variable 'name' cannot be overridden on the command line using the '-var' flag

This command will pass the validation and succeed:

atmos terraform apply my-component -s plat-ue2-dev

references