terraform-aws-modules / terraform-aws-dms

Terraform module to create AWS DMS (Database Migration Service) resources 🇺🇦
https://registry.terraform.io/modules/terraform-aws-modules/dms/aws
Apache License 2.0
60 stars 93 forks source link

Add The Ability To Set Lifecycle Rules To DMS Tasks #20

Open alordthorsen opened 2 years ago

alordthorsen commented 2 years ago

Is your request related to a new offering from AWS?

Is this functionality available in the AWS provider for Terraform? See CHANGELOG.md, too.

Is your request related to a problem? Please describe.

I will start off by saying that my company is currently experimenting with DMS and is looking at the costs and performance characteristics of the service on our systems. By default we don't want tasks to start in the "start" state.

Currently there's no way to pass a lifecycle configuration to the produced aws_dms_replication_task's that are produced by this module. The effect of this is that when tasks are turned on manually (like what I'm doing right now). The effect of this is that you get plans like

  # module.replicate_oltp.aws_dms_replication_task.this["cdc_all_postgresql_to_s3"] will be updated in-place
  ~ resource "aws_dms_replication_task" "this" {
        id                        = "dev-main-dms-postgresql-cdc-all-to-s3"
      ~ replication_task_settings = jsonencode(
          ~ {
              ~ ControlTablesSettings               = {
                  + historyTimeslotInMinutes      = 5
                    # (6 unchanged elements hidden)
                }
              ~ ErrorBehavior                       = {
                  - EventErrorPolicy                            = "IGNORE" -> null
                    # (21 unchanged elements hidden)
                }
              ~ Logging                             = {
                  + CloudWatchLogGroup  = null
                  + CloudWatchLogStream = null
                    # (2 unchanged elements hidden)
                }
                # (11 unchanged elements hidden)
            }
        )
        tags                      = {}
        # (10 unchanged attributes hidden)
    }

Where terraform is going to turn off a task that has been turned on.

The net effect of this is that if you want to have a system where

  1. Your resources are terraform managed.
  2. Tasks start in the stopped state.
  3. You want to be able to manually start tasks.

You need to accept that tasks will be stopped on each apply and you need to manually re-start them currently.

Describe the solution you'd like.

Add the ability to pass a lifecycle rule. Specifically being able to say

  lifecycle {
   ignore_changes        = [tags]
  }
}

Describe alternatives you've considered.

Manually accept restarting tasks. =P

mkohlmyr commented 2 years ago

This is a critical feature from my perspective, I've got a task settings file which seems to be getting re-ordered by AWS ahead of the diff, which means terraform attempts to shut down the task and replace the task settings on every apply.

This alone basically makes the service unusable for any purpose requiring high uptime in a continuous deployment environment. Add to that the fact that terraform can easily time out and fail when attempting to stop the task in order to update the settings and it comes to a point where DMS is no longer fit for purpose because of how terraform (and more specifically this module) is handling changes to task settings.

I will likely have to rewrite the terraform without the module at this stage to work around this issue.

bryantbiggs commented 2 years ago

unfortunately, we cannot use variables inside lifecycle rules https://github.com/hashicorp/terraform/issues/3116

github-actions[bot] commented 1 year ago

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

github-actions[bot] commented 1 year ago

This issue was automatically closed because of stale in 10 days

casey-robertson-paypal commented 1 year ago

Just running into this...this is painful. Aside from the manual stop/start I'd like to ignore task setting changes for a couple items (Cloudwatch log group and stream) but every time I run TF it's resetting them. I'm not sure how we will operationalize this.... would have to manually stop DMS tasks, run any terraform changes then restart them.

mkohlmyr commented 1 year ago

Just running into this...this is painful. Aside from the manual stop/start I'd like to ignore task setting changes for a couple items (Cloudwatch log group and stream) but every time I run TF it's resetting them. I'm not sure how we will operationalize this.... would have to manually stop DMS tasks, run any terraform changes then restart them.

Having just recently put DMS into production via Terraform I would strongly recommend just not using this library. It's not particularly complicated to set it up from scratch by comparison and you'll be able to control the lifecycle settings.

bryantbiggs commented 1 year ago

Just running into this...this is painful. Aside from the manual stop/start I'd like to ignore task setting changes for a couple items (Cloudwatch log group and stream) but every time I run TF it's resetting them. I'm not sure how we will operationalize this.... would have to manually stop DMS tasks, run any terraform changes then restart them.

https://github.com/hashicorp/terraform-provider-aws/issues/21512 https://github.com/hashicorp/terraform-provider-aws/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+dms+label%3Abug

casey-robertson-paypal commented 1 year ago

I'm regretting it a bit now - I might pull the module locally. Due to lifecycle being non-dynamic are you putting lifecycle settings hard-coded in the module? Or are you just listing out resources without iterators and using lifecycle settings as needed per-resource?

bryantbiggs commented 1 year ago

@mkohlmyr / @casey-robertson-paypal / @alordthorsen - would you mind sharing what you are specifying (or looking to specify) in the lifecycle ignore block, please? While we don't have a native way to variablize what settings are ignored by Terraform, we have supported "hacky" workarounds for common cases. I can't say that we can support every setting, but maybe there is a common group or a few that will make a difference. The reason we can only support a few is just overhead - we have to duplicate the resource (here, the task) for each scenario.

In the mean time, please feel free to use the module for reference and/or fork it to suit your immediate needs. If I can collect more information, this will help determine what changes we could make to make this work better

casey-robertson-paypal commented 1 year ago

The cloudwatch use case was the one that came to mind - I'll need to dedicate some time to try again. I had given up and just let it create the trails. I thought at first I'd like to ignore the start/stop status of the job but realized some of those messages or errors were coming from the API - i.e. you simply aren't allowed to update certain resources while jobs are running. This is an AWS limitation, not a module issue. Looking forward to hearing the use cases of the others too.

github-actions[bot] commented 1 year ago

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

kusold commented 1 year ago

@bryantbiggs The issue link regarding lifecycle interpolation was just closed, saying it is possible, depending on the scenario. Does that allow for new solutions to this issue?

Logging.LogComponents in the replication_task_settings is the property causing me the most pain. The elements inside the list get rearranged.

      ~ replication_task_settings = jsonencode(
          ~ {
              ~ Logging                             = {
                  ~ LogComponents    = [
                      ~ {
                          ~ Id       = "TRANSFORMATION" -> "DATA_STRUCTURE"
                            # (1 unchanged attribute hidden)
                        },
                      ~ {
                          ~ Id       = "SOURCE_UNLOAD" -> "COMMUNICATION"
                            # (1 unchanged attribute hidden)
                        },
                        {
                            Id       = "IO"
                            Severity = "LOGGER_SEVERITY_DEFAULT"
                        },
                      + {
                          + Id       = "COMMON"
                          + Severity = "LOGGER_SEVERITY_DEFAULT"
                        },
                      + {
                          + Id       = "FILE_FACTORY"
                          + Severity = "LOGGER_SEVERITY_DEFAULT"
                        },
                      + {
                          + Id       = "FILE_TRANSFER"
                          + Severity = "LOGGER_SEVERITY_DEFAULT"
                        },
                      + {
                          + Id       = "REST_SERVER"
                          + Severity = "LOGGER_SEVERITY_DEFAULT"
                        },
                      + {
                          + Id       = "ADDONS"
                          + Severity = "LOGGER_SEVERITY_DEFAULT"
                        },
                        {
                            Id       = "TARGET_LOAD"
                            Severity = "LOGGER_SEVERITY_DEFAULT"
                        },
                      ~ {
                          ~ Id       = "PERFORMANCE" -> "TARGET_APPLY"
                            # (1 unchanged attribute hidden)
                        },
...
tnightengale commented 2 months ago

Also have experienced a lot of annoyance, having tasks spuriously restarted because of the inability to specify the lifecycle.