argoproj / argo-cd

Declarative Continuous Deployment for Kubernetes
https://argo-cd.readthedocs.io
Apache License 2.0
18.01k stars 5.49k forks source link

Provide one-time sync option for resources #3843

Open cookandy opened 4 years ago

cookandy commented 4 years ago

Summary

It would be useful to support a "one-time sync" option for resources.

Motivation

There are scenarios where objects need to be created by Argo, but are then modified outside of Argo and should stay out of sync, even during subsequent syncs of the application. For example, we use kubernetes-replicator to replicate secrets across namespaces (specifically Docker registry and TLS secrets). This allows us to create a parent secret in a single namespace, and have it replicated to other namespaces automatically. In order to achieve this, we must create an empty secret with the correct annotations. Argo will either try to fix the resource, or will overwrite it on the next sync.

Walk through:

  1. Create empty secret via Argo with required kubernetes-replicator annotations
  2. Kubernetes Replicator detects the new secret and replicates it from another namespace
  3. If selfHeal is not disabled, Argo will detect the change and overwrite the secrets with the empty one. Steps 2-3 repeat endlessly.
  4. If selfHeal is disabled, Argo won't try to fix the modified secret, but it will overwrite it on the next sync action (which breaks kubernetes-replicator).
  5. Adding the argocd.argoproj.io/hook: Skip annotation will skip the sync, but then there's no way to manually sync the resource once.

Proposal

I can think of a couple different solutions:

  1. Provide a argocd.argoproj.io/hook: Sync-once annotation, which will sync the resource once, and never again.
  2. Allow resources with argocd.argoproj.io/hook: Skip to be selectively synced.
unicell commented 4 years ago

Another solution I'm thinking for Helm based application is adding a value flag to turn on and off argocd.argoproj.io/hook: Skip annotation, so as to allow 1st-time creation and let ArgoCD skip the resource by flipping the value afterward.

turkenh commented 4 years ago

Any update on this?

We have a the same problem but with another resource.

We have admission webhooks that we deploy with ArgoCD as helm applications. We are generating certificates for webhooks using cert-manager and rely on cert-manager ca-injector to inject ca into webhook configuration as described here. However, once ca-injector does its job, ArgoCD marks our application as out of sync since spec of ValidatingWebhookConfiguration (webhooks[0]. clientConfig.caBundle) modified.

jannfis commented 3 years ago

Hey folks, have you considered using argocd.argoproj.io/hook: Sync (or PreSync) with a deletion policy of HookFailed (which I'd assume would not fire on a standard K8s resource)?

I think this could satisfy your use-case of a one-time sync.

Tjhayhay commented 3 years ago

The problem is that is still tries to apply the manifest everytime with the hook=sync/presync. So in the event of a manifest like this I just want argo to apply this manifest once and then be done with it.

jannfis commented 3 years ago

Ah yeah, you're right.

I believe a hook would be the right entity to solve this problem, tho - maybe a new hook option would make sense then. Something like an immutable hook, that doesn't get re-applied when the specific resource already exists in the cluster.

So this would become a true one-shot resource, with the implication that even when you change the resource in Git, it would not be re-applied to the cluster unless the resource is deleted manually before the sync. Maybe an additional sync option (or using existing force sync), the immutable hook would become mutable and would be overwritten from Git again.

Just thinking out loud here.

simonlsk commented 2 years ago

It would be useful to use this hook as the substitute for helm's hook pre-install instead of PreSync, which is by the way both misleading and wrong. Generating a secret once at install time sounds like a trivial use case to me. I find it very hard to do, especially since argo-cd doesn't generate a virtual .Release.IsUpdate on sync. Please someone correct me if I'm wrong or missing something.

tchellomello commented 2 years ago

+1 for this feature

jungsooooo commented 11 months ago

+1 for this feature

zozo commented 8 months ago

+1

Looking for analog of helm post-install to execute script to initialize something like database migration and initial db values.

If using PreSync to run DB migration Job - it will fail on first sync since DB itself could be not available yet.

andrii-korotkov-verkada commented 1 week ago

I think ignoreDifferences can be useful here https://argo-cd.readthedocs.io/en/stable/user-guide/diffing/#known-kubernetes-types-in-crds-resource-limits-volume-mounts-etc. You can configure it to ignore the whole data section of the secret, so it won't show out of sync and won't override your secret's values. Please, give it a try and let me know if it works.