Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic block ignores block schema #1576

Closed
wata727 opened this issue Oct 26, 2022 · 1 comment · Fixed by #1583
Closed

Dynamic block ignores block schema #1576

wata727 opened this issue Oct 26, 2022 · 1 comment · Fixed by #1583
Labels

Comments

@wata727
Copy link
Member

wata727 commented Oct 26, 2022

Introduction

TFLint implicitly resolves dynamic blocks. For instance, it will return 2 blocks for the following configuration:

resource "aws_instance" "dynamic" {
  dynamic "ebs_block_device" {
    for_each = var.block_devices
    content {
      encrypted = false
    }
  }

  ebs_block_device {
    encrypted = false
  }
}
resources, _ := runner.GetResourceContent("aws_instance", &hclext.BodySchema{
	Blocks: []hclext.BlockSchema{
		{
			Type: "ebs_block_device",
			Body: &hclext.BodySchema{Attributes: []hclext.AttributeSchema{{Name: "encrypted"}}},
		},
	},
}, nil)

len(resources.Blocks[0].Body.Blocks) // => 2

But this dynamic block ignores the block type "ebs_block_device" and all dynamic blocks are returned.

Expected Behavior

It should return 2 blocks for the following configuration like

resource "aws_instance" "dynamic" {
  dynamic "network_interface" { # => should be ignored because this is not "ebs_block_device" block
    for_each = var.network_instances
    content {
      device_index = 0
    }
  }

  dynamic "ebs_block_device" {
    for_each = var.block_devices
    content {
      encrypted = false
    }
  }

  ebs_block_device {
    encrypted = false
  }
}

Actual behavior

3 blocks are returned.

resources, _ := runner.GetResourceContent("aws_instance", &hclext.BodySchema{
	Blocks: []hclext.BlockSchema{
		{
			Type: "ebs_block_device",
			Body: &hclext.BodySchema{Attributes: []hclext.AttributeSchema{{Name: "encrypted"}}},
		},
	},
}, nil)

len(resources.Blocks[0].Body.Blocks) // => 3

for _, block := range resources.Blocks[0].Body.Blocks {
	fmt.Printf("type: %s", block.Type)
}
// => type: network_interface
//    type: ebs_block_device
//    type: ebs_block_device

Step to Reproduce

See also terraform-linters/tflint-ruleset-aws#391

Additional Context

$ tflint -v
TFLint version 0.42.1
+ ruleset.aws (0.18.0)
+ ruleset.terraform (0.2.0-bundled)
$ terraform -v
Terraform v1.1.5
on darwin_arm64
+ provider registry.terraform.io/hashicorp/aws v4.36.1
@wata727 wata727 added the bug label Oct 26, 2022
@wata727
Copy link
Member Author

wata727 commented Oct 26, 2022

This is a bug related to dynamic block resolution. schemaWithDynamic gets all dynamic blocks, ignoring the block schema.
https://github.com/terraform-linters/tflint/blob/v0.42.2/terraform/module.go#L183-L194

Ideally, resolveDynamicBlocks should exclude blocks with different block schemas, but it doesn't.
https://github.com/terraform-linters/tflint/blob/v0.42.2/terraform/module.go#L211-L214

The handling of dynamic block resolution may need to be improved. By delegating this responsibility to hclext package, it may be easier and clearer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging a pull request may close this issue.

1 participant