[BUG] Identifying resources when using dynamic blocks
Mohitsharma44 opened this issue · comments
Describe the bug
Using regula on terraform resources that have dynamic blocks, generates mock_resources (and mock_input) that contains a "dynamic" list/array of maps but no "key" to identify what values corresponds to which argument.
How you're running Regula
Please include versions of all relevant tools. Some examples:
- regula version
❯ regula version 3.2.1, build fed1e44, built with OPA v0.46.0-dev
- I'm using Regula
3.2.1, build fed1e44
as a Rego library with OPAv0.46.0-dev
and a Terraform plan JSON input that I generated with Terraformv1.3.6
Operating System
macOS v13.3.1
Steps to reproduce
# Loding just the tf file...
❯ regula repl main.tf --no-built-ins
INFO Loaded 1 IaC configurations as test inputs
Regula 3.2.1 - built with OPA v0.46.0-dev
Run 'help' to see a list of commands.
> data.main_tf.mock_resources["aws_security_group.main"]
{
"_filepath": "main.tf",
"_provider": "aws",
"_tags": {
"Name": "AWS security group dynamic block"
},
"_type": "aws_security_group",
"dynamic": [
{
"content": [
{
"cidr_blocks": [
"0.0.0.0/0"
],
"description": "ingress.value.description",
"from_port": "ingress.value.port",
"protocol": "tcp",
"to_port": "ingress.value.port"
}
],
"for_each": [
{
"description": "foo-ing",
"port": "123"
},
{
"description": "bar-ing",
"port": "456"
}
]
},
{
"content": [
{
"cidr_blocks": [
"0.0.0.0/0"
],
"description": "egress.value.description",
"from_port": "egress.value.port",
"protocol": "tcp",
"to_port": "egress.value.port"
}
],
"for_each": [
{
"description": "foo-eg",
"port": "123"
},
{
"description": "bar-eg",
"port": "456"
}
]
}
],
"id": "aws_security_group.main",
"name": "resource_with_dynamic_block",
"tags": {
"Name": "AWS security group dynamic block"
},
"vpc_id": "foobar"
}
IaC Configuration
# main.tf
variable ingress_rules {
type = list(map(string))
default = [{
"description" = "foo-ing",
"port" = "123"
},{
"description" = "bar-ing",
"port" = "456"
}
]
}
variable egress_rules {
type = list(map(string))
default = [{
"description" = "foo-eg",
"port" = "123"
},{
"description" = "bar-eg",
"port" = "456"
}
]
}
resource "aws_security_group" "main" {
name = "resource_with_dynamic_block"
vpc_id = "foobar"
dynamic "ingress" {
for_each = var.ingress_rules
content {
description = ingress.value.description
from_port = ingress.value.port
to_port = ingress.value.port
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
dynamic "egress" {
for_each = var.egress_rules
content {
description = egress.value.description
from_port = egress.value.port
to_port = egress.value.port
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
tags = {
Name = "AWS security group dynamic block"
}
}
It'd be beneficial for dynamic list of maps to have a key that would identify the resource that the dynamic block belonged to.
So for example,
....
"dynamic": [
{
"ingress": [ <-------- instead of content
{
"cidr_blocks": [
"0.0.0.0/0"
],
"description": "ingress.value.description",
"from_port": "ingress.value.port",
"protocol": "tcp",
"to_port": "ingress.value.port"
}
],
"for_each": [
{
"description": "foo-ing",
"port": "123"
},
{
"description": "bar-ing",
"port": "456"
}
]
},
{
"egress": [ <-------- instead of content
{
"cidr_blocks": [
"0.0.0.0/0"
],
"description": "egress.value.description",
"from_port": "egress.value.port",
"protocol": "tcp",
"to_port": "egress.value.port"
}
],
"for_each": [
{
"description": "foo-eg",
"port": "123"
},
{
"description": "bar-eg",
"port": "456"
}
]
}
],
....
Additional context
Add any other context about the problem here.
I am facing the same issue with a dynamic block while checking the HCL code. Here is the sample code
resource "google_compute_subnetwork" "subnetwork" {
for_each = local.subnets
name = each.value.subnet_name
ip_cidr_range = each.value.subnet_ip
region = each.value.subnet_region
private_ip_google_access = lookup(each.value, "subnet_private_access", "false")
dynamic "log_config" {
for_each = lookup(each.value, "subnet_flow_logs", false) ? [{
aggregation_interval = lookup(each.value, "subnet_flow_logs_interval", "INTERVAL_5_SEC")
flow_sampling = lookup(each.value, "subnet_flow_logs_sampling", "0.5")
metadata = lookup(each.value, "subnet_flow_logs_metadata", "INCLUDE_ALL_METADATA")
}] : []
content {
aggregation_interval = log_config.value.aggregation_interval
flow_sampling = log_config.value.flow_sampling
metadata = log_config.value.metadata
}
}