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

Argo cd doesn't respect waves #8358

Closed
alekc opened this issue Feb 3, 2022 · 11 comments
Closed

Argo cd doesn't respect waves #8358

alekc opened this issue Feb 3, 2022 · 11 comments
Labels
bug Something isn't working

Comments

@alekc
Copy link

alekc commented Feb 3, 2022

Checklist:

  • [x ] I've searched in the docs and FAQ for my answer: https://bit.ly/argocd-faq.
  • [x ] I've included steps to reproduce the bug.
  • [ x] I've pasted the output of argocd version.

Similar to #5146 and #5585
Describe the bug

When applying multiple argocd application (not apps of the apps) with different sync waves annotations, they are not respected. I.e
Having

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  annotations:
    argocd.argoproj.io/sync-wave: "-20"
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"argoproj.io/v1alpha1","kind":"Application","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"-20"},"finalizers":["resources-finalizer.argocd.argoproj.io"],"name":"kyverno","namespace":"argocd"},"spec":{"destination":{"namespace":"runtime","server":"https://kubernetes.default.svc"},"project":"runtime","source":{"chart":"kyverno","helm":{"skipCrds":false,"values":""},"path":"","repoURL":"https://kyverno.github.io/kyverno/","targetRevision":"v2.1.10"},"syncPolicy":{"automated":{"prune":true,"selfHeal":true},"retry":{"backoff":{"duration":"5s","factor":2,"maxDuration":"3m"},"limit":10},"syncOptions":["CreateNamespace=true"]}}}
  creationTimestamp: "2022-02-03T14:38:47Z"
  finalizers:
  - resources-finalizer.argocd.argoproj.io
  generation: 17
  name: kyverno
  namespace: argocd
  resourceVersion: "105603"
  uid: d642eddc-74a9-4b25-8b78-ea3a699a6dcc
spec:
  destination:
    namespace: runtime
    server: https://kubernetes.default.svc
  project: runtime
  source:
    chart: kyverno
    repoURL: https://kyverno.github.io/kyverno/
    targetRevision: v2.1.10
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    retry:
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m
      limit: 10
    syncOptions:
    - CreateNamespace=true

and

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  annotations:
    argocd.argoproj.io/sync-wave: "0"
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"argoproj.io/v1alpha1","kind":"Application","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"0"},"finalizers":["resources-finalizer.argocd.argoproj.io"],"name":"cluster-overprovisioner","namespace":"argocd"},"spec":{"destination":{"namespace":"dummy","server":"https://kubernetes.default.svc"},"project":"runtime","source":{"chart":"cluster-overprovisioner","helm":{"skipCrds":false,"values":"deployments:\n  - name: default\n    replicaCount: 9\n    topologySpreadConstraints:\n      - maxSkew: 3\n        topologyKey: kubernetes.io/hostname\n        whenUnsatisfiable: ScheduleAnyway\n    resources:\n      requests:\n        cpu: 100m\n        memory: 100Mi\n"},"path":"","repoURL":"https://charts.deliveryhero.io/","targetRevision":"0.7.5"},"syncPolicy":{"automated":{"prune":true,"selfHeal":true},"retry":{"backoff":{"duration":"5s","factor":2,"maxDuration":"3m"},"limit":10},"syncOptions":["CreateNamespace=true"]}}}
  creationTimestamp: "2022-02-03T14:38:47Z"
  finalizers:
  - resources-finalizer.argocd.argoproj.io
  generation: 12
  name: cluster-overprovisioner
  namespace: argocd
  resourceVersion: "106793"
  uid: 72774a77-4ce3-4a06-a9ab-e8ef1c0c145e
spec:
  destination:
    namespace: dummy
    server: https://kubernetes.default.svc
  project: runtime
  source:
    chart: cluster-overprovisioner
    helm:
      values: |
        deployments:
          - name: default
            replicaCount: 9
            topologySpreadConstraints:
              - maxSkew: 3
                topologyKey: kubernetes.io/hostname
                whenUnsatisfiable: ScheduleAnyway
            resources:
              requests:
                cpu: 100m
                memory: 100Mi
    repoURL: https://charts.deliveryhero.io/
    targetRevision: 0.7.5
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    retry:
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m
      limit: 10
    syncOptions:
    - CreateNamespace=true

Kyverno starts much later

- deployStartedAt: "2022-02-03T14:39:18Z"
    deployedAt: "2022-02-03T14:39:33Z"

than overprovisioner

 - deployStartedAt: "2022-02-03T14:38:47Z"
    deployedAt: "2022-02-03T14:38:48Z"

I've also tried to follow https://argo-cd.readthedocs.io/en/stable/operator-manual/upgrading/1.7-1.8/#health-assessement-of-argoprojioapplication-crd-has-been-removed and changed my argocd-cm

apiVersion: v1
data:
resource.customizations: |
    argoproj.io/Application:
      health.lua: |
        hs = {}
        hs.status = "Progressing"
        hs.message = ""
        if obj.status ~= nil then
          if obj.status.health ~= nil then
            hs.status = obj.status.health.status
            if obj.status.health.message ~= nil then
              hs.message = obj.status.health.message
            end
          end
        end
        return hs

(for which btw there is no mention about it here https://argo-cd.readthedocs.io/en/stable/user-guide/sync-waves/)
but still no luck.

To Reproduce

Expected behavior

Resources pass from one wave to another only when the previous wave is finished and all applications are in synced and healthy state

Screenshots

Version

2.2.3

@alekc alekc added the bug Something isn't working label Feb 3, 2022
@jannfis
Copy link
Member

jannfis commented Feb 4, 2022

Hi. Sync-waves only apply during the same sync context, and not globally. So, they are not respected across different Applications, since each Application will have its own sync context.

There is some ongoing effort to implement dependencies between Applications (#7437, #3892).

I think we should close this issue as a duplicate.

@alekc
Copy link
Author

alekc commented Feb 4, 2022

Oh, I see. Docs description was not clear at all in regard.

So the only feasible way for this to work (right now) is to wrap these apps inside one giant helm chart to emulate apps of apps behaviour?

@alekc alekc closed this as completed Feb 7, 2022
@flaviomoringa
Copy link

@alekc I'm also having issues with installing kyverno using argocd. Even with app of apps, because kyverno needs to be up (CRD's installed) before the policies are installed I'm having issues :-(

Did you manage to fix this somehow? Maybe helm dependencies? But that does not make sure kyverno is installed first, it just installs other things :-(

Thanks for any help.

Cheers

@alekc
Copy link
Author

alekc commented Mar 25, 2022 via email

@flaviomoringa
Copy link

But in app of apps how do you define the dependencies using waves? I'm probably missing something obvious here :-(

And thanks for the help

@alekc
Copy link
Author

alekc commented Mar 25, 2022

@flaviomoringa yes, I've added that to argo cd config (not too sure if that was required, but won't hurt having it).

As for the declaration, here is a small example (it's a terraform based approach)

locals {
  wrappedApps = {
    // wave -25
    "priority-classes" = templatefile(
      "${path.module}/templates/argo-helm-app.yaml", merge(local.argocd_default_app_values, {
        name               = "priority-classes"
        namespace          = "runtime"
        project            = "runtime"
        helm_chart         = "any-resource"
        helm_chart_repoUrl = "https://kiwigrid.github.io"
        helm_chart_version = "0.1.0"
        argocd_wave        = "-25"
        // language=yaml
        helm_values = <<-EOT
anyResources:
  high_priority: |-
    apiVersion: scheduling.k8s.io/v1
    kind: PriorityClass
    metadata:
      name: high-priority
    value: 1000000
    globalDefault: false
    description: "high priority pods."
  medium_priority: |-
    apiVersion: scheduling.k8s.io/v1
    kind: PriorityClass
    metadata:
      name: medium-priority
    value: 500000
    globalDefault: false
    description: "medium priority pods."
EOT
    }))
// Wave -20
    "kyverno" = !var.app_kyverno_enable ? null : templatefile(
      "${path.module}/templates/argo-helm-app.yaml", merge(local.argocd_default_app_values, {
        name               = var.app_kyverno_helm_chart_name
        namespace          = "runtime"
        project            = "runtime"
        helm_chart         = var.app_kyverno_helm_chart_name
        helm_chart_repoUrl = var.app_kyverno_helm_chart
        helm_chart_version = var.app_kyverno_helm_chart_version
        argocd_wave        = "-20"
        helm_values        = <<-EOF
resources:
  requests:
    cpu: 109m
    memory: 226M
  limits:
    cpu: 109m
    memory: 226M
EOF
    }))
........

and then that local is looped and rendered with

resource "kubectl_manifest" "argocd-app-wrapper" {
  depends_on = [kubectl_manifest.argocd-project-runtime, kubectl_manifest.argocd-project-monitoring]
  wait       = true
  // language=yaml
  yaml_body = <<-EOT
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: bootstrap-app-wrapper
  namespace: argocd
  annotations:
    argocd.argoproj.io/sync-wave: "-100"
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    chart: any-resource
    repoURL: https://kiwigrid.github.io
    targetRevision: "0.1.0"
    helm:
      values: |
        anyResources:
%{~for key, val in local.wrappedApps}
%{~if val != null}
          ${key}: |-
            ${indent(12, val)}
%{~endif}
%{~endfor}
  destination:
    server: https://kubernetes.default.svc
    namespace: "default"
  syncPolicy:
    automated: # automated sync by default retries failed attempts 5 times with following delays between attempts ( 5s, 10s, 20s, 40s, 80s ); retry controlled using `retry` field.
      prune: true
      selfHeal: true
    syncOptions: # Sync options which modifies sync behavior
      - CreateNamespace=true
    retry:
      limit: 10 # number of failed sync attempt retries; unlimited number of attempts if less than 0
      backoff:
        duration: 5s # the amount to back off. Default unit is seconds, but could also be a duration (e.g. "2m", "1h")
        factor: 2 # a factor to multiply the base duration after each failed retry
        maxDuration: 3m # the maximum amount of time allowed for the backoff strategy
EOT

As you can see, we create an application called bootstrap-app-wrapper with priority argocd.argoproj.io/sync-wave: "-100" The application renders several argocd applications who has their wave value set by the argocd_wave parameter. Rendering is done through the terraform templating function, but you can pretty much replace it with already rendered config.

Let me know if you need further help.

@rafilkmp3
Copy link

this makes waves work ?

@alekc
Copy link
Author

alekc commented Apr 2, 2022 via email

@wrmedford
Copy link

@alekc Could you clarify if this preserved order only during bootstrap? Or does this also preserve order when syncing differences across both applications at the same time?

@alekc
Copy link
Author

alekc commented Jul 19, 2022

not sure I understand. As long as the apps manifesto are part of the same helm chart (see example above), it will respect the wave settings on them during the installation and during sync stages.

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

No branches or pull requests

5 participants