Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Directory block not saved in state for multi-source applications #418

Open
Ravitejareddykamidi opened this issue Sep 12, 2024 · 5 comments
Assignees
Labels
bug Something isn't working help wanted Community help wanted!

Comments

@Ravitejareddykamidi
Copy link

Ravitejareddykamidi commented Sep 12, 2024

Description:

I'm encountering an issue with the argocd Terraform provider (source: oboukili/argocd, version: 6.1.1) when trying to create a multi-source application. Specifically, the directory block for excluding and including files does not get saved in the Terraform state file. As a result, when I re-run terraform plan or terraform apply, it continuously shows that changes are required, even though no actual changes were made.

Terraform Version, ArgoCD Provider Version and ArgoCD Version

Terraform version: v1.3.4
ArgoCD provider version: oboukili/argocd v6.1.1
ArgoCD version: v2.8.0+

Affected Resource(s)

Terraform Configuration Files

resource "argocd_application" "traefik_source" {
  metadata {
    name      = "${lower(var.environment)}-traefik-app"
    namespace = "argocd"
  }

  spec {
    project = "default"

    # First source (Helm)
    source {
      repo_url        = "https://traefik.github.io/charts"
      chart           = "traefik"
      target_revision = var.apps_details["traefik"]["traefik-helm-revision"]
      helm {
        value_files = ["$values/${var.apps_details["traefik"]["values_file_path"]}"]
      }
    }

    # Second source (Git)
    source {
      repo_url        = "git@gitlab.com:XXXXX/XXXXXX/traefik_v2.git"
      target_revision = var.apps_details["traefik"]["traefik_git_revision"]
      ref             = "values"

      directory {
        exclude = "*.json"
        include = var.apps_details["traefik"]["include_files"]
      }
    }

    destination {
      server    = var.api_server_url
      namespace = var.apps_details["traefik"]["namespace"]
    }

    sync_policy {
      automated {
        prune       = false
        self_heal   = false
        allow_empty = false
      }
      sync_options = [
        "PruneLast=true",
        "CreateNamespace=true"
      ]

      retry {
        limit = 4
        backoff {
          duration     = "120s"
          factor       = 2
          max_duration = "3m0s"
        }
      }
    }

    revision_history_limit = 10
  }
}

Debug Output

 ~ source {
                # (3 unchanged attributes hidden)

              + directory {
                  + exclude = "*.json"
                  + include = "{staging-eks-ingress-cots.yaml,staging-eks-ingress-private.yaml,staging-eks-ingress-public.yaml,testing-eks-ingress-public.yaml}"
                }
            }

Panic Output

Steps to Reproduce

  1. Define a multi-source ArgoCD application using the argocd_application resource.
  2. Include the directory block in the second source with exclude and include options.
  3. Run terraform apply to create the application.
  4. Run terraform plan again and observe that the directory block is continuously reported as needing to be added.

Expected Behavior

The directory block should be saved in the Terraform state file after the first terraform apply, and no changes should be detected on subsequent terraform plan or terraform apply runs unless there are actual changes.

Actual Behavior

The directory block does not get saved in the Terraform state file, causing Terraform to continuously detect and attempt to apply changes related to this block on every terraform plan or terraform apply run, even though the ArgoCD UI already reflects the changes.

Terraform Plan shows the following every time:

+ directory {
    + exclude = "*.json"
    + include = "{staging-eks-ingress-cots.yaml,staging-eks-ingress-private.yaml,staging-eks-ingress-public.yaml,testing-eks-ingress-public.yaml}"
}

Important Factoids

The directory block is already present in the ArgoCD UI and contains the correct values.
This behavior only affects the directory block, while other resources function as expected.
This happens when defining multiple sources within an ArgoCD application.

directory:
      jsonnet: {}
      exclude: '*.json'
      include: >-
        {staging-eks-ingress-cots.yaml,staging-eks-ingress-private.yaml,staging-eks-ingress-public.yaml,testing-eks-ingress-public.yaml}

References

No specific references found yet.

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment
@Ravitejareddykamidi Ravitejareddykamidi added the bug Something isn't working label Sep 12, 2024
@mkilchhofer
Copy link
Collaborator

mkilchhofer commented Oct 14, 2024

Hi @Ravitejareddykamidi

Thanks for reporting. I remove the flag "bug" and add the "enhancement" label.
The provider is still using the Argo CD client in version 2.4. Multi-Source apps were introduced inside Argo CD 2.6.x.

So we need to
1. update the argocd library (go.mod)
2. make sure multi-source app is correctly represented inside Terraform (state/schema)

Update:
I mixed up some things. We are already using the libary version 2.9.x:

require (
	# ..
	github.com/argoproj/argo-cd/v2 v2.9.21
	github.com/argoproj/gitops-engine v0.7.3
	github.com/argoproj/pkg v0.13.7-0.20230627120311-a4dd357b057e
	# ..
)

Then we need to make sure that the multi-source app is correctly reflected into TF. I will add the bug label again.

@mkilchhofer mkilchhofer added enhancement New feature or request help wanted Community help wanted! bug Something isn't working and removed bug Something isn't working enhancement New feature or request labels Oct 14, 2024
@tonedefdev
Copy link
Contributor

@mkilchhofer - I'll pick this one up

@tonedefdev
Copy link
Contributor

tonedefdev commented Nov 9, 2024

Then we need to make sure that the multi-source app is correctly reflected into TF. I will add the bug label again.

I was doing some testing and the issue actually happens regardless if it's a multi-source application or not. If you even have a single source with a directory block it will not save the configuration values for exclude or include to state IF recurse = false or unset, or the jsonnet block isn't included with values.

I have a sneaking suspicion it's due to the DiffSuppressFunc on the directory schema:

DiffSuppressFunc: func(k, oldValue, newValue string, d *schema.ResourceData) bool {
	// Avoid drift when recurse is explicitly set to false
	// Also ignore the directory node if both recurse & jsonnet are not set or ignore
	if k == "spec.0.source.0.directory.0.recurse" && oldValue == "" && newValue == "false" {
		return true
	}
	if k == "spec.0.source.0.directory.#" {
		_, hasRecurse := d.GetOk("spec.0.source.0.directory.0.recurse")
		_, hasJsonnet := d.GetOk("spec.0.source.0.directory.0.jsonnet")

		if !hasJsonnet && !hasRecurse {
			return true
		}
	}
	return false
},

@Ravitejareddykamidi - a quick workaround while we figure this out is to either set recurse = true or the jsonnet block with the values it requires.

I'll do some more digging to figure out why exactly this is happening. My guess to why the DiffSuppressFunc was needed is due to ArgoCD's API not explicitly setting recurse: false even when you set it to false. If you change this value to false directly on the ArgoCD Application it will actually be entirely removed from the configuration.

@Ravitejareddykamidi
Copy link
Author

Hi @tonedefdev,

Thanks for the workaround suggestion! I set recurse = true and added the jsonnet block with the required values, and it worked perfectly. The configuration is now correctly detected in terraform plan without any issues.

Appreciate the quick solution and your help in figuring this out!

@tonedefdev
Copy link
Contributor

Hi @tonedefdev,

Thanks for the workaround suggestion! I set recurse = true and added the jsonnet block with the required values, and it worked perfectly. The configuration is now correctly detected in terraform plan without any issues.

Appreciate the quick solution and your help in figuring this out!

@Ravitejareddykamidi -- just wanted to clarify that you only need either the recurse option set to true or the jsonnnet block, not both

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Community help wanted!
Projects
None yet
Development

No branches or pull requests

4 participants