hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.73k stars 9.09k forks source link

Terraform doesn't understand that website_endpoint will change value #13393

Closed LinusU closed 1 month ago

LinusU commented 4 years ago

Community Note

Terraform Version

Terraform v0.12.24
+ provider.aws v2.60.0

Affected Resource(s)

Terraform Configuration Files

1. if you first have a bucket without a website endpoint

resource "aws_s3_bucket" "foobar" {
  acl    = "public-read"
  bucket = "foobar"
}

2. and then try to both turn on the website endpoint and use it

resource "aws_s3_bucket" "foobar" {
  acl    = "public-read"
  bucket = "foobar"

  website {
    index_document = "index.html"
  }
}

resource "aws_cloudfront_distribution" "foobar" {
  aliases         = ["foobar.com"]
  enabled         = true
  is_ipv6_enabled = true
  price_class     = "PriceClass_100"

  custom_error_response {
    error_code         = 404
    response_code      = 200
    response_page_path = "/index.html"
  }

  default_cache_behavior {
    allowed_methods        = ["GET", "HEAD"]
    cached_methods         = ["GET", "HEAD"]
    compress               = true
    target_origin_id       = "s3"
    viewer_protocol_policy = "redirect-to-https"

    forwarded_values {
      query_string = false

      cookies {
        forward = "none"
      }
    }
  }

  origin {
    origin_id   = "s3"
    domain_name = aws_s3_bucket.foobar.website_endpoint # <-- HERE

    custom_origin_config {
      http_port              = 80
      https_port             = 443
      origin_protocol_policy = "http-only"
      origin_ssl_protocols   = ["TLSv1.2"]
    }
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  viewer_certificate {
    acm_certificate_arn      = data.aws_acm_certificate.foobar.arn
    minimum_protocol_version = "TLSv1.2_2018"
    ssl_support_method       = "sni-only"
  }
}

Debug Output

Can I share a run from app.terraform.io here?

Panic Output

n/a

Expected Behavior

origin.0.domain_name should be "known after apply" instead of "null"

Actual Behavior

Error: "origin.0.domain_name": required field is not set

Steps to Reproduce

  1. terraform apply with first config
  2. terraform apply with second config

Important Factoids

n/a

References

n/a

amel-harrath commented 4 years ago

I'm having the same issue, any updates?

jeffmacdonald commented 4 years ago

Same here. Solution is to basically go into AWS console, and enable website hosting, then muck about with custom_origin_config until you get a plan that causes zero changes, the ship it :)

japgolly commented 4 years ago

A workaround that worked for me was:

  1. Change domain_name to some random string literal
  2. Run Terraform
  3. Change domain_name back to ...blah.website_endopint
  4. Run Terraform
justinretzolk commented 2 years ago

Hey @LinusU 👋 Thank you for taking the time to file this. Given that there's been a number of Terraform and AWS Provider releases since you initially filed this, can you confirm whether you're still experiencing this?

nottug commented 2 years ago

I actually just ran into this issue with virtually identical code to @LinusU. The workaround described above works but is definitely inconvenient.

A workaround that worked for me was:

1. Change `domain_name` to some random string literal

2. Run Terraform

3. Change `domain_name` back to `...blah.website_endopint`

4. Run Terraform
davidegiunchi commented 2 years ago

my workaround is to first modify only the bucket:

terraform apply -target=aws_s3_bucket.my_bucket_resource_name

then the rest:

terraform apply

anGie44 commented 2 years ago

Hi @LinusU et al. 👋 I'm able to reproduce this in the most recent version of the Terraform AWS provider, v4.9.0, but just wanted to note that migrating to the aws_s3_bucket_website_configuration is a possible workaround if you're able to upgrade to at least v3.75.0 or v4.9.0 of the provider without having to incur more refactoring of your config.

Rather than setting website in the source bucket, you can update your 2nd step to:

resource "aws_s3_bucket" "foobar" {
  acl    = "public-read"
  bucket = "foobar"

  lifecycle { # <-- only necessary if using v3.75.x
    ignore_changes = [website]
  }
}

resource "aws_s3_bucket_website_configuration" "foobar" {
  bucket = aws_s3_bucket.foobar.id
  index_document {
    suffix = "index.html"
  }
}

resource "aws_cloudfront_distribution" "foobar" {
  aliases         = ["foobar.com"]
  enabled         = true
  is_ipv6_enabled = true
  price_class     = "PriceClass_100"

  custom_error_response {
    error_code         = 404
    response_code      = 200
    response_page_path = "/index.html"
  }

  default_cache_behavior {
    allowed_methods        = ["GET", "HEAD"]
    cached_methods         = ["GET", "HEAD"]
    compress               = true
    target_origin_id       = "s3"
    viewer_protocol_policy = "redirect-to-https"

    forwarded_values {
      query_string = false

      cookies {
        forward = "none"
      }
    }
  }

  origin {
    origin_id   = "s3"
    domain_name = aws_s3_bucket_website_configuration.foobar.website_endpoint # <-- UPDATE RESOURCE REFERENCE HERE

    custom_origin_config {
      http_port              = 80
      https_port             = 443
      origin_protocol_policy = "http-only"
      origin_ssl_protocols   = ["TLSv1.2"]
    }
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  viewer_certificate {
    acm_certificate_arn      = data.aws_acm_certificate.foobar.arn
    minimum_protocol_version = "TLSv1.2_2018"
    ssl_support_method       = "sni-only"
  }
}
ryandiamond23 commented 2 years ago

Getting this same error when trying to spin up a new environment from scratch. Re-running the apply winds up working, though. Seems like maybe a timing thing.

Error: Missing required argument
with module.website.aws_cloudfront_distribution.website_cloudfront_distribution
on ../modules/s3-static-website/cloudfront.tf line 1, in resource "aws_cloudfront_distribution" "website_cloudfront_distribution":
resource "aws_cloudfront_distribution" "website_cloudfront_distribution" {
The argument "origin.0.domain_name" is required, but no definition was found.
ryandiamond23 commented 2 years ago

Hi @LinusU et al. 👋 I'm able to reproduce this in the most recent version of the Terraform AWS provider, v4.9.0, but just wanted to note that migrating to the aws_s3_bucket_website_configuration is a possible workaround if you're able to upgrade to at least v3.75.0 or v4.9.0 of the provider without having to incur more refactoring of your config.

Rather than setting website in the source bucket, you can update your 2nd step to:

resource "aws_s3_bucket" "foobar" {
  acl    = "public-read"
  bucket = "foobar"

  lifecycle { # <-- only necessary if using v3.75.x
    ignore_changes = [website]
  }
}

resource "aws_s3_bucket_website_configuration" "foobar" {
  bucket = aws_s3_bucket.foobar.id
  index_document {
    suffix = "index.html"
  }
}

resource "aws_cloudfront_distribution" "foobar" {
  aliases         = ["foobar.com"]
  enabled         = true
  is_ipv6_enabled = true
  price_class     = "PriceClass_100"

  custom_error_response {
    error_code         = 404
    response_code      = 200
    response_page_path = "/index.html"
  }

  default_cache_behavior {
    allowed_methods        = ["GET", "HEAD"]
    cached_methods         = ["GET", "HEAD"]
    compress               = true
    target_origin_id       = "s3"
    viewer_protocol_policy = "redirect-to-https"

    forwarded_values {
      query_string = false

      cookies {
        forward = "none"
      }
    }
  }

  origin {
    origin_id   = "s3"
    domain_name = aws_s3_bucket_website_configuration.foobar.website_endpoint # <-- UPDATE RESOURCE REFERENCE HERE

    custom_origin_config {
      http_port              = 80
      https_port             = 443
      origin_protocol_policy = "http-only"
      origin_ssl_protocols   = ["TLSv1.2"]
    }
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  viewer_certificate {
    acm_certificate_arn      = data.aws_acm_certificate.foobar.arn
    minimum_protocol_version = "TLSv1.2_2018"
    ssl_support_method       = "sni-only"
  }
}

Good idea -- this seems to have fixed the issue for me:

image

tormodmacleod commented 2 years ago

i think i have the same issue. i'm trying to set up a simple redirect for website.com to www.website.com

resource "aws_s3_bucket" "website" {
  bucket        = local.bucket_name
  force_destroy = true
}

resource "aws_s3_bucket_website_configuration" "redirect" {
  bucket = aws_s3_bucket.website.bucket

  redirect_all_requests_to {
    host_name = local.redirect
  }
}

resource "aws_cloudfront_distribution" "website_cdn_root" {
  enabled             = true
  price_class         = "PriceClass_100"
  aliases             = [local.domain_name]

  origin {
    domain_name = aws_s3_bucket_website_configuration.redirect.website_endpoint
    origin_id   = "s3"
  }

  default_cache_behavior {
    allowed_methods  = ["GET", "HEAD"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = "s3"
    min_ttl          = "0"
    default_ttl      = "300"
    max_ttl          = "1200"

    viewer_protocol_policy = "redirect-to-https"
    compress               = true

    forwarded_values {
      query_string = false
      cookies {
        forward = "none"
      }
    }
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  viewer_certificate {
    acm_certificate_arn = aws_acm_certificate.cloudfront_cert.arn
    ssl_support_method  = "sni-only"
  }
}

however, i get the error as below

│ Error: error creating CloudFront Distribution: InvalidArgument: The parameter Origin DomainName does not refer to a valid S3 bucket.
│       status code: 400, request id: 1d8a9ee7-41bc-425d-b7e7-8a275444d66c

if i configure this manually through the console it works fine

tormodmacleod commented 2 years ago

ignore my comment. i found that once i included a custom_origin_config block in my origin it worked just fine

anGie44 commented 2 years ago

Hi all, just noting here that while this is a bug in the aws_s3_bucket resource, the current alternative is to us the aws_s3_bucket_website_configuration's parameters for the updated data values as suggested in the comments above.

github-actions[bot] commented 2 months ago

Marking this issue as stale due to inactivity. This helps our maintainers find and focus on the active issues. If this issue receives no comments in the next 30 days it will automatically be closed. Maintainers can also remove the stale label.

If this issue was automatically closed and you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thank you!

github-actions[bot] commented 1 week 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.