Directory block not saved in state for multi-source applications
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 = "[email protected]: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
- Define a multi-source ArgoCD application using the argocd_application resource.
- Include the directory block in the second source with exclude and include options.
- Run terraform apply to create the application.
- 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
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 - I'll pick this one up
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.
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!
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