<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Ishan Sharma</title>
    <description>The latest articles on Forem by Ishan Sharma (@ishuar).</description>
    <link>https://forem.com/ishuar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1066177%2Fde3f142b-e6f0-4cbb-84e5-afffe0f3e4b6.jpeg</url>
      <title>Forem: Ishan Sharma</title>
      <link>https://forem.com/ishuar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ishuar"/>
    <language>en</language>
    <item>
      <title>Expanding Persistent Volume for Statefulsets in Kubernetes</title>
      <dc:creator>Ishan Sharma</dc:creator>
      <pubDate>Thu, 23 Nov 2023 16:51:49 +0000</pubDate>
      <link>https://forem.com/ishuar/expanding-persistent-volume-for-statefulsets-in-kubernetes-4886</link>
      <guid>https://forem.com/ishuar/expanding-persistent-volume-for-statefulsets-in-kubernetes-4886</guid>
      <description>&lt;p&gt;Expanding volumes in Kubernetes clusters is a routine maintenance activity and seemingly straightforward – or so I thought! Recently, a unique challenge arose when there was a request to increase the storage size for a Stateful Application running in a Kubernetes cluster.&lt;/p&gt;

&lt;p&gt;Let's jump into the story to share the real-world experience of this request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem Statement
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;In the realm of Kubernetes clusters, a statefulset application thrived. Its popularity soared to the extent that it demanded more storage than the currently attached volume could provide. The team, recognizing the need to meet this demand, set out to expand the storage of the persistent volume connected to the statefulset. However, quickly realized that this was easier said than done.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As &lt;a href="https://kubernetes.io/blog/2022/05/05/volume-expansion-ga/"&gt;kubernetes 1.24&lt;/a&gt;  supports volume expansion, Just like anyone who had the first encounter with this task, I anticipated that it was as simple as increasing the &lt;code&gt;spec.volumeClaimTemplates.spec.resources.requests.storage&lt;/code&gt; in the statefulset application. &lt;strong&gt;But&lt;/strong&gt; It was not !!&lt;/p&gt;

&lt;p&gt;Contrary to initial expectations, modifying the spec.volumeClaimTemplates.spec.resources.requests.storage alone does not trigger the expansion of volumes attached to statefulsets. Manual intervention is necessary to navigate this intricate landscape. Let’s learn how can we achieve it in this article.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites For Persistent Volume Expansion
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The underlying provider and CSI driver for the persistent volume must support volume expansion. You should refer to the documentation of your CSI driver to check the capability. (Managed Kubernetes with their inbuilt CSI driver supports this natively and the feature volume expansion is also enabled)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Volume expansion must be enabled on the respective storage class used by the persistent volume. This can be checked using the below command:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;## Output in Name of storageclass with support to ALLOWVOLUMEEXPANSION&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get storageclass &lt;span class="nt"&gt;-o&lt;/span&gt; custom-columns&lt;span class="o"&gt;=&lt;/span&gt;NAME:.metadata.name,ALLOWVOLUMEEXPANSION:.allowVolumeExpansion
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output from the above command will look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;NAME                    ALLOWVOLUMEEXPANSION
azurefile               &lt;span class="nb"&gt;true
&lt;/span&gt;azurefile-csi           &lt;span class="nb"&gt;true
&lt;/span&gt;azurefile-csi-premium   &lt;span class="nb"&gt;true
&lt;/span&gt;azurefile-premium       &lt;span class="nb"&gt;true
&lt;/span&gt;default                 &lt;span class="nb"&gt;true
&lt;/span&gt;managed                 &lt;span class="nb"&gt;true
&lt;/span&gt;managed-csi             &lt;span class="nb"&gt;true
&lt;/span&gt;managed-csi-premium     &lt;span class="nb"&gt;true
&lt;/span&gt;managed-premium         &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step-by-Step Guide With Example.
&lt;/h3&gt;

&lt;p&gt;To make it more practical, I will use Alertmanager application, which is installed with &lt;a href="https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack"&gt;kube-prometheus-stack&lt;/a&gt; helm chart.&lt;/p&gt;

&lt;h4&gt;
  
  
  Reproduce the problem
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Installation of helm chart.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
&lt;span class="nv"&gt;$ &lt;/span&gt;helm repo update
&lt;span class="nv"&gt;$ &lt;/span&gt;helm upgrade &lt;span class="nt"&gt;--install&lt;/span&gt; kube-prom-stack prometheus-community/kube-prometheus-stack &lt;span class="nt"&gt;--namespace&lt;/span&gt; kube-prom-stack &lt;span class="nt"&gt;--create-namespace&lt;/span&gt; &lt;span class="nt"&gt;--values&lt;/span&gt; custom-values.yaml
Release &lt;span class="s2"&gt;"kube-prom-stack"&lt;/span&gt; does not exist. Installing it now.
NAME: kube-prom-stack
LAST DEPLOYED: Thu Nov 23 10:42:39 2023
NAMESPACE: kube-prom-stack
STATUS: deployed
REVISION: 1
NOTES:
kube-prometheus-stack has been installed. Check its status by running:
  kubectl &lt;span class="nt"&gt;--namespace&lt;/span&gt; kube-prom-stack get pods &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="s2"&gt;"release=kube-prom-stack"&lt;/span&gt;

Visit https://github.com/prometheus-operator/kube-prometheus &lt;span class="k"&gt;for &lt;/span&gt;instructions on how to create &amp;amp; configure Alertmanager and Prometheus instances using the Operator.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Info:&lt;/strong&gt; Application details are out of the scope of this article.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;-&lt;code&gt;custom-values.yaml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;alertmanager&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ingress&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

  &lt;span class="na"&gt;podDisruptionBudget&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

  &lt;span class="na"&gt;alertmanagerSpec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;volumeClaimTemplate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;accessModes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ReadWriteOnce"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
          &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2Gi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Once the installation is complete, we can list the statefulsets.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Info:&lt;/strong&gt; kube-prom-stack namespace is set as the default namespace.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get statefulsets
NAME                                                   READY   AGE
alertmanager-kube-prom-stack-kube-prome-alertmanager   1/1     11m
prometheus-kube-prom-stack-kube-prome-prometheus       1/1     11m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Check the details of Persistent volume claim created by the &lt;code&gt;volumeClaimTemplates&lt;/code&gt; specification of the statefulset to verify if the correct values are applied.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;## Get the pvc name from the statefulset volumeClaimTemplate&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get sts alertmanager-kube-prom-stack-kube-prome-alertmanager &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{.spec.volumeClaimTemplates[0].metadata.name}'&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
alertmanager-kube-prom-stack-kube-prome-alertmanager-db

&lt;span class="c"&gt;## Get the pvc size request from the statefulset volumeClaimTemplate&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get sts alertmanager-kube-prom-stack-kube-prome-alertmanager &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{.spec.volumeClaimTemplates[0].spec.resources}'&lt;/span&gt; | jq
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"requests"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"storage"&lt;/span&gt;: &lt;span class="s2"&gt;"2Gi"&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;## Verify the size of the PVC from the statefulset volumeClaimTemplate&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get pvc alertmanager-kube-prom-stack-kube-prome-alertmanager-db-alertmanager-kube-prom-stack-kube-prome-alertmanager-0 &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{.spec.resources.requests}'&lt;/span&gt; | jq
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"storage"&lt;/span&gt;: &lt;span class="s2"&gt;"2Gi"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Storage is &lt;code&gt;2Gi&lt;/code&gt; which seems to be as per our provided &lt;code&gt;values.yaml&lt;/code&gt; ✅&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Extend the persistent volume claim storage request in the provided &lt;code&gt;values.yaml&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modified &lt;code&gt;custom-values.yaml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;alertmanager&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ingress&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

  &lt;span class="na"&gt;podDisruptionBudget&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

  &lt;span class="na"&gt;alertmanagerSpec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;volumeClaimTemplate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;accessModes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ReadWriteOnce"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
          &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5Gi&lt;/span&gt; &lt;span class="c1"&gt;## Increased ##&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Size is updated to &lt;code&gt;5Gi&lt;/code&gt;, will apply the new values and monitor the changes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Helm upgrade with new values.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;helm upgrade &lt;span class="nt"&gt;--install&lt;/span&gt; kube-prom-stack prometheus-community/kube-prometheus-stack &lt;span class="nt"&gt;--namespace&lt;/span&gt; kube-prom-stack &lt;span class="nt"&gt;--values&lt;/span&gt; custom-values.yaml
Release &lt;span class="s2"&gt;"kube-prom-stack"&lt;/span&gt; has been upgraded. Happy Helming!
NAME: kube-prom-stack
LAST DEPLOYED: Thu Nov 23 10:55:25 2023
NAMESPACE: kube-prom-stack
STATUS: deployed
REVISION: 2
NOTES:
kube-prometheus-stack has been installed. Check its status by running:
  kubectl &lt;span class="nt"&gt;--namespace&lt;/span&gt; kube-prom-stack get pods &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="s2"&gt;"release=kube-prom-stack"&lt;/span&gt;

Visit https://github.com/prometheus-operator/kube-prometheus &lt;span class="k"&gt;for &lt;/span&gt;instructions on how to create &amp;amp; configure Alertmanager and Prometheus instances using the Operator.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Check the details of the Persistent volume claim after updating the size.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;## Get the pvc name from the statefulset volumeClaimTemplate&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get sts alertmanager-kube-prom-stack-kube-prome-alertmanager &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{.spec.volumeClaimTemplates[0].metadata.name}'&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
alertmanager-kube-prom-stack-kube-prome-alertmanager-db

&lt;span class="c"&gt;## Get the PVC size request from the statefulset volumeClaimTemplate (UPDATED)&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get sts alertmanager-kube-prom-stack-kube-prome-alertmanager &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{.spec.volumeClaimTemplates[0].spec.resources}'&lt;/span&gt; | jq
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"requests"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"storage"&lt;/span&gt;: &lt;span class="s2"&gt;"5Gi"&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;## Verify the size of the pvc got from the statefulset volumeClaimTemplate (NOT-UPDATED)&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get pvc alertmanager-kube-prom-stack-kube-prome-alertmanager-db-alertmanager-kube-prom-stack-kube-prome-alertmanager-0 &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{.spec.resources.requests}'&lt;/span&gt; | jq
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"storage"&lt;/span&gt;: &lt;span class="s2"&gt;"2Gi"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even though the volumeClaimTemplate of statefulset(alertmanager) is updated yet the persistent volume claim is using the old size &lt;code&gt;2Gi&lt;/code&gt;. &lt;/p&gt;

&lt;h4&gt;
  
  
  Solution
&lt;/h4&gt;

&lt;p&gt;The following steps are required to increase the size from &lt;code&gt;2Gi&lt;/code&gt; to &lt;code&gt;5Gi&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;STEP 1:&lt;/strong&gt; In this case the statefulset is managed via the operator hence needs to be paused as well on the custom resource &lt;code&gt;alertmanager&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Get the name of alertmanager resource.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get alertmanager
NAME                                      VERSION   REPLICAS   READY   RECONCILED   AVAILABLE   AGE
kube-prom-stack-kube-prome-alertmanager   v0.26.0   1          1       True         True        61m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Patch the resource so that the operator does not recreate it.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl patch alertmanager/kube-prom-stack-kube-prome-alertmanager  &lt;span class="nt"&gt;--patch&lt;/span&gt; &lt;span class="s1"&gt;'{"spec": {"paused": true, "storage": {"volumeClaimTemplate": {"spec": {"resources": {"requests": {"storage":"5Gi"}}}}}}}'&lt;/span&gt; &lt;span class="nt"&gt;--type&lt;/span&gt; merge
alertmanager.monitoring.coreos.com/kube-prom-stack-kube-prome-alertmanager patched
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;STEP 2:&lt;/strong&gt; Patch the persistent volume claims associated with the statefulset.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;p &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;kubectl get pvc &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nv"&gt;alertmanager&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;kube-prom-stack-kube-prome-alertmanager &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{range .items[*]}{.metadata.name} {end}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  kubectl patch pvc/&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;p&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;--patch&lt;/span&gt; &lt;span class="s1"&gt;'{"spec": {"resources": {"requests": {"storage":"5Gi"}}}}'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;STEP 3:&lt;/strong&gt; Final step is to delete the statefulset with the orphan strategy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By passing &lt;code&gt;--cascade=orphan&lt;/code&gt; to kubectl delete, the Pods managed by the StatefulSet are left behind even after the StatefulSet object itself is deleted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl delete sts alertmanager-kube-prom-stack-kube-prome-alertmanager &lt;span class="nt"&gt;--cascade&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;orphan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;To verify if the PVC is extended.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;## PVC is updated&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get pvc alertmanager-kube-prom-stack-kube-prome-alertmanager-db-alertmanager-kube-prom-stack-kube-prome-alertmanager-0 &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{.spec.resources.requests}'&lt;/span&gt; | jq
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"storage"&lt;/span&gt;: &lt;span class="s2"&gt;"5Gi"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;STEP 4:&lt;/strong&gt; Resume the operator to take control of the alertmanager provisioning. This step is valid in statefultsets managed via operators only.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl patch alertmanager/kube-prom-stack-kube-prome-alertmanager &lt;span class="nt"&gt;--patch&lt;/span&gt; &lt;span class="s1"&gt;'{"spec": {"paused": false}}'&lt;/span&gt; &lt;span class="nt"&gt;--type&lt;/span&gt; merge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In Summary following steps need to be followed in the respective order to expand the persistent volume on statefulsets.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Patch the statefulset with the required(expanded) volumeClaimTemplates configuration.&lt;/li&gt;
&lt;li&gt;Patch the persistent volume claims with the required(expanded) size configuration associated with the statefulset.&lt;/li&gt;
&lt;li&gt;Delete the statefulset with &lt;code&gt;cascade=orphan&lt;/code&gt; strategy.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And that concludes our exploration into the dynamic world of scaling storage for stateful applications in Kubernetes.&lt;/p&gt;

&lt;p&gt;Expanding the persistent volumes in statefulsets is a well-known restriction and is been tracked in the &lt;a href="https://github.com/kubernetes/enhancements/issues/661"&gt;Support Volume Expansion Through StatefulSets&lt;/a&gt; and  &lt;a href="https://github.com/kubernetes/kubernetes/issues/68737"&gt;StatefulSet: support resize PVC storage in K8s v1.11&lt;/a&gt; GitHub issues in official Kubernetes repositories.&lt;/p&gt;

&lt;h2&gt;
  
  
  Acknowledgments
&lt;/h2&gt;

&lt;p&gt;Thank you for embarking on this Kubernetes adventure with me. Scaling storage in Kubernetes can be complex, but you've gained valuable insights to navigate this terrain. May your clusters be resilient, and your applications thrive. Happy reading, and until our next exploration!&lt;/p&gt;

&lt;h2&gt;
  
  
  Helpful Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/blog/2022/05/05/volume-expansion-ga/"&gt;Kubernetes 1.24: Volume Expansion Now A Stable Feature&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://prometheus-operator.dev/docs/operator/storage/#resizing-volumes"&gt;Resizing Prometheus Operator Volumes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kubernetes/kubernetes/issues/68737"&gt;StatefulSet: support resize pvc storage in K8s v1.11&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/storage/persistent-volumes/#expanding-persistent-volumes-claims"&gt;Expanding Persistent Volumes Claims&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>devops</category>
      <category>technology</category>
      <category>containers</category>
    </item>
    <item>
      <title>Terraform and Ansible: Teaming Up for Automated Cloud Magic</title>
      <dc:creator>Ishan Sharma</dc:creator>
      <pubDate>Thu, 17 Aug 2023 15:44:04 +0000</pubDate>
      <link>https://forem.com/ishuar/terraform-and-ansible-teaming-up-for-automated-cloud-magic-3ob0</link>
      <guid>https://forem.com/ishuar/terraform-and-ansible-teaming-up-for-automated-cloud-magic-3ob0</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;In the world of cloud automation, Terraform and Ansible form a seamless partnership. Terraform constructs infrastructure, while Ansible configures it. Leveraging dynamic inventories and GitHub Actions, the process gains efficiency.&lt;/p&gt;

&lt;p&gt;Explore my &lt;a href="https://github.com/ishuar/terraform-ansible-azure"&gt;GitHub repository&lt;/a&gt; for hands-on experience. Delve into Terraform's provisioning, Ansible's management, and GitHub's orchestration.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Unlock cloud automation with Terraform, Ansible, and GitHub's synergy.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the dynamic world of cloud computing, provisioning infrastructure and managing configurations are essential tasks. This is where Terraform and Ansible come into play, acting as a dynamic duo that enables you to orchestrate automated cloud magic.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Power of Terraform and Ansible
&lt;/h2&gt;



&lt;h3&gt;
  
  
  Terraform: Infrastructure Provisioning Simplified
&lt;/h3&gt;

&lt;p&gt;Terraform stands as a powerful infrastructure-as-code tool. It allows you to define your cloud infrastructure using a human-readable syntax. This approach streamlines the process of spinning up resources on cloud platforms like Azure. Whether it's virtual machines, networking components, or databases, Terraform's declarative approach ensures consistent provisioning across environments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ansible: Configuration Management Perfected
&lt;/h3&gt;

&lt;p&gt;On the other hand, Ansible specializes in configuration management. It allows you to define the desired state of your servers and applications. Ansible playbooks, written in simple YAML syntax, automate the process of configuring servers, installing software, and ensuring consistency across your infrastructure. This comes in handy when you're dealing with tasks like setting up web servers or managing security configurations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Complementary, Not Competitive
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Dispelling the Misconception
&lt;/h3&gt;

&lt;p&gt;One common misconception is that Terraform and Ansible compete with each other. In reality, they are highly complementary. Terraform focuses on creating and destroying resources, while Ansible excels in configuring and maintaining those resources. This synergy ensures that your infrastructure is not just provisioned but also tailored to meet your specific requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dynamic Inventories and Pipeline Automation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Dynamic Inventories: A Game Changer
&lt;/h3&gt;

&lt;p&gt;A remarkable feature that enhances this collaboration is the use of dynamic inventories. Instead of maintaining static inventory lists, Ansible can directly fetch information about your cloud resources from the likes of Azure using dynamic inventory plugins. This makes your playbooks flexible and adaptable to the evolving cloud landscape.&lt;/p&gt;

&lt;h3&gt;
  
  
  Seamless Automation with GitHub Actions
&lt;/h3&gt;

&lt;p&gt;Bringing it all together, GitHub Actions empowers you to automate your workflows. With GitHub as your source version control, you can leverage GitHub Actions to define pipelines that seamlessly integrate Terraform and Ansible. Pushing code triggers the orchestration of provisioning infrastructure and configuring it, all without manual intervention.&lt;/p&gt;

&lt;h2&gt;
  
  
  Embarking on Practical Cloud Journey
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Hands-On Learning
&lt;/h3&gt;

&lt;p&gt;For those eager to dive into practical knowledge, there's a treasure trove awaiting you. Inside the &lt;a href="https://github.com/ishuar/terraform-ansible-azure"&gt;GitHub repository&lt;/a&gt;, you'll find a rich collection of code that practically demonstrates the synergy between Terraform and Ansible. Each line of code showcases how to orchestrate cloud resources and configure them seamlessly.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ishuar"&gt;
        ishuar
      &lt;/a&gt; / &lt;a href="https://github.com/ishuar/terraform-ansible-azure"&gt;
        terraform-ansible-azure
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Terraform and Ansible: Teaming Up for Automated Azure Cloud Magic
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a href="https://github.com/ishuar/terraform-ansible/blob/main/LICENSE"&gt;&lt;img src="https://camo.githubusercontent.com/ec39814880dacc1110bd00b7e501639ed788766252ba8332f2c250de7372fa52/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6973687561722f7465727261666f726d2d616e7369626c653f7374796c653d666f722d7468652d6261646765" alt="License"&gt;&lt;/a&gt; &lt;a href="https://github.com/ishuar/terraform-ansible/graphs/contributors"&gt;&lt;img src="https://camo.githubusercontent.com/6d595aca709c842aea90c4650b52ffe8130e3ed437758329183c1f8810fd1149/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6e7472696275746f72732f6973687561722f7465727261666f726d2d616e7369626c653f7374796c653d666f722d7468652d6261646765" alt="Contributors"&gt;&lt;/a&gt; &lt;a href="https://github.com/ishuar/terraform-ansible/issues"&gt;&lt;img src="https://camo.githubusercontent.com/91580d05a247c3b633118fc58709eeb7a65bb1c53a7ba4af4848b4e7851ecd82/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f6973687561722f7465727261666f726d2d616e7369626c653f7374796c653d666f722d7468652d6261646765" alt="Issues"&gt;&lt;/a&gt; &lt;a href="https://github.com/ishuar/terraform-ansible/network/members"&gt;&lt;img src="https://camo.githubusercontent.com/867ed1cad2fffa353ad05382470c4c33330f3bc04ce99326a7a3ab1db273674d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f666f726b732f6973687561722f7465727261666f726d2d616e7369626c653f7374796c653d666f722d7468652d6261646765" alt="Forks"&gt;&lt;/a&gt; &lt;a href="https://github.com/ishuar/terraform-ansible/stargazers"&gt;&lt;img src="https://camo.githubusercontent.com/6ce32db7c7cf63ce8914d96ac8e13a0d3256d7a9c73f05c42ae27407da320f91/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6973687561722f7465727261666f726d2d616e7369626c653f7374796c653d666f722d7468652d6261646765" alt="Stargazers"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;br&gt;
&lt;div&gt;
   &lt;a href="https://github.com/ishuar/terraform-ansible"&gt;
    &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IbjEtK1h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/ishuar/terraform-ansible/raw/main/.vscode/extras/terraform-ansible-webservers.gif" alt="Logo"&gt;
  &lt;/a&gt;
  &lt;h1 id="user-content-terraform-and-ansible-hand-in-hand"&gt;&lt;a class="heading-link" href="https://github.com/ishuar/terraform-ansible-azure#terraform-and-ansible-hand-in-hand"&gt;&lt;strong&gt;Terraform and Ansible Hand In Hand&lt;/strong&gt;&lt;/a&gt;&lt;/h1&gt;
  &lt;p&gt;
    🌩️ Terraform and Ansible: Teaming Up for Automated Cloud Magic 🌩️
    &lt;br&gt;
    &lt;a href="https://github.com/ishuar/terraform-ansible/issues"&gt;&lt;strong&gt;Report Bug&lt;/strong&gt;&lt;/a&gt; or &lt;a href="https://github.com/ishuar/terraform-ansible/issues"&gt;&lt;strong&gt;Request Feature&lt;/strong&gt;&lt;/a&gt;
    &lt;br&gt;
    &lt;br&gt;
  &lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure#introduction"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ishuar/terraform-ansible-azure#prerequisites"&gt;Prerequisites&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure#conclusion"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ishuar/terraform-ansible-azure#examples-in-the-repository"&gt;Examples in the Repository&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/ishuar/terraform-ansible-azure#nginx-linux-webserver-with-azure-vms-behind-azure-load-balancer"&gt;Nginx Linux Webserver with Azure VMs Behind Azure Load Balancer&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure#terraform-configuration"&gt;Terraform Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ishuar/terraform-ansible-azure#ansible-playbook-for-configuring-web-servers"&gt;Ansible Playbook for Configuring Web Servers&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure#conclusion-1"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ishuar/terraform-ansible-azure#automation-with-github-actions"&gt;Automation with GitHub Actions&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure#github-actions-workflows"&gt;GitHub Actions Workflows&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure#conclusion-2"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure#local-development-vs-automation"&gt;Local Development vs. Automation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure#contributing"&gt;Contributing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure#license"&gt;License&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure#contact"&gt;Contact&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="user-content-introduction"&gt;&lt;a class="heading-link" href="https://github.com/ishuar/terraform-ansible-azure#introduction"&gt;Introduction&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Terraform and Ansible 🤝 are powerful tools that can work synergistically to provision and configure cloud infrastructure. In this repository, we'll explore how to utilize Terraform for infrastructure provisioning and Ansible for configuration management, all within the context of Microsoft Azure.&lt;/p&gt;
&lt;h2 id="user-content-prerequisites"&gt;&lt;a class="heading-link" href="https://github.com/ishuar/terraform-ansible-azure#prerequisites"&gt;Prerequisites&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before diving into using Terraform and Ansible for your Azure cloud infrastructure, ensure you have the following prerequisites in place:&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Prerequisite&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Azure Account&lt;/td&gt;
&lt;td&gt;You must have a valid &lt;a href="https://azure.com" rel="nofollow"&gt;Azure account&lt;/a&gt; to create and manage resources on the Azure cloud platform.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Terraform Installed&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli" rel="nofollow"&gt;Install&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/ishuar/terraform-ansible-azure"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;By immersing yourself in this repository, you're not just reading about automation; you're experiencing it firsthand. Through tinkering, testing, and exploration, you'll uncover the magic that comes to life when Terraform and Ansible work in harmony.&lt;/p&gt;

&lt;p&gt;A glimpse of the tools and components involved is as shown below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Vj13Fsc8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xuqglxzntg3nseiq5cm3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Vj13Fsc8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xuqglxzntg3nseiq5cm3.gif" alt="Architecture Diagram, where developer push code to github, github action using terraform provision azure infrastructure afterwards github action using ansible configures the azure virtual machines" width="800" height="537"&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Terraform as your spell book 📓
&lt;/h3&gt;

&lt;p&gt;First thing first, please refer to Readme file within the &lt;code&gt;terraform/linux-webserver-with-loadbalancer&lt;/code&gt; directory for pre-requisites to replicate the infrastructure on your local environment.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;INFO:&lt;/strong&gt; For best experience open all embedded links in a new browser window/tab 💻.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure/blob/main/terraform/linux-webserver-with-loadbalancer/local.tf" class="ltag_cta ltag_cta--branded"&gt;local.tf&lt;/a&gt;
 &lt;br&gt;
&lt;br&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure/blob/main/terraform/linux-webserver-with-loadbalancer/variables.tf" class="ltag_cta ltag_cta--branded"&gt;variables.tf&lt;/a&gt;
&lt;br&gt;
&lt;br&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure/blob/main/terraform/linux-webserver-with-loadbalancer/dependencies.tf" class="ltag_cta ltag_cta--branded"&gt;Dependencies&lt;/a&gt;
&lt;br&gt;
&lt;br&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure/blob/main/terraform/linux-webserver-with-loadbalancer/azure-load-balancer.tf" class="ltag_cta ltag_cta--branded"&gt;Azure Load Balancer&lt;/a&gt;
&lt;br&gt;
&lt;br&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure/blob/main/terraform/linux-webserver-with-loadbalancer/linux-virtual-machines.tf" class="ltag_cta ltag_cta--branded"&gt;Azure Linux Virtual Machines&lt;/a&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Ansible as your ancient scroll 📜
&lt;/h3&gt;

&lt;p&gt;First thing first, please refer to Readme file within the &lt;code&gt;ansible&lt;/code&gt; directory for pre-requisites to replicate the infrastructure on your local environment.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ansible Configuration.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="c1"&gt;##? Generate complete using: ansible-config init --disabled -t all &amp;gt; &amp;lt;path&amp;gt;/ansible.cfg&lt;/span&gt;

&lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;defaults&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# (boolean) Set this to "False" if you want to avoid host key checking by the underlying tools Ansible uses to connect to the host&lt;/span&gt;
&lt;span class="s"&gt;host_key_checking = False&lt;/span&gt;
&lt;span class="s"&gt;force_color = True&lt;/span&gt;

&lt;span class="c1"&gt;# (integer) Port to use in remote connections, when blank it will use the connection plugin default.&lt;/span&gt;
&lt;span class="c1"&gt;## As we have changed the default SSH port of our VMs&lt;/span&gt;
&lt;span class="s"&gt;remote_port=8822&lt;/span&gt;

&lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;privilege_escalation&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# (boolean) Toggle to prompt for privilege escalation password.&lt;/span&gt;
&lt;span class="s"&gt;become_ask_pass=False&lt;/span&gt;

&lt;span class="c1"&gt;# (string) Privilege escalation method to use when `become` is enabled.&lt;/span&gt;
&lt;span class="s"&gt;become_method=sudo&lt;/span&gt;

&lt;span class="c1"&gt;# (string) The user your login/remote user 'becomes' when using privilege escalation, most systems will use 'root' when no user is specified.&lt;/span&gt;
&lt;span class="s"&gt;become_user=root&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Dynamic Inventory&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Refer to &lt;a href="https://github.com/ishuar/terraform-ansible-azure/blob/main/ansible/README.md#local-development-environment"&gt;pre-requisites&lt;/a&gt; for local set environment set up.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;plugin&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;azure_rm&lt;/span&gt;

&lt;span class="na"&gt;include_vm_resource_groups&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ansible-vm-resources&lt;/span&gt;

&lt;span class="na"&gt;auth_source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;auto&lt;/span&gt;
&lt;span class="na"&gt;conditional_groups&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# since this will be true for every host, every host sourced from this inventory plugin config will be in the&lt;/span&gt;
  &lt;span class="c1"&gt;# group 'all_the_hosts'&lt;/span&gt;
  &lt;span class="na"&gt;all_the_hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;

&lt;span class="c1"&gt;# places hosts in dynamically-created groups based on a variable value.&lt;/span&gt;
&lt;span class="na"&gt;keyed_groups&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# places each host in a group named 'tag_(tag name)_(tag value)' for each tag on a VM.&lt;/span&gt;
  &lt;span class="c1"&gt;# - prefix: tag&lt;/span&gt;
  &lt;span class="c1"&gt;#   key: tags&lt;/span&gt;
  &lt;span class="c1"&gt;# places each host in a group named 'azure_loc_(location name)', depending on the VM's location&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;prefix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;azure_loc&lt;/span&gt;
    &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;location&lt;/span&gt;
  &lt;span class="c1"&gt;# places host in a group named 'some_tag_X' using the value of the 'sometag' tag on a VM as X, and defaulting to the&lt;/span&gt;
  &lt;span class="c1"&gt;# value 'none' (eg, the group 'some_tag_none') if the 'sometag' tag is not defined for a VM.&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;prefix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;role&lt;/span&gt;
    &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tags.role | default('none')&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure/tree/main/ansible/roles"&gt;&lt;strong&gt;&lt;code&gt;Ansible Roles Involved&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ansible Playbook&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Nginx Webserver on Ubuntu machine&lt;/span&gt;
  &lt;span class="na"&gt;gather_facts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;remote_user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;adminuser&lt;/span&gt;
  &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;dynamic_hosts&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
  &lt;span class="na"&gt;become&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;connection&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ssh&lt;/span&gt;
  &lt;span class="na"&gt;pre_tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
  &lt;span class="na"&gt;vars&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;dynamic_hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;role_slave_webservers&lt;/span&gt;

  &lt;span class="na"&gt;roles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;azure_vm_ufw&lt;/span&gt;
      &lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;enable_firewall | bool&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx_webserver&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Realm of GitHub Actions 🪐
&lt;/h3&gt;

&lt;p&gt;Concept of &lt;a href="https://docs.github.com/en/actions/using-workflows/reusing-workflows"&gt;Github reusable workflows&lt;/a&gt; are utilised in the repository, hence create workflow one time and then can re-use it for supporting used case.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reusable Workflows&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure/blob/main/.github/workflows/terraform-infra-set-up.yaml"&gt;&lt;code&gt;terraform-infra-set-up.yaml&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure/blob/main/.github/workflows/ansible-set-up.yaml"&gt;&lt;code&gt;ansible-set-up.yaml&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Deployment and Configuration Workflows&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;webservers-infra-terraform.yaml&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Create&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Webservers&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Infrastructure"&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;terraform-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;number&lt;/span&gt;
        &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
        &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1.5.4&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;The terraform version used for the github action.&lt;/span&gt;

      &lt;span class="na"&gt;cache-hash-file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
        &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
        &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/providers.tf'&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;The file used to create common hash cache naming.&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
      &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;terraform/**"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.github/workflows/terraform-infra-set-up.yaml"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.github/workflows/webservers-infra-terraform.yaml"&lt;/span&gt;

  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;terraform/**"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.github/workflows/terraform-infra-set-up.yaml"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.github/workflows/webservers-infra-terraform.yaml"&lt;/span&gt;

&lt;span class="na"&gt;concurrency&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;terraform-webservers&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;webserversInfra&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create infrastructure for webservers&lt;/span&gt;
    &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./.github/workflows/terraform-infra-set-up.yaml&lt;/span&gt;
    &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;terraform-dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;terraform/linux-webserver-with-loadbalancer"&lt;/span&gt;
      &lt;span class="na"&gt;terraform-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ inputs.terraform-version != '' &amp;amp;&amp;amp; inputs.terraform-version || vars.TERRAFORM_VERSION }}&lt;/span&gt;
    &lt;span class="na"&gt;secrets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;inherit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;webservers-config-ansible.yaml&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Configure&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Nginx&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Webservers&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;in&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Ubuntu&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;via&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Ansible"&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
    &lt;span class="c1"&gt;## in Case push to main by codeowners&lt;/span&gt;
    &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ansible/**"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.github/workflows/set-up-ubuntu-nginx-webserver.yaml"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.github/workflows/ansible-set-up.yaml"&lt;/span&gt;

  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ansible/**"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.github/workflows/set-up-ubuntu-nginx-webserver.yaml"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.github/workflows/ansible-set-up.yaml"&lt;/span&gt;

&lt;span class="na"&gt;concurrency&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ansible-webservers&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;webserversConfig&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Configure Nginx webservers&lt;/span&gt;
    &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./.github/workflows/ansible-set-up.yaml&lt;/span&gt;
    &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;playbook&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;set-up-ubuntu-nginx-webserver.yaml&lt;/span&gt;
      &lt;span class="na"&gt;terraform-output-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;terraform/linux-webserver-with-loadbalancer&lt;/span&gt;
      &lt;span class="na"&gt;nsg-ssh-port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8822&lt;/span&gt;
    &lt;span class="na"&gt;secrets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;ssh-private-key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.PASSWORDLESS_SSH_PRIVATE_KEY }}&lt;/span&gt;
      &lt;span class="na"&gt;AZURE_TENANT_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.ARM_TENANT_ID }}&lt;/span&gt;
      &lt;span class="na"&gt;AZURE_CLIENT_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.ARM_CLIENT_ID }}&lt;/span&gt;
      &lt;span class="na"&gt;AZURE_CLIENT_SECRET&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.ARM_CLIENT_SECRET }}&lt;/span&gt;
      &lt;span class="na"&gt;AZURE_SUBSCRIPTION_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ vars.ARM_SUBSCRIPTION_ID }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Terraform and Ansible are more than just tools; they represent a collaborative approach to cloud automation. By using Terraform for infrastructure provisioning and Ansible for configuration management, you unlock a potent synergy that ensures your cloud environment is both robust and adaptable. Add dynamic inventories and GitHub Actions into the mix, and you have a recipe for automated cloud magic that simplifies and streamlines your operations.&lt;/p&gt;

&lt;p&gt;Happy automating!&lt;/p&gt;
&lt;h3&gt;
  
  
  Thank You 🙏
&lt;/h3&gt;

&lt;p&gt;A heartfelt thank you and grateful for the time you've spent for reading the article. I hope I was able to ignite your curiosity and guided you through the realm of Terraform, Ansible, and cloud magic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your thoughts matter!&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;If this journey sparked ideas or questions, I'd love to hear from you. Share your feedback, suggestions via &lt;a href="https://github.com/ishuar/terraform-ansible-azure/issues"&gt;GitHub Issue&lt;/a&gt; or even a magical star ⭐️  for the project on GitHub.&lt;/p&gt;



&lt;p&gt;&lt;em&gt;Stay tuned for more tech insights.&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ishuar"&gt;
        ishuar
      &lt;/a&gt; / &lt;a href="https://github.com/ishuar/terraform-ansible-azure"&gt;
        terraform-ansible-azure
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Terraform and Ansible: Teaming Up for Automated Azure Cloud Magic
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a href="https://github.com/ishuar/terraform-ansible/blob/main/LICENSE"&gt;&lt;img src="https://camo.githubusercontent.com/ec39814880dacc1110bd00b7e501639ed788766252ba8332f2c250de7372fa52/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6973687561722f7465727261666f726d2d616e7369626c653f7374796c653d666f722d7468652d6261646765" alt="License"&gt;&lt;/a&gt; &lt;a href="https://github.com/ishuar/terraform-ansible/graphs/contributors"&gt;&lt;img src="https://camo.githubusercontent.com/6d595aca709c842aea90c4650b52ffe8130e3ed437758329183c1f8810fd1149/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6e7472696275746f72732f6973687561722f7465727261666f726d2d616e7369626c653f7374796c653d666f722d7468652d6261646765" alt="Contributors"&gt;&lt;/a&gt; &lt;a href="https://github.com/ishuar/terraform-ansible/issues"&gt;&lt;img src="https://camo.githubusercontent.com/91580d05a247c3b633118fc58709eeb7a65bb1c53a7ba4af4848b4e7851ecd82/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f6973687561722f7465727261666f726d2d616e7369626c653f7374796c653d666f722d7468652d6261646765" alt="Issues"&gt;&lt;/a&gt; &lt;a href="https://github.com/ishuar/terraform-ansible/network/members"&gt;&lt;img src="https://camo.githubusercontent.com/867ed1cad2fffa353ad05382470c4c33330f3bc04ce99326a7a3ab1db273674d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f666f726b732f6973687561722f7465727261666f726d2d616e7369626c653f7374796c653d666f722d7468652d6261646765" alt="Forks"&gt;&lt;/a&gt; &lt;a href="https://github.com/ishuar/terraform-ansible/stargazers"&gt;&lt;img src="https://camo.githubusercontent.com/6ce32db7c7cf63ce8914d96ac8e13a0d3256d7a9c73f05c42ae27407da320f91/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6973687561722f7465727261666f726d2d616e7369626c653f7374796c653d666f722d7468652d6261646765" alt="Stargazers"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;br&gt;
&lt;div&gt;
   &lt;a href="https://github.com/ishuar/terraform-ansible"&gt;
    &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IbjEtK1h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/ishuar/terraform-ansible/raw/main/.vscode/extras/terraform-ansible-webservers.gif" alt="Logo"&gt;
  &lt;/a&gt;
  &lt;h1 id="user-content-terraform-and-ansible-hand-in-hand"&gt;&lt;a class="heading-link" href="https://github.com/ishuar/terraform-ansible-azure#terraform-and-ansible-hand-in-hand"&gt;&lt;strong&gt;Terraform and Ansible Hand In Hand&lt;/strong&gt;&lt;/a&gt;&lt;/h1&gt;
  &lt;p&gt;
    🌩️ Terraform and Ansible: Teaming Up for Automated Cloud Magic 🌩️
    &lt;br&gt;
    &lt;a href="https://github.com/ishuar/terraform-ansible/issues"&gt;&lt;strong&gt;Report Bug&lt;/strong&gt;&lt;/a&gt; or &lt;a href="https://github.com/ishuar/terraform-ansible/issues"&gt;&lt;strong&gt;Request Feature&lt;/strong&gt;&lt;/a&gt;
    &lt;br&gt;
    &lt;br&gt;
  &lt;/p&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure#introduction"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ishuar/terraform-ansible-azure#prerequisites"&gt;Prerequisites&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure#conclusion"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ishuar/terraform-ansible-azure#examples-in-the-repository"&gt;Examples in the Repository&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/ishuar/terraform-ansible-azure#nginx-linux-webserver-with-azure-vms-behind-azure-load-balancer"&gt;Nginx Linux Webserver with Azure VMs Behind Azure Load Balancer&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure#terraform-configuration"&gt;Terraform Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ishuar/terraform-ansible-azure#ansible-playbook-for-configuring-web-servers"&gt;Ansible Playbook for Configuring Web Servers&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure#conclusion-1"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ishuar/terraform-ansible-azure#automation-with-github-actions"&gt;Automation with GitHub Actions&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure#github-actions-workflows"&gt;GitHub Actions Workflows&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure#conclusion-2"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure#local-development-vs-automation"&gt;Local Development vs. Automation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure#contributing"&gt;Contributing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure#license"&gt;License&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ishuar/terraform-ansible-azure#contact"&gt;Contact&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="user-content-introduction"&gt;&lt;a class="heading-link" href="https://github.com/ishuar/terraform-ansible-azure#introduction"&gt;Introduction&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Terraform and Ansible 🤝 are powerful tools that can work synergistically to provision and configure cloud infrastructure. In this repository, we'll explore how to utilize Terraform for infrastructure provisioning and Ansible for configuration management, all within the context of Microsoft Azure.&lt;/p&gt;

&lt;h2 id="user-content-prerequisites"&gt;&lt;a class="heading-link" href="https://github.com/ishuar/terraform-ansible-azure#prerequisites"&gt;Prerequisites&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Before diving into using Terraform and Ansible for your Azure cloud infrastructure, ensure you have the following prerequisites in place:&lt;/p&gt;


&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;br&gt;
&lt;thead&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;th&gt;Prerequisite&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/thead&gt;
&lt;br&gt;
&lt;tbody&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;Azure Account&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;You must have a valid &lt;a href="https://azure.com" rel="nofollow"&gt;Azure account&lt;/a&gt; to create and manage resources on the Azure cloud platform.&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;Terraform Installed&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;
&lt;br&gt;
&lt;a href="https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli" rel="nofollow"&gt;Install&lt;/a&gt;&lt;br&gt;
&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/tbody&gt;
&lt;br&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/ishuar/terraform-ansible-azure"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Guess what?&lt;/strong&gt; &lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

&lt;p&gt;This document got a little boost from AI magic, making it even more exciting. But don't worry, it's still your friendly guide, here to help you on your learning journey&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>ansible</category>
      <category>azure</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
