<p>Generally, a Helm chart would cover all your microservices - ideally, you should be able to deploy whole application in one chart. It may get a little messy if you include external 3rd party dependencies, where you would need to handle dependent charts, but I assume this is out of scope of your question.</p>
<p>More so, if your microservices are very similar you could write for loops, such as:</p>
<pre><code>{{- range $index, $service := .Values.myservices}}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-{{ $service.name }}
# --- etc ---
{{- end }}
</code></pre>
<p>Now, where to put your chart - in most cases a preferred way is to have a separate repo for all Ops CD files, including Helm chart - so this is where Helm chart would live. This is not to be mixed with CI files, such as Dockerfile - those should live alongside microservice repositories themselves.</p>

CC BY-SA 4.0
2021-02-17T21:36:25.143Z
Y, i'm leaning toward having my Helm charts in our separate Ops Git repo (we do this for ECS now). I'll explore this idea, thanks!
Chris F
CC BY-SA 4.0
2023-06-21T09:08:33.350Z
All micro services in one chart? So you just have 1 release for all your services? I don't think that's great. Your helm rollback could affect everything, even only if one thing is broken. I know it sounds like it should be fine, but I have seen case where, for example, the CRD API changes behind the scenes, so the rollback fails, and you need to update the CRD API in your yaml in order to proceed. Having everything in 1 release can lead to a mess
TigerBear
CC BY-SA 4.0
2023-06-21T09:31:27.983Z
Yes, single release for all services. In a distributed system you trade liveness for safety and you can never get 100% liveness guarantee - so no matter what you do you will find an example where liveness fails. Now, with a single release you always move from one well tested state to another - which is a strict requirement in many cases. Finally, for mission critical applications, test your rollback plan before the deployment - this will help avoid issues like the one you mentioned.
taleodor
CC BY-SA 4.0
2021-02-17T21:26:40.637Z
2021-02-17T21:26:40.637Z
taleodor
<p>I believe what you're asking is: &quot;Is there any way to create just one helm chart that can be used for all microservices in my application?&quot;. If so, then you can just use the values.yaml file to store all the values for your templates. This is not considered good practice, considering your template file needs to hold the information for each of your microservice deployments (and thus will become really difficult to manage), but it is possible.</p>
<p>One example: say you have two microservices, and you need one Helm chart that will create the template for both microservices. Generally, you would create separate templates for each service under the templates folder, and deploy each Helm chart for each service individually, but instead you could create multiple deployments in one template yaml file, like</p>
<pre><code># For service 1
apiVersion: apps/v1
type: Deployment
etc., etc... (stick in all values.yaml file values here for service 1)
---
# For service 2
apiVersion: apps/v1
type: Deployment
etc., etc... (stick in all values.yaml file values here for service 2)
</code></pre>
<p>In your values.yaml file, you would then just place in the values for each of your services, like</p>
<pre><code># Service 1 Keys/Values
foo: value
# Service 2 Keys/Values
bar: otherValue
</code></pre>
<p>So to answer your question, you can package all your services into one individual Helm chart using the above method, and Kubernetes will run each service as their own ReplicaSet as expected. However, when you have many services to manage, it can be tricky to manage the template YAML files and the values.yaml files when you put in values for all your services in one file, and so it's most likely not a good practice to do this.</p>
<p>This is just my understanding of Helm so far, as I'm still learning Helm myself. As such, I'm not 100% sure if this can be done, so you might want to double check with another person that this answer is actually correct.</p>
<p>EDIT: To summarize: like I mentioned above, in theory, it is possible to use one Helm chart per service. But in practice, it will be extremely messy later on to manage the values.yaml and the templates in the templates folder. So the answer would be, &quot;Yes in theory, but not recommended at all&quot;.</p>

CC BY-SA 4.0
2021-02-17T20:52:54.940Z
yes, this is exactly what I want. But what will be the directory structure to accomplish this? Each microservice is in it's own Git repo. So where will be the "generic" Helm charts be? Where will the microservice-specific `values.yaml` files be? How do I consolidate the two directory files? Remember, I want to be able to do a `helm install ...` from some diretory that has the complete chart.
Chris F
CC BY-SA 4.0
2021-02-17T21:07:35.453Z
@ChrisF You would only need to put the regular Helm directory structure (Chart.yaml, values.yaml, and the templates folder) in one service. At that point, you would need to build your Docker images/push them to the registry first. Then, because K8s references only images stored in the registry, when you install your Helm chart using the files in just one microservice, K8s can pull the container image for all of your services and run it as expected. So when you run helm install from one service, it will work, as Kubernetes doesn't reference the directory, it references the container image.
Rohit Karthik
CC BY-SA 4.0
2021-02-17T21:10:06.217Z
I think this is a bad way to do it.
Chris F
CC BY-SA 4.0
2021-02-17T21:11:32.040Z
Yes, like I said earlier this isn't a good way to go about it all, it makes more sense to just package each service using Helm separately, as this method is extremely messy. But, this shows it's possible. This is not the best way to do it though.
Rohit Karthik
CC BY-SA 4.0
2021-02-17T21:15:01.110Z
My answer highlighted the way to do it, but if you want a much cleaner way to manage each service, you would need to create individual Chart.yaml, values.yaml, and a templates folder for each app. While it might be some additional work in the beginning (have to replicate the same thing across many services), it will be a huge timesaver later on.
Rohit Karthik
CC BY-SA 4.0
2021-02-17T21:16:17.943Z
Then the correct answer is "No, you need a separate Helm chart per microservice."
Chris F
CC BY-SA 4.0
2021-02-17T21:17:45.680Z
@ChrisF Yes, you're right, unless you want to deal with a messy Helm structure later on. I'll update that in my answer.
Rohit Karthik
CC BY-SA 4.0
2021-02-17T20:39:30.287Z
2021-02-17T21:20:25.863Z
2021-02-17T21:20:25.863Z
Rohit Karthik
<p>I have worked multiple jobs where I wrote just one helm chart as a base for all services. Within that, if written correctly, you can call any dependency you may need.</p>
<p>A common library chart is a reusable, and composable chart; designed to encapsulate common configurations, templates, and logic that can be shared across multiple Helm charts. The common library chart serves as building blocks or modules to compose all of your internal Kubernetes Manifests. Overall we utilize the common library chart to manage Kubernetes services as cattle vs sheep.</p>
<p>Below are some key points explaining the setup of the library chart.</p>
<p>Key Points:
Reusability: Library charts promote code reuse by encapsulating commonly used configurations, templates, and logic. This reduces duplication and ensures consistency across multiple Helm charts.</p>
<p>Composition: Library charts can be combined with other charts to build more complex applications or services. This allows you to create modular and scalable Helm charts by composing smaller, reusable components.</p>
<p>Encapsulation: Library charts abstract away complex configurations and templates behind a simple interface, making it easier to manage and maintain Helm charts. Users can interact with library charts through well-defined parameters and values. Like in our <code>README.md</code> files fields.</p>
<p>Common Library Usage:
To use the common library chart in the main application chart:</p>
<p>We declare the library chart as a dependency in the <code>Chart.yaml</code> file.
Configure any parameters exposed by the library chart in our <code>values.yaml</code> file.
Use the templates and resources provided by the common library chart in the <code>templates/all.yaml</code> file
Drilling Down Example:</p>
<pre class="lang-yaml prettyprint-override"><code># Top level Chart.yaml
dependencies:
- name: common
  version: 1.0.0
  repository: file://lib/common

# Top level values.yaml files referring to common chart variables
configmap:
  config:
    enabled: true
    data:
      testing: &quot;hay&quot;

controller:
  enabled: true

image:
  repository: nginx
  pullPolicy: IfNotPresent
  # Overrides the image tag whose default is the chart appVersion.
  tag: &quot;latest&quot;
...

# Top level templates/all.yaml call the all() function inside common library chart.
{{- include &quot;common.all&quot; . }}

# Definition of the function all() inside lib/common/templates/_all.tpl
{{/*
Main entrypoint for the common library chart. It will render all underlying templates based on the provided values.
*/}}
{{- define &quot;common.all&quot; -}}
  {{- /* Merge the local chart values and the common chart defaults */ -}}
  {{- include &quot;common.values.setup&quot; . }}

  {{ include &quot;common.configmap&quot; . | nindent 0 }}

  {{- if .Values.controller.enabled }}
    {{- if eq .Values.controller.type &quot;deployment&quot; }}
      {{- include &quot;common.deployment&quot; . | nindent 0 }}
    {{ else if eq .Values.controller.type &quot;daemonset&quot; }}
      {{- include &quot;common.daemonset&quot; . | nindent 0 }}
    {{ else if eq .Values.controller.type &quot;statefulset&quot;  }}
      {{- include &quot;common.statefulset&quot; . | nindent 0 }}
    {{ else }}
      {{- fail (printf &quot;Not a valid controller.type (%s)&quot; .Values.controller.type) }}
    {{- end -}}
  {{- end -}}

  {{ include &quot;common.cronjob&quot; . | nindent 0 }}

  {{ include &quot;common.classes.hpa&quot; . | nindent 0 }}

  {{ include &quot;common.ingress&quot; .  | nindent 0 }}

  {{ include &quot;common.job&quot; . | nindent 0 }}

  {{ include &quot;common.kongingress&quot; . | nindent 0 }}

  {{ include &quot;common.kongplugin&quot; . | nindent 0 }}

  {{ include &quot;common.poddisruptionbudget&quot; .  | nindent 0 }}

  {{- include &quot;common.pvc&quot; . }}

  {{- if .Values.secret -}}
    {{ include &quot;common.secret&quot; .  | nindent 0 }}
  {{- end -}}

  {{ include &quot;common.service&quot; . | nindent 0 }}

  {{- if .Values.serviceAccount.create -}}
    {{- include &quot;common.serviceAccount&quot; . }}
  {{- end -}}

  {{ include &quot;common.crb&quot; . | nindent 0 }}

  {{ include &quot;common.secrets&quot; . | nindent 0 }}

{{- end -}}
</code></pre>

CC BY-SA 4.0
2024-04-23T15:30:17.653Z
Cool, I'll look at this. Thanks!
Chris F
CC BY-SA 4.0
2024-04-23T15:10:30.727Z
2024-04-23T19:11:27.363Z
2024-04-23T19:11:27.363Z
audgeTurco
<p>Subcharts are the way to go.</p>
<p>I've done a very similar thing as follows:</p>
<ul>
<li>Create one or more base charts which cover microservices that have similar configuration (e.g. one for backend microservices, another for frontend servers).</li>
<li>Create an overall chart for your application. This may be a bare bones chart without any resource configurations, but just a <code>Chart.yaml</code> and <code>values.yaml</code>. Or, you may also include some resources specific to your application overall and not a particular microservice (e.g. networkpolicy or ingress).</li>
</ul>
<p>You could put everything in one git repo e.g.:</p>
<pre><code>my-deployment-repo/
|- base-microservice/
   |- templates/
      |- deployment.yml
      |- service.yml
   |- Chart.yaml
   |- values.yaml
|- base-ui/
   |- templates/
      |- deployment.yml
      |- service.yml
   |- Chart.yaml
   |- values.yaml
|- myapp/
   |- Chart.yaml
   |- values.yaml
</code></pre>
<p>Then, your overall application chart (here <code>myapp</code>) can include the base charts multiple times as a dependency in its <code>Chart.yaml</code>. If you are putting all these charts in one git repo, you can use relative paths to point to them. E.g.</p>
<pre><code># Chart.yaml
dependencies:
  - alias: my-microservice-1
    name: base-microservice
    version: &quot;0.1.0&quot;
    repository: file://../base-microservice
  - alias: my-microservice-2
    name: base-microservice
    version: &quot;0.1.0&quot;
    repository: file://../base-microservice
  - alias: my-ui-1
    name: base-ui
    version: &quot;0.1.0&quot;
    repository: file://../base-ui
  - alias: my-ui-2
    name: base-ui
    version: &quot;0.1.0&quot;
    repository: file://../base-ui
</code></pre>
<p>The key thing here is <code>alias</code>. This <a href="https://helm.sh/docs/topics/charts/#alias-field-in-dependencies" rel="noreferrer">allows charts to be depended on multiple times</a>. It sets the name of the chart to the alias, so within the subcharts you can use <code>{{.Chart.Name}}</code>.</p>
<p>Finally, in <code>myapp</code>'s <code>values.yaml</code>, you can <a href="https://helm.sh/docs/topics/charts/#scope-dependencies-and-values" rel="noreferrer">pass different values to the subcharts</a> under their alias key, e.g. if you have used <code>{{.Values.image}}</code> in base-microservice, you can do the following in <code>myapp</code>'s <code>values.yaml</code>:</p>
<pre><code># values.yaml
my-microservice-1:
  image: foo

my-microservice-2:
  image: bar
</code></pre>
<p>When it comes to deploying <code>myapp</code>, run the following commands from within the <code>myapp</code> directory:</p>
<pre><code>helm dependency update
helm install myapp .
</code></pre>
<p>You must always run <code>helm dependency update</code> before installing/upgrading a chart if any of the subcharts have changed.</p>
<p>I recommend git ignoring .tgz files, so you don't end up with .tgz files created by <code>helm dependency update</code> getting committed to your repo.</p>

CC BY-SA 4.0
2022-10-14T17:56:56.863Z
I love this approach but sadly there are Helm bugs that prevent it from working right. You cannot reference the aliased names in the parent chart in various contexts.
(https://github.com/helm/helm/issues/7729, https://github.com/helm/helm/issues/2993, https://github.com/helm/helm/issues/7093,  https://github.com/helm/helm/issues/3457)
TrogDor
CC BY-SA 4.0
2023-01-24T17:39:32.797Z
I'm FINALLY getting back into this project (LOL) so I'll try this approach. Thanks!
Chris F
CC BY-SA 4.0
2023-01-24T18:23:29.340Z
So in the `myapp/templates/deployment.yaml` for example, how would you reference the `image.name` for each alias for `my-microservice-1`? Will I just do a `range` here, and it'll install ALL the `my-microservice-*`?
Chris F
CC BY-SA 4.0
2023-01-24T18:49:36.027Z
Ignore my last comment. I should mess with the `base-microservice` templates. Should I even have `myapp/templates/` ?
Chris F
CC BY-SA 4.0
2023-01-25T22:36:56.677Z
So with my idea, you wouldn't have a templates folder in myapp (unless you wanted some resource for the overall app and not for every microservice). The Chart.yaml pulls in the base charts multiple times as dependencies and values.yaml configures them.
emorris
CC BY-SA 4.0
2023-01-25T22:41:23.820Z
Re-reading your question again, you may not even need this. If you just need to use a chart multiple times but for differing microservices (and don't want to deploy them all at once), then just create one chart and do exactly that. Install it multiple times with different names and values files, nothing to stop charts being installed multiple times.
emorris
CC BY-SA 4.0
2023-02-01T20:57:07.237Z
Yes, I may want to deploy multiple microservices all at once, or at least in the same deployment cycle, and deploy them concurrently.
Chris F
CC BY-SA 4.0
2023-08-11T20:23:06.710Z
One of the nicest thing about this is the separation of concerns it allows. Individual service pipelines no longer need to know about the release environments; they only have to run their particular repo's operations (lint, build, test...) and deploy a minimalist chart to an OCI repo for the "umbrella" chart / pipeline to pick up later on. This is where you want environments and "top level" resources (secret manager, networking rules, reverse proxy, 3rd party subcharts...) to be defined. Required env config is then passed to subcharts as values. Efficient, clean and much easier to maintain.
Crono
CC BY-SA 4.0
2024-01-08T15:00:55.390Z
Can anyone please share a git repo link if manage to get it working? Thanks
Muhammad Hannan
CC BY-SA 4.0
2022-03-08T15:27:40.307Z
2022-03-08T15:27:40.307Z
emorris
<p>This is a follow up question to my post <a href="https://devops.stackexchange.com/questions/13298/parameterized-kubernetes-manifest-files">Parameterized Kubernetes manifest files?</a>.</p>
<p>I understand more about Helm now, after lots of reading, including the Learn Helm book (which I recommend). I still have this understanding that each microservice will have its OWN Helm chart? This defeats the purpose of what I wanted, where I just have ONE helm chart, and every time I want to use it, I just update the <code>Chart.yml</code> and <code>values.yml</code> files for each microservice, everything else is the same. For example, the microservice name, versions, and repo will change of course per microservice. Seems like I'm looking for a &quot;template&quot; for <code>Chart.yaml</code> and <code>values.yaml</code>. Is this possible to do? I don't know if it's recommended or not (I may not care).</p>
<p>I come from a CloudFoormation background, where I just have ONE parameterized CloudFormation template, and I just pass it parameters pertinent to each microservice.</p>
<p><strong>UPDATE:</strong> I'm aware of Helm library charts, and I don't think they can provide the functionality I want?</p>

CC BY-SA 4.0
2021-02-17T20:18:36.077Z
What problem are you trying to solve? Are there too many lines of yaml? You _can_ do as do describe, but it is not a good practice.
Jonas
CC BY-SA 4.0
2021-02-17T20:46:05.567Z
Hi again @Jonas. ALL my microservices (will) use the SAME set of charts. They will literally only differ in name, version, ingress path. If I had one Helm chart per microservice, which I think is the recommended way to do it, I will just literally copy/paste the chart files from one microservice to the other, all `templates` files will be the SAME, and I'll make changes in `Chart.yaml` (name, version, etc.) and `values.yaml` (image, ingress, etc.). So if I update a `templates` file in one, I'll have to do it in all. What's the point of doing all this?
Chris F
CC BY-SA 4.0
2021-02-17T21:09:40.923Z
It sounds like all applications is managed centrally in your org? Usually, different teams manage their own apps.
Jonas
CC BY-SA 4.0
2021-02-17T21:10:54.723Z
Yeah, I manage ALL of them, or at least their deployments. LOL.
Chris F
<kubernetes><helm><kubernetes-helm>
Use one Helm chart for ALL microservices?
Chris F
# Use one Helm chart for ALL microservices?

(Asked by: username_0 on 2021-02-17)

This is a follow up question to my post [Parameterized Kubernetes manifest files?](https://devops.stackexchange.com/questions/13298/parameterized-kubernetes-manifest-files).

I understand more about Helm now, after lots of reading, including the Learn Helm book (which I recommend). I still have this understanding that each microservice will have its OWN Helm chart? This defeats the purpose of what I wanted, where I just have ONE helm chart, and every time I want to use it, I just update the `Chart.yml` and `values.yml` files for each microservice, everything else is the same. For example, the microservice name, versions, and repo will change of course per microservice. Seems like I'm looking for a "template" for `Chart.yaml` and `values.yaml`. Is this possible to do? I don't know if it's recommended or not (I may not care).

I come from a CloudFoormation background, where I just have ONE parameterized CloudFormation template, and I just pass it parameters pertinent to each microservice.

**UPDATE:** I'm aware of Helm library charts, and I don't think they can provide the functionality I want?

**Tags:** kubernetes, helm, kubernetes-helm

> **Comments:**
> **username_1**: What problem are you trying to solve? Are there too many lines of yaml? You _can_ do as do describe, but it is not a good practice.  
> **username_0**: Hi again @username_1. ALL my microservices (will) use the SAME set of charts. They will literally only differ in name, version, ingress path. If I had one Helm chart per microservice, which I think is the recommended way to do it, I will just literally copy/paste the chart files from one microservice to the other, all `templates` files will be the SAME, and I'll make changes in `Chart.yaml` (name, version, etc.) and `values.yaml` (image, ingress, etc.). So if I update a `templates` file in one, I'll have to do it in all. What's the point of doing all this?  
> **username_1**: It sounds like all applications is managed centrally in your org? Usually, different teams manage their own apps.  
> **username_0**: Yeah, I manage ALL of them, or at least their deployments. LOL.  

---

## 4 answers

### Answer by username_6 on 2022-03-08. Score: 19 | Accepted answer

Subcharts are the way to go.
I've done a very similar thing as follows:

Create one or more base charts which cover microservices that have similar configuration (e.g. one for backend microservices, another for frontend servers).
Create an overall chart for your application. This may be a bare bones chart without any resource configurations, but just a Chart.yaml and values.yaml. Or, you may also include some resources specific to your application overall and not a particular microservice (e.g. networkpolicy or ingress).

You could put everything in one git repo e.g.:
my-deployment-repo/
|- base-microservice/
   |- templates/
      |- deployment.yml
      |- service.yml
   |- Chart.yaml
   |- values.yaml
|- base-ui/
   |- templates/
      |- deployment.yml
      |- service.yml
   |- Chart.yaml
   |- values.yaml
|- myapp/
   |- Chart.yaml
   |- values.yaml

Then, your overall application chart (here myapp) can include the base charts multiple times as a dependency in its Chart.yaml. If you are putting all these charts in one git repo, you can use relative paths to point to them. E.g.
# Chart.yaml
dependencies:
  - alias: my-microservice-1
    name: base-microservice
    version: "0.1.0"
    repository: file://../base-microservice
  - alias: my-microservice-2
    name: base-microservice
    version: "0.1.0"
    repository: file://../base-microservice
  - alias: my-ui-1
    name: base-ui
    version: "0.1.0"
    repository: file://../base-ui
  - alias: my-ui-2
    name: base-ui
    version: "0.1.0"
    repository: file://../base-ui

The key thing here is alias. This allows charts to be depended on multiple times. It sets the name of the chart to the alias, so within the subcharts you can use {{.Chart.Name}}.
Finally, in myapp's values.yaml, you can pass different values to the subcharts under their alias key, e.g. if you have used {{.Values.image}} in base-microservice, you can do the following in myapp's values.yaml:
# values.yaml
my-microservice-1:
  image: foo

my-microservice-2:
  image: bar

When it comes to deploying myapp, run the following commands from within the myapp directory:
helm dependency update
helm install myapp .

You must always run helm dependency update before installing/upgrading a chart if any of the subcharts have changed.
I recommend git ignoring .tgz files, so you don't end up with .tgz files created by helm dependency update getting committed to your repo.

> **Comments:**
> **username_7**: I love this approach but sadly there are Helm bugs that prevent it from working right. You cannot reference the aliased names in the parent chart in various contexts. (https://github.com/helm/helm/issues/7729, https://github.com/helm/helm/issues/2993, https://github.com/helm/helm/issues/7093,  https://github.com/helm/helm/issues/3457)  
> **username_0**: I'm FINALLY getting back into this project (LOL) so I'll try this approach. Thanks!  
> **username_0**: So in the `myapp/templates/deployment.yaml` for example, how would you reference the `image.name` for each alias for `my-microservice-1`? Will I just do a `range` here, and it'll install ALL the `my-microservice-*`?  
> **username_0**: Ignore my last comment. I should mess with the `base-microservice` templates. Should I even have `myapp/templates/` ?  
> **username_6**: So with my idea, you wouldn't have a templates folder in myapp (unless you wanted some resource for the overall app and not for every microservice). The Chart.yaml pulls in the base charts multiple times as dependencies and values.yaml configures them.  
> **username_6**: Re-reading your question again, you may not even need this. If you just need to use a chart multiple times but for differing microservices (and don't want to deploy them all at once), then just create one chart and do exactly that. Install it multiple times with different names and values files, nothing to stop charts being installed multiple times.  
> **username_0**: Yes, I may want to deploy multiple microservices all at once, or at least in the same deployment cycle, and deploy them concurrently.  
> **username_8**: One of the nicest thing about this is the separation of concerns it allows. Individual service pipelines no longer need to know about the release environments; they only have to run their particular repo's operations (lint, build, test...) and deploy a minimalist chart to an OCI repo for the "umbrella" chart / pipeline to pick up later on. This is where you want environments and "top level" resources (secret manager, networking rules, reverse proxy, 3rd party subcharts...) to be defined. Required env config is then passed to subcharts as values. Efficient, clean and much easier to maintain.  
> **username_9**: Can anyone please share a git repo link if manage to get it working? Thanks  

---

### Answer by username_2 on 2021-02-17. Score: 8

Generally, a Helm chart would cover all your microservices - ideally, you should be able to deploy whole application in one chart. It may get a little messy if you include external 3rd party dependencies, where you would need to handle dependent charts, but I assume this is out of scope of your question.
More so, if your microservices are very similar you could write for loops, such as:
{{- range $index, $service := .Values.myservices}}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-{{ $service.name }}
# --- etc ---
{{- end }}

Now, where to put your chart - in most cases a preferred way is to have a separate repo for all Ops CD files, including Helm chart - so this is where Helm chart would live. This is not to be mixed with CI files, such as Dockerfile - those should live alongside microservice repositories themselves.

> **Comments:**
> **username_0**: Y, i'm leaning toward having my Helm charts in our separate Ops Git repo (we do this for ECS now). I'll explore this idea, thanks!  
> **username_3**: All micro services in one chart? So you just have 1 release for all your services? I don't think that's great. Your helm rollback could affect everything, even only if one thing is broken. I know it sounds like it should be fine, but I have seen case where, for example, the CRD API changes behind the scenes, so the rollback fails, and you need to update the CRD API in your yaml in order to proceed. Having everything in 1 release can lead to a mess  
> **username_2**: Yes, single release for all services. In a distributed system you trade liveness for safety and you can never get 100% liveness guarantee - so no matter what you do you will find an example where liveness fails. Now, with a single release you always move from one well tested state to another - which is a strict requirement in many cases. Finally, for mission critical applications, test your rollback plan before the deployment - this will help avoid issues like the one you mentioned.  

---

### Answer by username_4 on 2021-02-17. Score: 3

I believe what you're asking is: "Is there any way to create just one helm chart that can be used for all microservices in my application?". If so, then you can just use the values.yaml file to store all the values for your templates. This is not considered good practice, considering your template file needs to hold the information for each of your microservice deployments (and thus will become really difficult to manage), but it is possible.
One example: say you have two microservices, and you need one Helm chart that will create the template for both microservices. Generally, you would create separate templates for each service under the templates folder, and deploy each Helm chart for each service individually, but instead you could create multiple deployments in one template yaml file, like
# For service 1
apiVersion: apps/v1
type: Deployment
etc., etc... (stick in all values.yaml file values here for service 1)
---
# For service 2
apiVersion: apps/v1
type: Deployment
etc., etc... (stick in all values.yaml file values here for service 2)

In your values.yaml file, you would then just place in the values for each of your services, like
# Service 1 Keys/Values
foo: value
# Service 2 Keys/Values
bar: otherValue

So to answer your question, you can package all your services into one individual Helm chart using the above method, and Kubernetes will run each service as their own ReplicaSet as expected. However, when you have many services to manage, it can be tricky to manage the template YAML files and the values.yaml files when you put in values for all your services in one file, and so it's most likely not a good practice to do this.
This is just my understanding of Helm so far, as I'm still learning Helm myself. As such, I'm not 100% sure if this can be done, so you might want to double check with another person that this answer is actually correct.
EDIT: To summarize: like I mentioned above, in theory, it is possible to use one Helm chart per service. But in practice, it will be extremely messy later on to manage the values.yaml and the templates in the templates folder. So the answer would be, "Yes in theory, but not recommended at all".

> **Comments:**
> **username_0**: yes, this is exactly what I want. But what will be the directory structure to accomplish this? Each microservice is in it's own Git repo. So where will be the "generic" Helm charts be? Where will the microservice-specific `values.yaml` files be? How do I consolidate the two directory files? Remember, I want to be able to do a `helm install ...` from some diretory that has the complete chart.  
> **username_4**: @ChrisF You would only need to put the regular Helm directory structure (Chart.yaml, values.yaml, and the templates folder) in one service. At that point, you would need to build your Docker images/push them to the registry first. Then, because K8s references only images stored in the registry, when you install your Helm chart using the files in just one microservice, K8s can pull the container image for all of your services and run it as expected. So when you run helm install from one service, it will work, as Kubernetes doesn't reference the directory, it references the container image.  
> **username_0**: I think this is a bad way to do it.  
> **username_4**: Yes, like I said earlier this isn't a good way to go about it all, it makes more sense to just package each service using Helm separately, as this method is extremely messy. But, this shows it's possible. This is not the best way to do it though.  
> **username_4**: My answer highlighted the way to do it, but if you want a much cleaner way to manage each service, you would need to create individual Chart.yaml, values.yaml, and a templates folder for each app. While it might be some additional work in the beginning (have to replicate the same thing across many services), it will be a huge timesaver later on.  
> **username_0**: Then the correct answer is "No, you need a separate Helm chart per microservice."  
> **username_4**: @ChrisF Yes, you're right, unless you want to deal with a messy Helm structure later on. I'll update that in my answer.  

---

### Answer by username_5 on 2024-04-23. Score: 0

I have worked multiple jobs where I wrote just one helm chart as a base for all services. Within that, if written correctly, you can call any dependency you may need.
A common library chart is a reusable, and composable chart; designed to encapsulate common configurations, templates, and logic that can be shared across multiple Helm charts. The common library chart serves as building blocks or modules to compose all of your internal Kubernetes Manifests. Overall we utilize the common library chart to manage Kubernetes services as cattle vs sheep.
Below are some key points explaining the setup of the library chart.
Key Points:
Reusability: Library charts promote code reuse by encapsulating commonly used configurations, templates, and logic. This reduces duplication and ensures consistency across multiple Helm charts.
Composition: Library charts can be combined with other charts to build more complex applications or services. This allows you to create modular and scalable Helm charts by composing smaller, reusable components.
Encapsulation: Library charts abstract away complex configurations and templates behind a simple interface, making it easier to manage and maintain Helm charts. Users can interact with library charts through well-defined parameters and values. Like in our README.md files fields.
Common Library Usage:
To use the common library chart in the main application chart:
We declare the library chart as a dependency in the Chart.yaml file.
Configure any parameters exposed by the library chart in our values.yaml file.
Use the templates and resources provided by the common library chart in the templates/all.yaml file
Drilling Down Example:
# Top level Chart.yaml
dependencies:
- name: common
  version: 1.0.0
  repository: file://lib/common

# Top level values.yaml files referring to common chart variables
configmap:
  config:
    enabled: true
    data:
      testing: "hay"

controller:
  enabled: true

image:
  repository: nginx
  pullPolicy: IfNotPresent
  # Overrides the image tag whose default is the chart appVersion.
  tag: "latest"
...

# Top level templates/all.yaml call the all() function inside common library chart.
{{- include "common.all" . }}

# Definition of the function all() inside lib/common/templates/_all.tpl
{{/*
Main entrypoint for the common library chart. It will render all underlying templates based on the provided values.
*/}}
{{- define "common.all" -}}
  {{- /* Merge the local chart values and the common chart defaults */ -}}
  {{- include "common.values.setup" . }}

  {{ include "common.configmap" . | nindent 0 }}

  {{- if .Values.controller.enabled }}
    {{- if eq .Values.controller.type "deployment" }}
      {{- include "common.deployment" . | nindent 0 }}
    {{ else if eq .Values.controller.type "daemonset" }}
      {{- include "common.daemonset" . | nindent 0 }}
    {{ else if eq .Values.controller.type "statefulset"  }}
      {{- include "common.statefulset" . | nindent 0 }}
    {{ else }}
      {{- fail (printf "Not a valid controller.type (%s)" .Values.controller.type) }}
    {{- end -}}
  {{- end -}}

  {{ include "common.cronjob" . | nindent 0 }}

  {{ include "common.classes.hpa" . | nindent 0 }}

  {{ include "common.ingress" .  | nindent 0 }}

  {{ include "common.job" . | nindent 0 }}

  {{ include "common.kongingress" . | nindent 0 }}

  {{ include "common.kongplugin" . | nindent 0 }}

  {{ include "common.poddisruptionbudget" .  | nindent 0 }}

  {{- include "common.pvc" . }}

  {{- if .Values.secret -}}
    {{ include "common.secret" .  | nindent 0 }}
  {{- end -}}

  {{ include "common.service" . | nindent 0 }}

  {{- if .Values.serviceAccount.create -}}
    {{- include "common.serviceAccount" . }}
  {{- end -}}

  {{ include "common.crb" . | nindent 0 }}

  {{ include "common.secrets" . | nindent 0 }}

{{- end -}}

> **Comments:**
> **username_0**: Cool, I'll look at this. Thanks!  

---

