F5Networks / terraform-provider-bigip

Terraform resources that can configure F5 BIG-IP products
https://registry.terraform.io/providers/F5Networks/bigip/latest/docs
Mozilla Public License 2.0
103 stars 119 forks source link

Application_list is forcing Per-App deployments to constantly change #987

Closed skenderidis closed 3 months ago

skenderidis commented 3 months ago

Environment

Summary

When deploying per-app AS3 declarations with Terraform on the SAME partition, tf_state incldes on the as3_json not only the declaration for that "per-app" but for all the previously deployed "per-apps" on that partition.

So if I create app1.json and app2.json (that I have attached below) and you look at the tfstate, app1 will have the correct as3_json because it was created first, but app2 will include on the as3_json not only it own declaration, but also app1. If I deploy a third application, it will include app1 and app2 declarations. This didnt happen before "application_list" was introduced.

providers.tf.txt app2.tf.txt app2.json.txt app1.tf.txt app1.json.txt

Please check the .tfstate below

{
  "version": 4,
  "terraform_version": "1.8.1",
  "serial": 3,
  "lineage": "b4790b26-ee83-0090-7c5b-092f6de1e231",
  "outputs": {},
  "resources": [
    {
      "mode": "managed",
      "type": "bigip_as3",
      "name": "app1",
      "provider": "provider[\"registry.terraform.io/f5networks/bigip\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "application_list": "path_app1",
            "as3_json": "{\"path_app1\":{\"class\":\"Application\",\"pool\":{\"class\":\"Pool\",\"members\":[{\"serverAddresses\":[\"192.20.1.10\",\"192.30.1.20\"],\"servicePort\":80}]},\"vs_name_app1\":{\"class\":\"Service_HTTP\",\"pool\":\"pool\",\"virtualAddresses\":[\"192.1.1.24\"]}},\"schemaVersion\":\"3.50.0\"}",
            "id": "dmz",
            "ignore_metadata": true,
            "per_app_mode": true,
            "task_id": "1aaa5739-926b-48a8-9a2a-b88af7baa687",
            "tenant_filter": "dmz",
            "tenant_list": "dmz",
            "tenant_name": "dmz"
          },
          "sensitive_attributes": [],
          "private": "bnVsbA=="
        }
      ]
    },
    {
      "mode": "managed",
      "type": "bigip_as3",
      "name": "app2",
      "provider": "provider[\"registry.terraform.io/f5networks/bigip\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "application_list": "path_app1,path_app2",
            "as3_json": "{\"path_app1\":{\"class\":\"Application\",\"pool\":{\"class\":\"Pool\",\"members\":[{\"serverAddresses\":[\"192.20.1.10\",\"192.30.1.20\"],\"servicePort\":80}]},\"vs_name_app1\":{\"class\":\"Service_HTTP\",\"pool\":\"pool\",\"virtualAddresses\":[\"192.1.1.24\"]}},\"path_app2\":{\"class\":\"Application\",\"pool\":{\"class\":\"Pool\",\"members\":[{\"serverAddresses\":[\"12.20.1.10\",\"12.30.1.20\"],\"servicePort\":80}]},\"vs_name_app2\":{\"class\":\"Service_HTTP\",\"pool\":\"pool\",\"virtualAddresses\":[\"192.1.1.234\"]}},\"schemaVersion\":\"3.50.0\"}",
            "id": "dmz",
            "ignore_metadata": true,
            "per_app_mode": true,
            "task_id": "f8ef5d9e-5e92-4590-93b9-2e1fcce0e0a9",
            "tenant_filter": "dmz",
            "tenant_list": "dmz",
            "tenant_name": "dmz"
          },
          "sensitive_attributes": [],
          "private": "bnVsbA=="
        }
      ]
    }
  ],
  "check_results": null
}

If you see as3_json includes the JSON from app1 and app2 on "app2" instance.

Now if I run terraform plan again, TF will suggest that it needs to DELETE app1 JSON from the app2 Instance. By the way, on BIGIP everything is deployed correctly.

This is the TF plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # bigip_as3.app2 will be updated in-place
  ~ resource "bigip_as3" "app2" {
      ~ as3_json         = jsonencode(
          ~ {
              - path_app1     = {
                  - class        = "Application"
                  - pool         = {
                      - class   = "Pool"
                      - members = [
                          - {
                              - serverAddresses = [
                                  - "192.20.1.10",
                                  - "192.30.1.20",
                                ]
                              - servicePort     = 80
                            },
                        ]
                    }
                  - vs_name_app1 = {
                      - class            = "Service_HTTP"
                      - pool             = "pool"
                      - virtualAddresses = [
                          - "192.1.1.24",
                        ]
                    }
                }
                # (2 unchanged attributes hidden)
            }
        )
        id               = "dmz"
        # (7 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: tfplan

To perform exactly these actions, run the following command to apply:

Expected Behavior

This prevents users from using the per-app deployment as every time, TF will send an update configuration.

pgouband commented 3 months ago

Hi,

Thanks for reporting. Added to the backlog and internal tracking ID for this request is: INFRAANO-1568.