Repository: tenable/terrascan (language: python)

Issue:
terrascan panic: not a string
* terrascan version:v1.2.0
* Operating System: Alpine Linux

### Description

When I scan repo at https://github.com/ismailyenigul/terraform-aws-pritunl/ with terrascan I got  ` panic: not a string`
Some variables did  not have default value. I set default values for all. But still the same problem.


```
#  cat terraform.tfvars 
aws_key_name = "mykey"
vpc_id = "vpc-035505708a99422"
whitelist = ["0.0.0.0/0"]
public_subnet_id = "subnet-05645874433c61e"
instance_type = "t3.micro"
aws_region = "eu-west-1"
volume_size = 10

```

Also updated tags varible as below:
```
variable "tags" {
  description = "A map of tags to add to all resources"
  type        = map(string)
  default     = {
   Name2  = "MyVPC"
   Owner = "Operations"}
}


```
still fails. Terraform plan works fine.
```
n execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_eip.pritunl will be created
  + resource "aws_eip" "pritunl" {
      + allocation_id        = (known after apply)
      + association_id       = (known after apply)
      + customer_owned_ip    = (known after apply)
      + domain               = (known after apply)
      + id                   = (known after apply)
      + instance             = (known after apply)
      + network_border_group = (known after apply)
      + network_interface    = (known after apply)
      + private_dns          = (known after apply)
      + private_ip           = (known after apply)
      + public_dns           = (known after apply)
      + public_ip            = (known after apply)
      + public_ipv4_pool     = (known after apply)
      + vpc                  = true
    }

  # aws_instance.pritunl will be created
  + resource "aws_instance" "pritunl" {
      + ami                          = "ami-02a97c354a6ae19a7"
      + arn                          = (known after apply)
      + associate_public_ip_address  = true
      + availability_zone            = (known after apply)
      + cpu_core_count               = (known after apply)
      + cpu_threads_per_core         = (known after apply)
      + get_password_data            = false
      + host_id                      = (known after apply)
      + id                           = (known after apply)
      + instance_state               = (known after apply)
      + instance_type                = "t3.micro"
      + ipv6_address_count           = (known after apply)
      + ipv6_addresses               = (known after apply)
      + key_name                     = "mykey"
      + outpost_arn                  = (known after apply)
      + password_data                = (known after apply)
      + placement_group              = (known after apply)
      + primary_network_interface_id = (known after apply)
      + private_dns                  = (known after apply)
      + private_ip                   = (known after apply)
      + public_dns                   = (known after apply)
      + public_ip                    = (known after apply)
      + secondary_private_ips        = (known after apply)
      + security_groups              = (known after apply)
      + source_dest_check            = true
      + subnet_id                    = "subnet-05645874433c61e"
      + tags                         = {
          + "Name"  = "pritunl-vpn"
          + "Name2" = "MyVPC"
          + "Owner" = "Operations"
        }
      + tenancy                      = (known after apply)
      + user_data                    = "a400f16e3aaef0609f47eafc17f8807245a8eef3"
      + volume_tags                  = (known after apply)
      + vpc_security_group_ids       = (known after apply)

      + ebs_block_device {
          + delete_on_termination = (known after apply)
          + device_name           = (known after apply)
          + encrypted             = (known after apply)
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + snapshot_id           = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = (known after apply)
          + volume_type           = (known after apply)
        }

      + ephemeral_block_device {
          + device_name  = (known after apply)
          + no_device    = (known after apply)
          + virtual_name = (known after apply)
        }

      + metadata_options {
          + http_endpoint               = (known after apply)
          + http_put_response_hop_limit = (known after apply)
          + http_tokens                 = (known after apply)
        }

      + network_interface {
          + delete_on_termination = (known after apply)
          + device_index          = (known after apply)
          + network_interface_id  = (known after apply)
        }

      + root_block_device {
          + delete_on_termination = true
          + device_name           = (known after apply)
          + encrypted             = (known after apply)
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = 10
          + volume_type           = (known after apply)
        }
    }

  # aws_security_group.allow_from_office will be created
  + resource "aws_security_group" "allow_from_office" {
      + arn                    = (known after apply)
      + description            = "Allows SSH connections and HTTP(s) connections from office"
      + egress                 = [
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = ""
              + from_port        = 0
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "-1"
              + security_groups  = []
              + self             = false
              + to_port          = 0
            },
        ]
      + id                     = (known after apply)
      + ingress                = [
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = "Allow HTTPS access from select CIDRs"
              + from_port        = 443
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 443
            },
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = "Allow ICMPv4 from select CIDRs"
              + from_port        = -1
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "icmp"
              + security_groups  = []
              + self             = false
              + to_port          = -1
            },
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = "Allow SSH access from select CIDRs"
              + from_port        = 22
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 22
            },
        ]
      + name                   = "pritunl-whitelist"
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + tags                   = {
          + "Name"  = "pritunl-whitelist"
          + "Name2" = "MyVPC"
          + "Owner" = "Operations"
        }
      + vpc_id                 = "vpc-035505708a99422"
    }

  # aws_security_group.pritunl will be created
  + resource "aws_security_group" "pritunl" {
      + arn                    = (known after apply)
      + description            = "pritunl-vpn"
      + egress                 = [
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = ""
              + from_port        = 0
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "-1"
              + security_groups  = []
              + self             = false
              + to_port          = 0
            },
        ]
      + id                     = (known after apply)
      + ingress                = [
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = ""
              + from_port        = 10000
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "udp"
              + security_groups  = []
              + self             = false
              + to_port          = 19999
            },
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = ""
              + from_port        = 80
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 80
            },
          + {
              + cidr_blocks      = [
                  + "10.0.0.0/16",
                ]
              + description      = ""
              + from_port        = -1
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "icmp"
              + security_groups  = []
              + self             = false
              + to_port          = -1
            },
          + {
              + cidr_blocks      = [
                  + "10.0.0.0/16",
                ]
              + description      = ""
              + from_port        = 22
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 22
            },
          + {
              + cidr_blocks      = [
                  + "10.0.0.0/16",
                ]
              + description      = ""
              + from_port        = 443
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 443
            },
        ]
      + name                   = "pritunl-vpn"
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + tags                   = {
          + "Name"  = "pritunl-vpn"
          + "Name2" = "MyVPC"
          + "Owner" = "Operations"
        }
      + vpc_id                 = "vpc-035505708a99422"
    }

Plan: 4 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
```


### What I Did

```
# terrascan -l debug scan -r git -i terraform --remote-url https://github.com/ismailyenigul/terraform-aws-pritunl

ernetes_pod/container_uses_secrets_in_env/containerUsesSecretsInEnvironmentVar.rego <nil>}
2020-11-30T16:16:54.049Z	debug	opa/engine.go:214	loaded 107 Rego rules from 9 rego files (107 metadata files).
2020-11-30T16:16:54.594Z	debug	runtime/executor.go:96	initialized executor
2020-11-30T16:16:54.772Z	debug	v12/load-dir.go:135	traversing through all modules in config tree
2020-11-30T16:16:54.783Z	debug	v12/resource.go:61	created resource config for resource 'pritunl', file: '/iac/terraform-aws-pritunl/main.tf'
2020-11-30T16:16:54.801Z	debug	v12/resource.go:61	created resource config for resource 'pritunl', file: '/iac/terraform-aws-pritunl/securitygroups.tf'
2020-11-30T16:16:54.802Z	debug	v12/variable-references.go:109	resolving variable ref "${var.resource_name_prefix}-vpn" in parent module call
2020-11-30T16:16:54.802Z	debug	v12/variable-references.go:57	extracted variable name "resource_name_prefix" from reference "${var.resource_name_prefix}-vpn"
2020-11-30T16:16:54.802Z	debug	v12/variable-references.go:84	resolved variable ref '${var.resource_name_prefix}-vpn', value: 'pritunl'
2020-11-30T16:16:54.802Z	debug	v12/variable-references.go:90	resolved str variable ref: '${var.resource_name_prefix}-vpn', value: 'pritunl-vpn'
2020-11-30T16:16:54.803Z	debug	v12/variable-references.go:109	resolving variable ref "${var.internal_cidrs}" in parent module call
2020-11-30T16:16:54.803Z	debug	v12/variable-references.go:57	extracted variable name "internal_cidrs" from reference "${var.internal_cidrs}"
panic: not a string

goroutine 1 [running]:
github.com/zclconf/go-cty/cty.Value.AsString(0x25cdc00, 0xc000523f00, 0x22497a0, 0xc003a84570, 0xc003a84570, 0x25cdc00)
	/home/runner/go/pkg/mod/github.com/zclconf/go-cty@v1.2.1/cty/value_ops.go:1173 +0x1a5
github.com/zclconf/go-cty/cty.Value.AsValueMap(0x25cdc80, 0xc004a6b090, 0x1e88a20, 0xc002d4a900, 0x7fa0f9615910)
	/home/runner/go/pkg/mod/github.com/zclconf/go-cty@v1.2.1/cty/value_ops.go:1245 +0x1a6
github.com/accurics/terrascan/pkg/iac-providers/terraform/v12.ctyToMap(0x25cdc80, 0xc004a6b090, 0x1e88a20, 0xc002d4a900, 0x1e88a20, 0x3481f80, 0x2575300, 0xc003a844e0)
	/home/runner/work/terrascan/terrascan/pkg/iac-providers/terraform/v12/cty-converters.go:67 +0x6a
github.com/accurics/terrascan/pkg/iac-providers/terraform/v12.(*RefResolver).ResolveVarRef(0xc006337698, 0xc005ea11e0, 0x15, 0x1eccc40, 0xc004a792b0)
	/home/runner/work/terrascan/terrascan/pkg/iac-providers/terraform/v12/variable-references.go:83 +0x1c5
github.com/accurics/terrascan/pkg/iac-providers/terraform/v12.(*RefResolver).ResolveStrRef(0xc006337698, 0xc005ea11e0, 0x15, 0xc001a907b0, 0xc0001d7a40)
	/home/runner/work/terrascan/terrascan/pkg/iac-providers/terraform/v12/references.go:166 +0x2a5
github.com/accurics/terrascan/pkg/iac-providers/terraform/v12.(*RefResolver).ResolveRefs(0xc006337698, 0xc003a84150, 0xf)
	/home/runner/work/terrascan/terrascan/pkg/iac-providers/terraform/v12/references.go:70 +0x1b2
github.com/accurics/terrascan/pkg/iac-providers/terraform/v12.(*RefResolver).ResolveRefs(0xc006337698, 0xc003a84120, 0x1a)
	/home/runner/work/terrascan/terrascan/pkg/iac-providers/terraform/v12/references.go:106 +0x6d5
github.com/accurics/terrascan/pkg/iac-providers/terraform/v12.(*TfV12).LoadIacDir(0x347fb58, 0xc00050af80, 0x1a, 0xc003a84030, 0x0, 0x0)
	/home/runner/work/terrascan/terrascan/pkg/iac-providers/terraform/v12/load-dir.go:155 +0x65f
github.com/accurics/terrascan/pkg/runtime.(*Executor).Execute(0xc0001d6600, 0x0, 0x0, 0x0, 0xc0005075c0, 0x1, 0x1, 0x0, 0x0)
	/home/runner/work/terrascan/terrascan/pkg/runtime/executor.go:107 +0x9a7
github.com/accurics/terrascan/pkg/cli.Run(0x0, 0x0, 0x0, 0x0, 0xc0005075c0, 0x1, 0x1, 0x0, 0x0, 0x2254df5, ...)
	/home/runner/work/terrascan/terrascan/pkg/cli/run.go:62 +0x2bc
github.com/accurics/terrascan/pkg/cli.scan(0x3429fc0, 0xc0006917e0, 0x0, 0x2)
	/home/runner/work/terrascan/terrascan/pkg/cli/scan.go:102 +0x1df
github.com/spf13/cobra.(*Command).execute(0x3429fc0, 0xc0006917a0, 0x2, 0x2, 0x3429fc0, 0xc0006917a0)
	/home/runner/go/pkg/mod/github.com/spf13/cobra@v1.0.0/command.go:846 +0x2c2
github.com/spf13/cobra.(*Command).ExecuteC(0x3429d20, 0xc00004c090, 0x3, 0x3)
	/home/runner/go/pkg/mod/github.com/spf13/cobra@v1.0.0/command.go:950 +0x375
github.com/spf13/cobra.(*Command).Execute(...)
	/home/runner/go/pkg/mod/github.com/spf13/cobra@v1.0.0/command.go:887
github.com/accurics/terrascan/pkg/cli.Execute()
	/home/runner/work/terrascan/terrascan/pkg/cli/register.go:85 +0x3c7
main.main()
	/home/runner/work/terrascan/terrascan/cmd/terrascan/main.go:22 +0x25
```



Discussion / hints:
I am running into this same issue.  It appears that it is not handling the list type variable correctly.  An example:

variable "ip_addresses" {
  type        = list(string)
  description = "Ip addresses"
  default     = ["1.2.3.4","1.2.3.5","1.2.3.6"]
}
We are also experiencing this same issue on an Azure resource with an attribute that calls a variable and does some data manipulation:

> 2020-12-31T12:17:48.364-0500	debug	v12/variable-references.go:57	extracted variable name "ip_range_azure_portal" from reference "${join(\",\", concat(var.ip_range_azure_portal, each.value.ip_range_filter))}"
> panic: not a string
> 
> goroutine 1 [running]:
> github.com/zclconf/go-cty/cty.Value.AsString(0x25cdc00, 0xc000761b70, 0x22497a0, 0xc0029b2de0, 0xc0029b2de0, 0x25cdc00)
> 	/home/runner/go/pkg/mod/github.com/zclconf/go-cty@v1.2.1/cty/value_ops.go:1173 +0x1a5
> github.com/zclconf/go-cty/cty.Value.AsValueMap(0x25cdc80, 0xc0033abef0, 0x1e88a20, 0xc0032f4dc0, 0x7f404b61a090)
> 	/home/runner/go/pkg/mod/github.com/zclconf/go-cty@v1.2.1/cty/value_ops.go:1245 +0x1a6
> github.com/accurics/terrascan/pkg/iac-providers/terraform/v12.ctyToMap(0x25cdc80, 0xc0033abef0, 0x1e88a20, 0xc0032f4dc0, 0x1e88a20, 0x3481f80, 0x2575300, 0xc0029b2d50)
> 	/home/runner/work/terrascan/terrascan/pkg/iac-providers/terraform/v12/cty-converters.go:67 +0x6a
> github.com/accurics/terrascan/pkg/iac-providers/terraform/v12.(*RefResolver).ResolveVarRef(0xc003c9f698, 0xc0044bacd0, 0x4b, 0x1eccc40, 0xc00061fc50)
> 	/home/runner/work/terrascan/terrascan/pkg/iac-providers/terraform/v12/variable-references.go:83 +0x1c5
> github.com/accurics/terrascan/pkg/iac-providers/terraform/v12.(*RefResolver).ResolveStrRef(0xc003c9f698, 0xc0044bacd0, 0x4b, 0x13, 0xc0001d9398)
> 	/home/runner/work/terrascan/terrascan/pkg/iac-providers/terraform/v12/references.go:166 +0x2a5
> github.com/accurics/terrascan/pkg/iac-providers/terraform/v12.(*RefResolver).ResolveRefs(0xc003c9f698, 0xc0029b2ae0, 0x1f)
> 	/home/runner/work/terrascan/terrascan/pkg/iac-providers/terraform/v12/references.go:70 +0x1b2
> github.com/accurics/terrascan/pkg/iac-providers/terraform/v12.(*TfV12).LoadIacDir(0x347fb58, 0xc000054960, 0x4e, 0xc00333da70, 0x0, 0x0)
> 	/home/runner/work/terrascan/terrascan/pkg/iac-providers/terraform/v12/load-dir.go:155 +0x65f
> github.com/accurics/terrascan/pkg/runtime.(*Executor).Execute(0xc000826000, 0x0, 0x0, 0x0, 0xc000166c20, 0x1, 0x1, 0x0, 0x0)
> 	/home/runner/work/terrascan/terrascan/pkg/runtime/executor.go:107 +0x9a7
> github.com/accurics/terrascan/pkg/cli.Run(0x0, 0x0, 0x0, 0x0, 0xc000166c20, 0x1, 0x1, 0x0, 0x0, 0x2254df5, ...)
> 	/home/runner/work/terrascan/terrascan/pkg/cli/run.go:62 +0x2bc
> github.com/accurics/terrascan/pkg/cli.scan(0x3429fc0, 0xc0000a22d0, 0x1, 0x5)
> 	/home/runner/work/terrascan/terrascan/pkg/cli/scan.go:102 +0x1df
> github.com/spf13/cobra.(*Command).execute(0x3429fc0, 0xc0000a2230, 0x5, 0x5, 0x3429fc0, 0xc0000a2230)
> 	/home/runner/go/pkg/mod/github.com/spf13/cobra@v1.0.0/command.go:846 +0x2c2
> github.com/spf13/cobra.(*Command).ExecuteC(0x3429d20, 0xc00078d010, 0xc0000906a0, 0x0)
> 	/home/runner/go/pkg/mod/github.com/spf13/cobra@v1.0.0/command.go:950 +0x375
> github.com/spf13/cobra.(*Command).Execute(...)
> 	/home/runner/go/pkg/mod/github.com/spf13/cobra@v1.0.0/command.go:887
> github.com/accurics/terrascan/pkg/cli.Execute()
> 	/home/runner/work/terrascan/terrascan/pkg/cli/register.go:85 +0x3c7
> main.main()
> 	/home/runner/work/terrascan/terrascan/cmd/terrascan/main.go:22 +0x25

Terraform plan and apply work fine.

This is the actual TF code for the resource attribute:
`ip_range_filter                   = join(",", concat(var.ip_range_azure_portal, each.value.ip_range_filter))`
Thank you for the reports all. Prioritizing this fix.

Fix patch:
diff --git a/pkg/iac-providers/terraform/v12/cty-converters.go b/pkg/iac-providers/terraform/v12/cty-converters.go
index 6d5578e0e..c31779d84 100644
--- a/pkg/iac-providers/terraform/v12/cty-converters.go
+++ b/pkg/iac-providers/terraform/v12/cty-converters.go
@@ -18,6 +18,8 @@ package tfv12
 
 import (
 	"fmt"
+	"strings"
+
 	"github.com/pkg/errors"
 	"github.com/zclconf/go-cty/cty"
 	"github.com/zclconf/go-cty/cty/gocty"
@@ -26,7 +28,7 @@ import (
 // list of available cty to golang type converters
 var (
 	ctyConverterFuncs       = []func(cty.Value) (interface{}, error){ctyToStr, ctyToInt, ctyToBool, ctyToSlice, ctyToMap}
-	ctyNativeConverterFuncs = []func(cty.Value) (interface{}, error){ctyToStr, ctyToInt, ctyToBool, ctyToSlice}
+	ctyNativeConverterFuncs = []func(cty.Value) (interface{}, error){ctyToStr, ctyToInt, ctyToBool}
 )
 
 // ctyToStr tries to convert the given cty.Value into golang string type
@@ -54,8 +56,25 @@ func ctyToBool(ctyVal cty.Value) (interface{}, error) {
 // interfce{}
 func ctyToSlice(ctyVal cty.Value) (interface{}, error) {
 	var val []interface{}
-	err := gocty.FromCtyValue(ctyVal, &val)
-	return val, err
+	var allErrs error
+
+	if strings.Contains(ctyVal.Type().FriendlyName(), "list") {
+		for _, v := range ctyVal.AsValueSlice() {
+			for _, converter := range ctyNativeConverterFuncs {
+				resolved, err := converter(v)
+				if err == nil {
+					val = append(val, resolved)
+					break
+				}
+				allErrs = errors.Wrap(allErrs, err.Error())
+			}
+		}
+		if allErrs != nil {
+			return nil, allErrs
+		}
+		return val, nil
+	}
+	return val, fmt.Errorf("incorrect type")
 }
 
 // ctyToMap tries to converts the incoming cty.Value into map[string]cty.Value


Test patch:
diff --git a/pkg/iac-providers/terraform/v12/load-dir_test.go b/pkg/iac-providers/terraform/v12/load-dir_test.go
index b28677a64..94a07ec60 100644
--- a/pkg/iac-providers/terraform/v12/load-dir_test.go
+++ b/pkg/iac-providers/terraform/v12/load-dir_test.go
@@ -138,6 +138,13 @@ func TestLoadIacDir(t *testing.T) {
 			tfv12:       TfV12{},
 			wantErr:     nil,
 		},
+		{
+			name:        "variables of list type",
+			tfConfigDir: "./testdata/list-type-vars-test",
+			tfJSONFile:  "./testdata/tfjson/list-vars-test.json",
+			tfv12:       TfV12{},
+			wantErr:     nil,
+		},
 	}
 
 	for _, tt := range table2 {
diff --git a/pkg/iac-providers/terraform/v12/testdata/list-type-vars-test/main.tf b/pkg/iac-providers/terraform/v12/testdata/list-type-vars-test/main.tf
new file mode 100644
index 000000000..0a7be6288
--- /dev/null
+++ b/pkg/iac-providers/terraform/v12/testdata/list-type-vars-test/main.tf
@@ -0,0 +1,15 @@
+data "aws_ami" "amazon_linux" {
+  most_recent = true
+}
+
+resource "aws_instance" "app" {
+  count = var.instance_count
+
+  ami           = data.aws_ami.amazon_linux.id
+  instance_type = var.instance_type
+
+  subnet_id              = var.subnet_ids[count.index % length(var.subnet_ids)]
+  vpc_security_group_ids = var.security_group_ids
+
+  tags = var.tags
+}
diff --git a/pkg/iac-providers/terraform/v12/testdata/list-type-vars-test/variables.tf b/pkg/iac-providers/terraform/v12/testdata/list-type-vars-test/variables.tf
new file mode 100644
index 000000000..4fda5beec
--- /dev/null
+++ b/pkg/iac-providers/terraform/v12/testdata/list-type-vars-test/variables.tf
@@ -0,0 +1,31 @@
+variable "instance_count" {
+  description = "Number of EC2 instances to deploy"
+  type        = list(number)
+  default = [1,2]
+}
+
+variable "instance_type" {
+  description = "Type of EC2 instance to use"
+  type        = string
+  default = "blah_instance"
+}
+
+variable "subnet_ids" {
+  description = "Subnet IDs for EC2 instances"
+  type        = list(string)
+  default = ["10.0.0.0/8"]
+}
+
+variable "security_group_ids" {
+  description = "Security group IDs for EC2 instances"
+  type        = list(string)
+}
+
+variable "tags" {
+  description = "Tags for instances"
+  type        = map
+  default     = {
+    "a" = "b"
+    "c" = "d"
+  }
+}
diff --git a/pkg/iac-providers/terraform/v12/testdata/tfjson/list-vars-test.json b/pkg/iac-providers/terraform/v12/testdata/tfjson/list-vars-test.json
new file mode 100644
index 000000000..af26a1a08
--- /dev/null
+++ b/pkg/iac-providers/terraform/v12/testdata/tfjson/list-vars-test.json
@@ -0,0 +1,28 @@
+{
+  "aws_instance": [
+    {
+      "id": "aws_instance.app",
+      "name": "app",
+      "source": "main.tf",
+      "line": 5,
+      "type": "aws_instance",
+      "config": {
+        "ami": "${data.aws_ami.amazon_linux.id}",
+        "count": [
+          1,
+          2
+        ],
+        "instance_type": "blah_instance",
+        "subnet_id": [
+          "10.0.0.0/8"
+        ],
+        "tags": {
+          "a": "b",
+          "c": "d"
+        },
+        "vpc_security_group_ids": "${var.security_group_ids}"
+      },
+      "skip_rules": null
+    }
+  ]
+}
\ No newline at end of file