Conflicting Dynamic Blocks

Hi,
I’ve run into a challenge with mutually exclusive dynamic blocks… specifically, I’m setting up a shared module for AWS S3 Redirect buckets - which is using the aws_s3_bucket_website_configuration resource.

This resource has 2 useful possible argument blocks:

  • routing_rule (conflicts with routing_rules)
  • routing_rules (conflicts with routing_rule)

I was hoping to do something like this:

resource "aws_s3_bucket_website_configuration" "redirect" {
...
...
  dynamic "routing_rule" {
    for_each = var.routing_rule
    content {
     ...
    }
  }
  dynamic "routing_rules" {
    for_each = var.routing_rules
    content {
    ...
    }
  }
}

…where in any given case either routing_rule or routing_rules is set - but not both. The default value for both is [].

But even with one set, I see this error:
Blocks of type "routing_rules" are not expected here.

I think perhaps the routing_rules block is being “initialised” - even though the variable is not set and hence no rules would be deployed.

I can see a possible workaround to have two separate resources (one for rule and one for rules).
But does anyone know of a way to do this within one resource? Or a better way?

Thanks,
Gareth

Hi @GarethE,

Checking the linked docs, it looks like routing_rules is not a block, but rather a string attribute that expects the rules in json format.

Ah! :person_facepalming:

You are exactly right. It should, of course, be just:

resource "aws_s3_bucket_website_configuration" "redirect" {
...
...
  dynamic "routing_rule" {
    for_each = var.routing_rule
    content {
     ...
    }
  }
  routing_rules = var.routing_rules
}

…and it works fine (providing routing_rules is null when routing_rule is not).

I had entirely missed the fact it was just a string.

Thank you @jbardin :+1: