Search code examples
terraformterraform-provider-awsaws-security-group

Terraform - Automatically create SGs for CloudFront IPs


I am trying to automatically create SGs for CloudFront IPs so I can associate them my ALB.

This article has a very good insight on how to achieve it, but unfortunately it didn't work on my environment.

This is the code:

data "aws_ip_ranges" "cloudfront" {
  regions = ["global"]
  services = ["cloudfront"]
}

locals {
  chunks_v4 = chunklist(data.aws_ip_ranges.cloudfront.cidr_blocks, 60)
}

resource "aws_security_group" "cloudfront" {
    count = length(local.chunks_v4)

    ingress {
        from_port = 443
        to_port   = 443
        protocol  = "tcp"
        cidr_blocks = [local.chunks_v4[count.index]]
    }

    egress {
        from_port = 0
        to_port   = 0
        protocol  = "-1"
        cidr_blocks = ["0.0.0.0/0"]
    }

    lifecycle {
        create_before_destroy = true
    }
}

and that is the error message:

╷
│ Error: Incorrect attribute value type
│ 
│   on main.tf line 34, in resource "aws_security_group" "cloudfront":
│   34:         cidr_blocks = [local.chunks_v4[count.index]]
│     ├────────────────
│     │ count.index is a number, known only after apply
│     │ local.chunks_v4 is a list of list of dynamic, known only after apply
│ 
│ Inappropriate value for attribute "cidr_blocks": element 0: string required.
╵

Shouldn't it be something like:

local.chunks_v4[count.index][0 to 59???]

How can I achieve it by using Terraform?


Solution

  • Edit: Since there is a hard limit of 60 CIDR blocks, we need to split it into chunks, thanks for the heads up @Marcin!

    locals {
      chunks_v4 = chunklist(data.aws_ip_ranges.cloudfront.cidr_blocks, 60)
    }
    
    data "aws_ip_ranges" "cloudfront" {
      regions  = ["global"]
      services = ["cloudfront"]
    }
    
    resource "aws_security_group" "cloudfront" {
      count = length(local.chunks_v4)
    
      ingress {
        from_port   = 443
        to_port     = 443
        protocol    = "tcp"
        cidr_blocks = local.chunks_v4[count.index]
      }
    
      egress {
        from_port   = 0
        to_port     = 0
        protocol    = "-1"
        cidr_blocks = ["0.0.0.0/0"]
      }
    
      lifecycle {
        create_before_destroy = true
      }
    }