- Terraform Policy
- v0.4.x (latest)
- v0.3.x (beta)
- v0.2.x (beta)
- v0.1.x (beta)
The core::getresources function
The core::getresources function returns a list of all resources of the specified type that match the filter, if any. You can also filter by attributes whose values are computed by Terraform, even if they are not explicitly defined in your configuration.
Signature
core::getresources(resource_type, filter)
Arguments
| Argument | Required | Type | Description |
|---|---|---|---|
resource_type | Yes | String | The type of resource to retrieve (For example: "aws_s3_bucket", "aws_instance"). |
filter | No | Map | A map of attribute names and values to filter the resources. If omitted, returns all resources of the specified type. |
Return value
Returns a list of resource objects that match the specified type and filter. Each resource object contains the resource's attributes.
Warning for incomplete coverage
When an attrs-only policy calls core::getresources and its operations list leaves out no-op, Terraform policy loads the policy with a warning. Such a policy runs only for resources the current run changes, so a cross-resource check can miss pre-existing resources. Add no-op to the list, or keep the list as it is if you intend the policy to run only on changes.
Terraform policy does not warn for policies that reference prior_attrs or for lists that contain delete, because you cannot add no-op to either. It also does not detect core::getresources calls in file-level locals.
Examples
The following examples demonstrate the use of retrieved resources for specific use cases.
Retrieve all resources of a type
In the following example, the core::getresources function fetches all available AWS S3 buckets.
locals {
all_s3_buckets = core::getresources("aws_s3_bucket", {})
}
resource_policy "aws_instance" "check_bucket_count" {
enforce {
condition = core::length(local.all_s3_buckets) <= 10
error_message = "Too many S3 buckets. Maximum allowed: 10, current: ${core::length(local.all_s3_buckets)}"
}
}
Filter resources by attribute
In the following example, the core::getresources function fetches an S3 bucket by name.
locals {
specific_bucket = core::getresources("aws_s3_bucket", {
bucket = "my-specific-bucket"
})
}
resource_policy "aws_s3_bucket_policy" "check_bucket_exists" {
enforce {
condition = core::length(local.specific_bucket) > 0
error_message = "Required S3 bucket 'my-specific-bucket' not found in configuration."
}
}
Check resource relationships
In the following example, the core::getresources function fetches an S3 bucket referenced by a resource.
resource_policy "aws_cloudtrail" "s3_bucket_private" {
locals {
s3_bucket_acl = core::getresources("aws_s3_bucket_acl", {
bucket = attrs.s3_bucket_name
})
is_private = core::length(local.s3_bucket_acl) > 0 && local.s3_bucket_acl[0].acl == "private"
}
enforce {
condition = local.is_private
error_message = "S3 bucket associated with CloudTrail must be private"
}
}
Filter by multiple attributes
In the following example, the core::getresources function fetches AWS instances filtered by AZ and tags.
locals {
# Retrieve instances in a specific region with a specific tag
tagged_instances = core::getresources("aws_instance", {
availability_zone = "us-east-1a"
tags = {
environment = "production"
}
})
}
resource_policy "aws_instance" "production_instance_check" {
filter = attrs.tags.environment == "production"
enforce {
condition = core::length(local.tagged_instances) <= 5
error_message = "Too many production instances in us-east-1a. Maximum: 5, current: ${core::length(local.tagged_instances)}"
}
}
Use with iteration
In the following example, the core::getresources function fetches security groups, and then iterates over them.
locals {
all_security_groups = core::getresources("aws_security_group", {})
# Check if any security group allows public access
has_public_access = core::anytrue([
for sg in local.all_security_groups :
core::contains([for rule in sg.ingress : rule.cidr_blocks], ["0.0.0.0/0"])
])
}
resource_policy "aws_security_group" "no_public_access" {
enforce {
condition = !local.has_public_access
error_message = "No security groups should allow ingress from 0.0.0.0/0"
}
}