<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Untitled Publication]]></title><description><![CDATA[Untitled Publication]]></description><link>https://blogs.subashneupane3.com.np</link><generator>RSS for Node</generator><lastBuildDate>Sat, 05 Sep 2026 11:01:21 GMT</lastBuildDate><atom:link href="https://blogs.subashneupane3.com.np/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Kubernetes Configmaps and Secrets]]></title><description><![CDATA[In this blog, we will delve into another pivotal aspect of Kubernetes – configmaps and secrets. Kubernetes primarily manages pods and containers, and the essential data needed by users for their containers is often accessed through environment variab...]]></description><link>https://blogs.subashneupane3.com.np/kubernetes-configmaps-and-secrets</link><guid isPermaLink="true">https://blogs.subashneupane3.com.np/kubernetes-configmaps-and-secrets</guid><category><![CDATA[configmaps]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[secrets]]></category><dc:creator><![CDATA[Subash Neupane]]></dc:creator><pubDate>Fri, 26 Jan 2024 15:19:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1706282317608/5c26a575-67e1-4dab-b592-a58de23c488d.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we will delve into another pivotal aspect of Kubernetes – configmaps and secrets. Kubernetes primarily manages pods and containers, and the essential data needed by users for their containers is often accessed through environment variables. To streamline this process, Kubernetes employs configmaps, allowing users to create centralized configurations within the cluster. These configmaps store crucial information such as ports, database details, and more. Consequently, users can seamlessly access and utilize this information within their Kubernetes pods by either mounting or incorporating the configmap data into their container file systems.</p>
<p>So, configmap is solving the problem of storing the information that can be used by the application.</p>
<p>Secrets in Kubernetes also deals the same as the configmaps but it deals with sensitive information. Non-sensitive information is stored in configmaps and sensitive information is stored in secrets. The sensitive data of secret before stored in etcd, gets encrypted in Rest. Kubernetes does the default encryption but it also allows us to do the custom encryption.</p>
<p>Strong RBAC is enforced for secrets and the least privileged access is implemented for secrets.</p>
<p>Let's get directly into the hands-on experience.</p>
<p>Let's create the configmap file as <strong>cm.yml</strong></p>
<pre><code class="lang-plaintext">apiVersion: v1
kind: ConfigMap
metadata:
  name: test-cm
data:
  db-port: "3306"
</code></pre>
<p>Apply</p>
<pre><code class="lang-plaintext">kubectl apply -f cm.yml
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706273076381/4854add6-244a-487c-b8a6-a658408adc9c.png" alt class="image--center mx-auto" /></p>
<p>Our configmap is created.</p>
<p>We will take these data as environment variable in the kubernetes cluster.</p>
<p>We have the deployment.yml</p>
<pre><code class="lang-plaintext">apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-python-app
  labels:
    app: sample-python-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: sample-python-app
  template:
    metadata:
      labels:
        app: sample-python-app
    spec:
      containers:
      - name: python-app
        image: subash07/python-app:latest
        ports:
        - containerPort: 8000
</code></pre>
<p>Create the deployment</p>
<pre><code class="lang-plaintext">kubectl apply -f deployment.yml
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706279578413/1fefeeb8-363e-4412-9155-4e1856c2e0f8.png" alt class="image--center mx-auto" /></p>
<p>We can see that there is no environment variable concerning db.</p>
<p>Let's modify the deployment.yml .</p>
<pre><code class="lang-yaml"><span class="hljs-attr">env:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">DB-PORT</span>
      <span class="hljs-attr">valueFrom:</span>
        <span class="hljs-attr">configMapKeyRef:</span>
          <span class="hljs-attr">name:</span> <span class="hljs-string">test-cm</span>
          <span class="hljs-attr">key:</span> <span class="hljs-string">db-port</span>
</code></pre>
<p>We will add this in the deployment.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706280219406/eb94a83f-5c6a-4b8c-b80b-8a3113b83a22.png" alt class="image--center mx-auto" /></p>
<p>Apply it</p>
<pre><code class="lang-yaml"><span class="hljs-string">kubectl</span> <span class="hljs-string">apply</span> <span class="hljs-string">-f</span> <span class="hljs-string">deployment.yml</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706280371321/14e5e318-0070-4d3a-b8d4-acbbf79e65fc.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706280420775/4be01fa3-6ff4-49a8-bdfa-ab525bd46258.png" alt class="image--center mx-auto" /></p>
<p>So our pods are getting restarted.</p>
<p>Lets exec into one of the pods</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706280569475/ab635efd-f096-4ea6-8f21-e646b24a41b3.png" alt class="image--center mx-auto" /></p>
<p>Perfect, it is working fine.</p>
<p>Instead of directly using the environment variable, we will mount it as a file.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706281121869/de0304c9-fc15-4e8e-be8c-78cfbcadc54d.png" alt class="image--center mx-auto" /></p>
<p>Apply</p>
<pre><code class="lang-yaml"><span class="hljs-string">kubectl</span> <span class="hljs-string">apply</span> <span class="hljs-string">-f</span> <span class="hljs-string">deployment.yml</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706281274318/798106c6-57e2-4e5b-9aa9-34e8a5e80c6b.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706281402173/1b407088-02a2-4380-b4c8-da77f770e6a7.png" alt class="image--center mx-auto" /></p>
<p>It's working perfectly fine. Now let's change the port from 3306 to 3307 in configmap and verify whether it gets updated or not.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706281580517/3b178c4a-3b59-44be-a8f5-5f3d73a935a8.png" alt class="image--center mx-auto" /></p>
<p>configmap is updated.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706281676588/9fadc39d-27e0-4bcd-8f02-0f1d0ff7ef69.png" alt class="image--center mx-auto" /></p>
<p>So the changes in the configmap are also updated in the app.</p>
<p>Let's create a simple secret to store the username password</p>
<pre><code class="lang-yaml"><span class="hljs-string">kubectl</span> <span class="hljs-string">create</span> <span class="hljs-string">secret</span> <span class="hljs-string">generic</span> <span class="hljs-string">test-secret</span> <span class="hljs-string">--from-literal=db-port="3307"</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706281940323/e6933869-ecbe-414e-a5e9-5289f21ed82e.png" alt class="image--center mx-auto" /></p>
<p>Our secret is created.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706282010905/352952c6-7916-40a8-b425-83e544c8b535.png" alt class="image--center mx-auto" /></p>
<p>Here the db-port is encrypted.</p>
<p>I hope you liked this blog. If any mistake, do comment down below 🚀.</p>
<p>Do like and share this blog♥️</p>
]]></content:encoded></item><item><title><![CDATA[Kubernetes RBAC]]></title><description><![CDATA[In this blog, we will learn about the Kubernetes RBAC concept. RBAC is a simple yet complex feature of Kubernetes because it is directly related to security. It is more important to understand the RBAC concepts than the roles, service account, and ro...]]></description><link>https://blogs.subashneupane3.com.np/kubernetes-rbac</link><guid isPermaLink="true">https://blogs.subashneupane3.com.np/kubernetes-rbac</guid><category><![CDATA[cluster role]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[rbac]]></category><category><![CDATA[clusterrolebindings]]></category><category><![CDATA[secrets]]></category><dc:creator><![CDATA[Subash Neupane]]></dc:creator><pubDate>Thu, 25 Jan 2024 15:09:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1706188414988/3131c48f-f8c5-4ec5-a798-714a0ff5635b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we will learn about the Kubernetes RBAC concept. RBAC is a simple yet complex feature of Kubernetes because it is directly related to security. It is more important to understand the RBAC concepts than the roles, service account, and role binding.</p>
<p>RBAC is abbreviated as "Role Based Access Control". It can be broadly devided into two groups:</p>
<ul>
<li><p>Users Management<br />  While acting as a root user in local development, such as when using Minikube, security considerations may not be as crucial. However, in organizational settings where multiple users have access to the cluster, there is a potential risk of users inadvertently or maliciously modifying sensitive resources. To avoid this risk, the cluster administrator or DevOps engineer must define user access, specifying who can access the cluster and edit resources. Role-Based Access Control (RBAC) is employed for this purpose, enabling DevOps engineers to define access based on roles..</p>
</li>
<li><p>Service Accounts</p>
<p>  Similar to User management, we can manage access to the services or the applications that are running on the Kubernetes cluster.</p>
</li>
</ul>
<p>Here are some key concepts in RBAC:</p>
<ol>
<li><p>Service Accounts/Roles</p>
</li>
<li><p>Role/ cluster role Bindings</p>
<ol>
<li>Role Binding/ClusterRoleBindings<br /> Kubernetes does not manage the users. Kubernetes offloads the user management to the Identity providers. For example, if we try to log into any application, we don't need to create a user account, we can simply use multiple options such as signing in with Google, Facebook, Twitter, GitHub, Instagram, and so on. This is exactly what Kubernetes does. It does not create the user but will pass it to the Identity providers. So the Kubernetes API server acts as an OAuth server which passes it to the identity providers.</li>
</ol>
</li>
</ol>
<p>If our cluster is in Amazon EKS, then we can use the AWS IAM users to log into the Kubernetes Cluster for which we need to create the IAM OAuth provider.</p>
<p>To grant access to users, we will first create the roles and assign these roles to the developers. The role is a YAML file where we mention the grants to be provided to the users. If the role is created within a specific namespace,then it is a role, but if the role is created across the cluster then it is called a cluster role.</p>
<p>To attach these roles to the users/developers, we will use the role-binding.</p>
<p>To create the service account in the required namespace.</p>
<pre><code class="lang-plaintext">kubectl -n kube-system create serviceaccount subash
</code></pre>
<blockquote>
<p>From Kubernetes Version 1.24, the secret for the service account has to be created separately with annotation</p>
</blockquote>
<p><strong>subash-secret.yaml</strong></p>
<pre><code class="lang-plaintext">apiVersion: v1
kind: Secret
metadata:
  name: subash
  namespace: kube-system
  annotations:
    kubernetes.io/service-account.name: subash
type: kubernetes.io/service-account-token
</code></pre>
<p>Create the cluster Role</p>
<p><strong>subash-cluster-role.yaml</strong></p>
<p>This YAML file creates only ready access to all namespaces</p>
<pre><code class="lang-plaintext">apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: subash
rules:
  #Allow read access to Pods and related resources in all namespaces.
  - apiGroups:
      - ""
    resources:
      - pods
      - pods/log
      - pods/status
      - pods/portforward
      - namespaces
      - services
      - cronjobs
    verbs:
      - get
      - list
      - watch
      - create
      - update
</code></pre>
<p>Cluster Role Binding</p>
<p><strong>subash-cluster-role-binding.yaml</strong></p>
<pre><code class="lang-plaintext">apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: subash-binding
subjects:
  - kind: ServiceAccount
    name: subash
    namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: subash
</code></pre>
<p>We've successfully created a Service Account named "<strong>subash</strong>" in the "kube-system" namespace, along with a corresponding secret. Additionally, we've created a ClusterRole named "<strong>subash</strong>" that provides read access to specific resources across all namespaces. We've also created a ClusterRoleBinding that associates the "<strong>subash</strong>" ServiceAccount with the "<strong>subash</strong>" ClusterRole in the "kube-system" namespace.</p>
<p>Now, if we want to use this Service Account in a Pod within the "kube-system" namespace or another namespace, we need to reference the Service Account in our Pod specification.</p>
<p><strong>spec.yml</strong></p>
<pre><code class="lang-plaintext">apiVersion: v1
kind: Pod
metadata:
  name: example-pod
  namespace: kube-system
spec:
  serviceAccountName: subash  # Reference the Service Account here
  containers:
  - name: my-container
    image: nginx:latest
</code></pre>
<p>Apply the pod</p>
<pre><code class="lang-plaintext">kubectl apply -f pod-spec.yaml
</code></pre>
<p>After applying the Pod specification, the Pod will run with the specified Service Account, and it will have the permissions defined in the "<strong>subash</strong>" ClusterRole. Adjust the Pod specification based on your application's requirements and the level of access needed for the Service Account.</p>
<p>I hope you liked this blog. If any mistake, do comment down below 🚀.</p>
<p>Do like and share this blog♥️</p>
]]></content:encoded></item><item><title><![CDATA[Securing AWS Instances with HashiCorp Vault and Terraform]]></title><description><![CDATA[In this blog, we will deep dive into the Terraform Vault. Terraform Vault is a Hashicorp tool that can store and manage different secrets such as tokens, passwords, API tokens, certificates, and so on. By smoothly integrating the terraform with the H...]]></description><link>https://blogs.subashneupane3.com.np/securing-aws-instances-with-hashicorp-vault-and-terraform</link><guid isPermaLink="true">https://blogs.subashneupane3.com.np/securing-aws-instances-with-hashicorp-vault-and-terraform</guid><category><![CDATA[Terraform]]></category><category><![CDATA[hashicorp-vault]]></category><category><![CDATA[AWS]]></category><category><![CDATA[secrets]]></category><category><![CDATA[instance]]></category><dc:creator><![CDATA[Subash Neupane]]></dc:creator><pubDate>Wed, 24 Jan 2024 15:12:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1706108182445/0c0e019a-c84c-4ef8-aa48-114d70c71e0f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we will deep dive into the Terraform Vault. Terraform Vault is a Hashicorp tool that can store and manage different secrets such as tokens, passwords, API tokens, certificates, and so on. By smoothly integrating the terraform with the Hashicorp vault, can ensure the integrity of our sensitive data and mitigate the risk of unauthorized access or data leaks. This integration empowers us to leverage secrets stored in the HashiCorp Vault directly within our Terraform workflows, enhancing security measures and safeguarding critical information.</p>
<p>Firstly, we will initiate the creation of an EC2 instance either manually from AWS ui or using Terraform. Subsequently, within the instance, our focus will shift to the installation of Hashicorp Vault. This installation lays the groundwork for subsequent integration with Terraform, establishing a smooth connection between the two tools. Through this orchestrated process, we aim to set up an environment where HashiCorp Vault becomes an integral part of our Terraform workflows, enhancing security and management of sensitive information.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706098409262/42934130-6902-44cf-9b15-62272045bc97.png" alt class="image--center mx-auto" /></p>
<p>Our instance is created and ready.</p>
<p>In the ec2 instance, we will install the Vault.</p>
<p><strong>Install gpg</strong></p>
<pre><code class="lang-plaintext">sudo apt update &amp;&amp; sudo apt install gpg
</code></pre>
<p><strong>Download the signing key to a new keyring</strong></p>
<pre><code class="lang-plaintext">wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
</code></pre>
<p><strong>Verify the key's fingerprint</strong></p>
<pre><code class="lang-plaintext">gpg --no-default-keyring --keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg --fingerprint
</code></pre>
<p><strong>Add the HashiCorp repo</strong></p>
<pre><code class="lang-plaintext">echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
</code></pre>
<pre><code class="lang-plaintext">sudo apt update
</code></pre>
<p><strong>Finally, Install Vault</strong></p>
<pre><code class="lang-plaintext">sudo apt install vault
</code></pre>
<p>To start the Vault</p>
<pre><code class="lang-plaintext">vault server -dev -dev-listen-address="0.0.0.0:8200"
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706099057523/01740d52-1077-4230-b755-b183a182bb0e.png" alt class="image--center mx-auto" /></p>
<p>After executing all the commands above, our vault is running successfully.</p>
<p>Open another terminal and log into the instance and run the following command that is displayed.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706099227200/c1d805f6-2c0a-4cf4-90ff-ffb4b61ed011.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706099320837/b6b2d5d1-4716-4e00-9834-6f7715dedaa5.png" alt class="image--center mx-auto" /></p>
<p>To access the vault we need to give the access to instance to access port 8200.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706099482468/b2d38167-38c9-4d2d-932f-c2d8e4028b91.png" alt class="image--center mx-auto" /></p>
<p>Lets access the Vault in http://<a target="_blank" href="http://3.88.160.206:8200">3.88.160.206:8200</a>/</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706099575549/815a95c0-9370-438b-a3a0-b237cf295cc3.png" alt class="image--center mx-auto" /></p>
<p>Now to log into the Vault, the token is available in the terminal. Copy the code and paste it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706099691856/7cdb2fe0-98e6-407e-9a8d-516ed09a28b5.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706099779714/94b679a3-1d5f-40d0-a108-393f15867176.png" alt class="image--center mx-auto" /></p>
<p>We have successfully logged into the Vault.</p>
<p>At the sidebar, we can see the Secret ENgines, Access, Policies. Let's know about these.</p>
<p><strong>Secret Engine</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706099975253/9d6fa0b6-b1e5-4640-b90e-7730856304e5.png" alt class="image--center mx-auto" /></p>
<p>The Secret Engine in HashiCorp Vault is responsible for managing and dispensing secrets, which are sensitive pieces of information such as API keys, passwords, or certificates. They are nothing but the different types of secrets that we can create in Hashicorp Vault.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706100334986/b8f0bf7b-5636-4c28-8938-ecf5d88c8826.png" alt class="image--center mx-auto" /></p>
<p>We create a simple engine and the engine is enabled. IT will be used to create the key-value pairs.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706100479834/d706b47c-1c9f-4ca8-98c9-e34bdb3f7b68.png" alt class="image--center mx-auto" /></p>
<p>A secret is created inside the Hashicorp Vault. only the root user has access to it. If anyone wants to access the secret through Terraform or Ansible, they need the grant. The grant is only possible from the <strong>Access</strong> feature of Vault. Here in the Hashicorp vault, Access can be considered as an IAM role and Policy can be considered as IAM policy.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706100929788/dfaa8761-6e50-45b2-8812-40603e96f3e9.png" alt class="image--center mx-auto" /></p>
<p>In the Access section, there are different authentication methods, we chose the AppRole. But we cannot create the role using UI, we need do it from the terminal.</p>
<p>Enable the authentication method</p>
<pre><code class="lang-plaintext">vault auth enable approle
</code></pre>
<p>Let's create the policy</p>
<pre><code class="lang-plaintext">vault policy write terraform - &lt;&lt;EOF
path "*" {
  capabilities = ["list", "read"]
}

path "secrets/data/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

path "kv/data/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}


path "secret/data/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

path "auth/token/create" {
capabilities = ["create", "read", "update", "list"]
}
EOF
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706104344710/ed64452c-8f9a-49a1-8e76-1f71a4ad696b.png" alt class="image--center mx-auto" /></p>
<p><strong>Create the Role</strong></p>
<pre><code class="lang-plaintext">vault write auth/approle/role/terraform \
    secret_id_ttl=10m \
    token_num_uses=10 \
    token_ttl=20m \
    token_max_ttl=30m \
    secret_id_num_uses=40 \
    token_policies=terraform
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706104383333/94530e28-1e1b-4f92-981e-69285637e1ac.png" alt class="image--center mx-auto" /></p>
<p>After creating the AppRole, you need to generate a Role ID and Secret ID pair. The Role ID is a static identifier, while the Secret ID is a dynamic credential.</p>
<p><strong>Generate Role ID</strong>:</p>
<pre><code class="lang-plaintext">vault read auth/approle/role/terraform/role-id
</code></pre>
<p><strong>Generate Secret ID</strong>:</p>
<pre><code class="lang-plaintext">vault write -f auth/approle/role/terraform/secret-id
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706104427374/5d6ba2e0-610d-4944-bf68-5af9a6bb298b.png" alt class="image--center mx-auto" /></p>
<p>We will create the instance and will use the secret created in the vault.</p>
<p><strong>main.tf</strong></p>
<pre><code class="lang-plaintext">provider "aws" {
  region = "us-east-1"
}

provider "vault" {
  address = "3.88.160.206:8200"
  skip_child_token = true

  auth_login {
    path = "auth/approle/login"

    parameters = {
      role_id = "ed169c1c-c96b-613a-479a-c1b82de9a720"
      secret_id = "5a65c56e-3132-2410-b83a-bd52658dfcf2"
    }
  }
}

data "vault_kv_secret_v2" "example" {
  mount = "kv" 
  name  = "test-secret" 
}

resource "aws_instance" "my_instance" {
  ami           = "ami-053b0d53c279acc90"
  instance_type = "t2.micro"

  tags = {
    Name = "test"
    Secret = data.vault_kv_secret_v2.example.data["subash"]
  }
}
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706102836322/56c72695-be80-497a-b14f-9454f08b299b.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-plaintext">terraform plan
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706105013828/4fbe2911-a11f-42e9-95b3-43a20ac0b073.png" alt class="image--center mx-auto" /></p>
<p>It shows the 1 to add and in the tag section name=" test" and secret="subash" will be imported from the hashicorp vault.</p>
<pre><code class="lang-plaintext">terraform apply
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706105738634/864cd6b5-7590-4023-9bf2-fe4ecbe1419f.png" alt class="image--center mx-auto" /></p>
<p>The Terraform apply is successful and the resource is added.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706105809298/eaef1121-8f3d-4618-b009-5ba014880c6d.png" alt class="image--center mx-auto" /></p>
<p>Our resource is created successfully.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706105858826/b1927572-43f8-457e-a34b-938eaf37d9c2.png" alt class="image--center mx-auto" /></p>
<p>We can see in the tag section the secret named "subash" is also imported from the Hashicorp vault that we had created earlier.</p>
<p>Destroy the resources</p>
<pre><code class="lang-plaintext">terraform destroy
</code></pre>
<p>This integration enhances the security of your infrastructure by centralizing and managing secrets in the HashiCorp Vault, allowing Terraform to securely access and use these secrets during infrastructure provisioning. It's a great practice for ensuring the integrity of sensitive data and minimizing the risk of unauthorized access or data leaks.</p>
<p>I hope you liked this blog. If any mistake, do comment down below 🚀.</p>
<p>Do like and share this blog♥️</p>
]]></content:encoded></item><item><title><![CDATA[Deploy an App using Terraform in AWS]]></title><description><![CDATA[In this blog, we will deploy an application in the AWS using the terraform. In this demo, a simple Python project will be deployed and run using Terraform. The application is simple and easy. We will be provisioning the different commands to run the ...]]></description><link>https://blogs.subashneupane3.com.np/deploy-an-app-using-terraform-in-aws</link><guid isPermaLink="true">https://blogs.subashneupane3.com.np/deploy-an-app-using-terraform-in-aws</guid><category><![CDATA[python application]]></category><category><![CDATA[file provision]]></category><category><![CDATA[remote provision]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Terraform]]></category><dc:creator><![CDATA[Subash Neupane]]></dc:creator><pubDate>Tue, 23 Jan 2024 15:15:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1706015647794/2fd246cc-8c93-4fea-bb6b-99868ca28a8e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we will deploy an application in the AWS using the terraform. In this demo, a simple Python project will be deployed and run using Terraform. The application is simple and easy. We will be provisioning the different commands to run the application.</p>
<p>We will copy the application code using file provision. The <strong>file</strong> provisioner is used to copy files or directories from the local machine to a remote machine. This is useful for deploying configuration files, scripts, or other assets to a provisioned instance.</p>
<p>The <strong>remote-exec</strong> provisioner is used to run scripts or commands on a remote machine over SSH connections. It's often used to configure or install software on provisioned instances.</p>
<p>Let's do it hands-on</p>
<p>We will create a simple Python application named <strong>"app.py"</strong></p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Flask

app = Flask(__name__)

<span class="hljs-meta">@app.route("/")</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">hello</span>():</span>
    <span class="hljs-keyword">return</span> <span class="hljs-string">"Hello, Terraform from DevOps Learner!"</span>

<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    app.run(host=<span class="hljs-string">"0.0.0.0"</span>, port=<span class="hljs-number">80</span>)
</code></pre>
<p>We created a simple Python application using the Flask framework. When it is executed, "Hello, Terraform from DevOps Learner!" will be printed in the browser.</p>
<p>Our application code is ready. Now let's provision the resources in the AWS.</p>
<p>Let's create the Terraform code <strong>"main.tf"</strong></p>
<p>Define the AWS provider configuration and all the resources that need to be created are explained in each block of code. We will merge these code at the end in the main.tf file.</p>
<pre><code class="lang-plaintext">provider "aws" {
  region = "us-east-1"  # Replace with your desired AWS region.
}

variable "cidr" {
  default = "10.0.0.0/16"
}
</code></pre>
<p>We provided the provider where we needed to create the resources. In this case, we have chosen the "aws" and the variable has a default value of "10.0.0.0/16," which represents the CIDR block for the VPC (Virtual Private Cloud).</p>
<p>Create key-pair</p>
<pre><code class="lang-plaintext">resource "aws_key_pair" "example" {
  key_name   = "terraform-demo-subash"  # Replace with your desired key name
  public_key = file("~/.ssh/id_rsa.pub")  # Replace with the path to your public key file
}
</code></pre>
<p>This block of code will create the key-pair file for the instance that is stored on our local machine.</p>
<ul>
<li>create VPC</li>
</ul>
<pre><code class="lang-plaintext">resource "aws_vpc" "myvpc" {
  cidr_block = var.cidr
}
</code></pre>
<p>In this block of code, the vpc will be created with the cidr that is declared in the variable block i.e 10.0.0.0/16.</p>
<ul>
<li>Create Subnet</li>
</ul>
<pre><code class="lang-plaintext">resource "aws_subnet" "sub1" {
  vpc_id                  = aws_vpc.myvpc.id
  cidr_block              = "10.0.0.0/24"
  availability_zone       = "us-east-1a"
  map_public_ip_on_launch = true
}
</code></pre>
<p>In this block of code, a subnet will be create with the single availabiltity zone.</p>
<ul>
<li>Create InternetGateway</li>
</ul>
<pre><code class="lang-plaintext">resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.myvpc.id
}
</code></pre>
<p>This block creates an internet gateway and associates it with the VPC.</p>
<ul>
<li>Create Route Table</li>
</ul>
<pre><code class="lang-plaintext">resource "aws_route_table" "RT" {
  vpc_id = aws_vpc.myvpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.igw.id
  }
}
</code></pre>
<p>This block creates a route table and adds a default route directing traffic to the internet gateway.</p>
<ul>
<li><strong>Route Table Association</strong></li>
</ul>
<pre><code class="lang-plaintext">resource "aws_route_table_association" "rta1" {
  subnet_id      = aws_subnet.sub1.id
  route_table_id = aws_route_table.RT.id
}
</code></pre>
<p>This block associates the subnet with the above route table.</p>
<ul>
<li><strong>Creating the security configuration</strong></li>
</ul>
<pre><code class="lang-plaintext">resource "aws_security_group" "webSg" {
  name   = "web"
  vpc_id = aws_vpc.myvpc.id

  ingress {
    description = "HTTP from VPC"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    description = "SSH"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "Web-sg"
  }
}
</code></pre>
<p>The <strong>ingress</strong> is used to configure the inbound configuration for the instance, we have added two security rules one for SSH and the other for TCP to serve the application. <strong>Egress</strong> is used to configure the outbound configuration for the instance</p>
<ul>
<li>Creating the ec2 instance</li>
</ul>
<pre><code class="lang-plaintext">resource "aws_instance" "server" {
  ami                    = "ami-0261755bbcb8c4a84"
  instance_type          = "t2.micro"
  key_name      = aws_key_pair.example.key_name
  vpc_security_group_ids = [aws_security_group.webSg.id]
  subnet_id              = aws_subnet.sub1.id
</code></pre>
<ul>
<li><strong>Connecting to the ec2-instance</strong></li>
</ul>
<pre><code class="lang-plaintext"> connection {
    type        = "ssh"
    user        = "ubuntu"  # Replace with the appropriate username for your EC2 instance
    private_key = file("~/.ssh/id_rsa")  # Replace with the path to your private key
    host        = self.public_ip
  }
</code></pre>
<ul>
<li><strong>File provision code</strong></li>
</ul>
<p>File provisioner to copy a file from local to the remote EC2 instance</p>
<pre><code class="lang-plaintext"> provisioner "file" {
    source      = "app.py"  # Replace with the path to your local file
    destination = "/home/ubuntu/app.py"  # Replace with the path on the remote instance
  }
</code></pre>
<ul>
<li><strong>Provision code</strong></li>
</ul>
<pre><code class="lang-plaintext">provisioner "remote-exec" {
    inline = [
      "echo 'Hello from the remote instance'",
      "sudo apt update -y",  # Update package lists (for ubuntu)
      "sudo apt-get install -y python3-pip",  # Example package installation
      "cd /home/ubuntu",
      "sudo pip3 install flask",
      "sudo python3 app.py &amp;",
    ]
  }
}
</code></pre>
<p>Now we will merge all code and apply the terraform commands.</p>
<p>Configure aws credentials</p>
<pre><code class="lang-plaintext">aws configure
</code></pre>
<pre><code class="lang-plaintext">terraform init
terraform plan
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706013014217/f8e5835e-1e21-495f-aa12-7cd430577140.png" alt class="image--center mx-auto" /></p>
<p>Here we will be creating the 8 resources.</p>
<pre><code class="lang-plaintext">terraform apply
</code></pre>
<p>g</p>
<p>All the resources are created successfully in our AWS account.</p>
<p>To list the resources created</p>
<pre><code class="lang-plaintext">terraform show
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706013631860/54bc5b0f-9af3-4aa3-ac70-d38931f8d722.png" alt class="image--center mx-auto" /></p>
<p>The instance is created and lets verify whether the app is running not.Copy the ip address of the instance and SSH into the instance.</p>
<pre><code class="lang-plaintext">ssh -i ~/.ssh/id_rsa ubuntu@public_ip
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706013997587/a6848cdb-bd8b-47d8-aec2-2fc8667be0e2.png" alt class="image--center mx-auto" /></p>
<p>Our app is inside the ec2 instance and the python3 is also installed but the application is not running. Since we had added "&amp;" at the end of the code and this code takes more time than the normal one so the terraform exits the process and moves to the other processes.</p>
<pre><code class="lang-plaintext">sudo python3 app.py
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706014304371/61fff2df-faf6-489b-9711-eeee24e302d6.png" alt class="image--center mx-auto" /></p>
<p>Great!! Our application is successfully deployed using the Terraform.</p>
<p>Delete the resources</p>
<pre><code class="lang-plaintext">terraform destroy
</code></pre>
<p>Throughout the entire blog, we covered the essential steps of creating AWS resources, including a VPC, subnet, security group, and EC2 instance, all orchestrated through Terraform's Infrastructure-as-Code (IaC) capabilities. The use of variables enhances flexibility, and the <strong>file</strong> and <strong>remote-exec</strong> provisioners enabled the smooth deployment of both infrastructure and application code.<br />Happy Learning!!</p>
]]></content:encoded></item><item><title><![CDATA[Terraform: Remote Backends and State Locking in Action]]></title><description><![CDATA[In this blog, we will learn about the different files used in Terraform while creating the resources. As the Terraform files especially state files, and lock files are sensitive we will look at how we can store these sensitive files remotely and acce...]]></description><link>https://blogs.subashneupane3.com.np/terraform-remote-backends-and-state-locking-in-action</link><guid isPermaLink="true">https://blogs.subashneupane3.com.np/terraform-remote-backends-and-state-locking-in-action</guid><category><![CDATA[state locking]]></category><category><![CDATA[Terraform]]></category><category><![CDATA[terraform-state]]></category><category><![CDATA[terraform remote backend]]></category><category><![CDATA[AWS]]></category><category><![CDATA[DynamoDB]]></category><dc:creator><![CDATA[Subash Neupane]]></dc:creator><pubDate>Mon, 22 Jan 2024 15:14:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1705925240673/184130c2-af4a-421c-a4d9-17f7a708d6ef.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we will learn about the different files used in Terraform while creating the resources. As the Terraform files especially state files, and lock files are sensitive we will look at how we can store these sensitive files remotely and access them securely. Let's know about the Terraform state files, and lock files, and get knowledge practically.</p>
<p><strong>Terraform State files</strong></p>
<p>Terraform state files commonly named "terraform.tfstate" maintain the current state of deployed infrastructures. These files store configurations, dependencies, and other essential information for Terraform to make informed decisions during subsequent runs. These files are updated upon each resource created.</p>
<p><strong>Advantages of Terraform State File:</strong></p>
<ul>
<li><p>Resource Tracking</p>
</li>
<li><p>Concurrency Control</p>
</li>
<li><p>Stores metadata of each resource</p>
</li>
</ul>
<p><strong>Disadvantage:</strong><br />Security Risk - If the state files are exposed then much sensitive information will be leaked.</p>
<p>To overcome the disadvantages, a remote backend will be used to store the Terraform state file outside of our local file system and version control. Using S3 as a remote backend is a popular choice due to its reliability and scalability.</p>
<p><strong>Terraform State Locking</strong></p>
<p>The lock file, typically ".terraform.lock.hcl", prevents concurrent modifications to the Terraform state. This helps avoid conflicts when multiple users or processes attempt to apply changes simultaneously. Suppose if two users are concurrently trying to create the resources in the cloud provider then the terraform will be confused whom to allow and whom not to allow. It cannot allow multiple users to create resources simultaneously. So, state locking is introduced which will allow only a user at a time to deploy the resourcesYour explanation is generally correct, but there seems to be a small confusion in the file name and some clarifications could be made. Here's a refined version:</p>
<hr />
<p><strong>Terraform State Locking</strong></p>
<p>The lock file in Terraform, typically named <strong>".terraform.lock.hcl",</strong> serves an important role in preventing concurrent modifications to the Terraform state. When multiple users or processes attempt to apply changes simultaneously, conflicts can arise. For instance, consider a scenario where two users are concurrently trying to create resources in a cloud provider(like AWS) using Terraform. Without state locking, Terraform might become confused about which changes to accept and which to reject.</p>
<p>The purpose of state locking is to ensure that only one user at a time can deploy changes to the infrastructure. This process prevents conflicts and maintains the integrity of the Terraform state. By using the lock file, Terraform serializes the execution of operations, allowing for a controlled and orderly deployment process. This is especially important in collaborative environments(like in organizations, or companies) where multiple users may be managing the same infrastructure concurrently.</p>
<p>Therefore, state locking is a protective measure that helps manage the coordination of Terraform operations, avoiding the potential pitfalls of conflicting changes when working on shared infrastructure.</p>
<p>DynamoDB is used for state locking when a remote backend is configured. It ensures that only one user or process can modify the Terraform state at a time.</p>
<p>Let's do it practically.</p>
<p>Create <strong>main.tf</strong>, <strong>variables.tf</strong> and <strong>terraform.tfvars</strong></p>
<pre><code class="lang-bash">provider <span class="hljs-string">"aws"</span> {
    region = <span class="hljs-string">"us-east-1"</span>

}
resource <span class="hljs-string">"aws_instance"</span> <span class="hljs-string">"subash_instance"</span> {
  ami = var.ami_value
  instance_type = var.instance_type_value
}
</code></pre>
<pre><code class="lang-bash">variable <span class="hljs-string">"ami_value"</span> {
    description = <span class="hljs-string">"ami value of the instance"</span>

}
variable <span class="hljs-string">"instance_type_value"</span> {
    description = <span class="hljs-string">"value for the instance type"</span>

}
</code></pre>
<pre><code class="lang-bash">ami_value = <span class="hljs-string">"ami-0c7217cdde317cfec"</span>
instance_type_value = <span class="hljs-string">"t2.micro"</span>
</code></pre>
<p>Let's deploy the resource</p>
<pre><code class="lang-bash">terraform init
terraform plan
terraform apply
</code></pre>
<p>Before this we need to configure the aws credentials</p>
<pre><code class="lang-bash">aws configure
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705915318456/ea09543b-7ce0-45a2-a4a6-971bcd7420d5.png" alt class="image--center mx-auto" /></p>
<p>We have configured the AWS credentials and now we are ready to deploy the resources using Terraform</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705916156544/26bfeb58-4ce7-4278-a976-ef366975bad7.png" alt class="image--center mx-auto" /></p>
<p>Resource is created and the state file is present.</p>
<p>To keep the statefile secure we will implement the remote backend. We will store the state file in the S3 bucket in AWS. For that, we will create the S3 bucket using Terraform.</p>
<p>In the main.tf file add the following resource</p>
<pre><code class="lang-bash">resource <span class="hljs-string">"aws_s3_bucket"</span> <span class="hljs-string">"s3_bucket"</span> {
    bucket = <span class="hljs-string">"subash1816-demo-bucket"</span>  
}
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705916388269/a15d96bd-62d8-4f9e-899e-0b0453a1c01f.png" alt class="image--center mx-auto" /></p>
<p>Let's verify if the bucket is created or not.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705916441697/673df213-0284-4703-b117-e21a97512b39.png" alt class="image--center mx-auto" /></p>
<p>Our bucket is created and now in this bucket, we will store the state file. For that we we create the <strong>backend.tf</strong> file.</p>
<pre><code class="lang-bash">terraform {
  backend <span class="hljs-string">"s3"</span> {
    bucket = <span class="hljs-string">"subash1816-demo-bucket"</span>
    key    = <span class="hljs-string">"subash/terraform.state"</span>
    region = <span class="hljs-string">"us-east-1"</span>
  }
}
</code></pre>
<p>In key attribute, we set the path for the state file to be stored. A Subash directory will be created and inside it we will have the state file.</p>
<pre><code class="lang-bash">terraform init
terraform apply
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705917988388/6bdcf726-b5ea-47e6-b02f-365c42db1eb1.png" alt class="image--center mx-auto" /></p>
<p>Once we hit the terraform apply, a folder named "subash" will be created and inside it the state file will be attached.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705918077433/2e388147-66d2-4f4d-85b6-107c3627aa62.png" alt class="image--center mx-auto" /></p>
<p>We can see inside the bucket, subash is the folder and terraform.state file is attached.</p>
<p>Now we will delete the terraform.state locally and we will hit the terraform apply command and check whether the new resources will be created or not.</p>
<p>As per the Terraform, when the state file is deleted, terraform will have no any data on whether the resource is created or not and it cannot compare the resources to be created with the provisioned resources since there is no state file. Without the state file, Terraform won't be able to track the current state of the infrastructure it manages.</p>
<p>In our case, the local state file will be deleted but the remote state file is present. So let's check it out.</p>
<p><strong>Apply:</strong></p>
<pre><code class="lang-bash">terraform init
terraform apply
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705918648239/2bf1b463-4925-4b1b-b986-6a723ccbe5a8.png" alt class="image--center mx-auto" /></p>
<p>To Implement the state-locking mechanism</p>
<p>To create the dynamodb, add the dynamodb resource in the main.tf file.</p>
<pre><code class="lang-bash">resource <span class="hljs-string">"aws_dynamodb_table"</span> <span class="hljs-string">"terraform_lock"</span> {
  name           = <span class="hljs-string">"terraform-lock"</span>
  billing_mode   = <span class="hljs-string">"PAY_PER_REQUEST"</span>
  hash_key       = <span class="hljs-string">"LockID"</span>

  attribute {
    name = <span class="hljs-string">"LockID"</span>
    <span class="hljs-built_in">type</span> = <span class="hljs-string">"S"</span>
  }
}
</code></pre>
<p>In the backend, add the following attribute.</p>
<pre><code class="lang-bash">encrypt        = <span class="hljs-literal">true</span>
dynamodb_table = <span class="hljs-string">"terraform-lock"</span>
</code></pre>
<p>Here once init the terraform, we will face the problem.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705921189330/bb08f3ae-5505-4502-a372-d51a3f583945.png" alt class="image--center mx-auto" /></p>
<p>So we need to create the s3, dynamodb before creating the remote backend.</p>
<p>So we deleted the backend.tf and applied the following command.</p>
<pre><code class="lang-bash">terraform init
terraform apply
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705922178486/a2577924-7b30-4a16-acdb-cfb1fe957433.png" alt class="image--center mx-auto" /></p>
<p>Our resources are created again. Now we will create the backend.tf</p>
<p>Previously we were not able to create the table since there was error. But now we are able to get the dynamodb table.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705922402480/53838c3f-91e0-475d-801f-fe8a0816cc85.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-bash">terraform {
  backend <span class="hljs-string">"s3"</span> {
    bucket = <span class="hljs-string">"subash1816-demo-bucket"</span>
    key    = <span class="hljs-string">"subash/terraform.state"</span>
    region = <span class="hljs-string">"us-east-1"</span>
    encrypt = <span class="hljs-literal">true</span>
    dynamodb_table = <span class="hljs-string">"terraform-lock"</span>
  }
}
</code></pre>
<p>Once the backend.tf is ready. Apply the command.</p>
<pre><code class="lang-bash">terraform init
terraform apply
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705923680916/c2c85935-2dfc-4d46-b5f8-e0a3f8ac499a.png" alt class="image--center mx-auto" /></p>
<p>Therefore, we have enabled the state locking by using the Dynamodb. DynamoDB is used by Terraform as a backend to store the state file and manage the state lock.</p>
<p>Terraform Destroy</p>
<p>Once the provision is completed, delete the resources.</p>
<pre><code class="lang-bash">terraform destroy
</code></pre>
<p>Great!! Using the blog, we explored the critical aspects of Terraform state files and state locking for secure infrastructure deployment in the cloud. This approach ensures that sensitive information is stored securely, conflicts are avoided, and infrastructure changes are managed in a controlled manner.</p>
<p>Happy Learning!!</p>
]]></content:encoded></item><item><title><![CDATA[Terraform: Launching the first infrastructure in AWS]]></title><description><![CDATA[In this blog, we will deep dive into the Terraform infrastructure deployment in the AWS cloud. Terraform has emerged as one of the top IaC tools to deploy infrastructures in the cloud. Let's learn more about the Terraform along with the hands-on expe...]]></description><link>https://blogs.subashneupane3.com.np/terraform-launching-the-first-infrastructure-in-aws</link><guid isPermaLink="true">https://blogs.subashneupane3.com.np/terraform-launching-the-first-infrastructure-in-aws</guid><category><![CDATA[AWS]]></category><category><![CDATA[Terraform]]></category><category><![CDATA[Infrastructure as code]]></category><category><![CDATA[EC2 instance]]></category><dc:creator><![CDATA[Subash Neupane]]></dc:creator><pubDate>Sun, 21 Jan 2024 15:06:31 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1705833072682/98e1f981-86bc-4df5-bc68-96bc934de3d1.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we will deep dive into the Terraform infrastructure deployment in the AWS cloud. Terraform has emerged as one of the top IaC tools to deploy infrastructures in the cloud. Let's learn more about the Terraform along with the hands-on experience.</p>
<h3 id="heading-terraform">Terraform</h3>
<p>Terraform is an open-source infrastructure as code (IaC) tool that allows us to define and provision infrastructure in a declarative configuration language. Terraform is a simple and superfast infrastructure deploying the tool. It supports different cloud providers like AWS, GCP, Azure, and so on.</p>
<p>Advantages of Terraform</p>
<ul>
<li><p>Infrastructure as Code</p>
</li>
<li><p>Multi-cloud support</p>
</li>
<li><p>Scalability</p>
</li>
<li><p>Community driven</p>
</li>
</ul>
<p>Terraform lifecycle</p>
<p>Terraform has a lifecycle that defines the stages involved in managing infrastructure using Terraform configurations. Here are the key stages in the Terraform lifecycle:</p>
<ul>
<li><p>Terraform init - Terraform downloads the required provider plugins and sets up the working directory in this stage.</p>
</li>
<li><p>Terraform Plan - In this stage, Terraform analyzes the configuration files and the current state of the infrastructure to determine what changes need to be made</p>
</li>
<li><p>Terraform Apply - In this stage Terraform executes the planned changes to the infrastructure and creates the infrastructure.</p>
</li>
<li><p>Terraform Destroy - In this stage the Terraform deletes all the infrastructures that were created/deployed.</p>
</li>
</ul>
<p>In Terraform HCL language is used. We can not remember the codes to create any resource so we will take the references from the official documentation.</p>
<p>Create an ec2 instance in the AWS using Terraform as IaC.</p>
<p>main.tf</p>
<pre><code class="lang-haml">provider "aws" {
    region = "us-east-1"

}
resource "aws_instance" "ubuntu" {
    ami = "ami-0c7217cdde317cfec"
    instance_type = "t2.micro"
    key_name = "nod.pem"

}
</code></pre>
<blockquote>
<p>Provider block specifies the provider for which we are configuring resources, in this case, it's the AWS provider and the region specifies at which location we are creating the resources.</p>
<p>In the resource block, aws_instance is the type of resource and the instance will be referred as "ubuntu". The remaining attributes like ami, instance_type are the mandatory attributes so we had mentioned in the code.</p>
</blockquote>
<p>Since we are creating the infrastructure in AWS, we will configure the AWS credentials in our terminal first.</p>
<pre><code class="lang-bash"> aws configure
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705834435034/8d284362-deda-42ed-aef7-eecad6101dd6.png" alt class="image--center mx-auto" /></p>
<p>We have our main.tf file and AWS is configured. Let's use the Terraform command.</p>
<pre><code class="lang-bash">Terraform init
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705834545501/f1ff0ed2-2c4a-416e-a4be-167227afa4ee.png" alt class="image--center mx-auto" /></p>
<p>Terraform is initialized successfully.</p>
<pre><code class="lang-bash">terraform plan
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705834841664/3489f60e-30ca-49fe-83f8-ee7dbb8a00c7.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-bash">terraform apply
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705835053593/c51285cd-f3db-42d7-bdab-a56ed8cf7339.png" alt class="image--center mx-auto" /></p>
<p>Once we hit the command, we need to enter a value "yes" to start the creation of resources. If not entered the resources will not be created.<br />Our resource is created and we will verify in AWS.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705835405697/1e14be1b-26ed-422c-b204-242f5cbc536d.png" alt class="image--center mx-auto" /></p>
<p>The ec2 instance is created successfully.</p>
<p>Destroy the resource</p>
<pre><code class="lang-bash">terraform destroy
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705839110198/696ad6f2-a793-4c32-a0af-09f8eb9c08ff.png" alt class="image--center mx-auto" /></p>
<p>The resource is destroyed successfully.</p>
<p><strong>Case2: Creating resources using variables and output</strong><br />But if we look at the code sensitive information like ami id, and instance type are exposed which should be kept secured. For this case, we will use the variables and if we want to get some information after the resources are created we will get that via the output.tf.</p>
<p>Let's create the resource using the variables and output.</p>
<p><strong>main.tf</strong></p>
<pre><code class="lang-bash">provider <span class="hljs-string">"aws"</span> {
    region = var.aws_region

}
resource <span class="hljs-string">"aws_instance"</span> <span class="hljs-string">"ubuntu"</span> {
    ami = var.ami_value
    instance_type = var.instance_type_value

}
</code></pre>
<p><strong>variables.tf</strong></p>
<pre><code class="lang-bash">variable <span class="hljs-string">"aws_region"</span> {
    description = <span class="hljs-string">"AWS region where the resources will be created"</span>

}
variable <span class="hljs-string">"ami_value"</span> {
    description = <span class="hljs-string">"value for the ami"</span>


}

variable <span class="hljs-string">"instance_type_value"</span> {
    description = <span class="hljs-string">"value for the instance type"</span>

}
</code></pre>
<p><strong>terraform.tfvars</strong></p>
<pre><code class="lang-bash">aws_region = <span class="hljs-string">"us-east-1"</span>
ami_value = <span class="hljs-string">"ami-0c7217cdde317cfec"</span>
instance_type_value = <span class="hljs-string">"t2.micro"</span>
</code></pre>
<p>terraform.tfvars is a file that allows us to store and organize variable values separately from our main Terraform configuration files. This file typically contains values for variables used in our Terraform configurations, and it provides a way to keep sensitive or environment-specific information separate from the main code.</p>
<p><strong>output.tf</strong></p>
<pre><code class="lang-bash">output <span class="hljs-string">"public-ip-address"</span> {
 value = aws_instance.ubuntu.public_ip 
}
</code></pre>
<p>This output definition allows us to easily access the public IP address once the Terraform configuration is applied. Output.tf files are useful for retrieving information about the provisioned infrastructure.</p>
<p>Our configuration is completed and let's deploy it.</p>
<p><strong>Terraform commands</strong></p>
<pre><code class="lang-bash">terraform init
terraform plan
terraform apply
</code></pre>
<p>Once these commands are run one by one we will get the following output at the end.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705837107547/6e3c2c23-ac3b-4eae-aec2-3f46ac54fc97.png" alt class="image--center mx-auto" /></p>
<p>As we mentioned the public IP address to be exposed in the output file, the public ip address is displayed. Let's verify it in the AWS.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705837223979/90dc4188-bb63-45f4-a3b2-67c9ad328608.png" alt class="image--center mx-auto" /></p>
<p>We can verify the public IP is the same i.e. 3.88.201.167. We have successfully created the resource and exposed the public IP.</p>
<p>Destroy the resources</p>
<pre><code class="lang-bash">terraform destroy
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705838993374/7faf69dd-ae7e-4fe7-8c62-fc1e332a8204.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705839266642/6f10f26d-9310-461c-8ce4-9a6db0e249fa.png" alt class="image--center mx-auto" /></p>
<p>We had created the two ec2 instances using different approaches are now terminated using the terraform command.</p>
<p>Through this hands-on experience, we demonstrated the creation of an EC2 instance in the AWS cloud, incorporating variables and outputs for enhanced security and information retrieval.</p>
<p>Happy Learning!!</p>
]]></content:encoded></item><item><title><![CDATA[Deploying a classic 2048 game on EKS]]></title><description><![CDATA[In this blog, we will do a real-time project based on EKS. But before deep dive into the project let's know about the EKS and its features.
What is EKS?
EKS, abbreviated as "Elastic Kubernetes Service", is an AWS service managed by the Amazon Web Ser...]]></description><link>https://blogs.subashneupane3.com.np/deploying-a-classic-2048-game-on-eks</link><guid isPermaLink="true">https://blogs.subashneupane3.com.np/deploying-a-classic-2048-game-on-eks</guid><category><![CDATA[application load balancer]]></category><category><![CDATA[AWS]]></category><category><![CDATA[EKS]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[vpc]]></category><category><![CDATA[2048 game]]></category><dc:creator><![CDATA[Subash Neupane]]></dc:creator><pubDate>Sat, 20 Jan 2024 15:11:05 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1705755878231/91dd94c1-d081-4e91-9658-6003e8db9f13.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we will do a real-time project based on EKS. But before deep dive into the project let's know about the EKS and its features.</p>
<p>What is EKS?</p>
<p>EKS, abbreviated as "Elastic Kubernetes Service", is an AWS service managed by the Amazon Web Service. Kubernetes is an open-source container orchestration platform that automates the deployment, scaling, and management of containerized applications.</p>
<p>With Amazon EKS, we can easily run K8s on AWS without having to manage any underlying infrastructure. It simplifies the process of setting up, operating, and scaling a K8s cluster. We can easily deploy, manage, and scale the containerized applications using Kubernetes while taking advantage of AWS services.</p>
<p><strong>The objective of the project:</strong> <em>To install the 2048 game on the EKS cluster in AWS. The game will be deployed in the private subnet and will be accessed from the external world in the public subnet via the Application Load Balancer (ALB)</em></p>
<p><strong>Prerequisites:</strong></p>
<ul>
<li><p>kubectl</p>
<p>  use the link: <a target="_blank" href="https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/">https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/</a></p>
</li>
<li><p>eksctl</p>
<pre><code class="lang-bash">  sudo wget -O /usr/<span class="hljs-built_in">local</span>/bin/eksctl https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz
  sudo chmod +x /usr/<span class="hljs-built_in">local</span>/bin/eksctl
  file /usr/<span class="hljs-built_in">local</span>/bin/eksctl
  eksctl version
</code></pre>
</li>
<li><p>AWS CLI</p>
<pre><code class="lang-bash">  sudo apt update
  sudo apt install -y awscli
</code></pre>
</li>
</ul>
<p>Download these tools on your machine if they are not installed. We can look for the official documentation for the installation of these tools.</p>
<p>Configure the AWS credentials</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705746287154/42d8865f-5889-4954-bd54-529af2c45bcb.png" alt class="image--center mx-auto" /></p>
<p>Configure your account details then only we can access the AWS services and able to create the EKS cluster in AWS.</p>
<p>Once the credentials are successfully done then create the EKS cluster.</p>
<p>Create a cluster using Fargate</p>
<pre><code class="lang-bash">eksctl create cluster --name game-cluster --region us-east-1 --fargate
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705746784062/7d65ac0d-84b5-42e2-8572-6abb67b97b3e.png" alt class="image--center mx-auto" /></p>
<p>Be patient and wait for the cluster to be created. It takes around 8-10 minutes to create the cluster.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705747672178/fa00542e-493f-4f8d-916a-43fdecaab5dd.png" alt class="image--center mx-auto" /></p>
<p>Our EKS cluster is ready now.</p>
<p>Update the kube-config file</p>
<p>We need to update the kubectl to work with our EKS cluster.</p>
<pre><code class="lang-bash">aws eks update-kubeconfig --name game-cluster --region us-east-1
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705747951589/3f144775-fc25-499f-bd43-a287729b1584.png" alt class="image--center mx-auto" /></p>
<p>The file is updated.</p>
<p>Let's create a deployment file for the 2048 game</p>
<p>First of all, let's create a fargate profile.</p>
<pre><code class="lang-bash">eksctl create fargateprofile \
    --cluster demo-cluster \
    --region us-east-1 \
    --name alb-sample-app \
    --namespace game-2048
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705749140411/9ba98b60-2040-4350-ab8c-0c0fa617eb87.png" alt class="image--center mx-auto" /></p>
<p>We can verify in the compute section of the cluster whether the profile is created or not.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705749235579/ab6d85cf-24da-4a72-b3fe-16425fdb738b.png" alt class="image--center mx-auto" /></p>
<p>The Fargate profile is created successfully and the namespace is game-2048. We can create the instances on both the namespaces.</p>
<p>Deploy the Deployment, Service and Ingress</p>
<pre><code class="lang-bash">kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.5.4/docs/examples/2048/2048_full.yaml
</code></pre>
<p>This is taken from the official documentation of AWS. If you want to learn from official click <a target="_blank" href="https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html">here.</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705750197656/ba840002-f172-4a67-af80-a5927af4fbd4.png" alt class="image--center mx-auto" /></p>
<p>We can see the pods are running and also the service is in a running state, we can see it is running on the node port but the external IP is not allocated. It means anybody within AWS VPC or having access to the VPC can communicate with the pod using the Node IP along with the port. But to access this game from the external world or by the customers we have deployed the ingress.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705750505525/24f15bbc-1d1e-4500-9065-06eb42528405.png" alt class="image--center mx-auto" /></p>
<p>Ingress is created with the class <strong>alb</strong> and port 80 but not the address. Only with the address, the customers can access the game. The address is not allocated because the Ingress controller is not created.</p>
<p>So we will create an Ingress controller that will look after the Ingress resources and create and configure the entire load balancer.</p>
<p>Before creating the Ingress controller, configure the IAM OIDC provider.</p>
<pre><code class="lang-bash">eksctl utils associate-iam-oidc-provider --cluster <span class="hljs-variable">$cluster_name</span> --approve
<span class="hljs-comment">#replace the cluster name</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705751139140/9943505c-f406-484f-80f4-6c736d3cf37d.png" alt class="image--center mx-auto" /></p>
<p>IAM OIDC is integrated successfully.</p>
<p>Every controller in Kubernetes is a pod. So we will install an ALB controller and grant this to access the AWS services such as ALB.</p>
<p>Download IAM policy</p>
<pre><code class="lang-bash">curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.5.4/docs/install/iam_policy.json
</code></pre>
<p>Create an IAM policy</p>
<pre><code class="lang-bash">aws iam create-policy \
    --policy-name AWSLoadBalancerControllerIAMPolicy \
    --policy-document file://iam_policy.json
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705751597342/aff84e19-e16a-43ff-8783-ea1db8cf8778.png" alt class="image--center mx-auto" /></p>
<p>Create IAM Role</p>
<pre><code class="lang-bash">eksctl create iamserviceaccount \
  --cluster=&lt;your-cluster-name&gt; \
  --namespace=kube-system \
  --name=aws-load-balancer-controller \
  --role-name AmazonEKSLoadBalancerControllerRole \
  --attach-policy-arn=arn:aws:iam::&lt;your-aws-account-id&gt;:policy/AWSLoadBalancerControllerIAMPolicy \
  --approve
<span class="hljs-comment">#replace the cluster name and the AWS account ID in above code</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705751890347/c512752c-ddfa-4ac6-ad5b-fe04ba0e52c7.png" alt class="image--center mx-auto" /></p>
<p>The role is created successfully.</p>
<h3 id="heading-deploy-alb-controller"><strong>Deploy ALB controller</strong></h3>
<p>Add the Helm repo</p>
<pre><code class="lang-bash">helm repo add eks https://aws.github.io/eks-charts
</code></pre>
<p>Update the repo</p>
<pre><code class="lang-bash">helm repo update eks
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705752434066/4654061d-9cb8-4e65-b95d-36481be710c2.png" alt class="image--center mx-auto" /></p>
<p>Install the controller</p>
<pre><code class="lang-bash">helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system \
  --<span class="hljs-built_in">set</span> clusterName=&lt;your-cluster-name&gt; \
  --<span class="hljs-built_in">set</span> serviceAccount.create=<span class="hljs-literal">false</span> \
  --<span class="hljs-built_in">set</span> serviceAccount.name=aws-load-balancer-controller \
  --<span class="hljs-built_in">set</span> region=&lt;region&gt; \
  --<span class="hljs-built_in">set</span> vpcId=&lt;your-vpc-id&gt;
<span class="hljs-comment">#replace cluster name, region, vpc-id</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705752498462/5494bd61-ee3a-41e9-a0db-12132822af3b.png" alt class="image--center mx-auto" /></p>
<p>Load Balancer is installed perfectly without any errors.</p>
<p>Verify the Deployments</p>
<pre><code class="lang-bash">kubectl get deployment -n kube-system aws-load-balancer-controller
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705752759415/865676d0-50c0-48af-9208-87fd2f4f7d28.png" alt class="image--center mx-auto" /></p>
<p>The load balancer controller is running with 2 replicas.</p>
<p>Let us see whether this load balancer controller has created an application load balancer or not.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705753515150/525539cf-8d92-45d3-a239-bf25603ff34e.png" alt class="image--center mx-auto" /></p>
<p>We can see the load balancer was created by the load balancer controller just a few minutes ago.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705753639833/8ffb5084-7eae-4fc2-a1f3-1964c393a1bd.png" alt class="image--center mx-auto" /></p>
<p>Watching this ingress resource, the load balancer controller created the load balancer. Copy the address: <a target="_blank" href="http://k8s-game2048-ingress2-6d3ad9a3d9-1213836616.us-east-1.elb.amazonaws.com">k8s-game2048-ingress2-6d3ad9a3d9-1213836616.us-east-1.elb.amazonaws.com</a> and access it on the web browser.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705754580269/c816a135-103b-43fe-9719-0abc80a250dc.png" alt class="image--center mx-auto" /></p>
<p>So our game is live and we can enjoy the game. Congratulations on completing the project smoothly.</p>
<blockquote>
<p>Note: Delete all the resouces once the project is done.</p>
</blockquote>
<p>We celebrate the successful deployment of the classic 2048 game on an Amazon EKS cluster, showcasing the power and simplicity of managing containerized applications on AWS. By carefully installing tools like <strong>kubectl, aws cli,</strong> and <strong>eksctl</strong>, configuring AWS credentials, and creating an EKS cluster with Fargate profiles, we laid the foundation for a smooth deployment.</p>
<p>Utilizing K8s resources and the AWS Load Balancer Controller, we ensured secure external access to the game through an Application Load Balancer. The journey concluded with the satisfaction of witnessing the game go live. In the future, we will bring many more projects based on Kubernetes. Stay updated and keep learning.</p>
<p>Happy Learning!!</p>
]]></content:encoded></item><item><title><![CDATA[Unleashing the Power of AWS CloudWatch for Optimal Resource Management]]></title><description><![CDATA[In this blog, we will deep dive into one of the important services offered by Amazon Web Services (AWS) – CloudWatch. As businesses increasingly migrate to the cloud, effective monitoring and management become crucial. AWS CloudWatch emerges as a smo...]]></description><link>https://blogs.subashneupane3.com.np/unleashing-the-power-of-aws-cloudwatch-for-optimal-resource-management</link><guid isPermaLink="true">https://blogs.subashneupane3.com.np/unleashing-the-power-of-aws-cloudwatch-for-optimal-resource-management</guid><category><![CDATA[AWS]]></category><category><![CDATA[#CloudWatch]]></category><category><![CDATA[monitoring]]></category><category><![CDATA[alert]]></category><category><![CDATA[Alarms]]></category><category><![CDATA[sns]]></category><dc:creator><![CDATA[Subash Neupane]]></dc:creator><pubDate>Fri, 19 Jan 2024 15:12:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1705570635837/84ff74c5-30be-4989-a8c2-6e765caaa7d3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we will deep dive into one of the important services offered by Amazon Web Services (AWS) – CloudWatch. As businesses increasingly migrate to the cloud, effective monitoring and management become crucial. AWS CloudWatch emerges as a smooth solution, providing a set of tools to monitor, manage, and optimize our AWS resources.</p>
<p>AWS CloudWatch is a centralized monitoring service that allows users to gain insights into the performance and operational health of our AWS resources. It collects and tracks metrics, monitors log files, and sets alarms to notify users of potential issues.</p>
<p>Essentially, CloudWatch acts as the gatekeeper for AWS which will help us in monitoring, alerting, reporting, and logging.</p>
<p>Why do we need Cloudwatch?</p>
<p>Cloudwatch solves several critical challenges:</p>
<ul>
<li><p>Proactive Monitoring</p>
</li>
<li><p>Resource optimization</p>
</li>
<li><p>Automated Response</p>
</li>
<li><p>Log Management</p>
</li>
</ul>
<p>Advantages of AWS CloudWatch:</p>
<ul>
<li><p>Comprehensive Monitoring: CloudWatch allows you to monitor various AWS resources such as EC2 instances, RDS databases, Lambda functions, and more.Real-Time Metrics: It provides real-time monitoring of metrics, allowing you to respond quickly to any issues or anomalies that might arise.</p>
</li>
<li><p>Automated Actions: With CloudWatch Alarms, we can set up automated actions like triggering an Auto Scaling group to scale in or out based on certain conditions.</p>
</li>
<li><p>Log Insights: CloudWatch Insights lets us to analyze and search log data from various AWS services, making it easier to troubleshoot problems and identify trends.</p>
</li>
<li><p>Dashboards and Visualization: Create custom dashboards to visualize your application and infrastructure metrics in one place, making it easier to understand the overall health of your system.</p>
</li>
</ul>
<p><strong>Real Usage of AWS CloudWatch:</strong></p>
<p><strong>1. Auto Scaling:</strong> CloudWatch plays a pivotal role in Auto Scaling by monitoring metrics such as CPU utilization. When a threshold is breached, Auto Scaling can dynamically adjust the number of instances to maintain optimal performance.</p>
<p><strong>2. Application Monitoring:</strong> CloudWatch is extensively used for monitoring the performance of applications deployed on AWS. Metrics such as latency, error rates, and request counts help in identifying and resolving issues promptly.</p>
<p><strong>3. Cost Management:</strong> By closely monitoring resource utilization metrics, CloudWatch assists in optimizing costs by identifying underutilized or overprovisioned resources.</p>
<p><strong>4. Log Analysis:</strong> CloudWatch Logs are widely employed for centralized log management. Developers and administrators can easily search, analyze, and visualize logs to troubleshoot issues efficiently.</p>
<p>Let's get the knowledge of Cloudwatch practically.</p>
<p>Log into your AWS account and search <strong>cloudwatch.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705558275817/36d724f2-8ac0-4f6b-91dc-0a7b7240aadc.png" alt class="image--center mx-auto" /></p>
<p>Once we click the cloudwatch we will see the following interface.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705560122603/6df17221-5f12-4cf5-8193-7a2d495910f4.png" alt class="image--center mx-auto" /></p>
<p>If we click on Logs and then to log group, it will display all the logs of our activities without any configuration.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705560889425/7bcec57a-17dd-405c-8ddb-1517acbc05d5.png" alt class="image--center mx-auto" /></p>
<p>We can access these logs anytime whenever we need it. It also gives log insights if the query is passed to it.</p>
<p>Another feature is metrics. It provides information about disk utility, CPU information,ec2 instances, and many more.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705561121349/63332c1d-9b2e-47c4-8e4c-147300239dd6.png" alt class="image--center mx-auto" /></p>
<p>We can see that the cloudwatch is monitoring 1002 default metrics. If we click on each service, we can know at which parameter it is monitoring the services.</p>
<p>Create an ec2 instance.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705561865638/c3315ab5-c66b-497f-9b78-f1f2b97ead6d.png" alt class="image--center mx-auto" /></p>
<p>Our instance is created and access the instance using SSH protocol.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705562047750/0ec5353b-fadb-42d5-98f1-270cc2ce7853.png" alt class="image--center mx-auto" /></p>
<p>Successfully accessed and run the command "top" to get the resource utilization.</p>
<p>Now move to the cloudwatch and click on metrics, we will choose the ec2 instance.</p>
<p>We have selected the CPU utilization metrics.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705562641413/27201f7a-07c3-4ecc-aaeb-e1b3cd9205e3.png" alt class="image--center mx-auto" /></p>
<p>Even in the ec2 dashboard, we can see the different monitoring options.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705562758156/15e4e08a-b68a-484e-8933-0ddb6b105e0a.png" alt class="image--center mx-auto" /></p>
<p>These monitoring are all related to the cloudwatch only. If we click on <strong>Manage Detailed Monitoring</strong> and enable it, we will get the metric every 1 minute.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705562966131/73e5005c-edd3-4366-82e6-412283136994.png" alt class="image--center mx-auto" /></p>
<p>In the ec2 instance, we will create a Python program to simulate an increase in CPU usage for testing CloudWatch.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705563607978/95310512-d5e7-4332-b999-98b69f0ee766.png" alt class="image--center mx-auto" /></p>
<p>Now after a minute, we will check the Cloudwatch metrics.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705564062079/523dd168-0148-44eb-ba42-0b11319663ce.png" alt class="image--center mx-auto" /></p>
<p>We can see the spikes in the CPU graph.</p>
<p>With metrics, we knew the critical challenges via monitoring but to act upon the metrics is done by the alarm. If the metrics reach a certain point, then the alarm will alert the developers/ admins about the metrics.</p>
<p>Click on Alarms</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705564584459/ce8cdfaa-ca2c-4b21-90f8-c3e5dba7cef1.png" alt class="image--center mx-auto" /></p>
<p>Create the alarm.</p>
<p>Choose to Select a metric &gt; ec2 instance &gt; across all instances/per instance &gt;choose CPU utilization.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705565258473/e4ca6ea5-b5bf-4f44-91d5-a692b5017bdd.png" alt class="image--center mx-auto" /></p>
<p>We have set the parameters for the alarm. Whenever the CPU spikes 50% or more, the alarm will be sent to the admin/users.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705565584937/c620c7ac-eb70-4380-a286-d1f4fda6b337.png" alt class="image--center mx-auto" /></p>
<p>Create the Topic. Click Next.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705565927008/6e480321-4e36-4378-b018-66efab485762.png" alt class="image--center mx-auto" /></p>
<p>We have set the message information for the alarm also. Click on create alarm.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705566180603/9cdf6400-8954-485f-9a16-b634ada901d0.png" alt class="image--center mx-auto" /></p>
<p>We can see the alarm is not created in the dashboard but the message is alerted. Click here and view the message.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705566336111/a748b627-f6e6-4c8f-98f4-fe2e1da79135.png" alt class="image--center mx-auto" /></p>
<p>We need to confirm the subscription via email.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705566450706/de4cb1b6-ff18-46ad-b8b2-224cc556108c.png" alt class="image--center mx-auto" /></p>
<p>Click on confirm subscription.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705566500877/64e97426-8ed6-4ef8-af2f-51fb0c51eb7d.png" alt class="image--center mx-auto" /></p>
<p>Confirmed.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705566591384/960b60d2-dea4-4aa9-8367-952cd23e26c0.png" alt class="image--center mx-auto" /></p>
<p>Now it is activated. But we will not get any alarm notification because the alarm is not triggered.</p>
<p>We will trigger it by running the Python script again in our ec2 instance.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705566889110/da4e32bf-4ee9-4c91-8bfb-17ca81c84029.png" alt class="image--center mx-auto" /></p>
<p>We can see the spike has reached above the 50%(threshold). It must send the email regarding this event. Let's check the email.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705567000920/81aef2a8-c91f-4eca-8853-f6781102837e.png" alt class="image--center mx-auto" /></p>
<p>We have received the mail and it clearly says the CPU utilization reached 50%.</p>
<p>We have successfully configured the ec2 resources and monitored them via the Cloudwatch.</p>
<blockquote>
<p>Do not forget to delete the resources</p>
</blockquote>
<p>Therefore, AWS CloudWatch stands out as a vital ally in the cloud landscape, offering a centralized and smooth monitoring solution for AWS resources. The practical walkthrough showcased its seamless integration with EC2 instances and the creation of alarms for timely notifications. CloudWatch not only provides comprehensive insights but also empowers users to take meaningful actions, making it an indispensable tool for maintaining optimal performance and ensuring the reliability of AWS resources in dynamic cloud environments.</p>
<p>Happy Learning!!</p>
]]></content:encoded></item><item><title><![CDATA[Monitoring Kubernetes Cluster  with Prometheus and Grafana]]></title><description><![CDATA[In this blog, we will know how to monitor the Kubernetes cluster and
What is a Kubernetes cluster?
A Kubernetes cluster is a system for orchestrating and managing containerized applications, providing a platform for automating the deployment, scaling...]]></description><link>https://blogs.subashneupane3.com.np/monitoring-kubernetes-cluster-with-prometheus-and-grafana</link><guid isPermaLink="true">https://blogs.subashneupane3.com.np/monitoring-kubernetes-cluster-with-prometheus-and-grafana</guid><category><![CDATA[Kubernetes]]></category><category><![CDATA[cluster]]></category><category><![CDATA[monitoring]]></category><category><![CDATA[#prometheus]]></category><category><![CDATA[Grafana]]></category><category><![CDATA[helm chart]]></category><dc:creator><![CDATA[Subash Neupane]]></dc:creator><pubDate>Thu, 18 Jan 2024 15:27:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1705512743026/d81ec9d4-5ec0-4f49-9b0f-7f635f649b8d.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we will know how to monitor the Kubernetes cluster and</p>
<p><strong>What is a Kubernetes cluster?</strong></p>
<p>A Kubernetes cluster is a system for orchestrating and managing containerized applications, providing a platform for automating the deployment, scaling, and operation of application containers.</p>
<p>The cluster consists of two main components: the <strong>master node</strong> and <strong>worker nodes</strong>. The master node controls and manages the overall state of the cluster, including scheduling applications, maintaining cluster configuration, and responding to events. On the other hand, worker nodes host the actual containers and execute the workloads. They communicate with the master node, receive instructions, and ensure that containers are running as intended.</p>
<p>Kubernetes automates tasks such as container scheduling, load balancing, and self-healing, providing a robust and scalable platform for deploying and managing applications across diverse environments.</p>
<p><strong>Why monitoring is required?</strong></p>
<p>Monitoring a Kubernetes cluster is important because it helps you to:</p>
<ul>
<li><p>Detect and resolve issues with the cluster and its applications before they become major problems</p>
</li>
<li><p>Optimize the performance of the cluster and its applications by identifying bottlenecks and other inefficiencies</p>
</li>
<li><p>Track the health and utilization of cluster resources such as nodes, pods, deployments, and persistent storage</p>
</li>
</ul>
<p><strong>How monitoring of the Kubernetes Cluster is done?</strong></p>
<p>In this blog, monitoring of the Kubernetes cluster will be done using Prometheus and Grafana. It involves deploying Prometheus within the cluster to collect metrics from various components and store them in a time-series database.</p>
<p>Grafana is then installed to create customized dashboards that visualize real-time metrics fetched from Prometheus. This monitoring stack is often set up using Helm charts, simplifying deployment and configuration.</p>
<p>Let's delve into the monitoring of clusters practically.</p>
<p>Start the Minikube cluster</p>
<pre><code class="lang-xml">minikube start
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705491616097/5a1f6bce-3c48-4127-a4b1-8f83af24851e.png" alt class="image--center mx-auto" /></p>
<p>Our local cluster is ready using the Minikube and it is in running state.</p>
<p>We will install the Prometheus and Grafana using the helm. If the helm is not installed use this <a target="_blank" href="https://helm.sh/docs/intro/install/#:~:text=Installing%20Helm%201%20From%20The%20Helm%20Project%20The,simple%20as%20getting%20a%20pre-built%20helm%20binary.%20">link</a>.</p>
<p>Add the Helm chart for Prometheus</p>
<pre><code class="lang-bash">helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
</code></pre>
<p>Update the Helm repo for the latest updates</p>
<pre><code class="lang-bash">helm repo update
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705492122758/8d38fcff-598d-43d7-bba0-fe019461a1ed.png" alt class="image--center mx-auto" /></p>
<p>Install the Prometheus</p>
<pre><code class="lang-bash">helm install prometheus prometheus-community/prometheus
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705492398347/58c26d9f-0936-43e7-9093-b5e15f215a75.png" alt class="image--center mx-auto" /></p>
<p>Our Prometheus is installed and can be accessed via port 9091</p>
<p>Let's verify the Prometheus installation</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705492544154/21b83850-126e-48b2-a3a5-e53da0baea82.png" alt class="image--center mx-auto" /></p>
<p>The Prometheus pods are running along with the Prometheus server. Kube-state-metrics as seen in the image is used to expose some Kubernetes metrices like API servers, deployments, pods, etc.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705493091667/ad58d339-36e3-4b3f-a147-3b75fc4b55fc.png" alt class="image--center mx-auto" /></p>
<p>The Prometheus server is created using the ClusterIP mode. Let's convert this service into a Nodeport service.</p>
<p><strong>Expose Prometheus Service</strong></p>
<pre><code class="lang-bash">kubectl expose service prometheus-server --<span class="hljs-built_in">type</span>=NodePort --target-port=9090 --name=prometheus-server-ext
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705493554843/a3141a51-a19c-47c8-8bfd-dbada266abf6.png" alt class="image--center mx-auto" /></p>
<p>We exposed the Prometheus server using the node port and got the Kubernetes cluster ip using Minikube IP. Now we will access the Prometheus using http://192.168.58.2:31958</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705493690690/60c4144d-dbe1-4010-84f5-fafb57cf00ba.png" alt class="image--center mx-auto" /></p>
<p>Our Prometheus server is ready to serve. The first step for monitoring the cluster is done.</p>
<p>Grafana</p>
<p>Add the helm repo</p>
<pre><code class="lang-bash">helm repo add grafana https://grafana.github.io/helm-charts
</code></pre>
<p>Update the helm repo</p>
<pre><code class="lang-bash">helm repo update
</code></pre>
<p>Install the Grafana</p>
<pre><code class="lang-bash">helm install grafana grafana/grafana
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705494259743/7ea7a8c0-2ba4-42d9-92c6-5ae4c59ac70e.png" alt class="image--center mx-auto" /></p>
<p>So our Grafana is installed and running.</p>
<p>To get the password for the Grafana run the command as shown in the reference image.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705494388139/6a0d9690-22a1-44af-90fc-b6ea9d58a2f4.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705494473429/5b136bd9-11d2-42d5-90da-9458b16be2e0.png" alt class="image--center mx-auto" /></p>
<p>We can see that the grafana is running in the ClusterIP.</p>
<p>Expose the Grafana</p>
<pre><code class="lang-bash">kubectl expose service grafana — <span class="hljs-built_in">type</span>=NodePort — target-port=3000 — name=grafana-ext
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705494671735/4921a16e-c1d0-4bc3-99a6-0945226ae56b.png" alt class="image--center mx-auto" /></p>
<p>Grafana is exposed.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705494920973/10b77c35-4e91-4109-b7c8-ab3fb9e37ade.png" alt class="image--center mx-auto" /></p>
<p>We can easily access the Grafana login page.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705496165712/f9edf955-426a-4005-9ccb-67339842fd70.png" alt class="image--center mx-auto" /></p>
<p>Successfully logged into the Grafana dashboard.</p>
<p>Now we will add Prometheus as the data source.</p>
<p>Click on Data Source &gt; choose Prometheus.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705496745822/eece165d-0d08-4746-bc98-56b0a83acec6.png" alt class="image--center mx-auto" /></p>
<p>In the connection: insert the Prometheus URL.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705496824429/222d7471-b9a5-4543-9f4e-d0f82df562dc.png" alt class="image--center mx-auto" /></p>
<p>Click on Save and test.</p>
<p>Now click on Building a dashboard or from the homepage we can create the dashboard.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705497158258/212fb12f-92fc-4070-96ea-4d7cbc5ff422.png" alt class="image--center mx-auto" /></p>
<p>Instead of creating the dashboard from the beginning, we can simply import the dashboard that is already pre-built.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705497632051/ea99f494-876d-403d-822f-54547379e1f3.png" alt class="image--center mx-auto" /></p>
<p>From here we can copy the ID of the dashboard i.e. 13332</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705497698682/b3b2a7fc-05a1-4c4e-8636-1201e5340cbd.png" alt class="image--center mx-auto" /></p>
<p>Click on load to load the dashboard.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705497744710/2316dae9-62f0-4c80-b9e8-0bbc8d3a8e09.png" alt class="image--center mx-auto" /></p>
<p>Click on Import.</p>
<p>You can import the multiple dashboards.</p>
<p>Using the id:15282<br />And the Dashboard can be visualized as below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705497526701/1038ce80-463a-4274-a170-6f52902908bd.png" alt class="image--center mx-auto" /></p>
<p>Using the dashboard:3662</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705501431302/28080b03-b771-40bf-99d7-81372f43d369.png" alt class="image--center mx-auto" /></p>
<p>We can also expose the kube-state metrices.</p>
<p>To expose Kube-state metrics</p>
<pre><code class="lang-bash">kubectl expose service prometheus-kube-state-metrics  --<span class="hljs-built_in">type</span>=NodePort --target-port=8080 --name=prometheus-kube-state-metrics-ext
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705502161149/06bcbaa9-ec28-42d8-aea3-d3cc1c8c139f.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705502169854/530608f8-015e-45e1-9313-ee8abf0df97c.png" alt class="image--center mx-auto" /></p>
<p>We can also set this kube-state-metrics endpoint as a job in Kubernetes to know about the kube-state details.</p>
<p>Hence, the detailed steps covered the installation of both monitoring tools (Prometheus and Grafana) using Helm charts. The exposure of services via NodePort for simplicity, and the integration of pre-built dashboards in Grafana to visualize Kubernetes metrics.</p>
<p>It is important to note, however, that while using NodePort for external access is suitable for local or testing environments, it may not be the best practice for production setups. In production, a more secure and scalable approach involves utilizing an Ingress controller or LoadBalancer service type for external access to Prometheus and Grafana. These options provide better control over routing and security, ensuring a more robust and production-ready monitoring solution for Kubernetes clusters.</p>
<p>Happy Learning!!</p>
]]></content:encoded></item><item><title><![CDATA[AWS CloudFront:Unlocking Website Speed]]></title><description><![CDATA[In this blog, we will learn about one of the most exciting AWS services i.e. CloudFront.In the vast world of the internet, speed matters. Imagine your website as a superstar with fans around the globe. AWS CloudFront is like the manager making sure y...]]></description><link>https://blogs.subashneupane3.com.np/aws-cloudfrontunlocking-website-speed</link><guid isPermaLink="true">https://blogs.subashneupane3.com.np/aws-cloudfrontunlocking-website-speed</guid><category><![CDATA[AWS]]></category><category><![CDATA[cloudfront]]></category><category><![CDATA[S3]]></category><category><![CDATA[bucket]]></category><category><![CDATA[website]]></category><category><![CDATA[Static Website]]></category><category><![CDATA[CDN]]></category><dc:creator><![CDATA[Subash Neupane]]></dc:creator><pubDate>Wed, 17 Jan 2024 15:09:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1705504071649/c03d55b3-174c-4e82-a63a-b3329bf3b893.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we will learn about one of the most exciting AWS services i.e. CloudFront.In the vast world of the internet, speed matters. Imagine your website as a superstar with fans around the globe. AWS CloudFront is like the manager making sure your fans get the best experience, no matter where they are.</p>
<p><strong>CloudFront</strong></p>
<p>AWS CloudFront is like a magic carpet for our website. It's a content delivery service that helps our web pages, images, and videos around the world at lightning speed. How? By storing copies of your website's stuff in special places called edge locations.</p>
<p>CloudFront acts as a Content Delivery Network (CDN) service, strategically caching website content at its edge locations. These locations are strategically placed worldwide, aligning with where users access the data.</p>
<p>Consider a scenario where a website is initially uploaded from Australia, and users, like User1 in India and User2 in the US, access the same site. Without CloudFront, the website would take time to load for both users due to the geographical distance. However, with CloudFront in action, copies of the website are distributed to the nearest edge locations, such as India for User1 and the US for User2. This way, when users access the site, it's like grabbing it from a nearby storage rather than halfway across the globe. CloudFront significantly reduces loading times, ensuring users around the world can effortlessly and swiftly access the website.</p>
<p>CDN provides the lowest latency as the content is cached to the nearest edge locations.</p>
<p>Let's deep dive into the practical so that we can get hands-on experience with CloudFront service.</p>
<p>Objective: Host the static website in the S3 bucket and access the website using CloudFront. Use Amazon S3 to store your static website content and use Amazon CloudFront to distribute and serve that content globally, providing a faster and more reliable experience for users</p>
<p>Log into the AWS account.</p>
<p>First of all, we will upload our static website in the S3 bucket.</p>
<p>Create a S3 bucket.</p>
<blockquote>
<p>AWS Region: default</p>
<p>Bucket name: <a target="_blank" href="http://www.demodevopsprofile.com">demodevopsprofile.com</a></p>
<p>Object Ownership: ACLs Disabled</p>
<p>Block Public Access settings for this bucket: Block all public access</p>
<p>Bucket Versioning: Enabled</p>
</blockquote>
<p>Click on Create bucket.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705476305742/093a67b9-5334-4808-b03a-57a81c440e05.png" alt class="image--center mx-auto" /></p>
<p>To host a static website, click on the bucket name and choose the properties tab. At the bottom choose the <strong>"edit"</strong> option on static website hosting.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705476522493/14fd928d-830f-498a-bb7d-a69c1780dfc8.png" alt class="image--center mx-auto" /></p>
<p>Now choose enabled and name the root file of the static website.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705476636980/6a90eee5-45ea-4420-8a94-4ca23b25b7a9.png" alt class="image--center mx-auto" /></p>
<p>Click on Save Changes.</p>
<p>Now go back to the bucket and upload the files of the website.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705476778609/f97fd2f0-1d92-4114-b1f9-a6742360a51a.png" alt class="image--center mx-auto" /></p>
<p>You can easily access the code using the <a target="_blank" href="https://github.com/imsubash-devops/cloudfront-static-website-deploy">GitHub link</a>.</p>
<p>We will try to access the website that we had uploaded.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705476947804/5dded207-5360-4063-8e8e-5a9fc7e755fc.png" alt class="image--center mx-auto" /></p>
<p>Copy the URL from here and try to access it in the browser.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705477028160/00836053-a656-4d37-b62f-35f6c1a9f16f.png" alt class="image--center mx-auto" /></p>
<p>We observe that direct access to the site is forbidden due to blocking all public access at the S3 bucket level. Accessing the site directly from the S3 bucket is not preferred, as it poses security concerns and tends to have longer loading times. To address this, we will implement a CloudFront distribution on top of the S3 bucket to enhance the website's accessibility.</p>
<p>Now we will move to CloudFront. In the search bar, search CloudFront.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705477318124/5140e01a-fc9c-426a-a18c-f4802675b0e4.png" alt class="image--center mx-auto" /></p>
<p>Click on Create Distribution</p>
<blockquote>
<p>Origin domain: website link</p>
<p>Origin access: Legacy access identities (create OAI)<br />\&gt;Bucket policy : Yes, update the bucket policy</p>
<p>Web Application Firewall (WAF): enabled (for enhanced security), for now we keept it default(disabled)</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705478235840/67df1757-7f49-4fa3-b895-f061ea6011d5.png" alt class="image--center mx-auto" /></p>
<p>Click on Create Distribution.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705482356752/3b692d7c-6fea-4047-85f6-50fb804d8028.png" alt class="image--center mx-auto" /></p>
<p>Our CloudFront distribution is created. Once the deployment is completed we will try to access the website using the link: <a target="_blank" href="https://d24tgcl2ko5qby.cloudfront.net">https://d24tgcl2ko5qby.cloudfront.net</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705482399136/a19ecbb1-42be-4537-84ac-445caaa34883.png" alt class="image--center mx-auto" /></p>
<p>Congratulations to us, we have successfully accessed our website using the CloudFront distribution instead of the S3 bucket.</p>
<p>In the end, AWS CloudFront is like having a super-fast, globally connected buddy for your website. It makes sure your fans get your awesome content without a hitch. So, if you want your website to be a rockstar, give CloudFront a try!  </p>
<p>Happy Learning!!</p>
]]></content:encoded></item><item><title><![CDATA[Amazon VPC for Secure and Scalable Infrastructures]]></title><description><![CDATA[In this blog, we will deep dive into one of the important services of AWS i.e. VPC. VPC is abbreviated as the Virtual Private Network.
Virtual Private Clouds (VPCs) have become a major factor in building scalable and secured infrastructures. It provi...]]></description><link>https://blogs.subashneupane3.com.np/amazon-vpc-for-secure-and-scalable-infrastructures</link><guid isPermaLink="true">https://blogs.subashneupane3.com.np/amazon-vpc-for-secure-and-scalable-infrastructures</guid><category><![CDATA[security groups]]></category><category><![CDATA[vpc]]></category><category><![CDATA[AWS VPC]]></category><category><![CDATA[subnet]]></category><category><![CDATA[#nacl]]></category><category><![CDATA[Internet Gateway]]></category><category><![CDATA[subnets]]></category><dc:creator><![CDATA[Subash Neupane]]></dc:creator><pubDate>Tue, 16 Jan 2024 15:09:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1704880046588/0e132993-8096-4ad1-9bb0-66a7c4102c67.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we will deep dive into one of the important services of AWS i.e. VPC. VPC is abbreviated as the Virtual Private Network.</p>
<p>Virtual Private Clouds (VPCs) have become a major factor in building scalable and secured infrastructures. It provides a way to create isolated and customizable networks within the cloud environment, offering businesses the flexibility and control they need. In this blog post, we will delve into the components that make up a Virtual Private Cloud and explore how they work together to create a robust and secure networking foundation.</p>
<p><strong>Why do we need VPC?</strong></p>
<ul>
<li><p>Isolation and Security</p>
</li>
<li><p>Customization of Network Architecture</p>
</li>
<li><p>Scalability</p>
</li>
<li><p>Hybrid Cloud Connectivity</p>
</li>
<li><p>High Availability and Fault Tolerance</p>
</li>
</ul>
<h3 id="heading-components-of-vpc">Components of VPC</h3>
<ol>
<li><p><strong>VPC:</strong> The VPC itself is the top-level container that holds all other components. It is a logically isolated section within the cloud where users can deploy their resources and make it more secure. VPCs allow any organization or users to define their IP address range, route tables, and subnets.</p>
</li>
<li><p><strong>Subnets:</strong> Subnets are subdivisions of a VPC and are associated with a specific availability zone. Subnets allow us to isolate and group resources based on the user's needs.</p>
</li>
<li><p><strong>Route Tables:</strong> Route tables define the rules for routing traffic within the VPC. Each subnet is associated with a route table, determining how traffic is directed. Route tables control the flow of traffic between subnets and the internet, ensuring proper communication.</p>
</li>
<li><p><strong>Internet Gateway (IGW):</strong> The Internet Gateway is a component that facilitates communication between instances within the VPC and the Internet. It acts as a gateway for outbound and inbound traffic, allowing instances to access the internet and be accessed from the internet.</p>
</li>
<li><p><strong>Network Access Control Lists (NACLs):</strong> NACLs are stateless filters that control traffic at the subnet level. They act as a firewall, allowing or denying traffic based on rules defined by the user. NACLs are operated at the subnet level and provide an additional layer of security.</p>
</li>
<li><p><strong>Security Groups:</strong> Security Groups are stateful firewalls that operate at the instance level. They control inbound and outbound traffic for instance by defining rules.</p>
</li>
<li><p><strong>Elastic Load Balancer (ELB):</strong> ELB is a service that automatically distributes incoming application traffic across multiple targets, such as EC2 instances, in multiple availability zones.</p>
</li>
<li><p><strong>Virtual Private Network (VPN) and Direct Connect:</strong> VPN establishes a secure tunnel over the public internet, while Direct Connect provides a dedicated network connection.</p>
</li>
<li><p><strong>Elastic IP Addresses:</strong> Elastic IP addresses provide a persistent IP address that remains associated with an instance, even if it is stopped and restarted.</p>
</li>
<li><p><strong>Peering Connections:</strong> VPC peering allows the connection of two VPCs, enabling them to communicate with each other as if they are within the same network. It is useful when resources from different VPCs need to interact.</p>
</li>
</ol>
<p>Now we know the basic terminologies that are used at the VPC level. Its time for us to practically implement and know the usage of AWS VPC services.</p>
<p><strong>Search VPC &gt; click on VPC &gt; create VPC</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704865239878/612dc5f3-bf6d-485f-a8e2-b3683b0e7059.png" alt class="image--center mx-auto" /></p>
<p>In clicking Create VPC, you will be prompted to fill in the details below:</p>
<blockquote>
<p>Resources to creat : VPC and more</p>
<p>Name tag auto-generation: aws-prod-project</p>
<p>IPv4 CIDR block**:** default</p>
<p>IPv6 CIDR block: No ipv6</p>
<p>Tenancy: default</p>
<p>Number of Availability Zones (AZs): 2</p>
<p>Number of public subnets:2</p>
<p>Number of private subnets:2</p>
<p>NAT gateways : 1 per AZ</p>
<p>VPC endpoints: None</p>
</blockquote>
<p>Then click on Create VPC</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704865925822/eff042b8-a7ff-48af-852a-a7935c5420ea.png" alt class="image--center mx-auto" /></p>
<p>This is the configuration that I have done.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704866134293/bfe2b8fb-b3da-4956-94dc-b0047fef9c93.png" alt class="image--center mx-auto" /></p>
<p>Our VPC is successfully created</p>
<p>Create ec2 with the autoscaling group</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704866636598/f985f407-d5a2-407e-a0e7-bbf86fd5802b.png" alt class="image--center mx-auto" /></p>
<p>In AWS autoscaling group cannot be created directly, we need to choose <strong><em>Create Launch Template.</em></strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704866997203/28be6e69-585c-4420-9648-21037030cc7e.png" alt class="image--center mx-auto" /></p>
<p>In the launch template page,enter the required details</p>
<ul>
<li><p>Launch template name <em>- required: aws-demo-proj</em></p>
</li>
<li><p>Template version description: describe the template</p>
</li>
<li><p>Application and OS Images (Amazon Machine Image) - required: choose any supposed Ubuntu</p>
</li>
<li><p>AMI: Free tier</p>
</li>
<li><p>instance type: t2.micro (Free Tier)</p>
</li>
<li><p>key pair: use existing or create a new key pair</p>
</li>
<li><p>In <strong>Network settings,</strong> subnet: default (do not change)</p>
</li>
<li><p>Firewall (security groups): create a security group</p>
<p>  -Add a security group name, description</p>
</li>
<li><p>VPC: Choose a newly created VPC</p>
</li>
<li><h5 id="heading-inbound-security-group-rules-add-2-rules-sshto-access-ec2-instance-and-custom-tcp-port-8000-to-access-the-application">Inbound Security Group Rules: add 2 rules ssh(to access ec2 instance) and custom TCP (port 8000 to access the application)</h5>
</li>
<li><p>Remaining all as it is (Default)</p>
</li>
</ul>
<p>Click Create Launch Template</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704868093558/a142aecf-4e4a-4b76-999f-ab53c8e7394c.png" alt class="image--center mx-auto" /></p>
<p>This is a sample of how I configured the template.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704868230253/93baa9fe-30a1-455e-a163-bf472527b51c.png" alt class="image--center mx-auto" /></p>
<p>Our template is successfully created and now create the autoscaling group.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704868382171/b939b293-4bc1-4d9f-83eb-dc38a241e46b.png" alt class="image--center mx-auto" /></p>
<p>Our template is now available, if you cannot see the template just refresh the page. After adding the details click next.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704868574792/1d1598dc-9c51-4ac0-b069-93f2e3d0b198.png" alt class="image--center mx-auto" /></p>
<p>Here we have chosen our VPC and in the Availability Zones and subnets, we choose the private subnets since we want our instances in the private subnet as in the architecture of the project.</p>
<p>Click on Next.</p>
<p>Configure advanced options: keep everything default</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704868811728/90850092-5945-40ba-8cf4-05c0e3189e20.png" alt class="image--center mx-auto" /></p>
<p>Click on Next.</p>
<p>In the Configure group size, keep desired capacity=2, min.=1, and max=4</p>
<p>Automatic scaling= No scaling policies</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704868914473/bdf3135f-ab93-479e-a806-e66b16424302.png" alt class="image--center mx-auto" /></p>
<p>Click on Next and after this all are optional to add notifications and tags. I have skipped these and created the autoscaling group.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704869164713/2050f9f7-6a4b-455c-b80f-1de0733e1b89.png" alt class="image--center mx-auto" /></p>
<p>We can see our 2 instances are launched as we kept desired state as two.</p>
<p>Now let's verify whether the autoscaling group has created instances in us-east-1a and us-east-1b.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704869316882/894e01a5-c317-4564-919c-ce663501f577.png" alt class="image--center mx-auto" /></p>
<p>Perfect the autoscaling group has created the two instances in two zones in the private subnet.</p>
<p>Before creating an application load balancer we need to install the application in the server(instances).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704869569801/122ba631-1450-409b-9f09-9576a290cd9b.png" alt class="image--center mx-auto" /></p>
<p>Since we need the public IPV4 address to ssh into any instance. We can see clearly in the image we have no IPv4 address as it is in a private subnet and we don't want our server to be access public. To solve this issue, a bastion host comes into the picture. Bastion host acts as a mediator between private subnet and public subnet.</p>
<p>So we will create a bastion host in the public subnet and try to access the server.</p>
<p>The process is the same to create a bastion host as creating the instance but in a bastion host, three important points are: <strong>VPC -</strong> choose the same VPC in which the above-created servers are running, choose auto-assign public IP <strong>enable</strong> and inbound rules <strong>allow ssh.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704870288872/92925814-9512-4914-9ee9-442207be2d47.png" alt class="image--center mx-auto" /></p>
<p>Click on the launch instance.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704870427141/c5fa2f6f-8f6c-4afd-8bae-4cc305f1128b.png" alt class="image--center mx-auto" /></p>
<p>Our instance is created and we will SSH into the bastion host and from this we will try to access the other two instances and install the application.</p>
<p>To get access to two of these private subnets, we also need a key-pairs file in Bastion. So we will copy our pem file in Bastion host also.</p>
<pre><code class="lang-bash">scp -i ~/Downloads/nod.pem ~/Downloads/nod.pem ubuntu@3.238.77.37:/home/ubuntu
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704871035871/12709912-0129-4cbd-9d90-5be5c5bdd525.png" alt class="image--center mx-auto" /></p>
<p>Now let's access the bastion-host instance using SSH protocol</p>
<pre><code class="lang-bash">ssh -i .pem_fiel ubuntu@3.238.77.37
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704871191453/dddf9d43-4b10-471b-95d8-99de8c1d419e.png" alt class="image--center mx-auto" /></p>
<p>We have done this step successfully.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704872435759/01cec4fa-16c4-47e5-a72e-68eb57256e16.png" alt class="image--center mx-auto" /></p>
<p>We can see our pem file is available in the instance. Now we will SSH into the other instance using the same pem file.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704872528157/a3e7415d-91e5-4469-999b-90e3796ef544.png" alt class="image--center mx-auto" /></p>
<p>As of now we are in the bastion-host instance and from here we will ssh into instance 1 using its private IP address</p>
<pre><code class="lang-bash">ssh -i pemfile ubuntu@private_ip
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704872671730/a4e4140a-8fc2-4ba5-8c2d-8523f042a1ac.png" alt class="image--center mx-auto" /></p>
<p>We can see the private IP of instance 1 so we have access to the instance. In this instance, we will create a very simple application and run it on port 8000.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704872889265/b718cf30-bba3-4322-82c0-f802ecbe4b84.png" alt class="image--center mx-auto" /></p>
<p>In the same way, we will create our second application on instance 2.</p>
<pre><code class="lang-bash">ssh -i nod.pem ubuntu@10.0.138.152
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704879004258/20a8189a-602f-4748-8dd5-fdb12b24d662.png" alt class="image--center mx-auto" /></p>
<p>Now, Create a Load balancer and attach these instances as target groups</p>
<p>In the EC2 Dashboard select load balancers. Then click on Create the load balancer.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704873055813/4ba70d63-fa53-47e8-aa79-c737b6954b60.png" alt class="image--center mx-auto" /></p>
<p>In the next step select Application load balancer.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704877328745/d3a73bd5-3e22-464f-8e03-ec77ac66a26c.png" alt class="image--center mx-auto" /></p>
<p>Click create.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704877372204/4548dc5b-d08b-44ab-b668-a364916fbb95.png" alt class="image--center mx-auto" /></p>
<p>Give the name to the load balancer and it must be internet-facing and has an IPV4 address type.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704877436827/5b8f8636-ea9d-46dc-af78-7b7ec3afdc15.png" alt class="image--center mx-auto" /></p>
<p>Choose the VPC that we created earlier as our servers are running on that VPC. In Loadbalancer we need to select the public subnets for mapping.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704877511925/cdf69d99-1acb-4046-9c10-4f56229eef64.png" alt class="image--center mx-auto" /></p>
<p>Select the Create security groups and port 80. For default action, if there is no any security group, click on Create Security group.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704877798461/c2bb43cd-3569-4476-b57e-de9fb77e2072.png" alt class="image--center mx-auto" /></p>
<p>Choose instance as our target, give the target group name, keep other default, and choose next.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704877919327/ade7adda-ca4a-43b1-b3c8-4e80fafdf297.png" alt class="image--center mx-auto" /></p>
<p>Select the target instances in which the application will be running or application is running and also click include as pending below. Then click Create Target group.</p>
<p>In the load balancer configuration select the recently created target group.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704878109384/91c2976f-00d3-4b76-b63d-3b1c910af44e.png" alt class="image--center mx-auto" /></p>
<p>Finally, our load balancer is created and also we can see the HTTP protocol at port 80 is not reachable. So click on the Security tab, choose security group, and in the inbound rule add HTTP at port 80.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704878369997/4c28b3e2-96f6-41a6-96a6-482ceb9065d1.png" alt class="image--center mx-auto" /></p>
<p>Now let's check the load balancers.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704878453296/ba700157-231a-427c-8b44-e4d6a8ce7d79.png" alt class="image--center mx-auto" /></p>
<p>Now it is reachable.</p>
<p>To check the health status of the Targets click on the project name.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704878409192/1b868309-679e-4200-aa3c-317c226b13db.png" alt class="image--center mx-auto" /></p>
<p>We can see our servers are both healthy. We will try to access our applications using this link <a target="_blank" href="http://aws-prod-project-1090487507.us-east-1.elb.amazonaws.com">aws-prod-project-1090487507.us-east-1.elb.amazonaws.com</a>, it will be available under the Details section (DNS name) in the load balancer page.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704878699298/f5eff12a-3e13-4696-885a-7370d485a29f.png" alt class="image--center mx-auto" /></p>
<p>Our first application is perfectly running.</p>
<p>Again let's try to access the same URL in another tab.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704878721506/da9f20a3-b942-4008-93a5-f0d0a5adca2c.png" alt class="image--center mx-auto" /></p>
<p>We can see our second app running on the second server is loaded successfully. Hence the load balancer has successfully distributed the server requests.</p>
<p>We covered the basic building blocks like subnets and route tables, and walked through practical steps for setting up a secure and scalable cloud environment. Think of VPCs as the foundation for creating a safe and flexible space in the cloud, and learning about them is a valuable skill for anyone working with online services.</p>
<p>Happy Learning!!</p>
]]></content:encoded></item><item><title><![CDATA[Know About Kubernetes Ingress Controller: A practical Guide]]></title><description><![CDATA[In this blog, we will learn about the Kubernetes Ingress controller and the need for an Ingress controller.
In our previous blog, we learned about the Service and its offerings like service discovery, load balancing, and exposure to the external worl...]]></description><link>https://blogs.subashneupane3.com.np/know-about-kubernetes-ingress-controller-a-practical-guide</link><guid isPermaLink="true">https://blogs.subashneupane3.com.np/know-about-kubernetes-ingress-controller-a-practical-guide</guid><category><![CDATA[AWS]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[Ingress Controllers]]></category><category><![CDATA[ingress]]></category><category><![CDATA[Load Balancer]]></category><dc:creator><![CDATA[Subash Neupane]]></dc:creator><pubDate>Mon, 15 Jan 2024 15:08:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1705051340810/01e2b91e-04ca-4a3b-a945-29ae5fc3573a.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we will learn about the Kubernetes Ingress controller and the need for an Ingress controller.</p>
<p>In our previous blog, we learned about the Service and its offerings like service discovery, load balancing, and exposure to the external world. Now why do we need the Ingress controller? Before Kubernetes released v1.1, there was no Ingress so people used to use Kubernetes with service only. Even before people migrated to Kubernetes, they used the legacy system like they use virtual machines or physical servers and on top of it they installed their applications and to access these applications they used enterprise-level load balancers like nginx.</p>
<p>The enterprise-level load balancing offered different capabilities like ratio-based load balancing, sticky session(if a request is going to a particular pod, then all the requests should go to the same pod), path-based load balancing, domain-based load balancing, whitelisting (allow specific IP range), black listing(block specific IP range) and so on.</p>
<p><strong>How does Ingress solve the problem?</strong></p>
<p>The load balancing offered by the Kubernetes service was a simple and round-robin mechanism i.e. simply distributing the traffic request. Kubernetes service was missing following services:</p>
<ol>
<li><p>Enterprise and TLS load balancing</p>
</li>
<li><p>For every load balancer type service, the cloud provider would charge for each static public IP address</p>
</li>
</ol>
<p>Ingress is solving the problem that Kubernetes service did not have enterprise-level load balancing capabilities. Kubernetes users will create a resource called an Ingress controller and the load balancing services like Nginx, will implement the Ingress controller and as a Kubernetes user, will deploy the ingress controller in the Kubernetes cluster using Helm chart or YAML manifest. Once it is deployed then the developer will create an Ingress yaml resource for their Kubernetes service. So the Ingress controller watches on Ingress resources.</p>
<p>Let's dive practically and understand how to deploy Ingress controller that watches on our Ingress resources.</p>
<p>Start the Minikube</p>
<pre><code class="lang-plaintext">minikube start
</code></pre>
<p>Previously in Kubernetes service, we had created the pods we will use the same pods. If you don't know how to do it please click here to create the pods.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705041086512/04ed6d03-c25a-4593-aa97-da3e09ba6634.png" alt class="image--center mx-auto" /></p>
<p>Now let's create an Ingress resource and setup a host based load balancing</p>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">networking.k8s.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Ingress</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">ingress-example</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">rules:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">host:</span> <span class="hljs-string">"foo.bar.com"</span>
    <span class="hljs-attr">http:</span>
      <span class="hljs-attr">paths:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">pathType:</span> <span class="hljs-string">Prefix</span>
        <span class="hljs-attr">path:</span> <span class="hljs-string">"/bar"</span>
        <span class="hljs-attr">backend:</span>
          <span class="hljs-attr">service:</span>
            <span class="hljs-attr">name:</span> <span class="hljs-string">python-django-service</span>
            <span class="hljs-attr">port:</span>
              <span class="hljs-attr">number:</span> <span class="hljs-number">80</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705044746525/ff417673-1b9d-4e66-a051-36e3de1711a7.png" alt class="image--center mx-auto" /></p>
<p>To apply</p>
<pre><code class="lang-plaintext">kubectl apply -f ingress.yml
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705042258000/9063ebf1-6241-4071-baf0-c9ec71e1cccf.png" alt class="image--center mx-auto" /></p>
<p>Our ingress resource is created.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705045150453/d8b7d772-ec08-43cb-b9a7-7b526c5d60d0.png" alt class="image--center mx-auto" /></p>
<p>We can the address field is empty.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705042501855/5463022e-4688-4f21-b949-2ff3e63d55bb.png" alt class="image--center mx-auto" /></p>
<p>We encountered the error as we could not reach our application because for this ingress resource we have not created the Ingress controller.</p>
<p>So let's install the INgress controller. IN the market there are lots of ingress controller, I am going to install the nginx ingress controller since it is very light-weight.</p>
<p>To enable the NGINX Ingress controller, run the following command:</p>
<pre><code class="lang-plaintext">minikube addons enable ingress
</code></pre>
<p>Verify that the NGINX Ingress controller is running</p>
<pre><code class="lang-plaintext">kubectl get pods -n ingress-nginx
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705043375217/b3ad07d6-0bdf-4516-88f0-94665572fcf7.png" alt class="image--center mx-auto" /></p>
<p>Let's check whether the INgress controller identifies the ingress resources that we had created.</p>
<pre><code class="lang-plaintext">kubectl logs ingress-nginx-controller-6cc5ccb977-tq2ll -n ingress-nginx
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705044588676/2ffc12c4-9bb3-4c24-ae8f-4fa7cdd42647.png" alt class="image--center mx-auto" /></p>
<p>So the ingress controller has identified our ingress resource and has successfully synced also.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705044948808/24bee4b4-3e3d-40b2-b98e-a47ba3bf3143.png" alt class="image--center mx-auto" /></p>
<p>If you noticed previously there was no IP address in the Address field but now there is IP allocated and updated. Now, we can access the ingress resources in foo.bar.com/bar since we have used the ingress controller and it has updated the configuration .</p>
<p>Now update the /etc/hosts configuration file so that whenever we hit the foo.bar.com the 192.168.58.2 will be accessed.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705045780231/e843cbaf-2e33-4afb-881c-576f42ccabdb.png" alt class="image--center mx-auto" /></p>
<p>We will try to access the foo.bar.com</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705045849485/cf90a7e8-c778-4873-b68c-a2348bc14c9b.png" alt class="image--center mx-auto" /></p>
<p>We are successfully able to send the request to the foo.bar.com. We have done it successfully.</p>
<p>By using Ingress controllers, Kubernetes users can efficiently manage external access to their applications, benefiting from features like host-based load balancing and improved traffic routing. As Kubernetes continues to evolve, understanding and using Ingress controllers will be important for optimizing application deployment and accessibility within a Kubernetes cluster.</p>
<p>Happy Learning!!</p>
]]></content:encoded></item><item><title><![CDATA[Automating Cloud Resources with AWS CloudFormation]]></title><description><![CDATA[In this blog, we are going to explore another service of AWS i.e. CloudFormationTempale (AWS CFT). It is the template that helps in cloud formation. Cloud in this case is AWS i.e. creating, managing, and updating the cloud resources.
AWS CFT implemen...]]></description><link>https://blogs.subashneupane3.com.np/automating-cloud-resources-with-aws-cloudformation</link><guid isPermaLink="true">https://blogs.subashneupane3.com.np/automating-cloud-resources-with-aws-cloudformation</guid><category><![CDATA[cloud resources]]></category><category><![CDATA[AWS]]></category><category><![CDATA[AWS CloudFormation]]></category><category><![CDATA[automation]]></category><category><![CDATA[YAML, JSON,DEVOPS]]></category><dc:creator><![CDATA[Subash Neupane]]></dc:creator><pubDate>Sun, 14 Jan 2024 15:06:42 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1705214670980/bc3e572e-3507-4ec8-a07b-77af710a4064.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we are going to explore another service of AWS i.e. CloudFormationTempale (AWS CFT). It is the template that helps in cloud formation. Cloud in this case is AWS i.e. creating, managing, and updating the cloud resources.</p>
<p>AWS CFT implements the principle of IAC which is not implemented by the AWS CLI. There are different IAC tools like Terraform, Crossplane but AWS CFT is majorly for the AWS cloud only. IAC is a concept where we write codes to create resources in the cloud. IAC tool acts as a middleman between the user and the cloud provider.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705215498884/cf438f6d-97e6-4692-a73a-4b402dc7ded4.png" alt class="image--center mx-auto" /></p>
<p>For quick actions, we can simply use the AWS CLI, but to create multi-structured resources, we can use AWS CloudFormation (AWS CFT). AWS CFT supports JSON and YAML templates. YAML is the preferred template as it is the most widely used template. But if you are comfortable with JSON then it is also good to use, the limitation of JSON is that we cannot make comments in between the codes which makes it difficult to understand the code if it is complex.</p>
<p>To get deep knowledge about AWS CFT use the official documentation link:<br /><a target="_blank" href="https://docs.aws.amazon.com/cloudformation/">https://docs.aws.amazon.com/cloudformation/</a></p>
<p>Let's dive into the AWS CFT practically.</p>
<p>Log into your AWS account. Search for <strong>CloudFormation</strong> and click on it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705218683487/b62baa15-c39b-4ff1-93cf-8801701026e0.png" alt class="image--center mx-auto" /></p>
<p>In the cloud formation page, click on Create Stack, stack is the one that implements the template that we have written.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705219035614/f4ed613d-d7e0-45ee-ada7-6b6569508022.png" alt class="image--center mx-auto" /></p>
<p>Then click on <strong>Create template in designer.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705219156286/c66494f7-2744-4c70-b327-42af36fd34d3.png" alt class="image--center mx-auto" /></p>
<p>You will get into this page, you can simply drag the resources in the plane and the code will be generated in JSON or YAML based on your requirement.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705219324507/9436e9a1-72f3-4611-958d-f8f2deae0b3b.png" alt class="image--center mx-auto" /></p>
<p>We simply dragged the bucket and the code is generated in the below terminal.</p>
<pre><code class="lang-yaml"><span class="hljs-attr">Resources:</span>
  <span class="hljs-attr">S3BUCKET:</span>
    <span class="hljs-attr">Type:</span> <span class="hljs-string">'AWS::S3::Bucket'</span>
    <span class="hljs-attr">Properties:</span> {}
</code></pre>
<p>The code snippet represents an AWS CloudFormation template to create an Amazon S3 bucket. The logical name is "S3BUCKET," and it specifies the resource type as 'AWS::S3::Bucket.' The template is currently basic, without additional properties, indicating a simple S3 bucket creation.</p>
<p>Since we have already created a template we will upload the yaml template.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705221919741/b943a3bc-bdc2-4b91-885e-f2ade510ec0b.png" alt class="image--center mx-auto" /></p>
<p>Our template file is uploaded. The sample yam file we uploaded is:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">Resources:</span>
  <span class="hljs-attr">S3BUCKET:</span>
    <span class="hljs-attr">Type:</span> <span class="hljs-string">'AWS::S3::Bucket'</span>
    <span class="hljs-attr">Properties:</span>
        <span class="hljs-attr">BucketName:</span> <span class="hljs-string">"demo-aws-subash1122"</span>
        <span class="hljs-attr">VersioningConfiguration:</span>
            <span class="hljs-attr">Status:</span> <span class="hljs-string">Enabled</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705222121568/7394f445-c12d-43e1-b3c4-9dae528f6288.png" alt class="image--center mx-auto" /></p>
<p>Give a name to the stack and skip all the pages and submit it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705222180397/5dc406d0-a3c6-4dca-b5d5-1336cfc36785.png" alt class="image--center mx-auto" /></p>
<p>We can see our resource is being created. Let's verify whether the bucket is created or not.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705223814590/fafd2314-2c52-446c-9b98-8c5157f2987f.png" alt class="image--center mx-auto" /></p>
<p>The bucket is created successfully along with a template file in S3. AWS Cloud saves all the templates in the S3 bucket that we created.</p>
<p>In Cloudformation there is a feature of drift, that allows you to identify and understand any changes made to the stack resources outside of CloudFormation.</p>
<p>Let's delete the bucket that we had created and check the drift status in cloudformation.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705224279504/f3b62d08-9572-43a2-866d-131dcf3242be.png" alt class="image--center mx-auto" /></p>
<p>The bucket is deleted.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705224562823/9fdb8ad0-386a-4bb7-bdef-81b228015039.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705224572844/5d36d297-14e2-485e-bfcc-8112fb3ded81.png" alt class="image--center mx-auto" /></p>
<p>Here we can see in the drifted results that the bucket is deleted.<br />In AWS CloudFormation, "drift" detects the difference between the expected stack resource configuration and the actual configuration of those resources in the deployed stack</p>
<p>Again let's create an Instance using the AWS CloudFormation Template.</p>
<p><strong>createinstance.yaml</strong></p>
<pre><code class="lang-yaml"><span class="hljs-attr">AWSTemplateFormatVersion:</span> <span class="hljs-string">"2010-09-09"</span>
<span class="hljs-attr">Description:</span> <span class="hljs-string">"This is our first instance using CloudFormation"</span>
<span class="hljs-attr">Resources:</span>
  <span class="hljs-attr">mydemoinstance:</span>
    <span class="hljs-attr">Type:</span> <span class="hljs-string">'AWS::EC2::Instance'</span>
    <span class="hljs-attr">Properties:</span> 
      <span class="hljs-attr">ImageId:</span> <span class="hljs-string">ami-0c7217cdde317cfec</span>
      <span class="hljs-attr">KeyName:</span> <span class="hljs-string">nod</span>
      <span class="hljs-attr">SecurityGroupIds:</span> 
        <span class="hljs-bullet">-</span> <span class="hljs-string">sg-047bf8e20308ceb4f</span>
      <span class="hljs-attr">InstanceType:</span> <span class="hljs-string">t2.micro</span>
</code></pre>
<blockquote>
<p>Note: for key pair either use existing one or create the new key pair from the EC2dashboard</p>
</blockquote>
<p>Let's upload it in the cloud formation.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705227980259/e62c0cd3-ad5c-4f31-9d1d-433f4617928f.png" alt class="image--center mx-auto" /></p>
<p>Our template file is uploaded and named the stack as ec2-instance.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705228222207/4633a795-db84-4d01-8ae6-f815e1ec981d.png" alt class="image--center mx-auto" /></p>
<p>We can see the creation is completed and we will verify it in ec2 dashboard.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705228308066/8836d900-1099-470f-b3ea-db30dd6030bd.png" alt class="image--center mx-auto" /></p>
<p>Hence the instance is also created successfully. You can also try the same template to create the instance and just replace the security groups and key pair files.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705229849484/e268dcc5-5473-40a4-98d4-26d10d10adfc.png" alt class="image--center mx-auto" /></p>
<p>We have successfully accessed the instance that we have created using the CloudFormation.</p>
<blockquote>
<p>Note: Don't forget to delete the resources that you created earlier and stay safe from the charges of AWS services</p>
</blockquote>
<p>In a nutshell, AWS CloudFormation is like a wizard for setting up our cloud resources on Amazon. It uses written instructions (templates) to create and manage your cloud resources, making it easier and more consistent. We showed how it can create an S3 bucket and an EC2 instance just by following the template. This is handy for automating and organizing your cloud infrastructure without manual hassle.</p>
<p>Happy Learning!!</p>
]]></content:encoded></item><item><title><![CDATA[Exploring Amazon S3: A Simple Guide to Storage in AWS]]></title><description><![CDATA[In this blog, we will deep dive into one of the important AWS services, S3. S3 is abbreviated as Simple Storage Service. AWS S3 is designed to store and retrieve any amount of data from anywhere on the web. It is a highly scalable and secure object s...]]></description><link>https://blogs.subashneupane3.com.np/exploring-amazon-s3-a-simple-guide-to-storage-in-aws</link><guid isPermaLink="true">https://blogs.subashneupane3.com.np/exploring-amazon-s3-a-simple-guide-to-storage-in-aws</guid><category><![CDATA[AWS]]></category><category><![CDATA[S3]]></category><category><![CDATA[bucket]]></category><category><![CDATA[IAM]]></category><category><![CDATA[Policy]]></category><category><![CDATA[Static Website]]></category><dc:creator><![CDATA[Subash Neupane]]></dc:creator><pubDate>Sat, 13 Jan 2024 15:11:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1705135985339/c45a2471-b6e5-444c-9913-3c7dcadf0ea6.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we will deep dive into one of the important AWS services, S3. S3 is abbreviated as Simple Storage Service. AWS S3 is designed to store and retrieve any amount of data from anywhere on the web. It is a highly scalable and secure object storage service offered by Amazon Web Services (AWS).</p>
<p><strong>S3 Buckets</strong></p>
<p>S3 buckets serve as containers for storing objects, which are essentially files, within Amazon S3. Each bucket must have a globally unique name across the entire AWS platform. Conceptually, you can liken an S3 bucket to a top-level directory that serves as a repository for organizing and storing your data.</p>
<p>Why S3 Buckets</p>
<p>S3 buckets offer a dependable and immensely scalable storage solution suitable for a multitude of use cases. They are simply utilized for different tasks such as backup and restoration, data archiving, storage of website content, and serving as a primary data source for big data analytics, S3 buckets prove versatile in meeting diverse storage needs.</p>
<p>Key Benefits of AWS S3 Buckets</p>
<ul>
<li><p><strong>Durability and availability:</strong> S3 provides high durability and availability for your data. S3 ensures 99.999999999% durability for stored objects by automatically replicating data across multiple servers and data centers.</p>
</li>
<li><p><strong>Scalability:</strong> You can store and retrieve any amount of data without worrying about capacity constraints.</p>
</li>
<li><p><strong>Security:</strong> S3 offers multiple security features including access control lists (ACLs), bucket policies, and integration with AWS Identity and Access Management (IAM).</p>
</li>
<li><p><strong>Performance:</strong> S3 is designed to deliver high performance for data retrieval and storage operations.</p>
</li>
<li><p><strong>Cost-effective:</strong> S3 offers cost-effective storage options and pricing models based on our usage patterns.</p>
</li>
</ul>
<p>Additionally, Versioning allows us to preserve, retrieve, and restore every version of every object stored in a bucket, providing protection against accidental deletion or overwrites.</p>
<p>Let's know more about S3 buckets and their usage practically.</p>
<p>Let's create a bucket, search S3&gt; click S3 &gt;Click Create Bucket</p>
<blockquote>
<p>AWS Region: default</p>
<p>Bucket name: <a target="_blank" href="http://demo-s3-prod-example.com">demo-s3-prod-example.com</a></p>
<p>Object Ownership: ACLs Disabled</p>
<p>Block Public Access settings for this bucket: Block all public access</p>
<p>Bucket Versioning: Disabled</p>
</blockquote>
<p>Then click on Create bucket and our bucket is created successfully.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705127199992/335a839e-9ff4-44a0-8dad-fdbebaefd845.png" alt class="image--center mx-auto" /></p>
<p>Upload a file/object in the S3 bucket</p>
<p>Let's add a simple file to our bucket.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705127772607/a03ac8d7-0833-4f44-b441-945250ccd64d.png" alt class="image--center mx-auto" /></p>
<p>The index.html file contains simple HTML code.</p>
<pre><code class="lang-xml"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>My First HTML Page<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Welcome to my page!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This is a paragraph.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>Item 1<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>Item 2<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>Item 3<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Let's try to upload the same file again and check whether the copy of the file can be uploaded or not without the change in the file.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705129429307/95c37ac7-4a72-4906-bde5-916ed3ec3b74.png" alt class="image--center mx-auto" /></p>
<p>We uploaded the same index.html file.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705129459005/27b6758d-c0cc-4453-b64e-a5f682c43868.png" alt class="image--center mx-auto" /></p>
<p>But we cannot see the copy of the file.</p>
<p>S3 also offers the versioning of the file like the version control systems. We can retrieve the file with any version.</p>
<p>Let's customize the code of index.html and upload it in the s3 bucket. But before that <strong>enable</strong> the versioning in the s3 bucket configuration</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705129829074/45f60589-cf52-430c-a2f6-cfd64b54af7f.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-xml"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>My First HTML Page<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Welcome to my page!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This is a paragraph.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705129928226/e435a821-4f5e-4982-acdd-6d6ef72379cb.png" alt class="image--center mx-auto" /></p>
<p>We can see the two versions of the index.html file. We can create multiple versions of the file and can retrieve any version of the file.</p>
<p><strong>Bucket Permission</strong></p>
<p>Anyone within the organization who has S3 full access permission and easily access the S3 bucket resources. Based on the requirements, we need to set the bucket permission so that the data within the buckets are safe and secure.</p>
<p>Let's create a use called demo-s3 with no access to the s3.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705127419038/83ae6640-16e4-494e-b8d8-2bb30ebe80dd.png" alt class="image--center mx-auto" /></p>
<p>Our user demo-s3 is created and we will log in as a demo-s3 and try to access the bucket that we created.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705127511444/7f3fa9cf-98f3-477d-98e2-ac9b8908ed80.png" alt class="image--center mx-auto" /></p>
<p>We cannot access the bucket since we have not given access to the user to access these buckets. We need to attach the policy for the users so that the user can access the S3 resources.</p>
<p>Now we will grant permission to this user so that the user can access the S3 buckets.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705131739250/aa299d34-bdc3-40b1-94a5-309161ebbc7d.png" alt class="image--center mx-auto" /></p>
<p>The permission is added to the demo-s3 user.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705131801974/b225764f-4772-4247-8f19-480ed9fc42d9.png" alt class="image--center mx-auto" /></p>
<p>Now the user can easily access the S3 bucket.</p>
<p>Though we have attached the policy so that the user can access the buckets but we don't want any users to do anything on our buckets. So lets make it more secure using the bucket policy.</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"Version"</span>: <span class="hljs-string">"2012-10-17"</span>,
  <span class="hljs-attr">"Id"</span>: <span class="hljs-string">"RestrictBucketToIAMUsersOnly"</span>,
  <span class="hljs-attr">"Statement"</span>: [
    {
      <span class="hljs-attr">"Sid"</span>: <span class="hljs-string">"AllowOwnerOnlyAccess"</span>,
      <span class="hljs-attr">"Effect"</span>: <span class="hljs-string">"Deny"</span>,
      <span class="hljs-attr">"Principal"</span>: <span class="hljs-string">"*"</span>,
      <span class="hljs-attr">"Action"</span>: <span class="hljs-string">"s3:*"</span>,
      <span class="hljs-attr">"Resource"</span>: [
        <span class="hljs-string">"arn:aws:s3:::your-bucket-name/*"</span>,
        <span class="hljs-string">"arn:aws:s3:::your-bucket-name"</span>
      ],
      <span class="hljs-attr">"Condition"</span>: {
        <span class="hljs-attr">"StringNotEquals"</span>: {
          <span class="hljs-attr">"aws:PrincipalArn"</span>: <span class="hljs-string">"arn:aws:iam::AWS_ACCOUNT_ID:root"</span>
        }
      }
    }
  ]
}
</code></pre>
<p>This policy says that the bucket is only accessible to the root user and restricted to other users.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705132658782/05ac25af-341f-45b2-9a16-b4732a02cacb.png" alt class="image--center mx-auto" /></p>
<p>This is what I have attached to the bucket policy. Now lets verify whether the user can retrieve the s3 bucket resources as they have s3 full access.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705132786435/9234afea-cd41-4bd4-b4a8-7364a92a8cd3.png" alt class="image--center mx-auto" /></p>
<p>We can see the user can not access the resources from the bucket. It is more important to identify whom to give access or not.</p>
<p><strong>Host a static website in S3 bucket</strong></p>
<p>Hosting a static website is very easy and simple in S3 as it is very cheap and affordable.</p>
<p>Let's upload an index.html file or use the previous index.html file as above. Now make the static website enabled. First, click on bucket-name &gt; permission &gt; static website hosting(edit)&gt;enabled&gt; index.html</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705133618733/ca1f547a-af0c-416c-9fc3-f528b31e3802.png" alt class="image--center mx-auto" /></p>
<p>As shown in the image you can follow the steps and save it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705133749772/e4147ae3-9a32-419e-bc6c-cf2e1eddcffc.png" alt class="image--center mx-auto" /></p>
<p>After saving it, at the bottom, you will find the URL to access the website. Now simply copy the link and paste it into the browser.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705133867570/aa7b67af-c2cd-4520-a96c-3025a4b27ede.png" alt class="image--center mx-auto" /></p>
<p>You can see we are not able to access our website and a 403 forbidden error is shown. This is because if you remember while we created the bucket we choosed "Block Public Access settings for this bucket: <strong>Block all public access"</strong> due to which we are not able to access the website.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705134061992/483c23fe-6898-4dee-a661-15dc678f69a2.png" alt class="image--center mx-auto" /></p>
<p>We will uncheck the block all public access so that we will be able to access the website.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705134156096/49ca97b0-c036-4bed-9e8a-9f58bcef598d.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705134164916/f33d99a0-e724-4363-ace2-b94f9a18a789.png" alt class="image--center mx-auto" /></p>
<p>Now we will try to access the website.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705134272901/6aebc7b3-9f69-4f15-91ae-b6cfaeba9998.png" alt class="image--center mx-auto" /></p>
<p>After doing everything right also we are not able to access the website. This is because we had set the bucket policy that only the root user will have access but not others. Now we will change the policy so that everyone can access the website having access to the internet.</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"Version"</span>: <span class="hljs-string">"2012-10-17"</span>,
    <span class="hljs-attr">"Statement"</span>: [
        {
            <span class="hljs-attr">"Sid"</span>: <span class="hljs-string">"PublicReadGetObject"</span>,
            <span class="hljs-attr">"Effect"</span>: <span class="hljs-string">"Allow"</span>,
            <span class="hljs-attr">"Principal"</span>: <span class="hljs-string">"*"</span>,
            <span class="hljs-attr">"Action"</span>: <span class="hljs-string">"s3:GetObject"</span>,
            <span class="hljs-attr">"Resource"</span>: <span class="hljs-string">"arn:aws:s3:::demo-s3-prod-example.com/*"</span>
        }
    ]
}
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705134558393/c2285a56-e28e-41fe-b3c4-3e5cc78c44fb.png" alt class="image--center mx-auto" /></p>
<p>Save the policy and refresh the browser.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705134665672/425f4004-8671-4436-9369-058bb604f22f.png" alt class="image--center mx-auto" /></p>
<p>We can access our sample website finally.</p>
<p>Through these practical demonstrations, we learned how to create an S3 bucket, upload files, and showcased the importance of versioning for better data management in AWS. The significance of permissions and security features, such as IAM user policies and bucket policies, was practically demonstrated for controlled access. Whether you're a developer, system administrator, or business owner, AWS S3 is an essential tool in the cloud computing landscape, empowering you to store, manage, and retrieve data smoothly.</p>
<p>Happy Learning!!</p>
]]></content:encoded></item><item><title><![CDATA[Know About the Kubernetes Services]]></title><description><![CDATA[In this blog, we will deep dive into another Kubernetes component i.e. Service. Service is one of the critical components of Kubernetes as at the production level we do not deploy pods but deployment. Most of the time, when we deploy the deployments ...]]></description><link>https://blogs.subashneupane3.com.np/know-about-the-kubernetes-services</link><guid isPermaLink="true">https://blogs.subashneupane3.com.np/know-about-the-kubernetes-services</guid><category><![CDATA[Kubernetes]]></category><category><![CDATA[services]]></category><category><![CDATA[kubernetes-services]]></category><category><![CDATA[container orchestration]]></category><category><![CDATA[minikube]]></category><dc:creator><![CDATA[Subash Neupane]]></dc:creator><pubDate>Fri, 12 Jan 2024 15:13:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1705055676659/8d404b6f-ab5a-46bd-98d2-1cd613c9c732.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we will deep dive into another Kubernetes component i.e. Service. Service is one of the critical components of Kubernetes as at the production level we do not deploy pods but deployment. Most of the time, when we deploy the deployments for each deployment, we create the services.</p>
<p><strong>Why Do We Need Kubernetes Services?</strong></p>
<p>In Kubernetes, a DevOps engineer deploying a pod as part of a deployment might face challenges when managing dynamic IP addresses, especially when scaling the application. For instance, if a pod goes down and a new one is created by the replica set, the associated IP address change can disrupt end-user access.</p>
<p>In the real world, this is not implemented. For example, an XYZ website does not tell its user to access the site in this and that IP as the request increases. This auto-healing behavior maintained the pods but not the IP address associated with which users use to access them.</p>
<ul>
<li>Load Balancing</li>
</ul>
<p>To solve the issues of the above scenario, we can create a service on the top of deployment. Service acts as a load balancer. Service uses the component of K8s that is kube-proxy. As the service offers load balancing, the test users can access the application by the service name provided by the Kubernetes instead of the IP address as it changes frequently. So based on the request received the load balancer distributes the requests to different pods.</p>
<ul>
<li>Service Discovery</li>
</ul>
<p>If the user tries to access the pod whose IP is changed then the service also resolves this problem. Service does not track the IP addresses as the pod is created frequently with a new IP every time. For large projects there may be multiple pods and IPs are changed frequently, if the Service starts to track the IPs then the service will fail. Now what the service does is the service would not bother about the IP. So service uses a new process the Labels and Selectors for service discovery. For every pod created, selectors and labels will be applied. So service will watch for the labels instead of the IP address.</p>
<ul>
<li>Expose to the external World</li>
</ul>
<p>Service can allow us to access our application outside the Kubernetes cluster. We can do it in many ways. Service provides 3 types of service:</p>
<ol>
<li><p>ClusterIP service<br /> If we create any service using clusterIP mode, as it is a default mode then the application can be accessed only inside the Kubernetes cluster.</p>
</li>
<li><p>Node Port service<br /> If we create any service using the Node port mode, then the application can be accessed within the organization i.e. anybody with the same network can access the application. They won't get the master node access but the work node access.</p>
</li>
<li><p>Loadbalancer service<br /> If we create a service of load balancing type then we will get the elastic load balancer IP address as it is the public IP address. So whoever wants to access our application from anywhere in the world can easily access the application using the elastic IP address. So this load balancing works on the cloud, depending upon the cloud provider as the cloud provider provides the creation of elastic IP.</p>
</li>
</ol>
<p>Let's dive into practical</p>
<p>Start the Minikube cluster</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704979354406/172c6f73-29a0-4c34-93cf-84d301e9b157.png" alt class="image--center mx-auto" /></p>
<p>Our Minikube is ready to use now.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704980210671/c3e644ec-6098-454b-921d-37b75e3d935a.png" alt class="image--center mx-auto" /></p>
<p>This is our Python application directory. If you want to use this application you can clone the repo here.</p>
<p>Let's build the docker image and push it into a public registry like DockerHub. In case you did not push it to the public registry then you will face the problem of <strong>Imagepull Backoff</strong> error and the pods will not get ready or start.</p>
<pre><code class="lang-yaml"><span class="hljs-string">docker</span> <span class="hljs-string">-t</span> <span class="hljs-string">image_name</span> <span class="hljs-string">name</span> <span class="hljs-string">path_of_docker_File</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704980744469/888e65ac-fa20-4a79-ba9c-99a1e79a020f.png" alt class="image--center mx-auto" /></p>
<p>So our image is built.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704980863343/6e8e13a5-5782-4b68-8f0f-a9dfc0043aa2.png" alt class="image--center mx-auto" /></p>
<p>Let's create a deployment file called "deployment.yml"</p>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">sample-python-app</span>
  <span class="hljs-attr">labels:</span>
    <span class="hljs-attr">app:</span> <span class="hljs-string">sample-python-app</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">replicas:</span> <span class="hljs-number">2</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">matchLabels:</span>
      <span class="hljs-attr">app:</span> <span class="hljs-string">sample-python-app</span>
  <span class="hljs-attr">template:</span>
    <span class="hljs-attr">metadata:</span>
      <span class="hljs-attr">labels:</span>
        <span class="hljs-attr">app:</span> <span class="hljs-string">sample-python-app</span>
    <span class="hljs-attr">spec:</span>
      <span class="hljs-attr">containers:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">python-app</span>
        <span class="hljs-attr">image:</span> <span class="hljs-string">subash07/python-app:latest</span> <span class="hljs-comment">#after I pushed the image to dockerhub</span>
        <span class="hljs-attr">ports:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">containerPort:</span> <span class="hljs-number">8000</span>
</code></pre>
<pre><code class="lang-yaml"><span class="hljs-string">kubectl</span> <span class="hljs-string">apply</span> <span class="hljs-string">-f</span> <span class="hljs-string">deployment.yml</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704981395069/ef0186d3-53c9-4a72-9328-5e46ed15869d.png" alt class="image--center mx-auto" /></p>
<p>Created.</p>
<p>To get the deployment information</p>
<pre><code class="lang-yaml"><span class="hljs-string">kubectl</span> <span class="hljs-string">get</span> <span class="hljs-string">deploy</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704981530287/bf032ba3-6093-47f8-a598-032a955815b1.png" alt class="image--center mx-auto" /></p>
<p>Here we can see the status as <strong>Imagepull Backoff</strong> and my pods are not ready.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704992544250/9c11178f-427d-47e0-8cb5-31239e0caa18.png" alt class="image--center mx-auto" /></p>
<p>This occurs because my docker image is not in the public registry, that'swhy it could not pull the image that I mentioned in the YAML file.</p>
<p>In case you want to use your local image run the following commands.</p>
<p>Execute the Minikube Docker daemon configuration:</p>
<pre><code class="lang-yaml"><span class="hljs-string">eval</span> <span class="hljs-string">$(minikube</span> <span class="hljs-string">docker-env)</span>
</code></pre>
<p>Build your Docker image:</p>
<pre><code class="lang-yaml"><span class="hljs-string">docker</span> <span class="hljs-string">build</span> <span class="hljs-string">-t</span> <span class="hljs-string">demo-pyapp</span> <span class="hljs-string">.</span>
</code></pre>
<p>This ensures that the Docker image is built using the Minikube Docker daemon, making it available for use within your Minikube cluster.</p>
<blockquote>
<p>If it doesnot work then push the image to dockerhub or any public registry and use the image name as I have done it</p>
</blockquote>
<p>We can get the IP address of the pods using <em>kubectl get pods -o wide</em></p>
<p>Our two pods are running as we set the replicas: 2 in deployment.yml</p>
<p>To get detailed information about pods we can add verbosity which ranges from 0-9</p>
<ul>
<li><p>Level 0: Normal output</p>
</li>
<li><p>Levels 1-3: Informational messages</p>
</li>
<li><p>Levels 4-6: Debugging information</p>
</li>
<li><p>Levels 7-9: Tracing information</p>
</li>
</ul>
<pre><code class="lang-yaml"><span class="hljs-string">kubectl</span> <span class="hljs-string">get</span> <span class="hljs-string">pods</span> <span class="hljs-string">-v=7</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704994708225/a6c8372a-b4b6-46ae-be09-1e073d456b87.png" alt class="image--center mx-auto" /></p>
<p>This helps us to debug the pod error.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704994548277/1c355408-7802-4c49-95cb-c14d3d1f76b2.png" alt class="image--center mx-auto" /></p>
<p>Using these given IP addresses we can access our application inside the cluster only not outside the cluster.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704994590982/799283fd-b567-488f-b3b0-d1dad5dc7e9e.png" alt class="image--center mx-auto" /></p>
<p>We can see our app is running inside the Minikube cluster. We can check in both IP addresses to see our app running inside the cluster.</p>
<p>But if we try to access the application from outside the cluster, we won't be able to access it. Since the IP of the external browser and clusterIP are not the same as our app is in ClusterIP(default).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704995360318/f522c441-32a4-4849-bc5f-1ba5aed4ed88.png" alt class="image--center mx-auto" /></p>
<p>If we delete the pod then the replica set will immediately create the new pod with a different IP but in the same subnet.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704994961082/c0cb2358-e4c7-46d0-8253-7c05c687b3c0.png" alt class="image--center mx-auto" /></p>
<p>So our application is only accessible to those who have clusterIP. To solve the problem of accessing the app from the same network and external world network we need the service.</p>
<p>Type= Nodeport: to access the app within the organization(Same network)</p>
<p>Type= LoadBalancer: to access the application from the external world anyone who has access to the internet.</p>
<p>Let's create the service file = service.yml</p>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Service</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">python-django-service</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">type:</span> <span class="hljs-string">NodePort</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">app:</span> <span class="hljs-string">sample-python-app</span>
  <span class="hljs-attr">ports:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">port:</span> <span class="hljs-number">80</span>
      <span class="hljs-attr">targetPort:</span> <span class="hljs-number">8000</span>
      <span class="hljs-attr">nodePort:</span> <span class="hljs-number">30007</span>
</code></pre>
<p>We need to select the label from the template section of deployment.yml to insert in the selector section of service.yml. The target port is set to 8000 as our application is running in the port 8000.</p>
<p>Run the service .yml file</p>
<pre><code class="lang-yaml"><span class="hljs-string">kubectl</span> <span class="hljs-string">apply</span> <span class="hljs-string">-f</span> <span class="hljs-string">service.yml</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704984960454/c10018f1-ab54-4d65-b7a2-b6756b6a916f.png" alt class="image--center mx-auto" /></p>
<p>To get services created</p>
<pre><code class="lang-yaml"><span class="hljs-string">kubectl</span> <span class="hljs-string">get</span> <span class="hljs-string">svc</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704996235223/e80f3236-be9f-4295-a81e-dae620ccca6b.png" alt class="image--center mx-auto" /></p>
<p>We can see the app running in the node port which is different from clusterIP. We can access the app either by doing Minikube SSH or using the Minikube IP address in our browser.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704996374187/d1436a80-ff94-4cd8-acdd-529d40d457df.png" alt class="image--center mx-auto" /></p>
<p>This is inside the cluster.</p>
<p>To access from the external browser within the same network.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704996910986/2b02a5f7-4dc3-40dd-b1d6-a85a14115802.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704996974062/6e7ee403-52fe-4328-b96f-ed7f0df755f9.png" alt class="image--center mx-auto" /></p>
<p>Here we can access the application from our browser also. If other people will try to access it, they won't be able to access the application as it is not a load balancer type service.</p>
<p>To access the application from the external browser from another IP we need to use load balancer type.</p>
<p>We changed the node port type to load balancer then the external IP is &lt;pending&gt; as we are executing it from the local environment. The load balancer IP is only provided by the cloud providers so we need to use it in the cloud services like EKS, GKE, AKS.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704997468448/531ab1a0-f68a-494d-a10c-a23ffb964785.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704997234657/5515fbd5-adeb-46c8-9ae8-4240fcc67375.png" alt class="image--center mx-auto" /></p>
<p>We can simply edit the svc file or create a new load balancer yaml file = Loadbalancer.yml file</p>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Service</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">python-django-service</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">type:</span> <span class="hljs-string">LoadBalancer</span>
  <span class="hljs-attr">selector:</span>
    <span class="hljs-attr">app:</span> <span class="hljs-string">sample-python-app</span>
  <span class="hljs-attr">ports:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">port:</span> <span class="hljs-number">80</span>
      <span class="hljs-attr">targetPort:</span> <span class="hljs-number">8000</span>
      <span class="hljs-attr">nodePort:</span> <span class="hljs-number">30007</span>
</code></pre>
<p>Kubeshark</p>
<p>Kubeshark is a very simple application that is used to show the real-time flow of the traffic request. <strong>Kubeshark</strong> offers real-time, cluster-wide, identity-aware, protocol-level visibility into API traffic, empowering its users to see with their own eyes what’s happening in all (hidden) corners of their K8s clusters.</p>
<p>To install in Linux</p>
<pre><code class="lang-plaintext">sh &lt;(curl -Ls https://kubeshark.co/install)
</code></pre>
<p>To run the CLI, use the <code>tap</code> command.</p>
<pre><code class="lang-plaintext">kubeshark tap
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704998751919/f59e16c5-f81b-4d75-aae9-1566d266a735.png" alt class="image--center mx-auto" /></p>
<p>In one of the tabs of the terminal Kubeshark is running.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704998777067/dd2c283a-4ecb-4bf3-a09f-22e36b3ac84a.png" alt class="image--center mx-auto" /></p>
<p>And in the next tab, we sent the 8-9 requests to our application, we will see this traffic request being distributed in the two pods with the IPs: 10.244.0.67 and 10.244.0.66. Let's check it out.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705000598089/a0b303cc-ad6e-4170-a4a6-fd21782e5b7e.png" alt class="image--center mx-auto" /></p>
<p>This is the sample image taken from the internet because I got the error on my minikube as kubeshark-worker-daemon-set pod did not create due to which the request sent from my terminal did not reach the KUbeshark. The error message "Error response from daemon: invalid CapAdd: capability not supported by your kernel or not available in the current environment: 'CAP_CHECKPOINT_RESTORE'" indicates that the <code>CAP_CHECKPOINT_RESTORE</code> capability is not supported or available in your Minikube kernel. But you can try from your side.</p>
<p>In summary, Kubernetes Services emerge as an important component in managing the complexities of deploying applications at scale. By adopting a label-based service discovery approach, Services overcome the limitations of tracking individual pod IPs. The practical implementation within a Minikube cluster highlighted the significance of Services in providing external access to applications.</p>
<p>Happy Learning!!</p>
]]></content:encoded></item><item><title><![CDATA[Automating AWS Cost Optimization: A Lambda Function Approach]]></title><description><![CDATA[In this blog, we delve into the pivotal role of Lambda functions and their profound impact on the tasks of DevOps engineers. Lambda functions, a cornerstone of serverless computing, empower DevOps professionals by streamlining and automating complex ...]]></description><link>https://blogs.subashneupane3.com.np/automating-aws-cost-optimization-a-lambda-function-approach</link><guid isPermaLink="true">https://blogs.subashneupane3.com.np/automating-aws-cost-optimization-a-lambda-function-approach</guid><category><![CDATA[AWS]]></category><category><![CDATA[#CloudWatch]]></category><category><![CDATA[serverless]]></category><category><![CDATA[AWS Cost Optimization]]></category><category><![CDATA[Lambda function]]></category><dc:creator><![CDATA[Subash Neupane]]></dc:creator><pubDate>Thu, 11 Jan 2024 15:18:49 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1704986685763/d5b986cf-26c4-4a6b-b216-d3922495fa13.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we delve into the pivotal role of Lambda functions and their profound impact on the tasks of DevOps engineers. Lambda functions, a cornerstone of serverless computing, empower DevOps professionals by streamlining and automating complex tasks. With the ability to run code without the hassle of server management, Lambda functions enhance efficiency, optimize resource utilization, and enable seamless integration into various AWS services. This exploration sheds light on how Lambda functions become an invaluable tool in the toolkit of DevOps engineers, contributing to agile, scalable, and cost-effective cloud operations.</p>
<p>What is Lambda Function?</p>
<p>AWS Lambda is a serverless computing service provided by Amazon Web Services (AWS). It allows you to run code without provisioning or managing servers.</p>
<p>Features:</p>
<p><strong>Serverless Computing</strong></p>
<p>EventDriven Execution</p>
<p>Pay-as-you-go model</p>
<h3 id="heading-real-time-use-case"><strong>Real-Time Use Case :</strong></h3>
<p><strong>Scenario: Automated Snapshot Cleanup</strong></p>
<p><strong>Problem Statement:</strong></p>
<ul>
<li>Suppose you want to ensure efficient resource management in AWS and avoid unnecessary costs associated with unattached EBS (Elastic Block Store) snapshots. This means you created unlimited resources that are inactive but are causing unnecessary costs. So we need to create an automated program that runs periodically and removes/deletes these inactive resources</li>
</ul>
<p><strong>How does AWS Lambda bring the solution?</strong></p>
<ol>
<li><p><strong>Lambda Function Creation:</strong></p>
<ul>
<li>Develop a Lambda function that identifies and deletes unattached EBS snapshots. This function utilizes the AWS SDK to interact with the AWS EC2 service.</li>
</ul>
</li>
<li><p><strong>CloudWatch Events:</strong></p>
<ul>
<li><p>Schedule the Lambda function to run at specific intervals using CloudWatch Events.</p>
</li>
<li><p>For example, you can set it to run daily or weekly to regularly clean up unattached snapshots.</p>
</li>
</ul>
</li>
<li><p><strong>Automation and Cost Optimization:</strong></p>
<ul>
<li><p>This Lambda function, triggered by CloudWatch, automates the cleanup process, ensuring that unattached EBS snapshots are regularly removed.</p>
</li>
<li><p>This automation optimizes costs by preventing the accumulation of unused storage resources.</p>
</li>
</ul>
</li>
</ol>
<p>This explained scenario is our main objective in this project. Let's start the project:</p>
<p><strong>Create an ec2 instance</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704352233545/09b1a1a1-3a9e-4786-897c-c20493111bf6.png" alt class="image--center mx-auto" /></p>
<p>Here for this instance, we have attached a volume with id <strong><em>vol-0b61a32be947716c3</em></strong> with 8GB capacity.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704352370771/27019909-b6a1-4571-b90f-286a4dd49628.png" alt class="image--center mx-auto" /></p>
<p>Create the Snapshot for Volume.</p>
<p>Go to ec2 dashboard &gt; click "snapshot" &gt; click "create snapshot"</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704352627291/9c43c4b9-3561-4a57-84cb-e21d9eb789bc.png" alt class="image--center mx-auto" /></p>
<p>Here, I've selected a volume and chosen the specific volume ID for which I intend to create a snapshot. Feel free to pick the available volume ID that corresponds to the snapshot you wish to generate.</p>
<p><strong>Create lambda function</strong></p>
<p>Search for "Lamda function" in the search bar &gt; click on "lambda" &gt;click "create lambda" then:</p>
<blockquote>
<p>Author from scratch</p>
<p>Function name: cost-optimize-ebs-snapshot</p>
<p>Runtime: python 3.12</p>
<p>architecture: x86_64</p>
<p>Permissions: default</p>
</blockquote>
<p>Save configuration</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704355011206/d7da5978-af68-4e10-aa82-5434612925d5.png" alt class="image--center mx-auto" /></p>
<p>Now copy the code for the Lambda from <a target="_blank" href="https://github.com/imsubash-devops/python-practice/blob/main/day13/ebs_stale_snapshot.py">GitHub</a>. Copy the code and paste it into the</p>
<p>editor.</p>
<p>This Python script, utilizing the Boto3 library, defines an AWS Lambda function for the automated cleanup of unattached EBS snapshots. The function fetches all owned snapshots and active EC2 instances and then iterates through the snapshots. Unattached snapshots are promptly deleted, and those attached to volumes not linked to running instances are also removed. Boto3 functions such as <code>describe_snapshots</code> and <code>delete_snapshot</code> simplify AWS interactions, showcasing efficient automation for cost optimization.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704355128625/ec18ccaf-a5e5-4a8d-ba44-4c20dea6cc43.png" alt class="image--center mx-auto" /></p>
<p>save the code and deploy. Once it is deployed, click on <strong>test,</strong> and a window will open and enter the event name.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704355596167/b50de009-fb45-4d41-93aa-2516f3ff74fa.png" alt class="image--center mx-auto" /></p>
<p>As we can see on clicking the Test, our code is failed and shows the following error.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704355544789/083023fa-b3ed-4786-9aa0-948490e09886.png" alt class="image--center mx-auto" /></p>
<p>Since the code execution timed out in just 3 seconds, so I have increased the execution time up to 10 seconds.</p>
<blockquote>
<p>Remember: Minimizing the execution time is advisable, as AWS charges are influenced by the duration of execution. AWS considers the execution time as a factor in determining costs.</p>
</blockquote>
<p>Let's test our code once the execution time is increased to 10 seconds.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704356304323/214d0cb6-beb0-4423-a10a-b97c2966d65d.png" alt class="image--center mx-auto" /></p>
<p>We can see that the error indicates that the user, with the given ARN (<code>arn:aws:sts::128571802491:assumed-role/cost-optimize-ebs-snapshot-role-g6a8dccq/cost-optimize-ebs-snapshot</code>), lacks the necessary permissions for the <code>ec2:DescribeSnapshots</code> action. So we are required to attach the policy, granting permissions for the <code>ec2:DescribeSnapshots</code> action.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704356692319/109c5567-4316-4a70-8493-96f67e41b01d.png" alt class="image--center mx-auto" /></p>
<p>click on the Execution role, a window will open, and click "Add permissions". Click on Create Inline Policy.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704357023016/f20457e2-1f8f-41b2-9cbf-506d6cf021ed.png" alt class="image--center mx-auto" /></p>
<p>Now we have chosen the policy rules including Describe Snapshots and DeleteSnapshots.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704358100577/fbf61982-34ea-4ab7-9b80-e7325faa0bfd.png" alt class="image--center mx-auto" /></p>
<p>Once completing the configuration click on Create Policy and name the Policy name as below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704358181592/359eff54-070f-4b08-9a7b-d9a9a241e7b2.png" alt class="image--center mx-auto" /></p>
<p>Now let's test the code after attaching the policy.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704358501837/47abbb62-8657-4b6f-bb7f-0dde6975dd56.png" alt class="image--center mx-auto" /></p>
<p>The error DescribeInstance shows that permission is not allowed.</p>
<p>Let's create a new policy that includes: <strong>DescribeInstance</strong> &amp; <strong>DescribeVolume</strong> in the same way in which we created the Snapshot policy. Once created save the policy as below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704364358636/242c5c54-c6cf-4288-a8fe-78fbd598c89b.png" alt class="image--center mx-auto" /></p>
<p>We can the below policies attached.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704364424206/73f8f3fe-f444-431f-9736-cfa99489b609.png" alt class="image--center mx-auto" /></p>
<p>Now let's execute and view the output.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704364456884/c68bcce3-fdbe-472c-87b0-8ce475a85e13.png" alt class="image--center mx-auto" /></p>
<p>Let's conduct a successful test run by deleting our EC2 instance along with the attached volume. Afterward, we'll execute the test to verify whether the unattached snapshot gets deleted or not.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704364536937/3c40e4cb-773c-4f68-88a6-25d95b701873.png" alt class="image--center mx-auto" /></p>
<p>Observing the deletion of an EBS snapshot with the snapshot ID, we have successfully initiated the Lambda function manually. Now, let's streamline this process by automating the execution through the CloudWatch service.</p>
<p><strong>CloudWatch</strong> is a monitoring and management service provided by Amazon Web Services (AWS). It helps you collect and track metrics, collect and monitor log files, and set alarms. With CloudWatch, you can gain system-wide visibility into resource utilization, application performance, and operational health.</p>
<p>To attach to the cloudwatch, search cloudwatch in the search bar and click on it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704364765132/9e27e84c-b8c2-49c6-8d96-5943904854d4.png" alt class="image--center mx-auto" /></p>
<p>In the Cloudwatch screen, we can see the <strong>events</strong> in the left pan and click on <strong>rules</strong> and then &gt; "Create Rule".</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704364936511/04373cac-300f-4cf5-9577-8bbbd9da6c63.png" alt class="image--center mx-auto" /></p>
<p>Now create the rule as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704365094130/87ead708-341a-422d-abee-9d7ee999a940.png" alt class="image--center mx-auto" /></p>
<p>Click on "Continue in EventBridge Scheduler"</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704365854790/4b33a077-3222-4608-85a7-851bc45493c4.png" alt class="image--center mx-auto" /></p>
<p>In this step, choose recurring schedule so that at any time if there is any unattached snapshot, it will automatically deleted once the recurring schedule is executed and for this set the cron job at what time you want the execution to be started.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704365972493/38815252-f8b0-4f30-84c1-96aac91ad5f2.png" alt class="image--center mx-auto" /></p>
<p>Now in this step, choose the AWS Lambda as this contains our cost optimization program.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704366046631/883a6dbf-4e4b-4fb5-b283-ca107a4c365b.png" alt class="image--center mx-auto" /></p>
<p>Choose <strong>cost-optimize-ebs-snapshot</strong> as the Lambda function.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704366105532/76c08bb7-93ee-47ac-b201-de4ed0f62f22.png" alt class="image--center mx-auto" /></p>
<p>Absolutely! We've successfully set up cost optimization in AWS using a Lambda function and automated it by scheduling the execution with CloudWatch using a cron job. This ensures that unattached snapshots are automatically deleted based on the specified schedule, reducing unnecessary costs and improving resource management.</p>
<p>After the completion of the project do not forget to terminate the services like lambda function, snapshots, and ec2 instances as they may incur higher charges.</p>
<p>Happy Learning!!</p>
]]></content:encoded></item><item><title><![CDATA[AWS IAM: Secure access control in AWS Cloud]]></title><description><![CDATA[In this blog, we are going to explore one of the AWS services i.e. IAM. IAM is abbreviated as Identity Access Management and it empowers users to manage access to AWS services securely.
What is IAM?
AWS IAM is a web service that enables Amazon Web Se...]]></description><link>https://blogs.subashneupane3.com.np/aws-iam-secure-access-control-in-aws-cloud</link><guid isPermaLink="true">https://blogs.subashneupane3.com.np/aws-iam-secure-access-control-in-aws-cloud</guid><category><![CDATA[AWS]]></category><category><![CDATA[iam role in aws]]></category><category><![CDATA[ABOUT AWS user , group , mfa, policies , permission]]></category><category><![CDATA[IAM group]]></category><dc:creator><![CDATA[Subash Neupane]]></dc:creator><pubDate>Wed, 10 Jan 2024 15:06:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1704777272090/70b00e70-b8ce-4afb-8f53-d76ba8d224a4.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we are going to explore one of the AWS services i.e. IAM. IAM is abbreviated as Identity Access Management and it empowers users to manage access to AWS services securely.</p>
<p><strong>What is IAM?</strong></p>
<p>AWS IAM is a web service that enables Amazon Web Services (AWS) customers to manage users and user permissions in the AWS cloud. It is a centralized service that enables us to manage access to AWS services and resources securely. The root user is the one who manages all the users and the permissions allowed to the permission. By using the IAM service, we can ensure that only authorized users have the right level of access to perform specific actions. In short AWS IAM does the authentication and authorization process. It defines the specific user to access the AWS services by authentication and the specific user to use the specific AWS services by authorization process.</p>
<p><strong>Key Components of IAM:</strong></p>
<ul>
<li><p><strong>Users:</strong> Users are the persons who interact with AWS services. They are created by the root user. They can use those resources if they have permission. Permissions are the policies attached to the user by the root user.</p>
</li>
<li><p><strong>Groups:</strong> Groups are the collection of IAM users. If a certain group of users have the same permissions and are performing the same actions then instead of creating a policy for each user, we can simply create a group, attach the policy to the group, and finally add those specific users to this group. Groups reduce the burden of creating each IAM user policy.</p>
</li>
<li><p><strong>Roles:</strong> IAM roles are similar to the users, but they are not associated with specific individuals. Instead, roles are assumed by entities such as AWS services or applications, providing temporary permissions.</p>
</li>
</ul>
<p><strong>IAM Policies:</strong></p>
<p>Policies are the building blocks of IAM. Policies define the permissions provided to the users, groups, or roles. AWS IAM uses JSON-based policy language, allowing fine-grained control over what actions can be performed on which resources. Policies must be attached else the users or any groups won't be able to use the AWS services. By default, the <strong><em>IAMUserChangePassword</em></strong> policy is attached to the user.</p>
<p>Let's create the users with and without attaching policies, attach them to the groups, and explore many more practically.</p>
<p>Log in as the Root user and create a user without attaching any policy.</p>
<p>In the search bar of AWS, search <strong>IAM &gt; Users &gt; Create user</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704779206688/31567759-f376-469e-85a9-a45eb99bac8b.png" alt class="image--center mx-auto" /></p>
<p>On the next page,</p>
<blockquote>
<p>User name : demo</p>
<p>Provide user access to the AWS Management Console - <em>optional: allow</em></p>
<p>choose: I want to create an IAM user</p>
<p>Console password: Autogenerated password</p>
<p>Users must create a new password at next sign-in - Recommended: allow</p>
<p>Click Next</p>
<p>Set permissions: Leave as it is. keep default</p>
<p>click next</p>
</blockquote>
<p>From the above steps, we got the following details.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704779706727/565493b1-3c0d-44fb-acce-7750b97447a2.png" alt class="image--center mx-auto" /></p>
<p>On creating the user, we will get the user credentials either by copying details or downloading the credentials in a CSV file.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704780017255/be5a393f-52de-43e6-8309-b537bcd074ab.png" alt class="image--center mx-auto" /></p>
<p>Note: Before logging in as a new user, as a root user I created a s3 bucket to verify whether an IAM user would be able to view it or not.</p>
<p>As you can see,I have two buckets in the S3</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704780244059/49186a51-9140-4930-9e48-fd83dee356c9.png" alt class="image--center mx-auto" /></p>
<p>Now let us log in as an IAM user - <strong>demo-subash</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704780493373/e83de933-111a-4833-9b50-fe2bc6ed697a.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p>note: Account ID or account alias is taken from console sign in url https://<mark>subash07</mark>.signin.aws.amazon.com/console which can be found in csv file. subash07 in the url is th account alias</p>
</blockquote>
<p>change the password once you are logged in as an IAM User</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704780674859/d5c5c60c-a761-4a6a-b990-23cd44a4fd0f.png" alt class="image--center mx-auto" /></p>
<p>Now let's try to access the s3 bucket that we created as a root user.</p>
<p>Search s3 in the AWS search bar &gt; click S3</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704780878791/1c705b24-8f45-4ff5-a840-674098b4e995.png" alt class="image--center mx-auto" /></p>
<p>Here you can see I am logged in as subash-demo and I don't have permission even to view the created S3 buckets. Not only this, we cannot use any resources in AWS with this account. This is why attaching policy is important in AWS IAM.</p>
<p>We are <strong>authenticated</strong> to use an AWS account but are not <strong>authorized</strong> to use any AWS services with this account.</p>
<p>Let's create a new IAM user with the attached policy.</p>
<p>After logging in as a root user, In the search bar of AWS, search <strong>IAM &gt; Users &gt; Create user</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704781650410/c6f8370b-41d7-47e1-8e2b-6f155c5d538f.png" alt class="image--center mx-auto" /></p>
<p>Every step is the same as the previous one, only at <strong>set permissions</strong> attach the required policy. I have attached the <strong><em>AmazonS3FullAccess</em></strong> policy with this policy a user can do anything with the bucket. This is for demo only, if you are working in a company then based on the requirements you to customize or edit the policy and then attach it to the user or groups.</p>
<p>Create the user and save the credentials.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704781904123/63c77b49-0ede-44cb-8203-71fa29a24fca.png" alt class="image--center mx-auto" /></p>
<p>Log in as a <strong>testuser1.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704782038719/82bf1c9e-db9e-45c4-a6b4-5e1496a3815b.png" alt class="image--center mx-auto" /></p>
<p>Access the S3 bucket.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704782161190/49e641b1-531d-4753-9d0d-eaff94a61148.png" alt class="image--center mx-auto" /></p>
<p>In this case, we can access the S3 buckets. Let's create a bucket as "testuser1".</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704782286439/d9a31d0d-2e18-4ee8-a3fb-09d2765733d9.png" alt class="image--center mx-auto" /></p>
<p>Since we have full s3 bucket access we can not only create but also delete, move, and configure the bucket permissions and securities.</p>
<p>From the above two users created, we have attached the different policies each time. It was just for demo but when we try to implement it at the company level then it will be the burden of work just to create the user and attach a policy to them every time. This is not an effective way to do the IAM management. So to overcome these burdens, groups are created in IAM so that similar users with the same access policy will be in the same group.</p>
<p>Let's create a group and explore it.</p>
<p>After logging in as a root user, In the search bar of AWS, search <strong>IAM &gt; Group Users &gt; Create Group</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704783853626/a2bcbdfc-1bd1-4b5d-8bcb-b5fdd3078b68.png" alt class="image--center mx-auto" /></p>
<p>We can see we have created the group and added the users inside the group. Furthermore, we have attached the policy to the group also. We can add the users later once the group is added and customize the policies based on the requirements of users in the group.</p>
<p>AWS IAM is a powerful tool for securing our AWS resources. By following best practices, staying informed about new features, and regularly auditing policies, we can create a simplified access control system. Mastering IAM is not just a best practice but it's a key pillar in building a secure and scalable AWS environment.</p>
<p>Happy Learning!!</p>
]]></content:encoded></item><item><title><![CDATA[Deploying our first app in the K8s pod]]></title><description><![CDATA[In this blog, we will explore more deeply about Kubernetes. In the previous blogs, we discussed the Kubernetes architecture and management tools like kOps as the fundamentals of Kubernetes. In this blog, we will know about the Pod and deploy our appl...]]></description><link>https://blogs.subashneupane3.com.np/deploying-our-first-app-in-the-k8s-pod</link><guid isPermaLink="true">https://blogs.subashneupane3.com.np/deploying-our-first-app-in-the-k8s-pod</guid><category><![CDATA[#Pods ]]></category><category><![CDATA[#k8scluster]]></category><category><![CDATA[containers]]></category><category><![CDATA[node]]></category><category><![CDATA[minikube]]></category><category><![CDATA[kubectl]]></category><dc:creator><![CDATA[Subash Neupane]]></dc:creator><pubDate>Tue, 09 Jan 2024 15:09:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1704791388729/2f08a3c3-4d62-4e22-a2df-50f226e5a194.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we will explore more deeply about Kubernetes. In the previous blogs, we discussed the Kubernetes architecture and management tools like kOps as the fundamentals of Kubernetes. In this blog, we will know about the Pod and deploy our application in the pod.</p>
<h3 id="heading-what-is-pod">What is Pod?</h3>
<p>A pod is similar to the container but the container is created using the Docker CLI commands while a Pod is created by writing the manifest in the YAML file. Therefore, to create a pod we should know YAML.</p>
<p>In a single pod, single or multiple containers can be created. By the way, in Kubernetes, everything is dealt with YAML file whether it is about creating pods, service, deployment, etc.</p>
<p>If we create multiple containers inside the pod, then Kubernetes provides shared networking and shared storage. In this way, the containers inside the pod can communicate with each other using the local host.</p>
<p><strong>Setup</strong></p>
<p>Kubectl - command line tool</p>
<p>Minikube - local development environment, single node architecture</p>
<ul>
<li>To install Kubectl</li>
</ul>
<pre><code class="lang-plaintext">sudo apt install kubectl -y
</code></pre>
<ul>
<li>TO install minikube</li>
</ul>
<pre><code class="lang-plaintext">sudo apt-get install -y minikube
</code></pre>
<ul>
<li>To start minikube</li>
</ul>
<pre><code class="lang-plaintext">minikube start
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704794115981/43ca43b9-58a8-4d7e-8dd7-0f0ea59b0962.png" alt class="image--center mx-auto" /></p>
<p>Our minikube is running and lets run some commands</p>
<ul>
<li>To get node information</li>
</ul>
<pre><code class="lang-plaintext">kubectl get nodes
</code></pre>
<ul>
<li>To get Pods information</li>
</ul>
<pre><code class="lang-plaintext">kubectl get pods
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704794290445/565346fb-1eb5-4d7a-8f34-d19ec242b8af.png" alt class="image--center mx-auto" /></p>
<ul>
<li>Let's write our first pod.yml file</li>
</ul>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Pod</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">nginx</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">containers:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">nginx</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">nginx:1.14.2</span>
    <span class="hljs-attr">ports:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">containerPort:</span> <span class="hljs-number">80</span>
</code></pre>
<p>Here, this YAML code describes a Kubernetes Pod named "nginx" that runs a single container using the NGINX image version 1.14.2. The container exposes port 80, allowing traffic to access the NGINX web server within the Pod. This Pod definition is a basic configuration used for deploying a simple NGINX web server in a Kubernetes cluster.</p>
<ul>
<li>To run the pod</li>
</ul>
<pre><code class="lang-yaml"><span class="hljs-string">kubectl</span> <span class="hljs-string">apply</span> <span class="hljs-string">-f</span> <span class="hljs-string">pod.yml</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704795311096/c5323bd6-c523-4f41-ad3e-214a75a374f7.png" alt class="image--center mx-auto" /></p>
<p>Our pod is created successfully.</p>
<ul>
<li>To get more details about the pod</li>
</ul>
<pre><code class="lang-yaml"><span class="hljs-string">kubectl</span> <span class="hljs-string">get</span> <span class="hljs-string">po</span> <span class="hljs-string">pod_name</span> <span class="hljs-string">-o</span> <span class="hljs-string">wide</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704795478856/f346407b-2314-4475-b708-06ae9b42d7ea.png" alt class="image--center mx-auto" /></p>
<ul>
<li>To enter into the container</li>
</ul>
<pre><code class="lang-bash">minikube ssh
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704795697700/24b2287b-e56e-46aa-bd3f-5aeb3208f868.png" alt class="image--center mx-auto" /></p>
<p>We do not need to enter the IP address to log into the container.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704795847187/526fd22e-e6bf-46e6-94db-0801fb8065d2.png" alt class="image--center mx-auto" /></p>
<p>We can see our first ever Kubernetes application is created and is running perfectly.</p>
<ul>
<li>To inspect the pod</li>
</ul>
<pre><code class="lang-bash">kubectl describe pods pod-name
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704796594980/f392bd39-f260-4db1-a192-cd3b9bbbe9fb.png" alt class="image--center mx-auto" /></p>
<ul>
<li>To get logs of the pod for any issue</li>
</ul>
<pre><code class="lang-bash">kubectl logs pod_name
</code></pre>
<p>In this way, we can debug and view the logs of the Kubernetes pods. Pods are simple and easy to use. To enhance with features like autoscaling, and auto-healing, we will use the services and deployments in the upcoming blogs.</p>
<p>Happy Learning!!</p>
]]></content:encoded></item><item><title><![CDATA[Kubernetes kOps: Manage K8s Clusters in AWS]]></title><description><![CDATA[The creation, deployment, and management of available Kubernetes clusters for production environments is often a complex and time-consuming process. The tasks get even more complex when it is related to provisioning AWS resources. So looking at this ...]]></description><link>https://blogs.subashneupane3.com.np/kubernetes-kops-manage-k8s-clusters-in-aws</link><guid isPermaLink="true">https://blogs.subashneupane3.com.np/kubernetes-kops-manage-k8s-clusters-in-aws</guid><category><![CDATA[Kops]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[AWS]]></category><category><![CDATA[EC2 instance]]></category><category><![CDATA[clusters]]></category><dc:creator><![CDATA[Subash Neupane]]></dc:creator><pubDate>Mon, 08 Jan 2024 15:16:06 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1704702054299/4e32b421-f507-47c0-87f8-ee5bdf6fcdf0.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The creation, deployment, and management of available Kubernetes clusters for production environments is often a complex and time-consuming process. The tasks get even more complex when it is related to provisioning AWS resources. So looking at this challenge, Kubernetes kOps emerges as a valuable solution, it offers teams a simple and scalable approach to configure and manage production-grade clusters.</p>
<p>Before we start our journey with kOps, we will get into its fundamental aspects, explore key features, draw comparisons with other popular alternatives, and go through a practical example illustrating how to use kOps on AWS which will give us hands-on experience with the necessary insights and skills using this effective tool.</p>
<h3 id="heading-development-level-environments-of-kubernetes">Development Level Environments of Kubernetes</h3>
<ul>
<li><p>Minikube</p>
</li>
<li><p>Kind</p>
</li>
<li><p>K3S</p>
</li>
<li><p>K3D</p>
</li>
<li><p>Micro k8S</p>
</li>
</ul>
<h3 id="heading-production-level-kubernetes-environments">Production Level Kubernetes Environments</h3>
<ul>
<li><p>EKS</p>
</li>
<li><p>AKS</p>
</li>
<li><p>GKE</p>
</li>
<li><p>Openshift</p>
</li>
<li><p>Rancher and so on</p>
</li>
</ul>
<h3 id="heading-what-is-kops">What is kOps?</h3>
<p>Kops, short for Kubernetes Operations, is an open-source tool designed to simplify the process of creating, deploying, and managing Kubernetes clusters, particularly in production environments. It is the most widely used tool.</p>
<p>With kOps, we can automate the management of Kubernetes clusters as kOps can easily create, apply, and update cluster configurations.</p>
<p>Kubernetes kOps is supported by AWS Cloud, Google Cloud Platform, Microsoft Azure, Digital Ocean, etc.</p>
<p><strong>Alternatives to kOps</strong></p>
<p>kOps is not the only tool available for cluster management. There are several alternatives to kOps but kOps appears ahead of all the tools available. Some tools are:</p>
<ul>
<li><p>Kubeadm - kubeadm does not support the provisioning of infrastructure.</p>
</li>
<li><p>Eksctl - Only supports AWS</p>
</li>
<li><p>kubespray - Kubespray does not support the provisioning of infrastructure</p>
</li>
</ul>
<h3 id="heading-to-set-up-a-kubernetes-cluster-in-aws-with-kops">To <strong>set up a Kubernetes Cluster in AWS with kOps</strong></h3>
<p><strong>Create an ec2 instance and install the following dependencies</strong></p>
<ul>
<li><p>Python3</p>
</li>
<li><p>AWS CLI</p>
</li>
<li><p>Kubectl</p>
</li>
<li><p>An active domain with a dedicated “kops” subdomain: For this demo, we will use <mark>.k8s.local</mark></p>
</li>
<li><p>IAM user with below permissions</p>
<ol>
<li><p>AmazonEC2FullAccess</p>
</li>
<li><p>AmazonS3FullAccess</p>
</li>
<li><p>IAMFullAccess</p>
</li>
<li><p>AmazonVPCFullAccess</p>
</li>
</ol>
</li>
</ul>
<p>Step 1: Create an IAM user called “kops” with the required permissions.</p>
<blockquote>
<p>Note: If you are using the admin user, the below permissions are available by default</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704693052041/0ff1402f-af2f-4634-b64d-a5d01c4f9b87.png" alt class="image--center mx-auto" /></p>
<p>Now login as an IAM user i.e kops so that we will create the instance, and k8s clusters.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704693392226/2f4f8e21-2985-41b6-919c-8396790fe701.png" alt class="image--center mx-auto" /></p>
<p>Once you log into your account, go to <strong>Security Credentials</strong> &gt; generate the Access key and Secret key to configure AWS in CLI.</p>
<p>Step 2 Create an ec2 instance and access it using ssh protocol</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704694621330/0668939b-57ba-44ba-9c49-286f30013363.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704694696076/a1a02cb0-678e-44f9-9162-8d597f284515.png" alt class="image--center mx-auto" /></p>
<p>Once you are logged into the ec2 instance then RUn aws configure to verify user credentials.</p>
<p>Note: Update the instance and Install AWS CLI in the ec2 instance</p>
<pre><code class="lang-bash">sudo apt update
sudo apt install awscli
aws configure
</code></pre>
<p>Install dependencies</p>
<pre><code class="lang-plaintext">curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
</code></pre>
<pre><code class="lang-plaintext">echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
</code></pre>
<pre><code class="lang-plaintext">sudo apt-get update
sudo apt-get install -y python3-pip apt-transport-https kubectl
</code></pre>
<pre><code class="lang-plaintext">pip3 install awscli --upgrade
</code></pre>
<pre><code class="lang-plaintext">export PATH="$PATH:/home/ubuntu/.local/bin/"
</code></pre>
<p><strong>Install kOPs</strong></p>
<pre><code class="lang-plaintext">curl -LO https://github.com/kubernetes/kops/releases/download/$(curl -s https://api.github.com/repos/kubernetes/kops/releases/latest | grep tag_name | cut -d '"' -f 4)/kops-linux-amd64

chmod +x kops-linux-amd64

sudo mv kops-linux-amd64 /usr/local/bin/kops
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704695279287/919c7be3-d70b-4454-a51c-0a7db1114759.png" alt class="image--center mx-auto" /></p>
<p>kOps is installed successfully.</p>
<h2 id="heading-kubernetes-cluster-installation">Kubernetes Cluster Installation</h2>
<h3 id="heading-create-an-s3-bucket-for-storing-the-kops-objects">Create an S3 bucket for storing the KOPS objects</h3>
<p>kOps stores its configurations, keys, and related items, in an S3 bucket to manage Kubernetes clusters. Therefore we need to create a dedicated S3 bucket for this purpose.</p>
<pre><code class="lang-plaintext">aws s3api create-bucket --bucket kops-subash-storage --region us-east-1
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704695825759/02295037-59f2-4cc0-9de9-9046eb6e606f.png" alt class="image--center mx-auto" /></p>
<p>Verify it in AWS</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704695842601/57ed4cb9-50aa-443f-aeb8-31a03c13d0f7.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-create-the-cluster">Create the cluster</h3>
<pre><code class="lang-plaintext">kops create cluster --name=demok8scluster.k8s.local --state=s3://kops-subash-storage --zones=us-east-1a --node-count=1 --node-size=t2.micro --master-size=t2.micro  --master-volume-size=8 --node-volume-size=8
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704697441896/c247d810-fc90-41c0-819d-49a7caf8d979.png" alt class="image--center mx-auto" /></p>
<p>Here our Kubernetes cluster configuration is created but not started. So to start the Kubernetes cluster run the command</p>
<pre><code class="lang-plaintext">kops update cluster --name demok8scluster.k8s.local --yes --admin
</code></pre>
<p>Output:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704697858421/4fbe4713-a85a-4811-99c0-c8370e27f5d8.png" alt class="image--center mx-auto" /></p>
<p>Run the comand</p>
<pre><code class="lang-plaintext">kops validate cluster --wait 10m
</code></pre>
<p>Wait for about 10 minutes for the cluster to come up.</p>
<p>When the cluster is ready, you will see output similar to this:</p>
<blockquote>
<p>Since I used t2.micrwhich has less storage and computing power we could not validate the configuration</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704698948911/206a2e83-63d3-4cce-ba45-94fa5f798739.png" alt class="image--center mx-auto" /></p>
<p>But after running the command <strong><em>kops validate cluster --wait 10m</em></strong> <em>clusters will be created.</em></p>
<p>To get nodes</p>
<pre><code class="lang-plaintext">kubectl get nodes
</code></pre>
<p>nodes:</p>
<ul>
<li><p>Master node</p>
</li>
<li><p>worker node</p>
</li>
</ul>
<p>Deploy a simple workload - nginx and expose it at port 80</p>
<pre><code class="lang-plaintext">kubectl create deployment my-nginx --image=nginx --replicas=1 --port=80 
kubectl expose deployment my-nginx --port=80 --type=LoadBalancer
</code></pre>
<p>Verify Nginx is running</p>
<pre><code class="lang-plaintext">kubectl get pods
</code></pre>
<p>To get the load balancer details</p>
<pre><code class="lang-plaintext">kubectl get svc my-nginx
</code></pre>
<p>Earlier, we saw that kOps created one master and one node by default.</p>
<pre><code class="lang-plaintext">kops get instance group
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704700098179/bcbec63e-aca8-4e8e-8646-e3c46e2e29f0.png" alt class="image--center mx-auto" /></p>
<p>Here, the instance group name ‘nodes-us-east-1a’ is for the node role. We can edit it and update the ‘maxSize’ and ‘minSize’ to values 3. First, open the editor with this command:</p>
<pre><code class="lang-plaintext">kops edit instancegroups nodes-us-east-1a
</code></pre>
<pre><code class="lang-plaintext"># Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
  creationTimestamp: "2024-1-8T05:16:35Z"
  labels:
    kops.k8s.io/cluster: demok8scluster.k8s.local
  name: nodes-us-east-1a
spec:
  image: 099720109477/ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-20211118
  instanceMetadata:
    httpPutResponseHopLimit: 1
    httpTokens: required
  machineType: t3.medium
  maxSize: 3
  minSize: 3
  nodeLabels:
    kops.k8s.io/instancegroup: nodes-us-east-1a
  role: Node
  subnets:
 —us-east-1a
</code></pre>
<p>Save and quit the editor. Apply the changes by running:</p>
<pre><code class="lang-plaintext">kops update cluster --name demok8scluster.k8s.local --yes --admin
</code></pre>
<p>After a few minutes, you can verify that the node count is 3.</p>
<pre><code class="lang-plaintext">kubectl get nodes
</code></pre>
<h3 id="heading-delete-the-demo-cluster-and-resources">Delete the demo cluster and resources</h3>
<p>Since we're operating a Kubernetes cluster in AWS, it's crucial to be aware that the underlying infrastructures such as EC2 instances and LoadBalancers—incur costs. Therefore, it's important to remember to delete the cluster once we've completed the demo to avoid unnecessary expenses.</p>
<p>Execute the following commands to effectively delete both the resources and the cluster:</p>
<pre><code class="lang-plaintext">kubectl delete svc my-nginx
kubectl delete deploy my-nginx
kops delete cluster --name demok8scluster.k8s.local --yes
</code></pre>
<p>In this way, we can use kOps for the different operations in Kubernetes. Furthermore, to know about kops CLI usage use this link <a target="_blank" href="https://kops.sigs.k8s.io/cli/kops/">https://kops.sigs.k8s.io/cli/kops/</a></p>
<p>Therefore, kOps makes managing our Kubernetes cluster on AWS easy by automating the setup of necessary resources like instances and load balancers. It strikes a balance between control and simplicity, simplifying our cluster management tasks.</p>
<p>Thank you!!</p>
<p>Happy Learning!!</p>
]]></content:encoded></item><item><title><![CDATA[Automate JIRA Creation on a Github Event using Python]]></title><description><![CDATA[In this blog, we are going to know how the automation is done between Github and Jira so that when an issue is created in a GitHub repository and marked by a developer's comment—potentially a specific word like '/jira'—a corresponding ticket is autom...]]></description><link>https://blogs.subashneupane3.com.np/automate-jira-creation-on-a-github-event-using-python</link><guid isPermaLink="true">https://blogs.subashneupane3.com.np/automate-jira-creation-on-a-github-event-using-python</guid><category><![CDATA[Jira automation]]></category><category><![CDATA[AWS]]></category><category><![CDATA[GitHub]]></category><category><![CDATA[Python]]></category><category><![CDATA[Flask Framework]]></category><category><![CDATA[APIs]]></category><dc:creator><![CDATA[Subash Neupane]]></dc:creator><pubDate>Sun, 07 Jan 2024 15:02:04 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1704610133203/0d1f5df2-61b1-4132-922d-a2c432b1c9d7.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we are going to know how the automation is done between Github and Jira so that when an issue is created in a GitHub repository and marked by a developer's comment—potentially a specific word like '/jira'—a corresponding ticket is automatically generated in Jira. But before diving into the process let's understand GitHub and Jira.</p>
<p><strong>GitHub:</strong></p>
<p>GitHub is a web-based platform for version control using Git. It provides different features such as code hosting, version tracking, and collaboration tools like pull requests and issues.</p>
<p><strong>Jira</strong></p>
<p>Jira is a versatile project management and issue-tracking software developed by Atlassian. It is widely adopted in software development as Jira allows teams to plan, track, and manage their work efficiently.</p>
<p>How we will integrate Github with Jira?</p>
<p>So, in this project, we will use Python API, and webhooks to communicate between GitHub and Jira.</p>
<p>Whenever an issue is created in the GitHub repository, webhooks tell GitHub to monitor a particular comment for eg: "<strong>/Jira"</strong> done by the developer or owners. Then the JSON parser provides the JSON file to the Python application which we created as an API whose URL is configured inside the webhooks. Then the Python API calls the Jira API by sending the JSON which was received from GitHub. ON receiving it, Jira creates the ticket automatically.</p>
<p>This streamlined process ensures that when developers or owners add a specific comment in GitHub, the Flask app acts as a bridge to communicate with Jira, triggering the automatic creation of a corresponding ticket.</p>
<p>Setup requirements:</p>
<blockquote>
<p>Jira Setup</p>
<p>Flask app</p>
<p>ec2 instance</p>
<p>Github webhooks</p>
<p>Jira API</p>
</blockquote>
<ul>
<li><strong>Setup Jira</strong></li>
</ul>
<p>Anyone can simply create an account at <a target="_blank" href="https://www.atlassian.com/software/jira">https://www.atlassian.com/software/jira</a>. Once creating the account click on your profile and choose <mark>Jira as the software</mark>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704558267462/2404c7ab-431c-4fcc-8702-4b8aa2839c20.png" alt class="image--center mx-auto" /></p>
<ul>
<li>Then click <strong><mark>Get it for free</mark></strong></li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704558540454/e042d9a0-7863-4d80-b372-669833018996.png" alt class="image--center mx-auto" /></p>
<ul>
<li>A page will open and we do not need to do anything and simply Click on next.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704558530489/72a3a0f7-12d4-4579-bd6f-e0fe8f2c46c1.png" alt class="image--center mx-auto" /></p>
<p>On the next page enter the email and site name, the site name is automatically generated or you can customize the site name as per your desire.</p>
<ul>
<li>After this choose Scrum as the template</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704559022783/edf049d1-0a9e-48c2-9e4d-b333969c688a.png" alt class="image--center mx-auto" /></p>
<ul>
<li>And Now choose "Select a team-managed project"</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704558861197/4d96280a-183a-4b0e-9bfa-7eb21057bc3b.png" alt class="image--center mx-auto" /></p>
<ul>
<li>Add the project details</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704559086325/b6376a88-309c-4018-b9c1-e78644c398f5.png" alt class="image--center mx-auto" /></p>
<ul>
<li>After configuring all these details, now our project is created.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704559186499/fe794690-8787-4544-81f9-edb97aedf2c7.png" alt class="image--center mx-auto" /></p>
<p>Now we have created our project and the Jira setup is done. To integrate our project with GitHub or to make communication between the two systems we need the API tokens.</p>
<p>Let's create the API token. In your profile Go to Security&gt; click Create and manage API tokens &gt;create API&gt; copy the API token</p>
<p>Note: Keep safely the API token, the same token can't be generated again, else we need to generate the new API token.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704559335484/950a53bd-a4d1-4081-8da2-96e72e943eb3.png" alt class="image--center mx-auto" /></p>
<p>We have created the API token successfully.</p>
<ul>
<li>From Jira API documentation, we need to get the Python code to create an issue.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704559708912/51a609dc-8281-4741-9bbd-f975e97180f2.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> requests
<span class="hljs-keyword">from</span> requests.auth <span class="hljs-keyword">import</span> HTTPBasicAuth
<span class="hljs-keyword">import</span> json

url = <span class="hljs-string">"https://your-domain.atlassian.net/rest/api/3/issue"</span> <span class="hljs-comment">#add your url</span>

auth = HTTPBasicAuth(<span class="hljs-string">"email@example.com"</span>, <span class="hljs-string">"&lt;api_token&gt;"</span>)

headers = {
  <span class="hljs-string">"Accept"</span>: <span class="hljs-string">"application/json"</span>,
  <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>
}

payload = json.dumps( {
  <span class="hljs-string">"fields"</span>: {
    <span class="hljs-string">"description"</span>: {
      <span class="hljs-string">"content"</span>: [
        {
          <span class="hljs-string">"content"</span>: [
            {
              <span class="hljs-string">"text"</span>: <span class="hljs-string">"My First Jira Ticket"</span>,
              <span class="hljs-string">"type"</span>: <span class="hljs-string">"text"</span>
            }
          ],
          <span class="hljs-string">"type"</span>: <span class="hljs-string">"paragraph"</span>
        }
      ],
      <span class="hljs-string">"type"</span>: <span class="hljs-string">"doc"</span>,
      <span class="hljs-string">"version"</span>: <span class="hljs-number">1</span>
    },
    <span class="hljs-string">"issuetype"</span>: {
      <span class="hljs-string">"id"</span>: <span class="hljs-string">"10007"</span>
    },
    <span class="hljs-string">"project"</span>: {
      <span class="hljs-string">"key"</span>: <span class="hljs-string">"SUB"</span> <span class="hljs-comment">#add your key</span>
    },
    <span class="hljs-string">"summary"</span>: <span class="hljs-string">"First Jira Ticket"</span>,
  },
  <span class="hljs-string">"update"</span>: {}
} )
response = requests.request(
   <span class="hljs-string">"POST"</span>,
   url,
   data=payload,
   headers=headers,
   auth=auth
)
print(json.dumps(json.loads(response.text), sort_keys=<span class="hljs-literal">True</span>, indent=<span class="hljs-number">4</span>, separators=(<span class="hljs-string">","</span>, <span class="hljs-string">": "</span>)))
</code></pre>
<p>I have removed the lines from the code as we don't need it. We only needed the project type*, issue type*, and summary* as they are the compulsory fields that need to be completed.</p>
<blockquote>
<p>Note: In the above code insert the url replace "https://your-domain.atlassian.net", insert your email address used to login jira and finally the api token that you had earlier created, in project key, check the project it will be at the side of you project name inside (), and for the issue type, check their ids from project&gt;board&gt;3 dots(...)&gt;configure board&gt;issue types&gt;choose any option&gt;check id in url</p>
</blockquote>
<ul>
<li>Once this is done, we can test our code whether the ticket is created or not.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704560889143/bda19339-f70d-4f4c-b09d-cd56c754e1eb.png" alt class="image--center mx-auto" /></p>
<ul>
<li>Our code is successfully run and the ticket is created and now let's verify it in the Jira.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704560836358/b62a8009-0733-4ee5-974b-beef8302240a.png" alt class="image--center mx-auto" /></p>
<p>Here we can see the tickets being created. By the way, there are three tickets because I executed the code three times that's why three tickets are generated.</p>
<p>Our Jira API is finely working and created our first Jira ticket, now let's create a Python Flask app framework</p>
<p>note: It is a skeleton of the main code</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> flask <span class="hljs-keyword">from</span> Flask
<span class="hljs-keyword">import</span> requests
<span class="hljs-keyword">from</span> requests.auth <span class="hljs-keyword">import</span> HTTPBasicAuth
<span class="hljs-keyword">import</span> json
app = Flask(__name__)
<span class="hljs-string">"@app.route("</span>/createJIRA<span class="hljs-string">", methods=['POST']"</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">createJIRA</span>():</span>
  <span class="hljs-comment">#jira_code here</span>

app.run(<span class="hljs-string">'0.0.0.0'</span>, port=<span class="hljs-number">5000</span>)
</code></pre>
<ul>
<li>You can access the source code here in this <a target="_blank" href="https://github.com/imsubash-devops/python-practice/tree/main/day14">GitHub link</a>.</li>
</ul>
<p>Now our Python application is also ready. We will create an ec2 instance in the AWS cloud.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704566016907/e1fda569-b5ba-48d8-82a0-47b76b198400.png" alt class="image--center mx-auto" /></p>
<ul>
<li><strong>Access the instance using SSH protocol as our instance is ready</strong></li>
</ul>
<pre><code class="lang-python">ssh -i ~/path-to-pemfile/pem_file user_name@ipv4address
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704566261277/2de09063-9b31-44fb-86ec-58afed71fe93.png" alt class="image--center mx-auto" /></p>
<ul>
<li>Create our flask application inside the instance along with .env file to store our API token details.</li>
</ul>
<p>Since the API token is very sensitive content, we need to keep it secure so that no one can misuse it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704566486812/861e0f3a-1942-41cd-b9e5-b3d563976cef.png" alt class="image--center mx-auto" /></p>
<ul>
<li>Let's see whether our flask app runs or not.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704567183137/1e0dbbb8-0633-42dd-97f1-c1d2e4c6e186.png" alt class="image--center mx-auto" /></p>
<p>Great! Our app is perfect working and now verify it using the GitHub Webhooks.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704568998732/63d3bba7-1880-43f5-9ccd-f48c9bf0ff5b.png" alt class="image--center mx-auto" /></p>
<p>To create a webhook, first, we need to choose the repo for which we need to configure the webhook. In the same repository window, click on <strong>settings &gt;</strong> click on <strong>webhooks &gt;</strong> click on <strong>Add Webhooks.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704606923037/f1faaecf-ee7b-4490-a96a-ba21238200b2.png" alt class="image--center mx-auto" /></p>
<ul>
<li>Then the following page will open.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704569284082/52fc73db-e370-4379-9fb4-1466c47196d6.png" alt class="image--center mx-auto" /></p>
<p>In this page enter the URL of your Python application and in <mark>Let Me select individual events</mark> choose <strong>ISSUES</strong>. Click on Add Webhook.</p>
<ul>
<li>Check whether the GitHub actions passed or not.</li>
</ul>
<blockquote>
<p>Note: Before testing the Github actions , you need to set the inbound rules for port 5000 in your ec2 instance otherwise the test will fail as it won't be able to access our python application as it is in the ec2 instance.</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704570043398/5d5ac29f-2851-405c-8d57-a4333f3e1684.png" alt class="image--center mx-auto" /></p>
<p>Success!!</p>
<ul>
<li>Let's do a comment on an issue and check in Jira whether a ticket is created or not.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704570557485/88e1fb7d-48bf-4da5-9d9d-9ee3db61270b.png" alt class="image--center mx-auto" /></p>
<ul>
<li>Now let's verify in Jira.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704570636816/bb90cdfc-26fb-4c9f-bfd4-5fe7050f7d3f.png" alt class="image--center mx-auto" /></p>
<p>As there are multiple tickets but the latest ticket is SUB 5 which is created just a minute ago. This means our implementation is perfectly done.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704570721137/56f0ee38-1f07-489c-8158-9baa5e9c52f8.png" alt class="image--center mx-auto" /></p>
<p>Webhook actions show the issues created and opened as we opened it in Jira.</p>
<p>What if the developer comments something else in the issues, then the Jira will create a ticket if we don't mention our logic while making the API call.</p>
<pre><code class="lang-python"> <span class="hljs-comment"># Check if the condition is true before making the API request</span>
    <span class="hljs-keyword">if</span> <span class="hljs-string">"/jira"</span> <span class="hljs-keyword">in</span> request.json[<span class="hljs-string">"issue"</span>][<span class="hljs-string">"body"</span>]:
        <span class="hljs-comment"># Perform the API request only if the condition is true</span>
        response = requests.post(url, data=payload, headers=headers, auth=auth)        
    <span class="hljs-keyword">else</span>:
        print(<span class="hljs-string">"Comment should be /jira only"</span>)
</code></pre>
<p>We have added this logic so that whenever there is a comment in the issue, it verifies whether the comment is "/jira". If yes then only the API call will be made and Jira creates a ticket otherwise if there is another comment it will notify telling that the comment should be only /jira.</p>
<p>Congratulations, we have successfully implemented the project. Using different technologies like Python, Flask, and webhooks, we've streamlined the process, promoting efficiency. We have also performed security practices by keeping sensitive information hidden.</p>
<p>Happy coding! Keep learning!!</p>
]]></content:encoded></item></channel></rss>