Skip to content

Policy Overview

It is a best practice to set auto governance policices for your infrastructure, which acts as a layer of defense from misconfigurations. InfraWeave has rego support by utilizing Open Policy Agent under the hood, and allows running them at the core of the jobs.

Policies

If you have a folder structure of policies. The only job you have to do is to create a policy.yaml manifest in each policy folder.

  • Directorypolicies/
    • Directoryaws/
      • Directoryallowed_regions/
        • helper.rego
        • policy.rego
        • policy.yaml
      • Directoryallowed_ec2_instances/
        • policy.rego
    • Directoryazure/
      • Directory…/

This is an example of a Policy manifest

policies/aws/allowed_regions.yaml
apiVersion: infraweave.io/v1
kind: Policy
metadata:
name: allowed-regions # The name of the policy you define
spec:
name: AllowedRegions # The name of the policy you define
version: 0.1.2 # The released version to use
reference: https://github.com/infraweave-io/policies/aws/allowed-regions # Link
description: |
# Allowed Regions
There are a set of regions that are allowed to be used, since these are the regions that the company has a presence in.
## Best practices
- Use the allowed regions to ensure that the company's data is stored in the regions where the company has a presence.
## Questions
If you need to use a region that is not in the list, please [reach out](mailto:security@acmecorp.com) to the security team
data:
allowed_regions:
- us-east-1
- eu-west-1
- eu-central-1

Policy Example

Below is an example of rego files that can be used together with the Policy manifest above

policies/aws/allowed_regions.rego
package infraweave.terraform_plan
import data.infraweave.helpers
deny[reason] {
not is_array(data.allowed_regions)
reason := "The data variable 'allowed_regions' has to be an array."
}
deny[reason] {
is_array(data.allowed_regions)
provider_name := helpers.get_basename(input.resource_changes[_].provider_name)
region := helpers.get_region(input, provider_name, data.env)
not helpers.contains(data.allowed_regions, region)
reason := concat("", ["Invalid region: '", region, "'. The allowed AWS regions are: ", sprintf("%s", [data.allowed_regions])])
}

It uses this file which contains help functions

policies/aws/helpers.rego
package infraweave.helpers
get_region(tfplan, provider_name, env) = region {
# If region is a reference to a variable
region_var_name := trim_prefix(tfplan.configuration.provider_config[provider_name].expressions.region.references[0], "var.")
region := tfplan.variables[region_var_name].value
}
get_region(tfplan, provider_name, env) = region {
# If region is provided as a constant value
region := tfplan.configuration.provider_config[provider_name].expressions.region.constant_value
}
get_region(tfplan, provider_name, env) = region {
# If AWS_DEFAULT_REGION is not set, check for AWS_REGION in env
region := env["AWS_REGION"]
}
get_basename(path) = basename {
arr := split(path, "/")
basename := arr[count(arr)-1]
}
contains(arr, elem) {
arr[_] == elem
}

Policy types

There are two main stages where governance policies can be applied in a Terraform workflow: before changes are applied and after changes are applied.

Pre-apply policy

This policy set will run against the planned changes (after terraform plan). The goal here is to deny any resources in the plan that violate your policies before they are actually applied.

Examples can be:

  • Only allow a set of regions for deploying infrastructure
  • Require that S3 Buckets have encryption enabled
  • Limit to a specific set of allowed EC2 instance types
  • Resource naming conventions

If a policy fails, it will immediately stop the deployment, preventing non-compliant infrastructure from being created.

Post-apply policy

The post-apply policy is meant to evaluate the actual state of your infrastructure once it has been created or modified. (e.g. after terraform apply)

Examples can be:

  • Check encryption on RDS snapshots in the final state
  • Verify that newly created EC2 instances do not receive a public IP address
  • Tagging compliance requirements

If a policy fails, a notice will appear in the deployment. You can also configure webhooks or other integrations to trigger actions (sending alerts, etc.) based on those policy results.


Why is not everything caught in pre-apply step?

Certain configurations only become apparent after resources are created. For instance:

  • Some cloud providers apply default settings at creation time that are not visible in the plan.
  • Additional attributes only exist after the resource is fully provisioned.
  • Final health checks, drift detection, and operational states (e.g., encrypted snapshots, active replication status) are often verifiable only in the live infrastructure.