'Is there a way to compare what is added and what is destroyed with a terraform plan?

I am currently refactoring a terraform repository and dont want to make any changes to the existing infrastructure. Because of new modules some resources have to be destroyed and be created again. To make sure that the resources are equal I want to compare what is destroyed to what is created without manually going through the plan. Is there an easier way for this?

     # module.Loadbalancer.module.Listener.module.ListenerRules.aws_lb_listener_rule.listener_rule_external-listener-443_9602[0] will be created
      + resource "aws_lb_listener_rule" "listener_rule_external-listener-443_9602" {
          + arn          = (known after apply)
          + id           = (known after apply)
          + listener_arn = "someListenerARN"
          + priority     = 9602
          + tags_all     = (known after apply)
    
          + action {
              + order = (known after apply)
              + type  = "redirect"
    
              + redirect {
                  + host        = "test.com"
                  + path        = "/path"
                  + port        = "#{port}"
                  + protocol    = "#{protocol}"
                  + query       = "#{query}"
                  + status_code = "HTTP_301"
                }
            }
    
          + condition {
              + host_header {
                  + values = [
                      + "test.de",
                    ]
                }
            }
          + condition {
    
              + path_pattern {
                  + values = [
                      + "/path-path",
                    ]
                }
            }
        }
    
  # module.Loadbalancer.module.Listener.module.ListenerRules.aws_lb_listener_rule.listener_rule_external-listener-443_9603 will be destroyed
  # (because resource uses count or for_each)
  - resource "aws_lb_listener_rule" "listener_rule_external-listener-at-443_9603" {
      - arn          = "someOldARN" -> null
      - id           = "someOldID" -> null
      - listener_arn = "someListenerARN" -> null
      - priority     = 9603 -> null
      - tags         = {} -> null
      - tags_all     = {} -> null

      - action {
          - order = 1 -> null
          - type  = "redirect" -> null

          - redirect {
              - host        = "test.com" -> null
              - path        = "/path" -> null
              - port        = "#{port}" -> null
              - protocol    = "#{protocol}" -> null
              - query       = "#{query}" -> null
              - status_code = "HTTP_301" -> null
            }
        }

      - condition {
          - host_header {
              - values = [
                  - "test.de",
                ] -> null
            }
        }
      - condition {

          - path_pattern {
              - values = [
                  - "/path-path",
                ] -> null
            }
        }
    }


Solution 1:[1]

It seems you have made the following changes in the configuration:

  • resource "aws_lb_listener_rule" "listener_rule_external-listener-443_9603" is now renamed to resource "aws_lb_listener_rule" "listener_rule_external-listener-443_9602" -- that is, the number on the end of the name is different.
  • The resource now has count enabled, so its first instance now has the instance key [0].

By default Terraform assumes that you intend to destroy the old object and create a new one at the new address, but you can override that behavior by writing a moved block alongside the resource block:

resource "aws_lb_listener_rule" "listener_rule_external-listener-443_9602" {
  count = 1

  # ...
}

moved {
  from = aws_lb_listener_rule.listener_rule_external-listener-443_9603
  to   = aws_lb_listener_rule.listener_rule_external-listener-443_9602[0]
}

This moved block serves as a hint to Terraform so that if it finds an object in your prior state for this module called aws_lb_listener_rule.listener_rule_external-listener-443_9603, it should pretend it was originally created as aws_lb_listener_rule.listener_rule_external-listener-443_9602[0]. This rule will have no effect if there isn't already an object in the state with the from address, so it's safe to include this in a module even if not all callers of the module will need it, and you can leave it in the module indefinitely after you've applied the change.

There's more information on this mechanism in the Terraform documentation section Refactoring.

With this moved block in place, you should see terraform apply just note that the address has changed, and not propose to make any changes to the object's own configuration. If you see it also proposing changes to the configuration then that suggests that you've changed the configuration in some other way, in which case Terraform will propose to apply that change in addition to rebinding the object to a new address.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Martin Atkins