Home > front end >  terraform loop over nested resource objets
terraform loop over nested resource objets

Time:08-02

im trying to create resources from a yaml file , im trying to create multipile environment variables inside one resource . the problem is with the rule_variables section , terraform thinks im trying to recreate the resource would appriciate any help.

yaml example :

rule_groups:
  - name: "TEST"
    allowed-domains:
     - ".go.microsoft.com"
     - ".signin.aws.amazon.com"
    source: "10.129.1.0/24"

  - name: "TEST2"
    allowed-domains:
     - ".go.microsoft.com"
     - ".vortex.data.microsoft.com"
     - ".vscodeexperiments.azureedge.net"
     - ".vscode-cdn.net"
     - ".vscode.blob.core.windows.net"
     - ".visualstudio.com"
    source: "10.129.12.0/24"    

terraform example :

i am trying to achieve one firewall rule group with multiple environment variables under that rule group

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_rule_group#rule_variables

locals {
list  = yamldecode(file("${path.module}/settings.yaml"))["rule_groups"]
fw_group_rule = flatten([for rule in local.list : {
      "name"                       = rule.name
      "allowed-domains"            = rule.allowed-domains
      "definition"                 = rule.source
    }
  ])
}

resource "aws_networkfirewall_rule_group" "limit-Domain-Access" {
  for_each = {
    for rule in local.fw_group_rule : rule.name => rule
    }
  capacity = 1000
  name     = "limit-Domain-Access"
  type     = "STATEFUL"
  rule_group {
  rule_variables {
    ip_sets {
      key = each.value.name
      ip_set {
        definition = [each.value.definition]
      }
   }
}
  rules_source {
    rules_string = <<EOF
    pass http ֿֿֿֿֿ${"$"}${each.value.name} any -> $EXTERNAL_NET any (http.host; dotprefix; content:"${join(", ", each.value.allowed-domains)}"; endswith; msg:"matching HTTP allowlisted FQDNs"; priority:1; flow:to_server, established; sid:1; rev:1;)
    EOF
  }
}
   tags = {
   Name = "limit-Domain-Access"
  }

error :

│ Error: error creating NetworkFirewall Rule Group limit-Domain-Access: InvalidRequestException: A resource with the specified name already exists
│ 
│   with aws_networkfirewall_rule_group.limit-Domain-Access["TEST"],
│   on domain_access_suricata.tf line 11, in resource "aws_networkfirewall_rule_group" "limit-Domain-Access":
│   11: resource "aws_networkfirewall_rule_group" "limit-Domain-Access" {

CodePudding user response:

The below works.

locals {
  list = yamldecode(file("${path.module}/settings.yaml"))["rule_groups"]
  fw_group_rule = flatten([for rule in local.list : {
    "name"            = rule.name
    "allowed-domains" = rule.allowed-domains
    "definition"      = rule.source
    }
  ])
}


resource "aws_networkfirewall_rule_group" "limit-Domain-Access" {
  name     = "limit-Domain-Access"
  capacity = 1000
  type     = "STATEFUL"
  rule_group {
    rule_variables {
      dynamic "ip_sets" {
        for_each = local.fw_group_rule
        content {
          key = ip_sets.value.name
          ip_set {
            definition = [ip_sets.value.definition]
          }
        }
      }
    }
    rules_source {
      rules_string = <<EOF
        %{for index,i in local.fw_group_rule~}
        pass http ֿֿֿֿֿ${"$"}${i.name} any -> $EXTERNAL_NET any (http.host; dotprefix; content:"${join(", ", i.allowed-domains)}"; endswith; msg:"matching HTTP allowlisted FQDNs"; priority:1; flow:to_server, established; sid:${index   1}; rev:1;)
        %{endfor~}
        EOF
    }
  }
  tags = {
    Name = "limit-Domain-Access"
  }
}

output "fw-group-rule" {
  value = <<EOF
    %{for i in local.fw_group_rule~}
    pass http ֿֿֿֿֿ${"$"}${i.name} any -> $EXTERNAL_NET any (http.host; dotprefix; content:"${join(", ", i.allowed-domains)}"; endswith; msg:"matching HTTP allowlisted FQDNs"; priority:1; flow:to_server, established; sid:1; rev:1;)
    %{endfor~}
    EOF
}

Output:

Plan: 1 to add, 0 to change, 0 to destroy.

Changes to Outputs:
    fw-group-rule = <<-EOT
                pass http ֿֿֿֿֿ$TEST any -> $EXTERNAL_NET any (http.host; dotprefix; content:".go.microsoft.com, .signin.aws.amazon.com"; endswith; msg:"matching HTTP allowlisted FQDNs"; priority:1; flow:to_server, established; sid:1; rev:1;)
                pass http ֿֿֿֿֿ$TEST2 any -> $EXTERNAL_NET any (http.host; dotprefix; content:".go.microsoft.com, .vortex.data.microsoft.com, .vscodeexperiments.azureedge.net, .vscode-cdn.net, .vscode.blob.core.windows.net, .visualstudio.com"; endswith; msg:"matching HTTP allowlisted FQDNs"; priority:1; flow:to_server, established; sid:1; rev:1;)
            
    EOT
aws_networkfirewall_rule_group.limit-Domain-Access: Creating...
aws_networkfirewall_rule_group.limit-Domain-Access: Creation complete after 1s [id=arn:aws:network-firewall:eu-central-1:756872068099:stateful-rulegroup/limit-Domain-Access]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
  • Related