Open andrewedstrom opened 9 months ago
I can relate to you. 🙂 I ended up simply running this before working with terraform:
terraform apply -refresh-only
This reconciles the state with reality a bit, and so the subsequent terraform apply
does not cause re-deploy.
Another option is to keep an eye on #171.
This issue has been automatically marked as stale because it has been open 30 days with no activity. Remove stale label or comment or this issue will be closed in 10 days
I can relate to you. 🙂 I ended up simply running this before working with terraform:
terraform apply -refresh-only
This reconciles the state with reality a bit, and so the subsequent
terraform apply
does not cause re-deploy.
This workaround does not seem to work for me.
Here is the output of refresh-only command:
Note: Objects have changed outside of Terraform
Terraform detected the following changes made outside of Terraform since the last "terraform apply" which may have affected this plan:
# module.app_env.module.ecs.module.service_images["xxx"].aws_ssm_parameter.ignore_value[0] has changed
~ resource "aws_ssm_parameter" "ignore_value" {
id = "xxx"
~ insecure_value = "xxx.dkr.ecr.eu-central-1.amazonaws.com/xxx:version1" -> "xxx.dkr.ecr.eu-central-1.amazonaws.com/xxx:version2"
name = "xxx"
tags = {}
~ version = 4 -> 5
# (5 unchanged attributes hidden)
}
# module.app_env.module.ecs.module.ecs.module.service["xxx"].aws_ecs_service.this[0] has changed
~ resource "aws_ecs_service" "this" {
id = "arn:aws:ecs:eu-central-1:xxx:service/xxx/xxx"
name = "xxx"
tags = {}
~ task_definition = "xxx:18" -> "xxx:19"
# (14 unchanged attributes hidden)
# (6 unchanged blocks hidden)
}
When I run it again, terraform detects no changes, however a regular plan/apply tries to update service & task def
# module.app_env.module.ecs.module.ecs.module.service["xxx"].data.aws_ecs_task_definition.this[0] will be read during apply
# (depends on a resource or a module with changes pending)
<= data "aws_ecs_task_definition" "this" {
+ arn = (known after apply)
+ arn_without_revision = (known after apply)
+ execution_role_arn = (known after apply)
+ family = (known after apply)
+ id = (known after apply)
+ network_mode = (known after apply)
+ revision = (known after apply)
+ status = (known after apply)
+ task_definition = "xxx"
+ task_role_arn = (known after apply)
}
# module.app_env.module.ecs.module.ecs.module.service["xxx"].aws_ecs_service.this[0] will be updated in-place
~ resource "aws_ecs_service" "this" {
id = "arn:aws:ecs:eu-central-1:xxx:service/xxx/xxx"
name = "xxx"
tags = {}
~ task_definition = "xxx:19" -> (known after apply)
# (14 unchanged attributes hidden)
# (6 unchanged blocks hidden)
}
# module.app_env.module.ecs.module.ecs.module.service["xxx"].aws_ecs_task_definition.this[0] must be replaced
+/- resource "aws_ecs_task_definition" "this" {
~ arn = "arn:aws:ecs:eu-central-1:xxx:task-definition/xxx:18" -> (known after apply)
~ arn_without_revision = "arn:aws:ecs:eu-central-1:xxx:task-definition/xxx" -> (known after apply)
~ container_definitions = jsonencode(
~ [
~ {
~ image = "xxx.dkr.ecr.eu-central-1.amazonaws.com/xxx-xxx:version1" -> "xxx.dkr.ecr.eu-central-1.amazonaws.com/xxx-xxx:version2"
name = "xxx"
# (17 unchanged attributes hidden)
},
] # forces replacement
)
~ id = "xxx" -> (known after apply)
~ revision = 18 -> (known after apply)
- tags = {} -> null
# (10 unchanged attributes hidden)
# (2 unchanged blocks hidden)
}
Even if I manually register new task definition in the aws console, the following change would still cause the service to be redeployed
# module.app_env.module.ecs.module.ecs.module.service["xxx"].aws_ecs_service.this[0] will be updated in-place
~ resource "aws_ecs_service" "this" {
id = "arn:aws:ecs:eu-central-1:xxx:service/xxx/xxx"
name = "xxx"
tags = {}
~ task_definition = "xxx:20" -> "xxx:21"
# (14 unchanged attributes hidden)
# (6 unchanged blocks hidden)
}
fyi I also apply the example with the latest image version stored in SSM.
I am working on a similiar task where our CI pipeline updates the image and creates a new revision in the console. SInce terraform is not aware of this change and still have old state file with some old revision, it tries to force replace the task definition.
I am currently trying to implement the logic where I can ignore these changes in my task definition module, but I cannot implement it smartly as I want user to choose if these changes can be ignored. Lifecycle block is useless here and I am looking for suggestions if anyone knows about the use case where solution like this has been implemented.
@andrewedstrom Did you find a workaround since February? I faced exactly the situation.
I'm also facing the same issue as OP. I have a centralized place where terraform and my CI/CD grab the same image value yet this reports that there is changes all the time.
I checked the task definition generated by CI/CD and the one generated by terraform and they are the exact same the only difference is the registeredAt
and registeredBy
and revision
. I tried adding tofu refresh
before the actual terraform plan and we still see the same problem.
@bryantbiggs Sorry to ping you, but have you any idea how we can deal with this issue? Is there any workaround to this workaround? Allowing to deploy through the CI and managing the task through Terraform sounds really perfect.
unfortunately, I think we have exhausted the various hacks and avenues for trying to deal with this at a module/resource level. the solution needs to ultimately come from the ECS API - I don't know if there is anything that could be done at the Terraform AWS provider level
Thx @bryantbiggs for your feedback. Is there anyplace where we can ask for such improvement? Out of curiosity, this workaround was working at somepoint?
I would highly encourage you to reach out to your AWS account team and provide them feedback on what you are trying to do with ECS and the challenges you are facing. This is how Amazon works (working backwards from the customer) and its how we will drive actual change from the service side, instead of pursuing hacks through the limited set of functionality we have at our disposal at the resource/module level
Thank you for the recommendation, I’ve sent a message to our AWS support team. Regarding this issue, here’s another discussion thread where it's being extensively talked about: https://github.com/hashicorp/terraform-provider-aws/issues/632
@bryantbiggs So the AWS support ask me to create an issue within the ECS roadmap repository. The point is I don’t know at all what to ask. I understood there is a lack within the ECS API, but which one exactly? May I ask you to create it? Perhaps the fact you work at AWS can help increasing the priority or help up to find a workaround.
There are already various existing requests on the containers roadmap, I've listed a few below that I believe are related/relevant:
we will attempt a change in v6.0 - but that attempt is to remove hacks and move the discussion further upstream. That could be the AWS provider or with the service itself
Description
My team triggers deploys to ECS via Github actions, and we did not want to have to update Terraform whenever we do a deploy.
We could not use the
ignore_task_definition_changes
, because that also (surprisingly) causes changes to the load balancer to be ignored (see https://github.com/terraform-aws-modules/terraform-aws-ecs/issues/154 and https://github.com/terraform-aws-modules/terraform-aws-ecs/issues/152).According to the design doc, there is an officially supported workaround:
We ended up going with this workaround, however it has an undesirable bug. Now, after a deploy via GitHub actions, whenever we make any change to our Terraform (even if it doesn't touch the ECS service in any way), the container_definitions of the service are recreated.
This does not cause downtime, but it does cause extra noise whenever we make a change to our terraform, and makes it hard to know during a
terraform plan
if the container definition has actually changed or if it's just being recreated without anything changing.Versions
Module version [Required]: 5.8.0
Terraform version: v1.5.7
Provider version(s):
Reproduction Code [Required]
Unfortunately, I do not have the time to make a fully reproducible example. However, the official docs don't even provide a full example of how to implement the workaround, so I think it's fair for me to provide an example that's much more full than the official docs and still shows the general shape of how this works.
Based on the comments in https://github.com/terraform-aws-modules/terraform-aws-ecs/issues/152, I get the impression that many teams want to use a similar setup, deploying with GitHub Actions, so it may be helpful to actually add something like this to the readme or
examples/
directory. Feel free to borrow from the code I've shared below as needed.ECS terraform:
GitHub action to deploy:
Expected behavior
After applying this terraform and then deploying from GitHub, if I change an unrelated
.tf
file in the same terraform project, then when I runterraform plan
, no changes should be shown in my container definition.Actual behavior
The container definition gets updated and the service is recreated.
I am 100% sure this is not due to task definition drift outside of GitHub Actions and Terraform, as the task definition has never been updated except by Github Actions and Terraform. We deploy to multiple environments using the same scripts and this bug appears in all of those environments.
Terminal Output Screenshot(s)
I cannot share a screenshot, but when I run
terraform plan
, it shows these two resources getting changedregisteredAt
,registeredBy
, andrevision
properties of the task definition always change after a deployment by GitHub Actions.Additional context
ignore_task_definition_changes = true
. I've filed a separate ticket for that suggestion: https://github.com/terraform-aws-modules/terraform-aws-ecs/issues/154