resource_policy
The resource_policy block defines policies for infrastructure resources managed by Terraform.
Configuration model
The resource_policy block supports the following configuration:
resource_policy"<resource_type>" "<policy_label>" block | repeatableenforceblock | repeatableconditionboolean expression | requirederror_messagestring | optionalinfo_messagestring | optional
enforcement_levelstring | optionalfilterboolean expression | optionallocalsblock | optional<name>any | repeatable
operationslist of strings | optional
Complete configuration example
The following example demonstrates a resource_policy block with all configuration options specified:
policies/example.policy.hcl
resource_policy "aws_instance" "testing" {
operations = ["create", "update"]
enforcement_level = "mandatory"
filter = attrs.tags.env == "testing"
locals {
allowed_type = "t3.micro"
}
enforce {
condition = attrs.instance_type == local.allowed_type
error_message = "Only ${local.allowed_type} instances are allowed in testing environments."
info_message = "Checking instance type: ${attrs.instance_type}"
}
enforce {
condition = attrs.monitoring == true
error_message = "Monitoring must be enabled for all instances."
}
}
Specification
A resource_policy block supports the following configuration.
Resource type
Specifies the resource type, such as aws_instance, google_compute_instance, or azurerm_windows_virtual_machine. You can use the * wildcard for all or part of the resource name to apply a policy to every resource defined in the configuration or every resource starting with a given prefix. Refer to the provider documentation for a list of supported resources for each provider.
Policy label
Specifies a unique name for this policy within the policy file.
enforce
The enforce block defines a condition that must evaluate to true for the policy to pass. You can declare more than one enforce block in each resource_policy block. If a condition in any enforce block fails during evaluation, then Terraform policy fails the entire policy and returns the corresponding error messages.
- Data type: Block
- Repeatable
An enforce block supports the following configuration.
condition
A boolean expression that must evaluate to true for the policy to pass.
- Data type: Boolean expression
- Required
error_message
The error message to display when the condition evaluates to false.
- Data type: String
- Default: None
info_message
An informational message to display regardless of whether the policy passes or fails.
- Data type: String
- Default: None
enforcement_level
Specifies the enforcement level for the policy. You can specify one of the following values:
"advisory": Allows the operation to continue but prints a warning when the conditions of the policy aren't met."mandatory": Stops the operation if the conditions of the policy aren't met."mandatory_overridable": Stops the operation if the conditions of the policy aren't met, but allows a user with appropriate permissions to override the policy and continue.Data type: String
Default:
"mandatory"
filter
Specifies a Boolean expression to filter which resources the policy applies to based on their attributes. Refer to Attributes for information about how to access resource attributes.
- Data type: Boolean expression
- Default: None
locals
Defines values that are local to the policy. You can only define one locals block per resource_policy block. The locals block nested in a resource_policy overrides locals blocks defined in the root of the policy file. Refer to the root-level locals block reference for more information.
- Data type: Block
- Default: None
operations
Specifies the Terraform operation during which to enforce this policy. You can configure the policy to evaluate during more than one operation. You can specify "create", "update", or "delete".
- Data type: List of strings
- Default:
["create", "update"]
When the policy references prior_attrs, you must set operations to "update", "delete", or both. You cannot include "create" because a create operation has no prior state.
Attributes
Within the resource_policy block, you have access to the following attributes.
| Object | Description |
|---|---|
attrs | Provides access to the resource attributes. |
prior_attrs | Provides access to the prior state of resource attributes. |
meta | Provides access to Terraform-defined information about the resource. |
Depending on the operation being evaluated, the value of the attrs and prior_attrs attributes will contain different values as described in the following table.
| Operation | attrs.<name> | prior_attrs.<name> |
|---|---|---|
| create | Target State | (unavailable/null) |
| update | Target State | Current State |
| delete | Target State (all resource attributes are null) | Current State |
Each Terraform provider defines the attributes available for each resource it supports. Refer to the provider documentation for a list of supported attributes.
meta object attributes
The following meta-arguments are available in resource_policy blocks.
| Name | Description | Type | Example |
|---|---|---|---|
meta.module_path | The module path the resource belongs to. | String | ".", "my-module" |
meta.operation | The operation being performed. | String | "create", "update", "delete" |
meta.provider_type | The type of the provider of the resource. | String | "aws", "azurerm" |
meta.type | The type of the resource. This is the first label of the matching resource block. | String | "aws_s3_bucket", "azurerm_managed_disk" |
Examples
The following examples demonstrate common resource policy configuration patterns for specific use cases.
Enforce instance type in testing environment
In the following example, the resource_policy block targets AWS instances in the testing environment and enforces that only t3.micro instances are allowed.
resource_policy "aws_instance" "testing" {
operations = ["create", "update"]
enforcement_level = "mandatory"
filter = attrs.tags.env == "testing"
enforce {
condition = attrs.instance_type == "t3.micro"
error_message = "Only t3.micro instances are allowed in testing environments."
}
}
Enforce encryption for EBS volumes
In the following example, the resource_policy block enforces that all EBS volumes must have encryption enabled.
resource_policy "aws_ebs_volume" "encryption_required" {
enforcement_level = "mandatory"
enforce {
condition = attrs.encrypted == true
error_message = "All EBS volumes must be encrypted."
}
}
Use wildcard to match multiple resource types
In the following example, the resource_policy block uses a wildcard pattern to apply a tagging requirement to all AWS resources.
resource_policy "aws_*" "require_tags" {
enforcement_level = "mandatory_overridable"
enforce {
condition = attrs.tags != null && core::length(core::keys(attrs.tags)) > 0
error_message = "All AWS resources must have at least one tag."
}
}
Enforce security group rules
In the following example, the resource_policy block uses a local value to check if a security group allows public ingress and enforces that it does not.
resource_policy "aws_security_group" "no_public_ingress" {
enforcement_level = "mandatory"
locals {
has_public_ingress = core::contains(
[for rule in attrs.ingress : rule.cidr_blocks],
["0.0.0.0/0"]
)
}
enforce {
condition = !local.has_public_ingress
error_message = "Security groups must not allow ingress from 0.0.0.0/0."
}
}
Multiple enforce blocks
In the following example, the resource_policy block uses multiple enforce blocks to validate different security requirements for S3 buckets.
resource_policy "aws_s3_bucket" "security_requirements" {
enforcement_level = "mandatory"
enforce {
condition = attrs.versioning[0].enabled == true
error_message = "S3 bucket versioning must be enabled."
}
enforce {
condition = attrs.server_side_encryption_configuration != null
error_message = "S3 bucket must have server-side encryption configured."
}
enforce {
condition = attrs.acl != "public-read" && attrs.acl != "public-read-write"
error_message = "S3 bucket must not have public ACL."
}
}