terraform-aws-modules / terraform-aws-cloudfront

Terraform module to create AWS CloudFront resources 🇺🇦
https://registry.terraform.io/modules/terraform-aws-modules/cloudfront/aws
Apache License 2.0
120 stars 252 forks source link

Creating ALB with Cloudfront using Terraform gives 504. Working with Manual resource creation #146

Closed mtahaahmed closed 3 months ago

mtahaahmed commented 3 months ago

Description

Using these AWS docs to integrate ALB with Cloudfront:

When I tested the setup manually, it worked. The request was reaching to my ingress controller.

Upon setting up terraform, it doesn't work and gives:

504 Gateway Timeout ERROR
The request could not be satisfied.
We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
Generated by cloudfront (CloudFront) HTTP3 Server
Request ID: ZDoU9i5gTZxVnq6G-Y3PJbDzXNI-8vJz0-__Da-O9aZbL-VjxnNWyA==

I tried creating another one manually and import the resource in terraform to see if I am missing something, but it all looks same (on the origin config). Yet TF still recreates the origin and the same working cloudfront starts giving the 504 error upon applying.

⚠️ Note

Versions

Reproduction Code [Required]

module "cdn" {
  source = "terraform-aws-modules/cloudfront/aws"
  version = "3.4.0"

  aliases = var.aliases

  comment             = "CDN with ALB origin for Ingress controller"
  price_class         = "PriceClass_All"
  wait_for_deployment = false
  http_version        = "http2and3"

  origin = {
    "${var.alb_dns_name}" = {
      domain_name = var.alb_dns_name
      origin_id   = var.ingress_domain
      custom_origin_config = {
        http_port              = 80
        https_port             = 443
        origin_protocol_policy = "https-only"
        origin_ssl_protocols   = ["TLSv1", "TLSv1.1", "TLSv1.2"]
      }
    }
  }

  default_cache_behavior = {
    allowed_methods        = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"]
    cached_methods         = ["GET", "HEAD", "OPTIONS"]
    target_origin_id       = var.ingress_domain
    viewer_protocol_policy = "redirect-to-https"
    forwarded_values = {
      headers      = ["*"]
      query_string = true
      cookies = {
        forward = "all"
      }
    }
  }

  viewer_certificate = {
    acm_certificate_arn = var.acm_certificate_arn
    ssl_support_method  = "sni-only"
  }
  tags = merge(local.default_tags, { origin = var.alb_dns_name })
}

variables.tf:

alb_dns_name        = "alb-dns-name.ap-south-1.elb.amazonaws.com"
acm_certificate_arn = "ACM cert ARN in us-east-1"
aliases             = ["*.env.domain.com"]
ingress_domain      = "env.domain.com"

The resource import I tried for the working CDN (which didn't work after completing the import):

terragrunt apply
module.cdn.aws_cloudfront_distribution.this[0]: Refreshing state... [id=dist-id]

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # module.cdn.aws_cloudfront_distribution.this[0] will be updated in-place
  ~ resource "aws_cloudfront_distribution" "this" {
      ~ comment                         = "testing CDN" -> "CDN with ALB origin for Ingress controller"
        id                              = "dist-id"
      ~ is_ipv6_enabled                 = true -> false
      ~ tags                            = {
          + "managed_by" = "terraform"
          + "origin"     = "alb-dns-name.ap-south-1.elb.amazonaws.com"
          + "app"  = "shared"
          + "env"  = "stg"
          + "team" = "infra"
        }
      ~ tags_all                        = {
          + "managed_by" = "terraform"
          + "origin"     = "alb-dns-name.ap-south-1.elb.amazonaws.com"
          + "app"  = "shared"
          + "env"  = "stg"
          + "team" = "infra"
        }
      ~ wait_for_deployment             = true -> false
        # (19 unchanged attributes hidden)

      ~ default_cache_behavior {
          - cache_policy_id            = "83da9c7e-98b4-4e11-a168-04f0df8e2c65" -> null
          ~ compress                   = true -> false
          - origin_request_policy_id   = "216adef6-5c7f-47e4-b989-5492eafa07d3" -> null
            # (13 unchanged attributes hidden)

          + forwarded_values {
              + query_string            = false
              + query_string_cache_keys = []

              + cookies {
                  + forward           = "none"
                  + whitelisted_names = (known after apply)
                }
            }
        }

      - origin {
          - connection_attempts      = 3 -> null
          - connection_timeout       = 10 -> null
          - domain_name              = "alb-dns-name.ap-south-1.elb.amazonaws.com" -> null
          - origin_id                = "env.domain.com" -> null
            # (2 unchanged attributes hidden)

          - custom_origin_config {
              - http_port                = 80 -> null
              - https_port               = 443 -> null
              - origin_keepalive_timeout = 5 -> null
              - origin_protocol_policy   = "https-only" -> null
              - origin_read_timeout      = 30 -> null
              - origin_ssl_protocols     = [
                  - "TLSv1.2",
                ] -> null
            }
        }
      + origin {
          + connection_attempts      = 3
          + connection_timeout       = 10
          + domain_name              = "alb-dns-name.ap-south-1.elb.amazonaws.com"
          + origin_id                = "env.domain.com"
            # (2 unchanged attributes hidden)

          + custom_origin_config {
              + http_port                = 80
              + https_port               = 443
              + origin_keepalive_timeout = 5
              + origin_protocol_policy   = "https-only"
              + origin_read_timeout      = 30
              + origin_ssl_protocols     = [
                  + "TLSv1",
                  + "TLSv1.1",
                  + "TLSv1.2",
                ]
            }
        }

      ~ viewer_certificate {
          ~ minimum_protocol_version       = "TLSv1.2_2021" -> "TLSv1"
            # (4 unchanged attributes hidden)
        }

        # (1 unchanged block hidden)
    }

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

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

module.cdn.aws_cloudfront_distribution.this[0]: Modifying... [id=dist-id]
module.cdn.aws_cloudfront_distribution.this[0]: Modifications complete after 2s [id=dist-id]

Expected Behavior

Upon restoring, the origin shouldn't get recreated.

mtahaahmed commented 3 months ago

Turns out, during console testing it was adding managed origin_policy and origin_request_policy_id

Adding them in TF helped resolved the issue.

github-actions[bot] commented 1 month ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.