data
Terraform data sources do not represent infrastructure directly managed by Terraform, so you will not directly write policies for them. However, in many Terraform configurations, data sources serve as the foundation for resource relationships, providing IDs or configurations fetched from existing infrastructure. You may need to mock these data sources in your policy tests to ensure that your policies correctly verify resources or modules that rely on this data.
Configuration model
The data block supports the following configuration:
data"<data_source_type>" "<data_source_label>" blockattrsobject<attribute_name>any | repeatable
Complete configuration example
The following example demonstrates a data block with all configuration options specified:
tests/example.policytest.hcl
data "aws_vpc" "corporate_network" {
attrs = {
id = "vpc-12345678"
cidr_block = "10.0.0.0/16"
}
}
Specification
A data block supports the following configuration.
Data source type
The data source type, such as aws_vpc and aws_ami. Refer to the provider documentation for a list of supported data sources.
Data source label
A unique name for this mock data source within the test file.
attrs
Data source attributes as returned by the provider. The attrs object contains the mock data that Terraform policy returns from a matching core::getdatasource() call. Include the arguments that the policy passes to core::getdatasource() in attrs so that Terraform policy can match the call to the mock. You can also include additional attributes that the function returns to the policy.
- Data type: Object
- Required
Behavior
Unlike resources, which may have a proposed state in a plan, Terraform data sources are read-only. In your tests, data blocks provide static attributes to policies and to resource or module mocks that reference the data source.
The first block label specifies the data source type that core::getdatasource() uses to find a matching mock. The second label uniquely identifies the mock in the test file and lets expressions reference its attributes with data.<TYPE>.<NAME>.<ATTRIBUTE>. Data blocks do not support a meta argument.
Examples
The following examples demonstrate common mock data source configuration patterns for specific use cases.
Mock AMI data source for instance testing
In the following example, the mock data block provides an approved AMI ID that an instance resource uses for its configuration.
data "aws_ami" "approved_ubuntu" {
attrs = {
id = "ami-12345678"
name = "ubuntu-22.04-approved"
architecture = "x86_64"
}
}
resource "aws_instance" "web" {
attrs = {
ami = data.aws_ami.approved_ubuntu.id
instance_type = "t3.micro"
}
}
Mock availability zones for multi-AZ resources
In the following example, the mock data block provides a list of available availability zones that a subnet resource uses to determine its placement.
data "aws_availability_zones" "available" {
attrs = {
names = ["us-east-1a", "us-east-1b", "us-east-1c"]
state = "available"
}
}
resource "aws_subnet" "private" {
attrs = {
vpc_id = "vpc-12345678"
cidr_block = "10.0.1.0/24"
availability_zone = data.aws_availability_zones.available.names[0]
}
}
Mock IAM policy document
In the following example, the mock data block provides a JSON-encoded IAM policy document that an IAM role policy resource uses for its policy configuration.
data "aws_iam_policy_document" "s3_read_only" {
attrs = {
json = core::jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"s3:GetObject",
"s3:ListBucket"
]
Resource = [
"arn:aws:s3:::example-bucket",
"arn:aws:s3:::example-bucket/*"
]
}
]
})
}
}
resource "aws_iam_role_policy" "s3_access" {
attrs = {
name = "s3-read-only"
role = "example-role"
policy = data.aws_iam_policy_document.s3_read_only.json
}
}
Multiple data sources for complex relationships
In the following example, multiple mock data blocks work together to provide VPC and subnet information that an instance resource uses to establish its network configuration.
data "aws_vpc" "main" {
attrs = {
id = "vpc-12345678"
cidr_block = "10.0.0.0/16"
}
}
data "aws_subnet" "private" {
attrs = {
id = "subnet-12345678"
vpc_id = data.aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
}
}
resource "aws_instance" "app" {
attrs = {
ami = "ami-12345678"
instance_type = "t3.micro"
subnet_id = data.aws_subnet.private.id
}
}