Skip to content

feat(deployment): Allow omitting replicas via null and support zero replicas #1452

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

na2na-p
Copy link

@na2na-p na2na-p commented Jun 14, 2025

This PR resolves #1451.

What does this PR do?

This pull request updates the logic for the deployment.replicas field to support two distinct, important use cases:

  1. Delegating Replica Management: Allows setting replicas: null to completely omit the replicas field from the rendered Deployment manifest.
  2. Scaling to Zero: Ensures that setting replicas: 0 correctly renders replicas: 0 in the manifest.

This is achieved by changing the rendering condition in deployment.yaml from replicas: {{ default 1 .Values.deployment.replicas }} to use an explicit non-nil check: {{- if and (not .Values.autoscaling.enabled) (not (eq .Values.deployment.replicas nil)) }}.

Motivation

The primary motivation is to solve the problem described in #1451, where users need to delegate replica management to external controllers like Argo Rollouts. This requires omitting the replicas field from the chart's output.

Following a discussion in the issue, we opted for a simpler approach of allowing replicas: null instead of introducing a new manageReplicas parameter. This PR implements that idea while also fixing a side effect where replicas: 0 would have been incorrectly ignored (as 0 is falsy in Go templates).

This solution provides the needed flexibility for modern GitOps patterns without adding new parameters and while maintaining backward compatibility.

More

  • Yes, I updated the tests accordingly
  • Yes, I updated the schema accordingly
  • Yes, I ran make test and all the tests passed

@na2na-p na2na-p force-pushed the feat/deployment-allow-zero-replicas branch from d2c2f42 to 78c0678 Compare June 14, 2025 05:54
@na2na-p

This comment was marked as outdated.

@na2na-p na2na-p marked this pull request as ready for review June 14, 2025 06:06
@mloiseleur
Copy link
Member

Thanks. It's missing a test when replicas is nullified.
Unless I missed something, the HPA can be configured with values, no need to use extraObjects.

Instead of hiding it in this PR, wdyt about adding an EXAMPLE on this use case ?

@na2na-p
Copy link
Author

na2na-p commented Jun 16, 2025

@mloiseleur

Thanks to comments!


It's missing a test when replicas is nullified.

Thanks for pointing that out! I've added the test case.


Unless I missed something, the HPA can be configured with values, no need to use extraObjects.

Good point. Unless I'm mistaken, my understanding is that the apiVersion and kind are hardcoded here and cannot be changed through values:

apiVersion: apps/v1
kind: Deployment

Additionally, this Helm chart is designed for the proxy workload to run as either a Deployment or a DaemonSet, so I believe there's little need to modify them.


Instead of hiding it in this PR, wdyt about adding an EXAMPLE on this use case ?

That's a great suggestion, thank you! I'll work on adding an Install with Argo Rollouts example in this same PR.

I'll start on the modifications now, so please give me a little time.

@na2na-p na2na-p marked this pull request as draft June 16, 2025 12:37
Comment on lines +81 to +82
When using [ArgoCD Rollouts](https://argoproj.github.io/rollouts/), one can delegate replica management to a `Rollout` resource, enabling progressive delivery strategies like canary and blue-green deployments.
To do so, `replicas` should be set to `0` and the `Rollout` resource defined in `extraObjects`.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a native English speaker, so I would appreciate it if you could point out any errors.
(Translate assisted with Gemini😇)

@na2na-p na2na-p marked this pull request as ready for review June 16, 2025 12:41
@mloiseleur
Copy link
Member

Unless I'm mistaken, my understanding is that the apiVersion and kind are hardcoded here and cannot be changed through values

\o that's right. I opened #1453 in order to add this feature.
Feel free to review and test it.

@mloiseleur mloiseleur added the kind/enhancement New feature or request label Jun 16, 2025
@na2na-p
Copy link
Author

na2na-p commented Jun 16, 2025

@mloiseleur

I'm planning to add conditional logic based on scaleTargetRef.apiVersion and scaleTargetRef.kind, so I think it would be best for me to rebase after #1453 is merged first.

It worked successfully after I applied this fix based on your code.
This works with the configuration below.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: traefik-testing-with-rollouts
  namespace: argocd
spec:
  destination:
    namespace: traefik-testing-with-rollouts
    server: https://kubernetes.default.svc
  source:
    repoURL: https://github.com/na2na-p/traefik-helm-chart.git
    targetRevision: feat/deployment-allow-zero-replicas-with-configuable-hpa
    path: traefik
    helm:
      values: |-
        deployment:
          replicas: 0
        autoscaling:
          enabled: true
          minReplicas: 5
          maxReplicas: 50
          metrics:
            - type: Resource
              resource:
                name: cpu
                target:
                  type: Utilization
                  averageUtilization: 80
          scaleTargetRef:
            apiVersion: argoproj.io/v1alpha1
            kind: Rollout
        extraObjects:
          - |
            apiVersion: argoproj.io/v1alpha1
            kind: Rollout
            metadata:
              name: {{ template "traefik.fullname" . }}
            spec:
              workloadRef:
                apiVersion: apps/v1
                kind: Deployment
                name: {{ template "traefik.fullname" . }}
              strategy:
                canary:
                  steps:
                  - setWeight: 10
                  - pause:
                      duration: 5m
  project: default
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
      - ServerSideApply=true

image

@na2na-p na2na-p marked this pull request as draft June 16, 2025 14:51
@na2na-p na2na-p marked this pull request as draft June 16, 2025 14:51
@na2na-p na2na-p marked this pull request as draft June 16, 2025 14:51
@na2na-p na2na-p force-pushed the feat/deployment-allow-zero-replicas branch from e363c82 to ad742a7 Compare June 16, 2025 14:56
Comment on lines +85 to +116
deployment:
replicas: 0
autoscaling:
enabled: true
minReplicas: 5
maxReplicas: 50
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 80
scaleTargetRef:
apiVersion: argoproj.io/v1alpha1
kind: Rollout
extraObjects:
- apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: "{{ template \"traefik.fullname\" . }}"
spec:
workloadRef:
apiVersion: apps/v1
kind: Deployment
name: "{{ template \"traefik.fullname\" . }}"
strategy:
canary:
steps:
- setWeight: 10
- pause:
duration: 5m
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had tested that

image image image image

@na2na-p na2na-p force-pushed the feat/deployment-allow-zero-replicas branch from ad742a7 to eabc5f8 Compare June 18, 2025 13:16
@na2na-p na2na-p marked this pull request as ready for review June 18, 2025 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add an option to disable rendering the 'replicas' field in Deployment
2 participants