terraform-provider-aws: aws_cloudfront_function PreconditionFailed: The request failed because it didn't meet the preconditions in one or more request-header fields.
Community Note
- Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
- Please do not leave “+1” or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
- If you are interested in working on this issue or have submitted a pull request, please leave a comment
Terraform CLI and Terraform AWS Provider Version
Terraform v0.13.5 Provider v3.42.0
Affected Resource(s)
- aws_cloudfront_function
Terraform Configuration Files
Please include all Terraform configurations required to reproduce the bug. Bug reports without a functional reproduction may be closed without investigation.
resource "aws_cloudfront_function" "cloudfront_security_headers" {
name = "MyFunction"
runtime = "cloudfront-js-1.0"
publish = true
code = file("${path.module}/../../src/index.js")
}
Debug Output
https://gist.github.com/hougholi/0f099da4f04599fbe26e38e0568b1f45
Expected Behavior
CloudFront function code should be updated.
Actual Behavior
Error: error updating CloudFront Function (dev-cloudfront-security-headers) configuration : PreconditionFailed: The request failed because it didn’t meet the preconditions in one or more request-header fields. status code: 412, request id: 38cb6e1b-b74a-4f1c-bb91-0c385e39c88d
Steps to Reproduce
Update CloudFront function code and run terraform apply.
Important Factoids
The function already exists in AWS, this error only occurs when updating the code and trying to run terraform apply
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 50
- Comments: 20 (5 by maintainers)
From: https://www.terraform.io/docs/cli/commands/refresh.html
Performing a plan/apply will refresh your state. The problem here is that with
publish=truetheetagretrieved is for the published (LIVE) version of the cloudfront function. If for some reason the etag of the published version and the unpublished (DEVELOPMENT) version does not match, the request to update the published function fails. I’ve fixed this in #19697 and I’ve been using a local version of the provider in production since I opened the PR in our production environment with no issues.A separate issue that causes a similar precondition errors happens if a plan will modify both the distribution & cloudfront function that is published. The cloudfront function being published actually modifies the etag of the distribution. Which is where @alexjurkiewicz first proposal would be useful as it would help alleviate inter-resource etag conflicts. You can see this already being done for cloudfront distribution deletions https://github.com/hashicorp/terraform-provider-aws/blob/bae3b38b6508172254ff696e8ba1126cf8c55ee8/aws/resource_aws_cloudfront_distribution.go#L1015-L1036
I am interested in fixing this issue, it causes problems for us. I can see a few ways forward:
terraform refreshto update the etagIf a maintainer could confirm the preferred approach, I will code it up.
This error is returned because the ETag value in state isn’t equal to the current value at AWS (because the function was updated outside Terraform):
https://github.com/hashicorp/terraform-provider-aws/blob/da4fb15cfa46e41bdcf4b596a3721f040d98511e/aws/resource_aws_cloudfront_function.go#L159-L182
I now have this issue with a function in production - so I can’t delete it and let Terraform recreate. So yeah it’s worth fixing.
Same here. I would expect it to work again after running
terraform refreshbut the same precondition error occurs.It appears that there’s a bug with
etagvalue for theLIVE&DEVELOPMENTstages of the function and havingpublish = true. Each stage has separate etag value and when the function is refreshed withpublish = truetheetagstored is the value of theLIVEfunction. I can see in the state of a cloudfront function not manually modified (but one that has been updated via terraform) the etag matches the function inDEVELOPMENTstage. In fact theetagofLIVE&DEVELOPMENTstages match.Running for the same exception. I am fixing it by running with
publish=falsethen after applied the code, run it back withpublish=trueit seems tf is getting lost dealing with trying publish it before saves the code.Your failure is when updating the cloudfront distribution, not the cloudfront function. Theres a separate issue I described in this comment https://github.com/hashicorp/terraform-provider-aws/issues/19529#issuecomment-877125478. I’ll create a bug report on it.
Another workaround is to remove it from the state file (terraform state rm) and add it back in (terraform import) before updating.
Thanks for reopening 👍 - yes I did the same, but it is still worth fixing I think - ideally manual changes would be detected and reset by terraform - they are ignored at the moment, I guess that’s a separate issue though