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
resource "<resource_type>" "<test_case_name>" {
meta = {
address = "<resource_address>"
}
attrs = {
<attribute_name> = <attribute_value>
}
operation = "<operation>"
prior_attrs = { <attributes> }
expect_failure = <boolean>
skip = <boolean>
input {
<input_name> = <input_value>
}
}
Complete configuration example
resource "aws_ebs_volume" "encrypted_pass" {
attrs = {
availability_zone = "us-east-1a"
size = 10
encrypted = true
}
}
resource "aws_ebs_volume" "unencrypted_fail" {
expect_failure = true
attrs = {
availability_zone = "us-east-1a"
size = 10
encrypted = false
}
}
resource "aws_instance" "update_operation" {
operation = "update"
prior_attrs = {
instance_type = "t3.micro"
tags = {
Environment = "dev"
}
}
attrs = {
instance_type = "t3.small"
tags = {
Environment = "production"
}
}
}
Specification
Labels
Resource blocks support two labels.
| Label | Required | Description |
|---|---|---|
| First label | Yes | The resource type (For example: aws_instance, google_compute_instance). |
| Second label | Yes | A unique name for this test case within the test file. |
Arguments
Resource blocks support the followng arguments.
| Argument | Required | Type | Description |
|---|---|---|---|
meta | No | Object | Meta-attributes for the resource, including address. |
attrs | Yes | Object | Resource attributes as defined by the provider schema. |
operation | No | String | The operation to test: "create", "update", or "delete". Defaults to "create" (or "update" if prior_attrs is set). |
prior_attrs | No | Object | The resource attributes before the operation (for update or delete operations). |
expect_failure | No | Boolean | Set to true to expect this mock to fail the matching policies. Defaults to false. |
skip | No | Boolean | Set to true to skip evaluating this mock against policies. Use for establishing relationships. Defaults to false. |
input | No | Block | Set input values specific to this test case. |
Depending on the operation being evaluated, the value of the attrs and prior_attrs attributes should 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 |
The meta argument
You can set the following meta values in the meta argument.
| Attribute | Type | Description | |
|---|---|---|---|
module_path | The module path the resource belongs to. | String | ".", "my-module" |
operation | The operation being performed. | String | "create", "update", "destroy" |
provider_type | The name of the provider of the resource. | String | "aws", "azurerm" |
resource_type | The type of the resource. This will be the first label of the matching resource block. | String | "aws_s3_bucket", "azurerm_managed_disk" |
The attrs argument
Set attributes for the mock provider with the attrs argument. Each provider defines the value attributes for each of its resources. Refer to the provider documentation for more information.
The prior_attrs argument
Set attributes for the mock provider with the attrs argument. Each provider defines the value attributes for each of its resources. Refer to the provider documentation for more information.
Replace block arguments
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. |
| Set nested | Assign a list of object values. |
| List nested | Assign a list of object values. |
Example: Single nested block
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"
}
}
}
Example: List/Set nested blocks
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
Test encryption requirement
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
resource "aws_s3_bucket" "tag_update" {
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
input "require_encryption" {
type = bool
default = true
}
resource "aws_ebs_volume" "configurable" {
attrs = {
availability_zone = "us-east-1a"
size = 10
encrypted = input.require_encryption
}
}
resource "aws_ebs_volume" "override_input" {
attrs = {
availability_zone = "us-east-1a"
size = 10
encrypted = false
}
input {
require_encryption = false
}
}
Test resource with 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
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"
}
}
Related documentation
- Write and run policy tests - Learn how to write and run tests
- The
resource_policy {}block - Resource policy reference