cloud-custodian / pytest-terraform

pytest terraform plugin with fixtures and offline replay support
56 stars 19 forks source link

Support for resources defined with `count` or `for_each` #47

Open mviamari opened 2 years ago

mviamari commented 2 years ago

Currently it appears that resources defined with count or for_each are not being parsed properly. The TerraformState.parse_state function always picks the first instance of each resource, so any resources defined as multiple instance resources lose the latter resources when the tfstate file is parsed.

https://github.com/cloud-custodian/pytest-terraform/blob/main/pytest_terraform/tf.py#L269

Example:

resource "aws_subnet" "subnets" {
  count             = length(data.aws_availability_zones.azs.names)
  availability_zone = data.aws_availability_zones.azs.names[count.index]
  cidr_block        = "192.168.${count.index}.0/24"
  vpc_id            = aws_vpc.vpc.id
}

in the state file

{
      "mode": "managed",
      "type": "aws_subnet",
      "name": "subnets",
      "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
      "instances": [
        {
          "index_key": 0,
          "schema_version": 1,
          "attributes": {
            "arn": "arn:aws:ec2:us-east-1:000000000000:subnet/subnet-7f9e6b32",
            "assign_ipv6_address_on_creation": false,
            "availability_zone": "us-east-1a",
            "availability_zone_id": "use1-az6",
            "cidr_block": "192.168.0.0/24",
            "customer_owned_ipv4_pool": "",
            "enable_dns64": false,
            "enable_resource_name_dns_a_record_on_launch": false,
            "enable_resource_name_dns_aaaa_record_on_launch": false,
            "id": "subnet-7f9e6b32",
            "ipv6_cidr_block": "",
            "ipv6_cidr_block_association_id": "",
            "ipv6_native": false,
            "map_customer_owned_ip_on_launch": false,
            "map_public_ip_on_launch": false,
            "outpost_arn": "",
            "owner_id": "000000000000",
            "private_dns_hostname_type_on_launch": "",
            "tags": null,
            "tags_all": {
              "Environment": "Local",
            },
            "timeouts": null,
            "vpc_id": "vpc-98fd3817"
          },
          "sensitive_attributes": [],
          "private": "...",
          "dependencies": [
            "aws_vpc.vpc",
            "data.aws_availability_zones.azs"
          ]
        },
        {
          "index_key": 1,
          "schema_version": 1,
          "attributes": {
            "arn": "arn:aws:ec2:us-east-1:000000000000:subnet/subnet-0c33e847",
            "assign_ipv6_address_on_creation": false,
            "availability_zone": "us-east-1b",
            "availability_zone_id": "use1-az1",
            "cidr_block": "192.168.1.0/24",
            "customer_owned_ipv4_pool": "",
            "enable_dns64": false,
            "enable_resource_name_dns_a_record_on_launch": false,
            "enable_resource_name_dns_aaaa_record_on_launch": false,
            "id": "subnet-0c33e847",
            "ipv6_cidr_block": "",
            "ipv6_cidr_block_association_id": "",
            "ipv6_native": false,
            "map_customer_owned_ip_on_launch": false,
            "map_public_ip_on_launch": false,
            "outpost_arn": "",
            "owner_id": "000000000000",
            "private_dns_hostname_type_on_launch": "",
            "tags": null,
            "tags_all": {
              "Environment": "Local",
            },
            "timeouts": null,
            "vpc_id": "vpc-98fd3817"
          },
          "sensitive_attributes": [],
          "private": "....",
          "dependencies": [
            "aws_vpc.vpc",
            "data.aws_availability_zones.azs"
          ]
        },
        .... (items 2-5 skipped for brevity)
    ]
}
ajkerrigan commented 2 years ago

Good call @mviamari . We'll need to be careful about not breaking existing tests when fixing this, but we should certainly support resources with more than one instance. Thank you!