<?xml version="1.0" encoding="utf-8" standalone="yes"?><?xml-stylesheet href="/feed_style.xsl" type="text/xsl"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="https://www.rssboard.org/media-rss">
  <channel>
    <title>Posts on Kord&#39;s dev blog</title>
    <link>https://blog.4kord.com/posts/</link>
    <description>Recent content in Posts on Kord&#39;s dev blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <copyright>Kord - [Creative Commons Attribution 4.0 International License](https://creativecommons.org/licenses/by/4.0/).</copyright>
    <lastBuildDate>Sun, 12 May 2024 10:00:00 +0000</lastBuildDate><atom:link href="https://blog.4kord.com/posts/index.xml" rel="self" type="application/rss+xml" /><icon>https://blog.4kord.com/logo.svg</icon>
    
    
    <item>
      <title>Creating a simple universal deployment helm chart</title>
      <link>https://blog.4kord.com/posts/creating_a_simple_universal_deployment_helm_chart/</link>
      <pubDate>Sun, 12 May 2024 10:00:00 +0000</pubDate>
      
      <guid>https://blog.4kord.com/posts/creating_a_simple_universal_deployment_helm_chart/</guid>
      <description><![CDATA[<p>Helm is a powerful package manager for Kubernetes that simplifies the deployment and management of applications. In this article, we will walk through the process of creating a simple universal deployment Helm chart that can be used to deploy applications in a Kubernetes cluster. This chart will include a deployment, service, ingress, and horizontal pod autoscaler (HPA). Additionally, we will set up a CI/CD pipeline to automate the packaging and uploading of our Helm chart.</p>
<h2 id="how-helm-works">How Helm Works</h2>
<p>Helm uses a packaging format called charts, which are collections of files that describe a related set of Kubernetes resources. A Helm chart contains:</p>
<ul>
<li><strong>Templates</strong>: These are Kubernetes manifest files that are parameterized using Go templating. They allow you to define how your resources should be created.</li>
<li><strong>Values</strong>: A <code>values.yaml</code> file that contains default configuration values for your templates.</li>
<li><strong>Chart Metadata</strong>: A <code>Chart.yaml</code> file that contains metadata about the chart, such as its name, version, and description.</li>
</ul>
<p>When you install a Helm chart, Helm renders the templates using the values provided and creates the corresponding Kubernetes resources.</p>
<h2 id="project-structure">Project Structure</h2>
<p>Before we dive into the code, let&rsquo;s outline the structure of our Helm chart:</p>
<pre tabindex="0"><code>.
├── .gitlab-ci.yml
├── README.md
└── deployment
    ├── Chart.yaml
    ├── templates
    │   ├── _helpers.tpl
    │   ├── deployment.yaml
    │   ├── hpa.yaml
    │   ├── ingress.yaml
    │   └── service.yaml
    └── values.yaml
</code></pre><h4 id="explanation-of-each-file">Explanation of Each File</h4>
<ul>
<li>
<p><strong><code>.gitlab-ci.yml</code></strong>: This file contains the CI/CD pipeline configuration for GitLab. It automates the process of packaging and uploading the Helm chart to a Helm repository.</p>
</li>
<li>
<p><strong><code>README.md</code></strong>: This file provides documentation for the Helm chart, including instructions on how to use it.</p>
</li>
<li>
<p><strong><code>Chart.yaml</code></strong>: This file contains metadata about the Helm chart, such as its name, version, and description.</p>
</li>
<li>
<p><strong><code>values.yaml</code></strong>: This file defines default configuration values for the chart. Users can override these values during installation.</p>
</li>
<li>
<p><strong><code>templates/</code></strong>: This directory contains the Kubernetes resource templates that Helm will render.</p>
<ul>
<li>
<p><strong><code>_helpers.tpl</code></strong>: This file contains helper functions that can be reused across different templates. It helps to avoid code duplication and makes the templates cleaner and more maintainable.</p>
</li>
<li>
<p><strong><code>deployment.yaml</code></strong>: This template defines a Kubernetes Deployment resource. It specifies how many replicas of the application to run, the container image to use, and the ports to expose.</p>
</li>
<li>
<p><strong><code>service.yaml</code></strong>: This template defines a Kubernetes Service resource. It specifies how to expose the application to other services or external traffic.</p>
</li>
<li>
<p><strong><code>ingress.yaml</code></strong>: This template defines an Ingress resource, which manages external access to the services in a cluster, typically HTTP. It allows you to define rules for routing traffic to different services based on the request&rsquo;s host and path.</p>
</li>
<li>
<p><strong><code>hpa.yaml</code></strong>: This template defines a Horizontal Pod Autoscaler resource, which automatically scales the number of pods in a deployment based on observed CPU utilization or other select metrics.</p>
</li>
</ul>
</li>
</ul>
<h3 id="1-create-the-chart">1. Create the Chart</h3>
<p>To create the Helm chart, use the Helm CLI:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>helm create deployment
</span></span></code></pre></div><p>This command initializes a new Helm chart named <code>deployment</code>.</p>
<h3 id="2-chartyaml">2. Chart.yaml</h3>
<p>The <code>Chart.yaml</code> file contains metadata about the chart. Update it as follows:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">apiVersion</span>: <span style="color:#ae81ff">v2</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">name</span>: <span style="color:#ae81ff">deployment</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">description</span>: <span style="color:#ae81ff">The Universal Deployment Helm Chart</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">type</span>: <span style="color:#ae81ff">application</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">version</span>: <span style="color:#ae81ff">1.0.0</span>
</span></span></code></pre></div><p>This file defines the chart&rsquo;s name, description, type, and version.</p>
<h3 id="3-valuesyaml">3. values.yaml</h3>
<p>The <code>values.yaml</code> file defines default configuration values for the chart:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#75715e"># Default values for a &#34;deployment&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">replicaCount</span>: <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">deploymentStrategy</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">type</span>: <span style="color:#ae81ff">RollingUpdate</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">rollingUpdate</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">maxUnavailable</span>: <span style="color:#ae81ff">25</span><span style="color:#ae81ff">%</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">maxSurge</span>: <span style="color:#ae81ff">25</span><span style="color:#ae81ff">%</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">image</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">repository</span>: <span style="color:#e6db74">&#34;nginx&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">tag</span>: <span style="color:#e6db74">&#34;latest&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">imagePullPolicy</span>: <span style="color:#ae81ff">IfNotPresent</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">imagePullSecrets</span>: []
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">service</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">enabled</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">port</span>: <span style="color:#ae81ff">80</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">targetPort</span>: <span style="color:#ae81ff">80</span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e"># externalTrafficPolicy: Local</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">type</span>: <span style="color:#ae81ff">ClusterIP</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">ingress</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">enabled</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">className</span>: <span style="color:#e6db74">&#34;nginx&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">annotations</span>: {}
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># nginx.ingress.kubernetes.io/force-ssl-redirect: &#34;true&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># nginx.ingress.kubernetes.io/ssl-passthrough: &#34;true&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">hosts</span>: []
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">tls</span>: []
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">#  - secretName: chart-example-tls</span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">#    hosts:</span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">#      - chart-example.local</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">env</span>: {}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">autoscaling</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">enabled</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">minReplicas</span>: <span style="color:#ae81ff">2</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">maxReplicas</span>: <span style="color:#ae81ff">6</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">targetCPUUtilizationPercentage</span>: <span style="color:#ae81ff">75</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">targetMemoryUtilizationPercentage</span>: <span style="color:#ae81ff">90</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">resources</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">limits</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">cpu</span>: <span style="color:#ae81ff">100m</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">memory</span>: <span style="color:#ae81ff">128Mi</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">requests</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">cpu</span>: <span style="color:#ae81ff">50m</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">memory</span>: <span style="color:#ae81ff">64Mi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">livenessProbe</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">enabled</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">initialDelaySeconds</span>: <span style="color:#ae81ff">10</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">periodSeconds</span>: <span style="color:#ae81ff">10</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">timeoutSeconds</span>: <span style="color:#ae81ff">5</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">successThreshold</span>: <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">failureThreshold</span>: <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">probeType</span>: <span style="color:#ae81ff">httpGet</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">scheme</span>: <span style="color:#ae81ff">HTTP</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">path</span>: <span style="color:#ae81ff">/healthz</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">port</span>: <span style="color:#ae81ff">http</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">readinessProbe</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">enabled</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">initialDelaySeconds</span>: <span style="color:#ae81ff">5</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">periodSeconds</span>: <span style="color:#ae81ff">10</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">timeoutSeconds</span>: <span style="color:#ae81ff">5</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">successThreshold</span>: <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">failureThreshold</span>: <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">probeType</span>: <span style="color:#ae81ff">httpGet</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">scheme</span>: <span style="color:#ae81ff">HTTP</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">path</span>: <span style="color:#ae81ff">/healthz</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">port</span>: <span style="color:#ae81ff">http</span>
</span></span></code></pre></div><p>This file allows users to customize the deployment by overriding default values.</p>
<h3 id="4-_helperstpl">4. _helpers.tpl</h3>
<p>The <code>_helpers.tpl</code> file contains reusable template functions for generating consistent names and labels across the chart:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span>{{<span style="color:#ae81ff">/*</span>
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">Define the standardized name of this helm chart and its objects</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">*/}}</span>
</span></span><span style="display:flex;"><span>{{- <span style="color:#ae81ff">define &#34;name&#34; -}}</span>
</span></span><span style="display:flex;"><span>{{- <span style="color:#ae81ff">.Release.Name | trunc 63 | trimSuffix &#34;-&#34; -}}</span>
</span></span><span style="display:flex;"><span>{{- <span style="color:#ae81ff">end -}}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>{{<span style="color:#ae81ff">/*</span>
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">Define the standardized namespace</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">*/}}</span>
</span></span><span style="display:flex;"><span>{{- <span style="color:#ae81ff">define &#34;namespace&#34; -}}</span>
</span></span><span style="display:flex;"><span>{{- <span style="color:#ae81ff">.Release.Namespace | trunc 63 | trimSuffix &#34;-&#34; -}}</span>
</span></span><span style="display:flex;"><span>{{- <span style="color:#ae81ff">end -}}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>{{<span style="color:#ae81ff">/*</span>
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">Generate basic labels for pods/services/etc</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">Sample Usage</span>: {{- <span style="color:#ae81ff">include &#34;labels&#34; . | indent 2 }}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">*/}}</span>
</span></span><span style="display:flex;"><span>{{- <span style="color:#ae81ff">define &#34;labels&#34; }}</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">labels</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">app.kubernetes.io/name</span>: {{ <span style="color:#ae81ff">.Release.Name | trunc 63 | trimSuffix &#34;-&#34; | quote }}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">app.kubernetes.io/instance</span>: {{ <span style="color:#ae81ff">.Release.Name | trunc 63 | trimSuffix &#34;-&#34; | quote }}</span>
</span></span><span style="display:flex;"><span>  {{- <span style="color:#ae81ff">if .Chart.AppVersion }}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">app.kubernetes.io/version</span>: {{ <span style="color:#ae81ff">.Chart.AppVersion | replace &#34;+&#34; &#34;_&#34; | trunc 63 | trimSuffix &#34;-&#34; | quote }}</span>
</span></span><span style="display:flex;"><span>  {{- <span style="color:#ae81ff">end }}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">app.kubernetes.io/created-by</span>: <span style="color:#e6db74">&#34;alexey@4kord.com&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">app.kubernetes.io/managed-by</span>: <span style="color:#e6db74">&#34;helm&#34;</span>
</span></span><span style="display:flex;"><span>{{- <span style="color:#ae81ff">end }}</span>
</span></span></code></pre></div><p>These functions help maintain consistency and reduce duplication in the templates.</p>
<h3 id="5-deployment-template">5. Deployment Template</h3>
<p>Create the deployment template in <code>templates/deployment.yaml</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">apiVersion</span>: <span style="color:#ae81ff">apps/v1</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">kind</span>: <span style="color:#ae81ff">Deployment</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">metadata</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">name</span>: {{ <span style="color:#ae81ff">include &#34;name&#34; . }}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">namespace</span>: {{ <span style="color:#ae81ff">include &#34;namespace&#34; . }}</span>
</span></span><span style="display:flex;"><span>  {{- <span style="color:#ae81ff">include &#34;labels&#34; . | indent 2 }}</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">spec</span>:
</span></span><span style="display:flex;"><span>  {{- <span style="color:#ae81ff">if not .Values.autoscaling.enabled }}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">replicas</span>: {{ <span style="color:#ae81ff">required &#34;Specify replicaCount&#34; .Values.replicaCount }}</span>
</span></span><span style="display:flex;"><span>  {{- <span style="color:#ae81ff">end }}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">strategy</span>:
</span></span><span style="display:flex;"><span>    {{- <span style="color:#ae81ff">with .Values.deploymentStrategy }}</span>
</span></span><span style="display:flex;"><span>    {{- <span style="color:#ae81ff">toYaml . | nindent 4 }}</span>
</span></span><span style="display:flex;"><span>    {{- <span style="color:#ae81ff">end }}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">selector</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">matchLabels</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">app.kubernetes.io/name</span>: {{ <span style="color:#ae81ff">.Release.Name }}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">template</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">metadata</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">labels</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">app.kubernetes.io/name</span>: {{ <span style="color:#ae81ff">.Release.Name }}</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">spec</span>:
</span></span><span style="display:flex;"><span>      {{- <span style="color:#ae81ff">with .Values.image.imagePullSecrets }}</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">imagePullSecrets</span>:
</span></span><span style="display:flex;"><span>        {{- <span style="color:#ae81ff">toYaml . | nindent 8 }}</span>
</span></span><span style="display:flex;"><span>      {{- <span style="color:#ae81ff">end }}</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">containers</span>:
</span></span><span style="display:flex;"><span>        - <span style="color:#f92672">name</span>: {{ <span style="color:#ae81ff">.Chart.Name }}</span>
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">image</span>: <span style="color:#e6db74">&#34;{{ .Values.image.repository }}:{{ .Values.image.tag }}&#34;</span>
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">imagePullPolicy</span>: {{ <span style="color:#ae81ff">.Values.image.imagePullPolicy }}</span>
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">ports</span>:
</span></span><span style="display:flex;"><span>            - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">http</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">protocol</span>: <span style="color:#ae81ff">TCP</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">containerPort</span>: {{ <span style="color:#ae81ff">.Values.service.targetPort }}</span>
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">env</span>:
</span></span><span style="display:flex;"><span>            <span style="color:#75715e"># Default env variables we want all containers to have</span>
</span></span><span style="display:flex;"><span>            - <span style="color:#f92672">name</span>: <span style="color:#e6db74">&#34;K8S_POD_NAME&#34;</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">valueFrom</span>:
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">fieldRef</span>:
</span></span><span style="display:flex;"><span>                  <span style="color:#f92672">fieldPath</span>: <span style="color:#ae81ff">metadata.name</span>
</span></span><span style="display:flex;"><span>            - <span style="color:#f92672">name</span>: <span style="color:#e6db74">&#34;K8S_NAMESPACE&#34;</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">valueFrom</span>:
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">fieldRef</span>:
</span></span><span style="display:flex;"><span>                  <span style="color:#f92672">fieldPath</span>: <span style="color:#ae81ff">metadata.namespace</span>
</span></span><span style="display:flex;"><span>            - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">K8S_NODE_NAME</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">valueFrom</span>:
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">fieldRef</span>:
</span></span><span style="display:flex;"><span>                  <span style="color:#f92672">fieldPath</span>: <span style="color:#ae81ff">spec.nodeName</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>            {{- <span style="color:#ae81ff">range $key, $value := .Values.env }}</span>
</span></span><span style="display:flex;"><span>            - <span style="color:#f92672">name</span>: <span style="color:#e6db74">&#34;{{ $key }}&#34;</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">value</span>: <span style="color:#e6db74">&#34;{{ $value }}&#34;</span>
</span></span><span style="display:flex;"><span>            {{- <span style="color:#ae81ff">end }}</span>
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">resources</span>:
</span></span><span style="display:flex;"><span>          {{- <span style="color:#ae81ff">with .Values.resources }}</span>
</span></span><span style="display:flex;"><span>          {{- <span style="color:#ae81ff">toYaml . | nindent 12 }}</span>
</span></span><span style="display:flex;"><span>          {{- <span style="color:#ae81ff">end }}</span>
</span></span><span style="display:flex;"><span>          {{- <span style="color:#ae81ff">if .Values.livenessProbe.enabled }}</span>
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">livenessProbe</span>:
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">initialDelaySeconds</span>: {{ <span style="color:#ae81ff">.Values.livenessProbe.initialDelaySeconds }}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">periodSeconds</span>: {{ <span style="color:#ae81ff">.Values.livenessProbe.periodSeconds }}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">timeoutSeconds</span>: {{ <span style="color:#ae81ff">.Values.livenessProbe.timeoutSeconds }}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">successThreshold</span>: {{ <span style="color:#ae81ff">.Values.livenessProbe.successThreshold }}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">failureThreshold</span>: {{ <span style="color:#ae81ff">.Values.livenessProbe.failureThreshold }}</span>
</span></span><span style="display:flex;"><span>            {{- <span style="color:#ae81ff">if eq .Values.livenessProbe.probeType &#34;httpGet&#34; }}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">httpGet</span>:
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">scheme</span>: {{ <span style="color:#ae81ff">.Values.livenessProbe.scheme }}</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">path</span>: {{ <span style="color:#ae81ff">.Values.livenessProbe.path }}</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">port</span>: {{ <span style="color:#ae81ff">.Values.livenessProbe.port }}</span>
</span></span><span style="display:flex;"><span>            {{- <span style="color:#ae81ff">else if eq .Values.livenessProbe.probeType &#34;tcpSocket&#34; }}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">tcpSocket</span>:
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">port</span>: {{ <span style="color:#ae81ff">.Values.livenessProbe.port }}</span>
</span></span><span style="display:flex;"><span>            {{- <span style="color:#ae81ff">else if eq .Values.livenessProbe.probeType &#34;exec&#34; }}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">exec</span>:
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">command</span>:
</span></span><span style="display:flex;"><span>            {{- <span style="color:#ae81ff">with .Values.livenessProbe.command }}</span>
</span></span><span style="display:flex;"><span>            {{- <span style="color:#ae81ff">toYaml . | nindent 16 }}</span>
</span></span><span style="display:flex;"><span>            {{- <span style="color:#ae81ff">end }}</span>
</span></span><span style="display:flex;"><span>            {{- <span style="color:#ae81ff">end }}</span>
</span></span><span style="display:flex;"><span>          {{- <span style="color:#ae81ff">end }}</span>
</span></span><span style="display:flex;"><span>          {{- <span style="color:#ae81ff">if .Values.readinessProbe.enabled }}</span>
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">readinessProbe</span>:
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">initialDelaySeconds</span>: {{ <span style="color:#ae81ff">.Values.readinessProbe.initialDelaySeconds }}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">periodSeconds</span>: {{ <span style="color:#ae81ff">.Values.readinessProbe.periodSeconds }}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">timeoutSeconds</span>: {{ <span style="color:#ae81ff">.Values.readinessProbe.timeoutSeconds }}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">successThreshold</span>: {{ <span style="color:#ae81ff">.Values.readinessProbe.successThreshold }}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">failureThreshold</span>: {{ <span style="color:#ae81ff">.Values.readinessProbe.failureThreshold }}</span>
</span></span><span style="display:flex;"><span>            {{- <span style="color:#ae81ff">if eq .Values.readinessProbe.probeType &#34;httpGet&#34; }}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">httpGet</span>:
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">scheme</span>: {{ <span style="color:#ae81ff">.Values.readinessProbe.scheme }}</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">path</span>: {{ <span style="color:#ae81ff">.Values.readinessProbe.path }}</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">port</span>: {{ <span style="color:#ae81ff">.Values.readinessProbe.port }}</span>
</span></span><span style="display:flex;"><span>            {{- <span style="color:#ae81ff">else if eq .Values.readinessProbe.probeType &#34;tcpSocket&#34; }}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">tcpSocket</span>:
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">port</span>: {{ <span style="color:#ae81ff">.Values.readinessProbe.port }}</span>
</span></span><span style="display:flex;"><span>            {{- <span style="color:#ae81ff">else if eq .Values.readinessProbe.probeType &#34;exec&#34; }}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">exec</span>:
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">command</span>:
</span></span><span style="display:flex;"><span>            {{- <span style="color:#ae81ff">with .Values.readinessProbe.command }}</span>
</span></span><span style="display:flex;"><span>            {{ <span style="color:#ae81ff">toYaml . | indent 16 }}</span>
</span></span><span style="display:flex;"><span>            {{- <span style="color:#ae81ff">end -}}</span>
</span></span><span style="display:flex;"><span>          {{- <span style="color:#ae81ff">end -}}</span>
</span></span><span style="display:flex;"><span>          {{- <span style="color:#ae81ff">end }}</span>
</span></span></code></pre></div><p>This template defines a Deployment resource that manages a set of identical pods. Key components include:</p>
<ul>
<li><strong>metadata</strong>: Contains the name of the deployment, generated using the helper function for consistency.</li>
<li><strong>spec</strong>: Specifies the desired state of the deployment, including the number of replicas and the pod template.</li>
<li><strong>template</strong>: Defines the pod specification, including the container image and the ports to expose.</li>
</ul>
<h3 id="6-service-template">6. Service Template</h3>
<p>Create the service template in <code>templates/service.yaml</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span>{{- <span style="color:#ae81ff">if .Values.service.enabled -}}</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">apiVersion</span>: <span style="color:#ae81ff">v1</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">kind</span>: <span style="color:#ae81ff">Service</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">metadata</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">name</span>: {{ <span style="color:#ae81ff">include &#34;name&#34; . }}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">namespace</span>: {{ <span style="color:#ae81ff">include &#34;namespace&#34; . }}</span>
</span></span><span style="display:flex;"><span>  {{- <span style="color:#ae81ff">include &#34;labels&#34; . | nindent 2 }}</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">spec</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">selector</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">app.kubernetes.io/name</span>: {{ <span style="color:#ae81ff">include &#34;name&#34; . }}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">ports</span>:
</span></span><span style="display:flex;"><span>  - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">http</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">protocol</span>: <span style="color:#ae81ff">TCP</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">port</span>: {{ <span style="color:#ae81ff">.Values.service.port }}</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">targetPort</span>: {{ <span style="color:#ae81ff">.Values.service.targetPort }}</span>
</span></span><span style="display:flex;"><span>  {{- <span style="color:#ae81ff">if .Values.service.externalTrafficPolicy }}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">externalTrafficPolicy</span>: {{ <span style="color:#ae81ff">.Values.service.externalTrafficPolicy }}</span>
</span></span><span style="display:flex;"><span>  {{- <span style="color:#ae81ff">end }}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">type</span>: {{ <span style="color:#ae81ff">.Values.service.type }}</span>
</span></span><span style="display:flex;"><span>{{- <span style="color:#ae81ff">end }}</span>
</span></span></code></pre></div><p>This template defines a Service resource that provides a stable endpoint for accessing the application. It includes:</p>
<ul>
<li><strong>selector</strong>: Identifies the pods that the service routes traffic to.</li>
<li><strong>ports</strong>: Specifies the ports exposed by the service.</li>
<li><strong>type</strong>: Determines how the service is exposed (e.g., ClusterIP, NodePort).</li>
</ul>
<h3 id="7-ingress-template">7. Ingress Template</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span>{{- <span style="color:#ae81ff">if .Values.ingress.enabled -}}</span>
</span></span><span style="display:flex;"><span>{{- <span style="color:#ae81ff">$name := include &#34;name&#34; . -}}</span>
</span></span><span style="display:flex;"><span>{{- <span style="color:#ae81ff">$namespace := include &#34;namespace&#34; . -}}</span>
</span></span><span style="display:flex;"><span>{{- <span style="color:#ae81ff">$port := .Values.service.port -}}</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">apiVersion</span>: <span style="color:#ae81ff">networking.k8s.io/v1</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">kind</span>: <span style="color:#ae81ff">Ingress</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">metadata</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">name</span>: {{ <span style="color:#ae81ff">$name }}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">namespace</span>: {{ <span style="color:#ae81ff">$namespace }}</span>
</span></span><span style="display:flex;"><span>  {{- <span style="color:#ae81ff">include &#34;labels&#34; . | indent 2 }}</span>
</span></span><span style="display:flex;"><span>  {{- <span style="color:#ae81ff">with .Values.ingress.annotations }}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">annotations</span>:
</span></span><span style="display:flex;"><span>    {{- <span style="color:#ae81ff">toYaml . | nindent 4 }}</span>
</span></span><span style="display:flex;"><span>  {{- <span style="color:#ae81ff">end }}</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">spec</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">ingressClassName</span>: {{ <span style="color:#ae81ff">.Values.ingress.className }}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">rules</span>:
</span></span><span style="display:flex;"><span>    {{- <span style="color:#ae81ff">range .Values.ingress.hosts }}</span>
</span></span><span style="display:flex;"><span>    - <span style="color:#f92672">host</span>: {{ <span style="color:#ae81ff">.host | quote }}</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">http</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">paths</span>:
</span></span><span style="display:flex;"><span>          {{- <span style="color:#ae81ff">range .paths }}</span>
</span></span><span style="display:flex;"><span>          - <span style="color:#f92672">path</span>: {{ <span style="color:#ae81ff">.path }}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">pathType</span>: {{ <span style="color:#ae81ff">.pathType }}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">backend</span>:
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">service</span>:
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">name</span>: {{ <span style="color:#ae81ff">$name }}</span>
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">port</span>:
</span></span><span style="display:flex;"><span>                  <span style="color:#f92672">number</span>: {{ <span style="color:#ae81ff">$port }}</span>
</span></span><span style="display:flex;"><span>          {{- <span style="color:#ae81ff">end }}</span>
</span></span><span style="display:flex;"><span>    {{- <span style="color:#ae81ff">end }}</span>
</span></span><span style="display:flex;"><span>{{- <span style="color:#ae81ff">end }}</span>
</span></span></code></pre></div><p>This template defines an Ingress resource that manages external access to the services. It includes:</p>
<ul>
<li><strong>rules</strong>: Specifies how to route traffic based on the host and path.</li>
<li><strong>backend</strong>: Defines the service to which traffic should be directed.</li>
</ul>
<h3 id="8-hpa-template">8. HPA Template</h3>
<p>Next, we will create the deployment template. Create <code>templates/hpa.yaml</code> and add the following content:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span>{{- <span style="color:#ae81ff">if .Values.autoscaling.enabled }}</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">apiVersion</span>: <span style="color:#ae81ff">autoscaling/v2</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">kind</span>: <span style="color:#ae81ff">HorizontalPodAutoscaler</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">metadata</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">name</span>: {{ <span style="color:#ae81ff">template &#34;name&#34; . }}</span>
</span></span><span style="display:flex;"><span>      {{- <span style="color:#ae81ff">include &#34;labels&#34; . | indent 2 }}</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">spec</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">scaleTargetRef</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">apiVersion</span>: <span style="color:#ae81ff">apps/v1</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">kind</span>: <span style="color:#ae81ff">Deployment</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">name</span>: {{ <span style="color:#ae81ff">template &#34;name&#34; . }}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">minReplicas</span>: {{ <span style="color:#ae81ff">.Values.autoscaling.minReplicas }}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">maxReplicas</span>: {{ <span style="color:#ae81ff">.Values.autoscaling.maxReplicas }}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">metrics</span>:
</span></span><span style="display:flex;"><span>  {{- <span style="color:#ae81ff">if .Values.autoscaling.targetCPUUtilizationPercentage }}</span>
</span></span><span style="display:flex;"><span>    - <span style="color:#f92672">type</span>: <span style="color:#ae81ff">Resource</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">resource</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">name</span>: <span style="color:#ae81ff">cpu</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">target</span>:
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">type</span>: <span style="color:#ae81ff">Utilization</span>
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">averageUtilization</span>: {{ <span style="color:#ae81ff">.Values.autoscaling.targetCPUUtilizationPercentage }}</span>
</span></span><span style="display:flex;"><span>  {{- <span style="color:#ae81ff">end }}</span>
</span></span><span style="display:flex;"><span>  {{- <span style="color:#ae81ff">if .Values.autoscaling.targetMemoryUtilizationPercentage }}</span>
</span></span><span style="display:flex;"><span>    - <span style="color:#f92672">type</span>: <span style="color:#ae81ff">Resource</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">resource</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">name</span>: <span style="color:#ae81ff">memory</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">target</span>:
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">type</span>: <span style="color:#ae81ff">Utilization</span>
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">averageUtilization</span>: {{ <span style="color:#ae81ff">.Values.autoscaling.targetMemoryUtilizationPercentage }}</span>
</span></span><span style="display:flex;"><span>  {{- <span style="color:#ae81ff">end }}</span>
</span></span><span style="display:flex;"><span>{{- <span style="color:#ae81ff">end }}</span>
</span></span></code></pre></div><p>This template defines a Horizontal Pod Autoscaler (HPA) resource that automatically scales the number of pods based on CPU utilization. It includes:</p>
<ul>
<li><strong>scaleTargetRef</strong>: Specifies the deployment to scale.</li>
<li><strong>minReplicas and maxReplicas</strong>: Define the scaling limits.</li>
<li><strong>metrics</strong>: Specifies the resource metrics used for scaling.</li>
</ul>
<h3 id="9-setting-up-cicd">9. Setting up CI/CD</h3>
<p>Finally, we need to set up a CI/CD pipeline to automate the packaging and uploading of our Helm chart. Create the .gitlab-ci.yml file:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">variables</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">PIPELINE_TYPE</span>: <span style="color:#ae81ff">helm</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">workflow</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">rules</span>:
</span></span><span style="display:flex;"><span>   - <span style="color:#f92672">if</span>: <span style="color:#ae81ff">$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">stages</span>:
</span></span><span style="display:flex;"><span>  - <span style="color:#ae81ff">upload</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">upload</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">stage</span>: <span style="color:#ae81ff">upload</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">image</span>: 
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">name</span>: <span style="color:#ae81ff">alpine/helm:3.14.3</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">entrypoint</span>: [<span style="color:#e6db74">&#34;&#34;</span>]
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">variables</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">CHARTS_DIR</span>: <span style="color:#e6db74">&#34;.&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">CHANNEL</span>: <span style="color:#e6db74">&#34;stable&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">before_script</span>:
</span></span><span style="display:flex;"><span>    - <span style="color:#ae81ff">apk update</span>
</span></span><span style="display:flex;"><span>    - <span style="color:#ae81ff">apk add curl</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">script</span>:
</span></span><span style="display:flex;"><span>    - |<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">      for chart_dir in $CHARTS_DIR/*; do
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        if [ -f &#34;$chart_dir/Chart.yaml&#34; ]; then
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">          chart_name=$(cat &#34;$chart_dir/Chart.yaml&#34; | grep &#39;^name:&#39; | awk &#39;{print $2}&#39;)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">          chart_version=$(cat &#34;$chart_dir/Chart.yaml&#34; | grep &#39;^version:&#39; | awk &#39;{print $2}&#39;)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">          helm package $chart_dir -d $chart_dir/dist
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">          curl --request POST \
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">               --user gitlab-ci-token:$CI_JOB_TOKEN \
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">               --form &#34;chart=@$chart_dir/dist/$chart_name-$chart_version.tgz&#34; \
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">               &#34;${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/helm/api/${CHANNEL}/charts&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        fi
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">      done</span>
</span></span></code></pre></div><p>Explanation of .gitlab-ci.yml</p>
<ul>
<li><strong>variables</strong>: Defines environment variables for the pipeline.</li>
<li><strong>workflow</strong>: Specifies when the pipeline should run (e.g., on the default branch).</li>
<li><strong>stages</strong>: Defines the stages of the pipeline, in this case, just the upload stage.</li>
<li><strong>upload</strong>: This job packages the Helm chart and uploads it to the GitLab Helm repository.</li>
</ul>
<h2 id="conclusion">Conclusion</h2>
<p>In this article, we created a simple universal deployment Helm chart that includes essential Kubernetes resources such as deployments, services, ingress, and HPA. We also set up a CI/CD pipeline to automate the packaging and uploading of the Helm chart. This setup allows for efficient management and deployment of applications in a Kubernetes environment, streamlining the process of scaling and updating applications.</p>
<p><strong>Key Takeaways</strong></p>
<ul>
<li><strong>Helm Charts</strong>: Helm simplifies the deployment of applications on Kubernetes by using charts, which package all necessary resources and configurations.</li>
<li><strong>Modular Design</strong>: By structuring the chart with templates for deployments, services, ingress, and HPA, we can easily manage and customize our application deployments.</li>
<li><strong>CI/CD Integration</strong>: Automating the packaging and deployment process with a CI/CD pipeline ensures that the latest versions of our applications are always available and reduces the risk of human error during deployments.</li>
</ul>
]]></description>
      
        <media:thumbnail url="https://blog.4kord.com/images/Creating_A_Simple_Universal_Deployment_Helm_Chart/CICD.png" />
      
    </item>
    
    
  </channel>
</rss>
