resource
To test a resource policy, add a mock resource block to your test file. Use the meta attribute to set meta-attributes for the resource, if required. Use the attrs attribute to set values for any resource attributes defined by the provider.
Configuration model
The resource block supports the following configuration:
resource"<resource_type>" "<test_label>" blockattrsobject | optional<attribute_name>any | repeatable
expect_failureboolean | optionalinputsblock | optional<input_name>any | repeatable
metaobject | optionalmodule_pathstringoperationstringprovider_typestringtypestring
prior_attrsobject | optional<attribute_name>any | repeatable
skipboolean | optional
Complete configuration example
The following example demonstrates a resource block with all configuration options specified:
tests/example.policytest.hcl
resource "aws_instance" "all_options" {
expect_failure = true
skip = false
meta = {
type = "aws_instance"
provider_type = "aws"
operation = "update"
module_path = "."
}
prior_attrs = {
instance_type = "t3.micro"
tags = {
Environment = "dev"
}
}
attrs = {
instance_type = "t3.small"
tags = {
Environment = "production"
}
}
inputs {
max_instance_size = "t3.large"
}
}
Specification
A resource block supports the following configuration.
Resource type
The resource type, such as aws_instance and google_compute_instance. Refer to the provider documentation for a list of supported resources.
Test label
A unique name for this test case within the test file.
attrs
Resource attributes as defined by the provider schema. Each provider defines the value attributes for each of its resources. Refer to the provider documentation for more information.
- Data type: Object
- Default: None
Depending on the operation being evaluated, the value of the attrs should contain different values as described in the following table.
| Operation | attrs.<name> |
|---|---|
| create | Target State |
| update | Target State |
| delete | Target State (all resource attributes are null) |
expect_failure
Set to true to expect this mock to fail the matching policies.
- Data type: Boolean
- Default:
false
inputs
Set policy input values specific to this test case.
- Data type: Block
- Default: None
meta
Metadata for the resource, including its lifecycle operation.
- Data type: Object
- Default: None
You can set the following meta values in the meta argument.
| Attribute | Type | Description | Example |
|---|---|---|---|
module_path | String | The module path the resource belongs to. | ".", "my-module" |
operation | String | The operation being performed. | "create", "update", "delete" |
provider_type | String | The name of the resource provider. | "aws", "azurerm" |
type | String | The resource type. This is the first label of the matching resource block. | "aws_s3_bucket", "azurerm_managed_disk" |
prior_attrs
Specifies the resource attributes before the operation for update or delete operations. Each provider defines the value attributes for each of its resources. Refer to the provider documentation for more information.
- Data type: Object
- Default: None
Depending on the operation being evaluated, the value of the prior_attrs should contain different values as described in the following table.
| Operation | prior_attrs.<name> |
|---|---|
| create | (unavailable/null) |
| update | Current State |
| delete | Current State |
skip
Set to true to skip evaluating this mock against policies. Use for establishing relationships.
- Data type: Boolean
- Default:
false
Replace block arguments
The following section describes how to handle nested block arguments in mock resources.
Terraform resource arguments use various types, including nested block arguments. For most argument types, you will assign a value of the matching type within the attrs argument. However, Terraform policy does not support including blocks within the attrs object. In order to mock resources that use nested blocks, replace the block with a named attribute.
Nested block types
The type of each argument, including nested blocks, is defined by the provider's schema. There are three types of nested blocks:
| Block Type | Terraform policy attribute value |
|---|---|
| Single nested | Assign an object value to an attribute with the same name as the block. |
| List nested | Assign a list of object values. |
| Set nested | Assign a set of object values. |
Single nested block
The following example demonstrates how to assign a value to the admin_ssh_key and os_disk single nested blocks.
resource "azurerm_linux_virtual_machine" "example" {
attrs = {
name = "public-vm"
admin_ssh_key = {
username = "azureuser"
public_key = "ssh-rsa AAAAB3..."
}
os_disk = {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
}
}
List or set nested blocks
The following example demonstrates how to assign set or list of values to the service_account nested block. The syntax for assigning set and list values is the same.
resource "google_compute_instance" "example" {
attrs = {
name = "my-instance"
machine_type = "n2-standard-2"
service_account = [
{
email = "service-account-1@example.com"
scopes = ["cloud-platform"]
},
{
email = "service-account-2@example.com"
scopes = ["monitoring"]
}
]
}
}
Test resource relationships
You can create relationships between mock resources by referencing attributes of one resource within another:
resource "aws_s3_bucket_acl" "example" {
skip = true
attrs = {
bucket = "example-bucket"
acl = "private"
}
}
resource "aws_cloudtrail" "example" {
attrs = {
name = "example-log"
s3_bucket_name = aws_s3_bucket_acl.example.bucket
enable_logging = true
}
}
Examples
The following examples demonstrate common mock resource configuration patterns for specific use cases.
Test encryption requirement
In the following example, two mock resource blocks test an encryption policy. The first block mocks a passing scenario and the second block mocks the failing scenario.
resource "aws_ebs_volume" "encrypted" {
attrs = {
availability_zone = "us-east-1a"
size = 10
encrypted = true
}
}
resource "aws_ebs_volume" "unencrypted" {
expect_failure = true
attrs = {
availability_zone = "us-east-1a"
size = 10
encrypted = false
}
}
Test update operation
In the following example, the mock resource block simulates an update operation by providing both prior_attrs and attrs to test tag changes.
resource "aws_s3_bucket" "tag_update" {
meta = {
operation = "update"
}
prior_attrs = {
bucket = "demo-bucket"
tags = {
Owner = "platform-team"
}
}
attrs = {
bucket = "demo-bucket"
tags = {
Owner = "platform-team"
Environment = "production"
}
}
}
Test with input variables
In the following example, mock resource blocks test a policy that uses input variables, with one test case overriding the input value.
The policy file declares the input:
input "require_encryption" {
type = bool
default = true
}
The policy test file overrides the input for an individual resource test case:
resource "aws_ebs_volume" "configurable" {
attrs = {
availability_zone = "us-east-1a"
size = 10
encrypted = true
}
}
resource "aws_ebs_volume" "override_input" {
attrs = {
availability_zone = "us-east-1a"
size = 10
encrypted = false
}
inputs {
require_encryption = false
}
}
Test resource with tags
In the following example, mock resource blocks test a tagging policy with one resource that has all required tags and another that is missing tags.
resource "aws_instance" "tagged" {
attrs = {
instance_type = "t3.micro"
ami = "ami-12345678"
tags = {
Environment = "production"
Owner = "platform-team"
Project = "web-app"
}
}
}
resource "aws_instance" "missing_tags" {
expect_failure = true
attrs = {
instance_type = "t3.micro"
ami = "ami-12345678"
tags = {
Environment = "production"
}
}
}
Skip resource for relationship testing
In the following example, a mock resource block with skip = true provides data for another resource to reference without being evaluated against policies.
resource "aws_vpc" "main" {
skip = true
attrs = {
cidr_block = "10.0.0.0/16"
id = "vpc-12345678"
}
}
resource "aws_subnet" "public" {
attrs = {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
}
}