Terraform plan destroys, replaces and changes existing resources despite having a matching configuration written?

I’ve written out azurerm_network_security_group resources and their associated rules.

In the terraform plan output, they match exactly to the state file. Exactly. Formatting and everything.

Yet Terraform plan wants to “change” the nsgs “in-place” by deleting the NSG rules and…re-adding new rules that match exactly what already exists?

Why?

Show the output from terraform plan.

Terraform will tell you why as part of that.

For example:

# azurerm_network_security_group.EXAMPLE-NSG will be updated in-place
  ~ resource "azurerm_network_security_group" "EXAMPLE-NSG" {
        id                  = "/subscriptions/<id>/resourceGroups/<rg>/networkSecurityGroups/EXAMPLE-NSG"
        name                = "EXAMPLE-NSG"
      ~ security_rule       = [
          - {
              - access                                     = "Allow"
              - description                                = ""
              - destination_address_prefix                 = "*"
              - destination_address_prefixes               = []
              - destination_application_security_group_ids = []
              - destination_port_range                     = "*"
              - destination_port_ranges                    = []
              - direction                                  = "Inbound"
              - name                                       = "Ping"
              - priority                                   = 100
              - protocol                                   = "ICMP"
              - source_address_prefix                      = "*"
              - source_address_prefixes                    = []
              - source_application_security_group_ids      = []
              - source_port_range                          = "*"
              - source_port_ranges                         = []
            },
          + {
              + access                                     = "Allow"
              + description                                = ""
              + destination_address_prefix                 = "*"
              + destination_address_prefixes               = []
              + destination_application_security_group_ids = []
              + destination_port_range                     = "*"
              + destination_port_ranges                    = []
              + direction                                  = "Inbound"
              + name                                       = "Ping"
              + priority                                   = 100
              + protocol                                   = "Icmp"
              + source_address_prefix                      = "*"
              + source_address_prefixes                    = []
              + source_application_security_group_ids      = []
              + source_port_range                          = "*"
              + source_port_ranges                         = []
            },

As you can see, it is literally deleting the rule and reapplying the exact same configuration. It is doing this for every rule defined in every NSG.

Now, I just tried creating a fresh directory with JUST one NSG and associated resource group.

Terraform init

Imported both the NSG and RG via terraform import

did terraform plan

and now it matches my existing state in a fresh directory performing same steps as before but with just one NSG?

Very confused. Perhaps I should be doing terraform plan after every individual import? This could take a while.

The protocol value is different - “ICMP” and “Icmp”.

Oh lord I am something else. I literally just fixed that exact issue in an earlier Pull Request from a coworker…thanks stuart let me try that.

EDIT: Revised the values but they aren’t reflected even after saving the file and rerunning terraform plan. Think my best bet is to scorch earth and start over in the clean directory that is working properly. Thanks.