Open stuffandthings opened 7 years ago
I narrowed it down to an issue with these two setting options. My current workaround is to just comment them out:
setting {
namespace = "aws:elasticbeanstalk:application"
name = "Application Healthcheck URL"
value = "HTTP:80/elb-status"
}
setting {
namespace = "aws:autoscaling:launchconfiguration"
name = "SSHSourceRestriction"
value = "tcp, 22, 22, ${var.bastion_security_group}"
}
One of the side effects of this ends up being a security critical issue. Not being able to configure SSHSourceRestriction
to avoid the constant refreshes by default will keep port 22
open to the world.
I'm having this issue as well. I can't not use the Application Healthcheck URL without compromising my deployment, so I'm stuck letting it update every environment on each apply.
This also happens with the aws:autoscaling:launchconfiguration
IamInstanceProfile
setting. Looks like the setting ID changes every time.
Terraform v0.11.7
But running into issues with: setting { name = "SSLReferencePolicy" namespace = "aws:elb:policies:TLSHighPolicy" value = "ELBSecurityPolicy-TLS-1-2-2017-01" }
I'm also facing the same issue, any update or work around?
It's annoying to wait 10 min for beanstalk update even there no changes
+1 - Also facing this issue which causes unnecessary deployment time.
+1 I'm having this issue as well
<> terraform version Terraform v0.11.8
Any update on this? Having the same issue when using aws:autoscaling:launchconfiguration IamInstanceProfile setting. I have to give an instance profile. Is there any workaround to suppress updates?
Same problems... Really a PITA
@mitchellh Any chance of getting some official word on this? It's a pretty big usability issue.
I have to agree that this is pretty serious, it's completely crippling my IaC, not only does this apply every time for no reason, it also prevents other resources from being updated because it fails to update constantly with:
aws_elastic_beanstalk_environment.default: Error waiting for Elastic Beanstalk Environment (e-nwn8rhh3xs) to become ready: 2 errors occurred:
* 2019-02-27 19:33:27.54 +0000 UTC (e-nwn8rhh3xs) : Service:AmazonCloudFormation, Message:No updates are to be performed.
* 2019-02-27 19:33:28.574 +0000 UTC (e-nwn8rhh3xs) : Environment tag update failed.
This is pretty much unusable for my purposes.
Any updates??? Seems like IamInstanceProfile and SecurityGroups settings force this change...
*Edit So, after searching a bit, I found out that
Another important point for the SSHSourceRestriction
setting: do NOT put spaces after commas.
This will trigger an update, so do not use it:
setting {
namespace = "aws:autoscaling:launchconfiguration"
name = "SSHSourceRestriction"
value = "tcp, 22, 22, ${var.bastion_security_group}"
}
while this WILL NOT:
setting {
namespace = "aws:autoscaling:launchconfiguration"
name = "SSHSourceRestriction"
value = "tcp,22,22,${var.bastion_security_group}"
}
So I found a bug in the beanstalk API almost a year ago that essentially meant they were returning null values in certain situations with SSHSourceRestriction. They emailed me this morning say it should be fixed now, perhaps it'll solve this problem.
I have this issues with many other elements. see below (- & +) removing and adding. Terraform v0.12.3
provider.aws v2.20.0
/+ setting {
* /+ setting { + name = "Subnets" + namespace = "aws:ec2:vpc" + value = "subnet-0533bc84xxxxx, subnet-0849547f75xxxx" } - setting { - name = "Subnets" -> null - namespace = "aws:ec2:vpc" -> null - value = "subnet-0533bc84xxxxx,subnet-0849547f75xxxx" -> null }
@krunalsabnis this is because you have a space between the first and the second subnet, after the comma. Try removing the space in the value, and it should stop this behavior
I observed ultra strange behavior - the post by @GarlicDipping prompted me to try this, so thanks!
My EB deployment had a bunch of custom settings, and each Terraform apply would re-apply these settings as a no-op. These were settings like subnets, sgs, load balancer settings, service role, instance profile, etc.
I changed only the IamInstanceProfile
from a full ARN to just the name, and instantly the entire problem went away for all settings.
Previous: arn:aws:iam::xxx:instance-profile/eb-ec2-role
After: eb-ec2-role
Update: In a different EB app, this trick didn't resolve the problem.
Adding resource = ""
to setting section fixes my issue.
Similar to @krunalsabnis I get this for every setting when applying terraform to Beanstalk environment Using terraform v 0.12.6.
Bug is present in provider "aws" { version = "~> 2.30" }
released 2019-09-26.
Two changes work around it for me:
resource=""
to each setting
section. (Thanks @Rmannn ! 👍)Working version:
resource "aws_elastic_beanstalk_environment" "api_service" {
name = "${var.instance_name}-api-service"
application = aws_elastic_beanstalk_application.api_service.name
cname_prefix = "com-company-${var.instance_name}-api"
version_label = aws_elastic_beanstalk_application_version.api_service.name
# https://docs.aws.amazon.com/elasticbeanstalk/latest/platforms/platforms-supported.html
solution_stack_name = "64bit Amazon Linux 2018.03 v2.9.2 running Java 8"
# https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/command-options-general.html#command-options-general-elasticbeanstalkenvironment
# Prod & Staging get expensive Load Balancers. Other deployments get cheap Elastic IPs.
setting {
namespace = "aws:elasticbeanstalk:environment"
name = "EnvironmentType"
value = var.is_prod_or_staging ? "LoadBalanced" : "SingleInstance"
// These empty 'resource' values prevent updating the environment on every apply.
// See https://github.com/terraform-providers/terraform-provider-aws/issues/1471#issuecomment-522977469
resource = ""
}
// Include the 'LoadBalancerType' setting only in Prod/Staging deployments.
// The Beanstalk API ignores the LoadBalancerType setting when EnvironmentType=SingleInstance.
// When Terraform queries the application's settings, the Beanstalk API does not return the
// LoadBalancerType entry, so Terraform tries to add it. This makes Terraform update the
// application on *every* apply.
// See https://github.com/terraform-providers/terraform-provider-aws/issues/1471#issuecomment-522977469
// This 'dynamic' ugly hack is required because Terraform has no conditionals.
// See https://github.com/hashicorp/terraform/issues/19853
// TODO(dev1) Switch to Pulumi once it's mature enough and get away from this nonsense.
dynamic "setting" {
for_each = var.is_prod_or_staging ? [
1] : []
content {
namespace = "aws:elasticbeanstalk:environment"
name = "LoadBalancerType"
# classic, application, or network
value = "application"
resource = ""
}
}
...
Faced exact same issue. What solved the issue for me (these are not my solutions, found them from reading this and other posts):
resource = ""
in every environment settingHope these help :)
Same issue here when trying to use aws:elb:policies:backendkey
PublicKey
, Terraform force the update with exactly the same certificate PEM content.
setting {
namespace = "aws:elb:policies:backendencryption"
name = "PublicKeyPolicyNames"
value = "backendkey"
resource = ""
}
setting {
namespace = "aws:elb:policies:backendencryption"
name = "InstancePorts"
value = "443"
resource = ""
}
setting {
namespace = "aws:elb:policies:backendkey"
name = "PublicKey"
value = tls_self_signed_cert.backend.cert_pem
resource = ""
}
EDIT: To fix this issue, the public key must be passed instead of the certificate and it must be formatted to contain only the raw key:
setting {
namespace = "aws:elb:policies:backendencryption"
name = "PublicKeyPolicyNames"
value = "backendkey"
resource = ""
}
setting {
namespace = "aws:elb:policies:backendencryption"
name = "InstancePorts"
value = "443"
resource = ""
}
setting {
namespace = "aws:elb:policies:backendkey"
name = "PublicKey"
value = replace(replace(tls_private_key.backend.public_key_pem, "/-----[A-Z ]+-----/", ""), "/\\s/", "")
resource = ""
}
As others have mentioned, you need to watch out for spaces in your subnets. In addition the subnets appear to be sorted alphabetically.
setting {
namespace = "aws:ec2:vpc"
name = "Subnets"
value = join(",", sort(var.private_subnets))
resource = ""
}
where var.private_subnets
is a list(string) of subnets fixed my issue.
One other thing I just noticed was that when you have lists of things (subnets, security groups), sometimes they come back in a different order than your TF config specifies, so it detects a diff every time. Reorder the entries in the value to match what's coming back, and it should be set. That, plus the resource = ""
hack is what fixed it all for me.
I have the same problem but only for "ServiceRole" an empty resource property does not help.
setting {
name = "ServiceRole"
namespace = "aws:elasticbeanstalk:environment"
value = aws_iam_role.eb_service_role.arn
resource = ""
}
Still having this problem, resource=""
doesn't work for me.
Still experience this with terraform 0.14.10 and the aws provider 3.22.0 and the resource = ""
in the setting.
# module.eb-name.aws_elastic_beanstalk_environment.default will be updated in-place
~ resource "aws_elastic_beanstalk_environment" "default" {
id = "e-xxxxxxxxxx"
name = "eb-name"
tags = {}
# (15 unchanged attributes hidden)
+ setting {
+ name = "ConfigDocument"
+ namespace = "aws:elasticbeanstalk:healthreporting:system"
+ value = jsonencode(
{
+ Rules = {
+ Environment = {
+ Application = {
+ ApplicationRequests4xx = {
+ Enabled = false
}
}
+ ELB = {
+ ELBRequests4xx = {
+ Enabled = true
}
}
}
}
+ Version = 1
}
)
}
- setting {
- name = "ConfigDocument" -> null
- namespace = "aws:elasticbeanstalk:healthreporting:system" -> null
- value = jsonencode(
{
- Rules = {
- Environment = {
- Application = {
- ApplicationRequests4xx = {
- Enabled = false
}
}
- ELB = {
- ELBRequests4xx = {
- Enabled = true
}
}
}
}
- Version = 1
}
) -> null
}
Same as @nueces, I also tried manually configure ConfigDocument
and that didn't work as well.
Actually I solved the problem - we need to sort the JSON content exactly like how the provider expects, otherwise it would think they're different.
Hi @zen0wu, what do you mean by "sort the JSON content exactly like how the provider expect" ? Could you share a sample please ?
Thanks
@eballetbaz in my case instead of using jsonencode, I crafted the json as
value = "{\"Version\":1,\"Rules\":{\"Environment\":{\"ELB\":{\"ELBRequests4xx\":{\"Enabled\":false}}},\"Application\":{\"ApplicationRequests4xx\":{\"Enabled\":true}}}}}}"
To found the correct format I used the json output and then compare the old value for the field. Using this commands:
terraform plan -out plan.out
terraform show -json plan.out | jq > plan.json
I thought it might be due to a string interpolated value with a space after comma, e.g.:
setting {
namespace = "aws:autoscaling:launchconfiguration"
name = "SecurityGroups"
value = "${data.aws_security_group.somegroup.id}, ${data.aws_security_group.someothergroup.id}"
#--------------------------------------------------- ^ this space
}
Which elasticbeanstalk would adjust every time:
- setting {
- name = "SecurityGroups" -> null
- namespace = "aws:autoscaling:launchconfiguration" -> null
- value = "sg-abc, sg-def -> null
}
+ setting {
+ name = "SecurityGroups"
+ namespace = "aws:autoscaling:launchconfiguration"
+ value = "sg-abc,sg-def"
}
Removing the space from the string value did not solve this happening every time though
Still experience this with terraform 0.14.10 and the aws provider 3.22.0 and the
resource = ""
in the setting.# module.eb-name.aws_elastic_beanstalk_environment.default will be updated in-place ~ resource "aws_elastic_beanstalk_environment" "default" { id = "e-xxxxxxxxxx" name = "eb-name" tags = {} # (15 unchanged attributes hidden) + setting { + name = "ConfigDocument" + namespace = "aws:elasticbeanstalk:healthreporting:system" + value = jsonencode( { + Rules = { + Environment = { + Application = { + ApplicationRequests4xx = { + Enabled = false } } + ELB = { + ELBRequests4xx = { + Enabled = true } } } } + Version = 1 } ) } - setting { - name = "ConfigDocument" -> null - namespace = "aws:elasticbeanstalk:healthreporting:system" -> null - value = jsonencode( { - Rules = { - Environment = { - Application = { - ApplicationRequests4xx = { - Enabled = false } } - ELB = { - ELBRequests4xx = { - Enabled = true } } } } - Version = 1 } ) -> null }
I think this happens because jsonencode()
orders the document and EB is expecting it in a specific order
related -> https://github.com/hashicorp/terraform/issues/27880
This is still an issue in 3.74.0
. How has this not been resolved? This is an absolute show stopper when it comes to creating or managing Elastic Beanstalk applications in Terraform - especially if you're importing an existing one. This creates a giant blindspot in an organization's ability to guarantee that infrastructure can be reliably managed using one tool.
seems like the workaround from https://github.com/hashicorp/terraform-provider-aws/issues/1471#issuecomment-522977469 works for almost all cases.
seems like the workaround from #1471 (comment) works for almost all cases.
It does not work in my case whatsoever.
does it work after the first apply? have been using it for a few months and not had any of the same issues. there seem to be some underlying implicit configuration setting that happens that will update the state transparently on future plans, but plans have no updates.
does it work after the first apply? have been using it for a few months and not had any of the same issues. there seem to be some underlying implicit configuration setting that happens that will update the state transparently on future plans, but plans have no updates.
Great question. I have an app that was created from the start using Terraform that I'll add resource = ""
to each setting and see if that helps. In this case, I'm dealing with an imported environment. It seems risky to do an apply without knowing what it will actually alter, but there may be no choice.
yea, not sure there is a good way to automate that process, but there's only so many settings to go through, so it may be bearable for manual review if you only have a few environments. :shrug:
A workaround that seems to have worked for my team is adding resource = ""
to every setting, as well as sorting any interpolated strings, like:
setting {
namespace = "aws:autoscaling:asg"
name = "Availability Zones"
value = "Any"
resource = "" # Add an empty resource
}
setting {
namespace = "aws:autoscaling:launchconfiguration"
name = "SecurityGroups"
value = join(",", sort([data.aws_security_group.this.id, data.aws_security_group.that.id])) # Use join() and sort()
resource = ""
}
@g4rb1 correct me if I'm wrong.
setting {
name = "SSHSourceRestriction"
namespace = "aws:autoscaling:launchconfiguration"
value = "tcp,22,22,192.0.0.34/32"
resource = ""
}
Every time I use this option it causes my beanstalk to require an update. if i comment it out it works fine.
I'd like to make sure its included, any way to resolve this?
Also I'm not specifying the keypair setting, i'm wondering does it need to be used in conjunction with the keypair setting to work?
Adding resource = ""
solved it. Both tf and provider are the latest versions.
Any idea how to fix DBSubnets ?
resource "aws_elastic_beanstalk_environment" "eb_env" {
id = "e-zfvjkxrhap"
name = "api-prod"
tags = {}
# (17 unchanged attributes hidden)
+ setting {
+ name = "DBSubnets"
+ namespace = "aws:ec2:vpc"
+ value = "subnet-071aa19a12d37195e,subnet-083bb9cec8b75cfcc"
}
# (27 unchanged blocks hidden)
}
depending on how you are supplying the subnets you might need to sort them. sorting them fixed my issue with subnets changing.
EG: sort(["subnet-1", "subnet-2"])
@snipergotya I am already sorting the subnets
setting {
namespace = "aws:ec2:vpc"
name = "DBSubnets"
value = join(",", sort(module.vpc.private_subnets))
resource = ""
}
@khavishbhundoo try then to do a reverse
before the join. You need to preset the string as terraform expect.
You can check try to inspecting the output in json format to get more clues
terraform plan -out plan.out
terraform show -json plan.out > plan.json
@nueces
All i can see is the setting with the proper subnet in the json
{
"name": "DBSubnets",
"namespace": "aws:ec2:vpc",
"resource": "",
"value": "subnet-071aa19a12d37195e,subnet-083bb9cec8b75cfcc"
},
@nueces
All i can see is the setting with the proper subnet in the json
But what about the previous value that was stored? can you found it and paste it here?
@nueces
There is no value for DBSubnets
for elastic beanstalk in resource_changes
in before section but i see DBSubnets
in after section
{
"name": "DBSubnets",
"namespace": "aws:ec2:vpc",
"resource": "",
"value": "subnet-071aa19a12d37195e,subnet-083bb9cec8b75cfcc"
},
Hello,
Every time I run
terraform apply
my elastic beanstalk environment is marked for update, which in turn re-creates my environment. This is clearly undesirable behavior.Terraform Version
Affected Resource(s)
Terraform Configuration Files
Output
Expected Behavior
No change should be detected
Actual Behavior
Terraform thinks I've made a change
Steps to Reproduce
terraform apply
terraform apply
again with no changes