jfrog/terraform-provider-artifactory

Terraform Apply Repeatedly Indicates Changes on Identical Reruns

Closed this issue · 1 comments

Describe the bug
We're experiencing an issue with terraform apply where it does not behave idempotically across consecutive runs under identical conditions. Specifically, the initial execution of terraform apply completes as expected, indicating no errors and applying the necessary changes successfully. However, when the command is re-executed without any alterations to the configuration or the state, Terraform incorrectly reports a diff, suggesting that changes are needed when, in reality, there have been no modifications to the infrastructure or the Terraform configuration files. This behavior results in a perpetual diff, misleadingly indicating a need for further actions.

This issue has been observed and tested with the Artifactory Provider versions 9.9.1 and the latest 10.3.3, indicating that it persists across multiple versions. The environment and configurations were kept constant during testing to ensure accuracy.

Requirements for and issue

  • A description of the bug

We're encountering an issue with setting up Artifactory permission targets, specifically for managing Terraform backends for different environments (development, staging, production). The process involves creating a unique permission target for each Terraform backend corresponding to these environments. This approach aligns with our standard practice for configuring permissions across various services.

However, we've observed that while this method functions correctly for other types of permissions and repositories, it uniquely fails or encounters problems with the repositories designated for the Terraform backend. The issue appears to be isolated to these Terraform backend repositories, as we have not experienced similar problems with any other repository types or permission configurations within Artifactory.

This unexpected behavior raises concerns specifically when attempting to apply our standard permission configuration process to the Terraform backend repositories, indicating a potential inconsistency or bug within Artifactory's handling of these specific repository types.

  • A fully functioning terraform snippet that can be copy&pasted (no outside files or ENV vars unless that's part of the issue). If this is not supplied, this issue will likely be closed without any effort expended.
resource "artifactory_permission_target" "octaura_terraform_backend_local" {
  for_each = artifactory_local_terraformbackend_repository.octaura_terraform_backend_local

  name = "Octaura Terraform Backend ${title(each.key)} Local Permissions"

  repo {
    repositories = [
      each.value.key,
    ]

    actions {
      groups {
        name = artifactory_group.octaura_group.name
        permissions = [
          "read",
        ]
      }

      users {
        name = module.octaura_terraform_backend_local_readonly_service_user[each.key].artifactory_service_user_name
        permissions = [
          "read",
        ]
      }

      users {
        name = module.octaura_terraform_backend_local_service_user[each.key].artifactory_service_user_name
        permissions = [
          "read",
          "write",
          "annotate",
        ]
      }
    }
  }
}
  • Artifactory SaaS v7.81.2
  • Terraform version: v1.5.5
  • Terraform provider version: v9.9.1

Expected behavior
Current Output:
[03-changed.log](https://github.com/jfrog/terraform-provider-artifactory/files/14643219/03-changed.log)0 to add, 3 to change, 0 to destroyExpected Output:No changes. Your infrastructure matches the configuration

Additional context
The logs below can be provided if needed.
01-no-changes.log: Logs when run on main branch (clean slate)
02-added.log: Logs when permissions were being created
03-changed.log: Logs when rerunning show resources changing even though nothing changed

@travis-jfrog I reproduced the state drift issue using the following configuration:

terraform {
  required_providers {
    artifactory = {
      source  = "jfrog/artifactory"
      version = "10.4.0"
    }
  }
}

provider "artifactory" {
  //  supply ARTIFACTORY_ACCESS_TOKEN / JFROG_ACCESS_TOKEN / ARTIFACTORY_API_KEY and ARTIFACTORY_URL / JFROG_URL as env vars
}

resource "artifactory_local_docker_v2_repository" "my-docker-local" {
  key = "my-docker-local"
}

resource "artifactory_managed_user" "test-user" {
  name     = "terraform"
  email    = "test-user@artifactory-terraform.com"
  password = "<redacted>"
}

resource "artifactory_permission_target" "my-permission-target" {
  name = "my-permission-target"
  repo {
    repositories = [
      artifactory_local_docker_v2_repository.my-docker-local.key
    ]

    actions {
      users {
        name = artifactory_managed_user.test-user.name
        permissions = ["read",]
      }

      users {
        name = artifactory_managed_user.test-user.name
        permissions = ["read", "write"]
      }
    }
  }
}

Note the duplicate set of users.name which is also shown in the log files you shared with me.

After a successful terraform apply, the output of terraform plan contains the expected issue:

alexh@alexh-mac terraform-provider-artifactory % terraform plan
artifactory_managed_user.test-user: Refreshing state... [id=terraform]
artifactory_local_docker_v2_repository.my-docker-local: Refreshing state... [id=my-docker-local]
artifactory_permission_target.my-permission-target: Refreshing state... [id=my-permission-target]

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:

  # artifactory_permission_target.my-permission-target will be updated in-place
  ~ resource "artifactory_permission_target" "my-permission-target" {
        id   = "my-permission-target"
        name = "my-permission-target"

      ~ repo {
            # (3 unchanged attributes hidden)

          ~ actions {
              + users {
                  + name        = "terraform"
                  + permissions = [
                      + "read",
                    ]
                }

                # (1 unchanged block hidden)
            }
        }
    }

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

│ Warning: Deprecated Resource

│   with artifactory_permission_target.my-permission-target,
│   on sample.tf line 24, in resource "artifactory_permission_target" "my-permission-target":
│   24: resource "artifactory_permission_target" "my-permission-target" {

│ This resource has been deprecated in favor of "platform_permission" (https://registry.terraform.io/providers/jfrog/platform/latest/docs/resources/permission)
│ resource.

│ (and one more similar warning elsewhere)


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

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

Removing the duplicate users attribute:

terraform {
  required_providers {
    artifactory = {
      source  = "jfrog/artifactory"
      version = "10.4.0"
    }
  }
}

provider "artifactory" {
  //  supply ARTIFACTORY_ACCESS_TOKEN / JFROG_ACCESS_TOKEN / ARTIFACTORY_API_KEY and ARTIFACTORY_URL / JFROG_URL as env vars
}

resource "artifactory_local_docker_v2_repository" "my-docker-local" {
  key = "my-docker-local"
}

resource "artifactory_managed_user" "test-user" {
  name     = "terraform"
  email    = "test-user@artifactory-terraform.com"
  password = "<redacted>"
}

resource "artifactory_permission_target" "my-permission-target" {
  name = "my-permission-target"
  repo {
    repositories = [
      artifactory_local_docker_v2_repository.my-docker-local.key
    ]

    actions {
      # users {
      #   name = artifactory_managed_user.test-user.name
      #   permissions = ["read",]
      # }

      users {
        name = artifactory_managed_user.test-user.name
        permissions = ["read", "write"]
      }
    }
  }
}

Then run terraform apply returns no state drift:

alexh@alexh-mac terraform-provider-artifactory % terraform plan
artifactory_managed_user.test-user: Refreshing state... [id=terraform]
artifactory_local_docker_v2_repository.my-docker-local: Refreshing state... [id=my-docker-local]
artifactory_permission_target.my-permission-target: Refreshing state... [id=my-permission-target]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

│ Warning: Deprecated Resource

│   with artifactory_permission_target.my-permission-target,
│   on sample.tf line 24, in resource "artifactory_permission_target" "my-permission-target":
│   24: resource "artifactory_permission_target" "my-permission-target" {

│ This resource has been deprecated in favor of "platform_permission" (https://registry.terraform.io/providers/jfrog/platform/latest/docs/resources/permission)
│ resource.

│ (and one more similar warning elsewhere)