Policy examples
This page provides example policies written for the Terraform policy framework. Refer to these examples to learn how to implement your own policies.
Encrypt EBS volumes
This example demonstrates a resource policy that ensures all AWS EBS volumes are encrypted and use an approved KMS key. It also shows how to use core::getdatasource() to retrieve data sources and the data test block to mock them.
Policy
The policy checks that each aws_ebs_volume resource is encrypted and uses the approved KMS key. It applies a policy block that enforces encryption. A second block uses a filter to enforce the KMS key requirement on encrypted volumes.
policies/encrypted_ebs.policy.hcl
locals {
approved_kms_key = core::getdatasource("aws_kms_key", {
key_id = "alias/approved-ebs-key"
})
}
resource_policy "aws_ebs_volume" "ebs_encrypted" {
enforce {
condition = attrs.encrypted == true
error_message = "EBS volume is not encrypted"
}
}
resource_policy "aws_ebs_volume" "approved_kms_key" {
filter = attrs.encrypted == true
enforce {
condition = attrs.kms_key_id == local.approved_kms_key.id
error_message = "EBS volume must use the approved KMS key: ${local.approved_kms_key.id}"
}
}
Tests
This test demonstrates using the data block to mock a KMS key data source. It includes a test case that passes both policies, a case that fails when the data source isn't encrypted, and a case that fails when the data source uses the wrong KMS key.
tests/encrypted_ebs.policytest.hcl
policytest {
targets = ["../policies/encrypted_ebs.policy.hcl"]
}
data "aws_kms_key" "approved" {
attrs = {
key_id = "alias/approved-ebs-key"
id = "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
arn = "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
}
}
resource "aws_ebs_volume" "pass" {
attrs = {
availability_zone = "us-east-1a"
size = 10
encrypted = true
kms_key_id = data.aws_kms_key.approved.id
}
}
resource "aws_ebs_volume" "fail_not_encrypted" {
expect_failure = true
attrs = {
availability_zone = "us-east-1a"
size = 10
encrypted = false
}
}
resource "aws_ebs_volume" "fail_wrong_key" {
expect_failure = true
attrs = {
availability_zone = "us-east-1a"
size = 10
encrypted = true
kms_key_id = "arn:aws:kms:us-east-1:123456789012:key/wrong-key-id"
}
}
Validate and test
Validate the policy syntax:
$ tfpolicy validate --policies=policies/encrypted_ebs.policy.hcl
Success! Policy is valid.
Run the tests:
$ tfpolicy test --policies=policies/encrypted_ebs.policy.hcl --tests=tests/encrypted_ebs.policytest.hcl
# encrypted_ebs.policytest.hcl... running
# resource.aws_ebs_volume.pass... pass
# resource.aws_ebs_volume.fail_not_encrypted... pass
# resource.aws_ebs_volume.fail_wrong_key... pass
# encrypted_ebs.policytest.hcl... pass
Sample Terraform configuration
The following Terraform configuration demonstrates EBS volumes that would pass and fail these policies:
main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "us-west-2"
}
resource "aws_kms_key" "ebs" {
description = "KMS key for EBS volume encryption"
deletion_window_in_days = 10
}
resource "aws_kms_alias" "ebs" {
name = "alias/approved-ebs-key"
target_key_id = aws_kms_key.ebs.key_id
}
data "aws_kms_key" "approved" {
key_id = aws_kms_alias.ebs.name
}
resource "aws_ebs_volume" "pass" {
availability_zone = "us-west-2a"
size = 10
encrypted = true
kms_key_id = data.aws_kms_key.approved.id
}
resource "aws_ebs_volume" "fail_not_encrypted" {
availability_zone = "us-west-2b"
size = 10
encrypted = false
}
resource "aws_ebs_volume" "fail_wrong_key" {
availability_zone = "us-west-2c"
size = 10
encrypted = true
}
Ensure Azure managed disks have encryption settings
This example demonstrates a resource policy that validates nested attributes in Azure managed disks. It also shows how to use input blocks to parameterize policies, the inputs block in tests to set and override input values, and the mandatory_overridable enforcement level to allow exceptions with approval.
Policy
The policy uses an input variable to make the encryption requirement configurable. It sets enforcement_level = "mandatory_overridable" to allow users with appropriate permissions to override the policy when needed, such as for development environments.
policies/azure_disk_encryption.policy.hcl
input "require_encryption" {
type = bool
description = "Whether to require encryption on managed disks"
default = true
}
resource_policy "azurerm_managed_disk" "require_encryption" {
enforcement_level = "mandatory_overridable"
enforce {
condition = !input.require_encryption || attrs.encryption_settings_collection[0].enabled == true
error_message = "The managed disk must have encryption settings enabled."
}
}
Tests
This test demonstrates using the inputs block at both the file level and per test case. The top-level inputs block sets a default value that applies to all test cases, while individual test cases can override it.
tests/azure_disk_encryption.policytest.hcl
policytest {
targets = ["../policies/azure_disk_encryption.policy.hcl"]
}
inputs {
require_encryption = true
}
resource "azurerm_managed_disk" "pass" {
attrs = {
name = "test-disk"
location = "East US"
resource_group_name = "test-rg"
storage_account_type = "Standard_LRS"
create_option = "Empty"
disk_size_gb = 10
encryption_settings_collection = [
{
enabled = true
}
]
}
}
resource "azurerm_managed_disk" "fail" {
expect_failure = true
attrs = {
name = "test-disk-unencrypted"
location = "East US"
resource_group_name = "test-rg"
storage_account_type = "Standard_LRS"
create_option = "Empty"
disk_size_gb = 10
encryption_settings_collection = [
{
enabled = false
}
]
}
}
resource "azurerm_managed_disk" "pass_no_requirement" {
inputs {
require_encryption = false
}
attrs = {
name = "test-disk-optional"
location = "East US"
resource_group_name = "test-rg"
storage_account_type = "Standard_LRS"
create_option = "Empty"
disk_size_gb = 10
encryption_settings_collection = [
{
enabled = false
}
]
}
}
Validate and test
Validate the policy syntax:
$ tfpolicy validate --policies=policies/azure_disk_encryption.policy.hcl
Success! Policy is valid.
Run the tests:
$ tfpolicy test --policies=policies/azure_disk_encryption.policy.hcl --tests=tests/azure_disk_encryption.policytest.hcl
# azure_disk_encryption.policytest.hcl... running
# resource.azurerm_managed_disk.pass... pass
# resource.azurerm_managed_disk.fail... pass
# resource.azurerm_managed_disk.pass_no_requirement... pass
# azure_disk_encryption.policytest.hcl... pass
Sample Terraform configuration
The following Terraform configuration defines Azure managed disks that would pass and fail this policy:
main.tf
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
}
}
required_version = ">= 1.2.0"
}
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "example" {
name = "example-resources"
location = "East US"
}
# This disk would pass the policy (encryption enabled)
resource "azurerm_managed_disk" "pass" {
name = "data-disk-01"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
storage_account_type = "Standard_LRS"
create_option = "Empty"
disk_size_gb = 10
encryption_settings {
enabled = true
}
}
# This disk would fail the policy (encryption disabled)
resource "azurerm_managed_disk" "fail" {
name = "shadow-disk-02"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
storage_account_type = "Standard_LRS"
create_option = "Empty"
disk_size_gb = 10
encryption_settings {
enabled = false
}
}
Verify module sources and versions
This example demonstrates a module policy that validates module sources and versions using meta-attributes and the semverconstraint function. It uses enforcement_level = "advisory" to provide recommendations rather than hard requirements, allowing teams flexibility when needed.
Policy
The policy recommends that VPC modules are sourced from an internal private registry and use version 2.0.0 or higher. Because the enforcement level is set to advisory, violations generate warnings but don't block operations.
policies/module_validation.policy.hcl
module_policy "aws_vpc" "registry_check" {
enforcement_level = "advisory"
enforce {
condition = core::startswith(meta.source, "app.terraform.io/my-org/")
error_message = "The VPC module should be sourced from the internal private registry (app.terraform.io/my-org/)."
}
enforce {
condition = core::semverconstraint(meta.version, ">= 2.0.0")
error_message = "The VPC module should be version 2.0.0 or higher for latest features and security fixes."
}
}
Tests
This test includes multiple failure scenarios to ensure the policy works correctly.
tests/module_validation.policytest.hcl
policytest {
targets = ["../policies/module_validation.policy.hcl"]
}
module "aws_vpc" "pass" {
meta = {
source = "app.terraform.io/my-org/vpc/aws"
version = "2.1.0"
}
attrs = {
enable_flow_log = true
}
}
module "aws_vpc" "fail_version" {
expect_failure = true
meta = {
source = "app.terraform.io/my-org/vpc/aws"
version = "1.9.0"
}
attrs = {
enable_flow_log = true
}
}
module "aws_vpc" "fail_source" {
expect_failure = true
meta = {
source = "terraform-aws-modules/vpc/aws"
version = "2.1.0"
}
attrs = {
enable_flow_log = true
}
}
Validate and test
Validate the policy syntax:
$ tfpolicy validate --policies=policies/module_validation.policy.hcl
Success! Policy is valid.
Run the tests:
$ tfpolicy test --policies=policies/module_validation.policy.hcl --tests=tests/module_validation.policytest.hcl
# module_validation.policytest.hcl... running
# module.aws_vpc.pass... pass
# module.aws_vpc.fail_version... pass
# module.aws_vpc.fail_source... pass
# module_validation.policytest.hcl... pass
Sample Terraform configuration
The following Terraform configuration uses modules that would pass and fail this policy:
main.tf
terraform {
required_version = ">= 1.2.0"
}
module "pass" {
source = "app.terraform.io/my-org/vpc/aws"
version = "2.1.0"
vpc_cidr = "10.10.0.0/16"
enable_flow_log = true
}
module "fail_version" {
source = "app.terraform.io/my-org/vpc/aws"
version = "1.9.0"
vpc_cidr = "10.20.0.0/16"
enable_flow_log = true
}
module "fail_source" {
source = "terraform-aws-modules/vpc/aws"
version = "2.1.0"
vpc_cidr = "10.30.0.0/16"
enable_flow_log = true
}
Ensure only the official AWS provider is used
This example demonstrates a provider policy that validates the provider source.
Policy
The policy ensures that only the official HashiCorp AWS provider is used.
policies/aws_provider.policy.hcl
provider_policy "aws" "official_source" {
enforce {
condition = meta.source == "hashicorp/aws"
error_message = "Only the official HashiCorp AWS provider is permitted."
}
}
Tests
This test includes multiple failure scenarios including untrusted sources.
tests/provider_validation.policytest.hcl
policytest {
targets = ["../policies/aws_provider.policy.hcl"]
}
provider "aws" "pass" {
meta = {
source = "hashicorp/aws"
}
attrs = {
region = "us-east-1"
}
}
provider "aws" "fail" {
expect_failure = true
meta = {
source = "untrusted-registry.com/fake/aws"
}
attrs = {
region = "us-east-1"
}
}
Validate and test
Validate the policy syntax:
$ tfpolicy validate --policies=policies/aws_provider.policy.hcl
Success! Policy is valid.
Run the tests:
$ tfpolicy test --policies=policies/aws_provider.policy.hcl --tests=tests/provider_validation.policytest.hcl
# provider_validation.policytest.hcl... running
# provider.aws.pass... pass
# provider.aws.fail... pass
# provider_validation.policytest.hcl... pass
Sample Terraform configuration
The following Terraform configuration uses providers that would pass and fail this policy:
main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
alias = "pass"
region = "us-east-1"
}
provider "aws" {
alias = "fail"
region = "us-east-1"
}
resource "aws_s3_bucket" "example" {
provider = aws.pass
bucket = "my-example-bucket"
}
Validate CloudTrail S3 bucket ACL
This example demonstrates using core::getresources() to validate relationships between resources. It uses enforcement_level = "mandatory_overridable" to allow exceptions for special cases, such as public audit trails, with appropriate approval.
Policy
The policy ensures that CloudTrail resources are associated with S3 buckets that have private ACLs. Because the enforcement level is set to mandatory_overridable, users with appropriate permissions can override this requirement when necessary.
policies/cloudtrail_s3_acl.policy.hcl
resource_policy "aws_cloudtrail" "must_be_private" {
enforcement_level = "mandatory_overridable"
locals {
s3_bucket_acl = core::getresources("aws_s3_bucket_acl", {
bucket = attrs.s3_bucket_name
})
}
enforce {
condition = core::length(local.s3_bucket_acl) > 0 && local.s3_bucket_acl[0].acl == "private"
error_message = "CloudTrail S3 bucket must have a private ACL."
}
}
Tests
This test demonstrates using the skip attribute to mock dependencies without evaluating policies against them.
tests/cloudtrail_s3_acl.policytest.hcl
policytest {
targets = ["../policies/cloudtrail_s3_acl.policy.hcl"]
}
resource "aws_s3_bucket_acl" "pass" {
skip = true
attrs = {
bucket = "cloudtrail-logs-private"
acl = "private"
}
}
resource "aws_cloudtrail" "pass" {
attrs = {
name = "secure-trail"
s3_bucket_name = aws_s3_bucket_acl.pass.bucket
enable_logging = true
}
}
resource "aws_s3_bucket_acl" "fail" {
skip = true
attrs = {
bucket = "cloudtrail-logs-public"
acl = "public-read"
}
}
resource "aws_cloudtrail" "fail" {
expect_failure = true
attrs = {
name = "insecure-trail"
s3_bucket_name = aws_s3_bucket_acl.fail.bucket
enable_logging = true
}
}
Validate and test
Validate the policy syntax:
$ tfpolicy validate --policies=policies/cloudtrail_s3_acl.policy.hcl
Success! Policy is valid.
Run the tests:
$ tfpolicy test --policies=policies/cloudtrail_s3_acl.policy.hcl --tests=tests/cloudtrail_s3_acl.policytest.hcl
# cloudtrail_s3_acl.policytest.hcl... running
# resource.aws_cloudtrail.pass... pass
# resource.aws_cloudtrail.fail... pass
# cloudtrail_s3_acl.policytest.hcl... pass
Sample Terraform configuration
The following Terraform configuration defines CloudTrail and S3 bucket resources that would be evaluated against this policy:
main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "us-west-2"
}
resource "aws_s3_bucket" "cloudtrail_bucket" {
bucket = "my-cloudtrail-logs-bucket"
}
resource "aws_s3_bucket_acl" "my_bucket_acl" {
bucket = aws_s3_bucket.cloudtrail_bucket.id
acl = "private"
}
resource "aws_cloudtrail" "my_cloudtrail" {
name = "my-cloudtrail"
s3_bucket_name = aws_s3_bucket.cloudtrail_bucket.id
enable_logging = true
}
Multiple policies with core functions and plugins
This example demonstrates working with multiple policies in a single project, including both core functions and custom plugins. The policies validate Azure network interface security group associations and Azure subnet CIDR ranges.
Policies
Create two policy files in the policies/ directory.
The first policy ensures that all network interfaces are associated with a network security group using core::getresources():
policies/azure_nic_nsg.policy.hcl
resource_policy "azurerm_network_interface" "require_nsg_association" {
locals {
associations = core::getresources("azurerm_network_interface_security_group_association", {network_interface_id = attrs.id})
}
enforce {
condition = core::length(local.associations) > 0
error_message = "The Network Interface ${attrs.name} must be associated with a Network Security Group."
}
}
The second policy uses a custom plugin function to validate that subnet CIDR ranges don't overlap with reserved ranges:
policies/azure_subnet_cidr.policy.hcl
policy {
plugins {
network = {
source = "../plugins/bin/cidr_utils"
}
}
}
resource_policy "azurerm_subnet" "no_cidr_overlap" {
locals {
reserved_cidrs = ["10.0.0.0/24", "10.0.1.0/24"]
}
enforce {
condition = !plugin::network::cidr_overlaps(attrs.address_prefixes[0], local.reserved_cidrs)
error_message = "Subnet CIDR ${attrs.address_prefixes[0]} overlaps with reserved ranges."
}
}
Plugin
The above policy uses the following plugin, authored in Go. It implements the logic to compare a CIDR against a restricted list and serves the function via the plugin server.
plugins/src/cidr_utils/main.go
package main
import (
"fmt"
"net/netip"
"github.com/hashicorp/terraform-policy-plugin-framework/policy-plugin/plugins"
)
func main() {
plugins.RegisterFunction("cidr_overlaps", cidr_overlaps)
plugins.Serve()
}
func cidr_overlaps(checkStr string, restrictedStrs []string) (bool, error) {
checkPrefix, err := netip.ParsePrefix(checkStr)
if err != nil {
return false, fmt.Errorf("Invalid CIDR format")
}
for _, s := range restrictedStrs {
restrictedPrefix, err := netip.ParsePrefix(s)
if err != nil {
continue
}
if checkPrefix.Overlaps(restrictedPrefix) {
return true, nil
}
}
return false, nil
}
Before you can use your plugin in your policies, you must compile it.
Change into the plugin source directory.
$ cd plugins/src/cidr_utils
Initialize go modules.
$ go mod init cidr_utils
Download and verify go modules.
$ go mod tidy
Build the plugin.
$ go build -o ../../bin/cidr_utils main.go
Tests
Create two test files in the tests/ directory to test both policies.
The first test validates the Azure network interface policy:
tests/azure_nic_nsg.policytest.hcl
policytest {
targets = ["../policies/azure_nic_nsg.policy.hcl"]
}
resource "azurerm_network_interface" "pass" {
attrs = {
name = "web-nic-01"
id = "/subscriptions/sub1/resourceGroups/rg1/providers/Microsoft.Network/networkInterfaces/web-nic-01"
}
}
resource "azurerm_network_interface_security_group_association" "nic_link" {
attrs = {
network_interface_id = azurerm_network_interface.pass.id
network_security_group_id = "/subscriptions/sub1/resourceGroups/rg1/providers/Microsoft.Network/networkSecurityGroups/web-nsg"
}
}
resource "azurerm_network_interface" "fail" {
expect_failure = true
attrs = {
name = "rogue-nic-02"
id = "/subscriptions/sub1/resourceGroups/rg1/providers/Microsoft.Network/networkInterfaces/rogue-nic-02"
}
}
The second test validates the CIDR overlap policy:
tests/azure_subnet_cidr.policytest.hcl
policytest {
targets = ["../policies/azure_subnet_cidr.policy.hcl"]
}
resource "azurerm_subnet" "pass" {
attrs = {
name = "example-subnet"
address_prefixes = ["10.0.2.0/24"]
virtual_network_name = "example-vnet"
resource_group_name = "example-rg"
}
}
resource "azurerm_subnet" "fail" {
expect_failure = true
attrs = {
name = "reserved-subnet"
address_prefixes = ["10.0.0.0/24"]
virtual_network_name = "example-vnet"
resource_group_name = "example-rg"
}
}
Validate and test
Validate both policies:
$ tfpolicy validate --policies=policies/
Success! All policies are valid.
Run all tests:
$ tfpolicy test --policies=policies/ --tests=tests/
# azure_nic_nsg.policytest.hcl... running
# resource.azurerm_network_interface.pass... pass
# resource.azurerm_network_interface.fail... pass
# azure_nic_nsg.policytest.hcl... pass
# azure_subnet_cidr.policytest.hcl... running
# resource.azurerm_subnet.pass... pass
# resource.azurerm_subnet.fail... pass
# azure_subnet_cidr.policytest.hcl... pass
Sample Terraform configuration
The following Terraform configuration demonstrates Azure resources that would be evaluated against both policies:
example-main.tf
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
}
}
required_version = ">= 1.2.0"
}
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "example" {
name = "example-resources"
location = "East US"
}
resource "azurerm_virtual_network" "example" {
name = "example-vnet"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
}
resource "azurerm_network_security_group" "example" {
name = "web-nsg"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
}
# This subnet would pass the CIDR policy (no overlap with reserved ranges)
resource "azurerm_subnet" "pass" {
name = "allowed-subnet"
resource_group_name = azurerm_resource_group.example.name
virtual_network_name = azurerm_virtual_network.example.name
address_prefixes = ["10.0.2.0/24"]
}
# This subnet would fail the CIDR policy (overlaps with reserved range)
resource "azurerm_subnet" "fail" {
name = "reserved-subnet"
resource_group_name = azurerm_resource_group.example.name
virtual_network_name = azurerm_virtual_network.example.name
address_prefixes = ["10.0.0.0/24"]
}
# This network interface would pass the NSG policy (has NSG association)
resource "azurerm_network_interface" "pass" {
name = "web-nic-01"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
ip_configuration {
name = "internal"
subnet_id = azurerm_subnet.pass.id
private_ip_address_allocation = "Dynamic"
}
}
resource "azurerm_network_interface_security_group_association" "pass" {
network_interface_id = azurerm_network_interface.pass.id
network_security_group_id = azurerm_network_security_group.example.id
}
# This network interface would fail the NSG policy (no NSG association)
resource "azurerm_network_interface" "fail" {
name = "rogue-nic-02"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
ip_configuration {
name = "internal"
subnet_id = azurerm_subnet.pass.id
private_ip_address_allocation = "Dynamic"
}
}
Prevent EBS volume downsizing
This example demonstrates using the operations parameter to control when policies are enforced and the prior_attrs attribute to access previous resource state. This is useful for preventing dangerous operations such as reducing volume sizes that could cause data loss.
Policy
The policy uses operations = ["update"] so that only enforce during update operations trigger evaluation. During evaluation, the policy compares prior_attrs.size with attrs.size to prevent downsizing.
policies/prevent_downsize.policy.hcl
resource_policy "aws_ebs_volume" "prevent_downsize" {
operations = ["update"]
enforce {
condition = attrs.size >= prior_attrs.size
error_message = "EBS volume size cannot be reduced from ${prior_attrs.size}GB to ${attrs.size}GB. Downsizing volumes can cause data loss."
}
}
Tests
This test demonstrates using prior_attrs in test resources to simulate update operations. It includes a scenario that passes when the EBS volume increases in size, a scenario that passes when the volume remains the same size, and a scenario that fails when the volume size decreases.
tests/prevent_downsize.policytest.hcl
policytest {
targets = ["../policies/prevent_downsize.policy.hcl"]
}
resource "aws_ebs_volume" "pass_increase" {
prior_attrs = {
availability_zone = "us-east-1a"
size = 50
encrypted = true
}
attrs = {
availability_zone = "us-east-1a"
size = 100
encrypted = true
}
}
resource "aws_ebs_volume" "pass_same_size" {
prior_attrs = {
availability_zone = "us-east-1a"
size = 50
encrypted = true
}
attrs = {
availability_zone = "us-east-1a"
size = 50
encrypted = true
}
}
resource "aws_ebs_volume" "fail_decrease" {
expect_failure = true
prior_attrs = {
availability_zone = "us-east-1a"
size = 100
encrypted = true
}
attrs = {
availability_zone = "us-east-1a"
size = 50
encrypted = true
}
}
Validate and test
Validate the policy syntax:
$ tfpolicy validate --policies=policies/prevent_downsize.policy.hcl
Success! Policy is valid.
Run the tests:
$ tfpolicy test --policies=policies/prevent_downsize.policy.hcl --tests=tests/prevent_downsize.policytest.hcl
# prevent_downsize.policytest.hcl... running
# resource.aws_ebs_volume.pass_increase... pass
# resource.aws_ebs_volume.pass_same_size... pass
# resource.aws_ebs_volume.fail_decrease... pass
# prevent_downsize.policytest.hcl... pass
Sample Terraform configuration
The following Terraform configuration demonstrates an EBS volume that would be evaluated against this policy during updates:
main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "us-west-2"
}
resource "aws_ebs_volume" "example" {
availability_zone = "us-west-2a"
size = 50
encrypted = true
tags = {
Name = "example-volume"
}
}