<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ravindra Singh</title>
    <description>The latest articles on DEV Community by Ravindra Singh (@ravindras).</description>
    <link>https://dev.to/ravindras</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1197801%2Fdbe218cb-52e9-4537-9087-e8ff2e45956c.jpeg</url>
      <title>DEV Community: Ravindra Singh</title>
      <link>https://dev.to/ravindras</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ravindras"/>
    <language>en</language>
    <item>
      <title>Cross-Account Amazon ECR Image Access from EC2: A Secure IAM-Based Approach</title>
      <dc:creator>Ravindra Singh</dc:creator>
      <pubDate>Thu, 04 Dec 2025 12:21:52 +0000</pubDate>
      <link>https://dev.to/aws-builders/how-to-pull-aws-ecr-images-across-accounts-using-ec2-2cgd</link>
      <guid>https://dev.to/aws-builders/how-to-pull-aws-ecr-images-across-accounts-using-ec2-2cgd</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;br&gt;
In many real-world AWS environments, applications and workloads often run in one AWS account while container images are stored in another. This pattern is common in multi-account setups, enterprises, managed service providers, and vendor-hosted solutions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A typical example:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Account A (Consumer): Runs EC2 instances or applications&lt;/li&gt;
&lt;li&gt;Account B (Source): Hosts container images in Amazon ECR&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The challenge:&lt;/strong&gt;&lt;br&gt;
EC2 instances in Account A cannot directly pull Docker images from ECR in Account B.&lt;/p&gt;

&lt;p&gt;👉 To solve this, AWS supports secure cross-account ECR access using IAM Roles + ECR Repository Policies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architecture Overview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fron4o8kp6ng6t3uaz0af.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fron4o8kp6ng6t3uaz0af.png" alt="Image of Cross Account" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;EC2 instance in Account A assumes an IAM Role&lt;/li&gt;
&lt;li&gt;IAM Role has permission to authenticate with ECR&lt;/li&gt;
&lt;li&gt;ECR Repository in Account B trusts this IAM role&lt;/li&gt;
&lt;li&gt;EC2 logs in → pulls the container image&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create IAM Role for EC2 in Account A&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You need an IAM Role that your EC2 instance will use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.1 Choose EC2 as the trusted entity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;During IAM role creation:&lt;/p&gt;

&lt;p&gt;Trusted Entity: EC2&lt;br&gt;
“Allows EC2 instances to call AWS services on your behalf”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyodot3yxqsm4n11rw0a4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyodot3yxqsm4n11rw0a4.png" alt="Ec2" width="800" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.2 Attach the policy below:&lt;/strong&gt;&lt;br&gt;
🔐 IAM Policy: Allow EC2 to Pull Images from Account B&lt;/p&gt;

&lt;p&gt;(This goes into Account A, attached to the EC2 IAM Role)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "GetAuthToken",
            "Effect": "Allow",
            "Action": "ecr:GetAuthorizationToken",
            "Resource": "*"
        },
        {
            "Sid": "PullImages",
            "Effect": "Allow",
            "Action": [
                "ecr:BatchGetImage",
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchCheckLayerAvailability"
            ],
            "Resource": "arn:aws:ecr:us-east-1:&amp;lt;ACCOUNT_B_ID&amp;gt;:repository/&amp;lt;REPO_NAME&amp;gt;"
        }
    ]
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why "Resource": "*" on GetAuthorizationToken?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because AWS does not support resource-level restrictions for this API.&lt;br&gt;
This is required and safe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Attach the IAM Role to the EC2 instance&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EC2 → Instance → Actions → Security → Modify IAM Role → Select your role
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your EC2 is now authorized to pull images — but ECR in Account B must still trust it.&lt;/p&gt;

&lt;p&gt;🔐 &lt;strong&gt;ECR Repository Policy (Account B → Allows Account A to Pull)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This explicitly tells the ECR repo that the IAM role from Account A is allowed to pull images.&lt;/p&gt;

&lt;p&gt;👉 We need to update the ECR repository permissions in Account B.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq7pks6n71c4h5ujim9h1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq7pks6n71c4h5ujim9h1.png" alt=" " width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Install Docker &amp;amp; AWS CLI on EC2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you haven't installed Docker:&lt;/p&gt;

&lt;p&gt;For Amazon Linux 3:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo yum update -y
sudo yum install -y docker
sudo service docker start
sudo usermod -aG docker ec2-user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 5: Authenticate Docker to the Account B ECR&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws ecr get-login-password --region us-east-1 \
| docker login --username AWS \
  --password-stdin &amp;lt;ACCOUNT_B_ID&amp;gt;.dkr.ecr.us-east-1.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 6: Pull the Image&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker pull &amp;lt;ACCOUNT_B_ID&amp;gt;.dkr.ecr.us-east-1.amazonaws.com/&amp;lt;REPO_NAME&amp;gt;:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Troubleshooting Checklist&lt;/strong&gt;&lt;br&gt;
❌ Error: no basic auth credentials&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;docker login not executed&lt;/li&gt;
&lt;li&gt;IAM role missing pull permissions &lt;/li&gt;
&lt;li&gt;ECR repo does not trust Account A&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;❌ Error: access denied&lt;/p&gt;

&lt;p&gt;ECR repo policy missing Account A IAM role&lt;/p&gt;

&lt;p&gt;❌ Error: repository not found&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;wrong region&lt;/li&gt;
&lt;li&gt;wrong repo name&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;❌ Error: docker not found&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;✔ Always use IAM Roles, never access keys&lt;br&gt;
✔ Always restrict pull access using ECR repository policy&lt;br&gt;
✔ Never use wildcard "&lt;em&gt;" for image pull actions&lt;br&gt;
✔ Use "&lt;/em&gt;" only for GetAuthorizationToken (required by AWS)&lt;br&gt;
✔ Consider using Lifecycle Policies for cleaning old images&lt;br&gt;
✔ Consider enabling ECR scan-on-push for security&lt;/p&gt;

</description>
      <category>iam</category>
      <category>crossaccount</category>
      <category>ecr</category>
      <category>aws</category>
    </item>
    <item>
      <title>Securely Connect GitHub Actions to AWS Using IAM Roles and OIDC</title>
      <dc:creator>Ravindra Singh</dc:creator>
      <pubDate>Fri, 25 Jul 2025 17:24:24 +0000</pubDate>
      <link>https://dev.to/aws-builders/securely-connect-github-actions-to-aws-using-iam-roles-and-oidc-4ek2</link>
      <guid>https://dev.to/aws-builders/securely-connect-github-actions-to-aws-using-iam-roles-and-oidc-4ek2</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Traditional CI/CD pipelines often rely on long-lived AWS access keys stored as GitHub secrets, which introduces risks such as secret exposure and poor traceability. With GitHub Actions' support for OpenID Connect (OIDC), you can authenticate securely to AWS without static credentials. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source Code link:&lt;/strong&gt; &lt;a href="https://github.com/ravindrasinghh/github-actions-s3-workshop/blob/master/.github/workflows/deploy-to-s3.yml" rel="noopener noreferrer"&gt;https://github.com/ravindrasinghh/github-actions-s3-workshop/blob/master/.github/workflows/deploy-to-s3.yml&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;we will walk through setting up an automated deployment pipeline that takes your static website from GitHub repository to live S3 hosting with just a git push.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl5o5043z3xxh6qv9phwn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl5o5043z3xxh6qv9phwn.png" alt=" " width="800" height="247"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with Traditional Approaches
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Security Challenges with Access Keys:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Long-lived credentials&lt;/strong&gt; stored in GitHub secrets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Risk of credential exposure&lt;/strong&gt; if secrets are compromised&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual rotation&lt;/strong&gt; required for security compliance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Broad permissions&lt;/strong&gt; often granted for simplicity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No audit trail&lt;/strong&gt; of which specific workflow used credentials&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The OIDC Solution:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No stored credentials&lt;/strong&gt; in GitHub&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Temporary tokens&lt;/strong&gt; with automatic expiration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fine-grained permissions&lt;/strong&gt; per repository/branch&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complete audit trail&lt;/strong&gt; of all AWS actions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Principle of least privilege&lt;/strong&gt; enforcement&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How OIDC Works with GitHub Actions and AWS
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Authentication Flow:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Actions&lt;/strong&gt; requests an OIDC token from GitHub's OIDC provider&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token contains claims&lt;/strong&gt; about the repository, branch, and workflow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS STS&lt;/strong&gt; validates the token against the configured trust policy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Temporary credentials&lt;/strong&gt; are issued for the specified IAM role&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Actions&lt;/strong&gt; uses these credentials to access AWS services&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step-by-Step Implementation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Create an OIDC Identity Provider in AWS
&lt;/h3&gt;

&lt;p&gt;1.Open the IAM console in your AWS account.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In the left-hand navigation, click Identity providers.&lt;/li&gt;
&lt;li&gt;Choose Add provider.&lt;/li&gt;
&lt;li&gt;For Provider type, select OpenID Connect.&lt;/li&gt;
&lt;li&gt;For Provider URL, enter:
&lt;a href="https://token.actions.githubusercontent.com" rel="noopener noreferrer"&gt;https://token.actions.githubusercontent.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;For Audience, enter: sts.amazonaws.com&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2snlin3sc84w5jk5oqlz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2snlin3sc84w5jk5oqlz.png" alt=" " width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Assign a Role
&lt;/h3&gt;

&lt;p&gt;Once the OIDC provider is created, click "Assign role" or "Create new role" to configure access.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe96bexc689c5qh5z0a2n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe96bexc689c5qh5z0a2n.png" alt=" " width="800" height="259"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click Next to proceed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Configure Web Identity Trust
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;On the Trusted entity type page, choose Web identity.&lt;/li&gt;
&lt;li&gt;For Identity provider, select the one you just created.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fill in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Organization/Username (e.g., ravindrasinghh)&lt;/li&gt;
&lt;li&gt;Repository name (e.g., github-actions-s3-workshop)&lt;/li&gt;
&lt;li&gt;Branch name (e.g., master)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuunvggdi5gni3sjmdveh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuunvggdi5gni3sjmdveh.png" alt=" " width="800" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click Next.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Attach Permissions to the Role
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Choose either a Managed policy or create a Custom policy.&lt;/li&gt;
&lt;li&gt;For demonstration purposes, can use AmazonS3FullAccess.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;⚠️ In production, use least privilege policies instead of full access.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjg8f155mapevurfuercr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjg8f155mapevurfuercr.png" alt=" " width="800" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click Next.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Name and Create the Role
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Provide a Role name (e.g., GitHubOIDCRole)&lt;/li&gt;
&lt;li&gt;Add an optional description for future reference.&lt;/li&gt;
&lt;li&gt;Review the trust policy and click Create Role.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz0svych57il4k4jhxoc2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz0svych57il4k4jhxoc2.png" alt=" " width="800" height="344"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::434605749312:oidc-provider/token.actions.githubusercontent.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
                },
                "StringLike": {
                    "token.actions.githubusercontent.com:sub": "repo:ravindrasinghh/github-actions-s3-workshop:ref:refs/heads/master"
                }
            }
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This policy ensures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only workflows from the ravindrasinghh/argocd repository on the master branch can assume the role.&lt;/li&gt;
&lt;li&gt;Only tokens with audience sts.amazonaws.com are accepted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Security Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;aud&lt;/code&gt; condition ensures tokens are intended for AWS STS&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sub&lt;/code&gt; condition restricts access to specific repository and branch&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;StringLike&lt;/code&gt; allows for flexible branch matching if needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 4: Update GitHub Actions Workflow for OIDC&lt;br&gt;
Update .github/workflows/deploy-to-s3.yml with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Deploy Static Website to S3

on:
  push:
    branches: [ main ]
  workflow_dispatch:  # Allows manual triggering

# OIDC permissions for keyless authentication
permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout repository
      uses: actions/checkout@v3

    # No build step needed for this simple static website
    # Just update the deployment timestamp in the JavaScript file
    - name: Update deployment timestamp
      run: |
        echo "// Updating timestamp for deployment on $(date)" &amp;gt;&amp;gt; js/script.js
        echo "// Deployment ID: ${{ github.run_id }}" &amp;gt;&amp;gt; js/script.js

    # # Configure AWS credentials
    # - name: Configure AWS credentials
    #   uses: aws-actions/configure-aws-credentials@v1
    #   with:
    #     aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
    #     aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    #     aws-region: "ap-south-1"

    # OIDC/IRSA Authentication - No more access keys!
    - name: Configure AWS credentials via OIDC
      uses: aws-actions/configure-aws-credentials@v4
      with:
        role-to-assume: "arn:aws:iam::434605749312:role/GitHubOIDCRole"
        role-session-name: GitHubActions-Backend-${{ github.run_id }}
        aws-region: "ap-south-1"

    # Deploy to S3 bucket - directly sync the repository contents
    - name: Deploy to S3
      run: |
        aws s3 sync ./ s3://${{ secrets.S3_BUCKET_NAME }}/ \
          --delete \
          --exclude ".git/*" \
          --exclude ".github/*" \
          --exclude "README.md" 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Troubleshooting Common Issues
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. "Incorrect token audience" Error
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause&lt;/strong&gt;: Trust policy audience mismatch&lt;br&gt;
&lt;strong&gt;Solution&lt;/strong&gt;: Ensure audience is exactly &lt;code&gt;sts.amazonaws.com&lt;/code&gt; (no trailing dots)&lt;/p&gt;

&lt;h3&gt;
  
  
  2. "No permission to assume role" Error
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause&lt;/strong&gt;: Trust policy subject condition too restrictive&lt;br&gt;
&lt;strong&gt;Solution&lt;/strong&gt;: Verify repository name and branch in trust policy&lt;/p&gt;

&lt;h3&gt;
  
  
  3. "OIDC provider not found" Error
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause&lt;/strong&gt;: OIDC provider not created or incorrect ARN&lt;br&gt;
&lt;strong&gt;Solution&lt;/strong&gt;: Verify OIDC provider exists and ARN is correct&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Workflow permissions Error
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause&lt;/strong&gt;: Missing OIDC permissions in workflow&lt;br&gt;
&lt;strong&gt;Solution&lt;/strong&gt;: Add &lt;code&gt;id-token: write&lt;/code&gt; and &lt;code&gt;contents: read&lt;/code&gt; permissions&lt;/p&gt;

&lt;p&gt;By using OIDC with IAM roles, you enhance the security posture of your GitHub Actions workflows. This is the modern, recommended way to connect GitHub to AWS — eliminating the risks of leaked secrets and manual credential management.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>githubactions</category>
      <category>iam</category>
    </item>
    <item>
      <title>Automating Static Website Deployment with GitHub Actions and AWS S3</title>
      <dc:creator>Ravindra Singh</dc:creator>
      <pubDate>Wed, 23 Jul 2025 05:42:18 +0000</pubDate>
      <link>https://dev.to/aws-builders/automating-static-website-deployment-with-github-actions-and-aws-s3-12ad</link>
      <guid>https://dev.to/aws-builders/automating-static-website-deployment-with-github-actions-and-aws-s3-12ad</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In today's fast-paced development environment, automating your deployment process is no longer a luxury—it's a necessity. Continuous Integration and Continuous Deployment (CI/CD) has become the industry standard for delivering software efficiently and reliably. In this blog post, I'll walk you through setting up a complete CI/CD pipeline using GitHub Actions to automatically deploy a static website to Amazon S3.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flncujjr7wo99tiv9zjkw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flncujjr7wo99tiv9zjkw.png" alt=" " width="800" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why CI/CD Matters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before diving into the technical details, let's understand why CI/CD is so important:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Faster Delivery&lt;/strong&gt;: Automate repetitive tasks to release features more quickly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Higher Quality&lt;/strong&gt;: Catch bugs early through automated testing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduced Risk&lt;/strong&gt;: Small, incremental changes are easier to troubleshoot&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency&lt;/strong&gt;: Every deployment follows the same process&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer Focus&lt;/strong&gt;: Less time on operations means more time for coding&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For static websites specifically, a CI/CD pipeline ensures that every change you push to your repository is automatically tested and deployed, eliminating manual FTP uploads or console interactions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Architecture&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Our CI/CD pipeline follows this simple flow:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Developer pushes code to GitHub repository&lt;/li&gt;
&lt;li&gt;GitHub Actions detects the change and triggers a workflow&lt;/li&gt;
&lt;li&gt;The workflow builds and tests the website&lt;/li&gt;
&lt;li&gt;If successful, the workflow deploys the site to AWS S3&lt;/li&gt;
&lt;li&gt;The website is immediately available to visitors&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;This architecture provides several benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: S3 can handle virtually unlimited traffic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost-Effective&lt;/strong&gt;: Pay only for what you use&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliable&lt;/strong&gt;: AWS's infrastructure ensures high availability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure&lt;/strong&gt;: Access controls and encryption protect your content&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Source Git Link:&lt;/strong&gt; &lt;a href="https://github.com/ravindrasinghh/github-actions-s3-workshop/tree/master" rel="noopener noreferrer"&gt;https://github.com/ravindrasinghh/github-actions-s3-workshop/tree/master&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To follow along with this tutorial, you'll need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A GitHub account&lt;/li&gt;
&lt;li&gt;An AWS account&lt;/li&gt;
&lt;li&gt;Basic understanding of HTML, CSS, and JavaScript&lt;/li&gt;
&lt;li&gt;Familiarity with Git commands&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Setting Up Your S3 Bucket&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, we need to create an S3 bucket configured for static website hosting:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log in to the AWS Management Console and navigate to S3&lt;/li&gt;
&lt;li&gt;Click "Create bucket"&lt;/li&gt;
&lt;li&gt;Enter a globally unique name for your bucket&lt;/li&gt;
&lt;li&gt;Choose your preferred region&lt;/li&gt;
&lt;li&gt;Uncheck "Block all public access" (since this is a public website)&lt;/li&gt;
&lt;li&gt;Enable "Static website hosting" under the Properties tab&lt;/li&gt;
&lt;li&gt;Set "index.html" as both the index and error document&lt;/li&gt;
&lt;li&gt;Add a bucket policy to allow public read access:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PublicReadGetObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"s3:GetObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::your-bucket-name/*"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Creating IAM Credentials&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For GitHub Actions to access your S3 bucket, you'll need IAM credentials:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to IAM in the AWS Console&lt;/li&gt;
&lt;li&gt;Create a new policy with the following permissions:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:PutObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:GetObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:ListBucket"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:DeleteObject"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::your-bucket-name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::your-bucket-name/*"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create a new IAM user with programmatic access&lt;/li&gt;
&lt;li&gt;Attach the policy you just created&lt;/li&gt;
&lt;li&gt;Save the Access Key ID and Secret Access Key securely&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Setting Up Your GitHub Repository&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a new repository or use an existing one&lt;/li&gt;
&lt;li&gt;Add your static website files to the repository&lt;/li&gt;
&lt;li&gt;Navigate to Settings &amp;gt; Secrets and variables &amp;gt; Actions&lt;/li&gt;
&lt;li&gt;Add the following secrets:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt;: Your IAM user's access key&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt;: Your IAM user's secret key&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;S3_BUCKET_NAME&lt;/code&gt;: Your S3 bucket name&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Creating the GitHub Actions Workflow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The heart of our CI/CD pipeline is the GitHub Actions workflow file. Create a new file at &lt;code&gt;.github/workflows/deploy-to-s3.yml&lt;/code&gt; with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy Static Website to S3&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;main&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# Allows manual triggering&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout repository&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;

    &lt;span class="c1"&gt;# No build step needed for this simple static website&lt;/span&gt;
    &lt;span class="c1"&gt;# Just update the deployment timestamp in the JavaScript file&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Update deployment timestamp&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;echo "// Updating timestamp for deployment on $(date)" &amp;gt;&amp;gt; js/script.js&lt;/span&gt;
        &lt;span class="s"&gt;echo "// Deployment ID: ${{ github.run_id }}" &amp;gt;&amp;gt; js/script.js&lt;/span&gt;

    &lt;span class="c1"&gt;# Configure AWS credentials&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Configure AWS credentials&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/configure-aws-credentials@v1&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;aws-access-key-id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AWS_ACCESS_KEY_ID }}&lt;/span&gt;
        &lt;span class="na"&gt;aws-secret-access-key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AWS_SECRET_ACCESS_KEY }}&lt;/span&gt;
        &lt;span class="na"&gt;aws-region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ap-south-1"&lt;/span&gt;

    &lt;span class="c1"&gt;# Deploy to S3 bucket - directly sync the repository contents&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to S3&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;aws s3 sync ./ s3://${{ secrets.S3_BUCKET_NAME }}/ \&lt;/span&gt;
          &lt;span class="s"&gt;--delete \&lt;/span&gt;
          &lt;span class="s"&gt;--exclude ".git/*" \&lt;/span&gt;
          &lt;span class="s"&gt;--exclude ".github/*" \&lt;/span&gt;
          &lt;span class="s"&gt;--exclude "README.md" &lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Let's break down what this workflow does:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Triggers&lt;/strong&gt;: The workflow runs whenever code is pushed to the main branch or when manually triggered&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Checkout&lt;/strong&gt;: Fetches the latest code from your repository&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timestamp&lt;/strong&gt;: Adds a deployment timestamp to your JavaScript file&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Credentials&lt;/strong&gt;: Configures AWS credentials using your GitHub secrets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment&lt;/strong&gt;: Syncs your website files to the S3 bucket, excluding unnecessary files&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confirmation&lt;/strong&gt;: Outputs the URL where your website can be accessed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Testing the Pipeline&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now it's time to see your CI/CD pipeline in action:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Commit and push your changes to the main branch&lt;/li&gt;
&lt;li&gt;Go to the "Actions" tab in your GitHub repository&lt;/li&gt;
&lt;li&gt;Watch as your workflow runs automatically&lt;/li&gt;
&lt;li&gt;Once completed, click on the workflow run to see the details&lt;/li&gt;
&lt;li&gt;Visit your website URL to confirm the deployment was successful&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Understanding the Workflow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's dive deeper into some key aspects of our GitHub Actions workflow:&lt;/p&gt;

&lt;h3&gt;
  
  
  The Trigger
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;main&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This section defines when the workflow should run. In our case, it runs on pushes to the main branch and can also be triggered manually using the "workflow_dispatch" event.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS Credentials&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Configure AWS credentials&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/configure-aws-credentials@v1&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;aws-access-key-id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AWS_ACCESS_KEY_ID }}&lt;/span&gt;
    &lt;span class="na"&gt;aws-secret-access-key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AWS_SECRET_ACCESS_KEY }}&lt;/span&gt;
    &lt;span class="na"&gt;aws-region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;us-east-1'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This step uses the official AWS GitHub Action to configure credentials. The credentials are stored securely as GitHub secrets and are never exposed in logs.&lt;/p&gt;

&lt;h3&gt;
  
  
  S3 Sync
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to S3&lt;/span&gt;
  &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
    &lt;span class="s"&gt;aws s3 sync ./ s3://${{ secrets.S3_BUCKET_NAME }}/ \&lt;/span&gt;
      &lt;span class="s"&gt;--delete \&lt;/span&gt;
      &lt;span class="s"&gt;--exclude ".git/*" \&lt;/span&gt;
      &lt;span class="s"&gt;--exclude ".github/*" \&lt;/span&gt;
      &lt;span class="s"&gt;--exclude "README.md" \&lt;/span&gt;
      &lt;span class="s"&gt;--exclude "*.md" \&lt;/span&gt;
      &lt;span class="s"&gt;--exclude ".vscode/*"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;aws s3 sync&lt;/code&gt; command efficiently uploads only the files that have changed. The &lt;code&gt;--delete&lt;/code&gt; flag removes files from the bucket that don't exist in your repository, ensuring your website is always in sync with your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Issues and Troubleshooting
&lt;/h2&gt;

&lt;p&gt;Here are some common issues you might encounter and how to fix them:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Access Denied Errors&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you see "Access Denied" errors in your workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Double-check your IAM permissions&lt;/li&gt;
&lt;li&gt;Verify that your bucket policy allows the necessary actions&lt;/li&gt;
&lt;li&gt;Ensure your GitHub secrets are correctly set&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Files Not Updating&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your website isn't reflecting the latest changes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check that you're pushing to the correct branch&lt;/li&gt;
&lt;li&gt;Look for errors in the GitHub Actions logs&lt;/li&gt;
&lt;li&gt;Try clearing your browser cache&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Workflow Not Triggering&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your workflow isn't running:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify that the workflow file is in the correct location (&lt;code&gt;.github/workflows/&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Check that the trigger conditions match your push event&lt;/li&gt;
&lt;li&gt;Ensure the workflow file has valid YAML syntax&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Setting up a CI/CD pipeline with GitHub Actions and AWS S3 is a powerful way to streamline your website deployment process. By automating these tasks, you can focus on what matters most—building great websites.&lt;/p&gt;

&lt;p&gt;I hope this guide helps you implement your own automated deployment pipeline. Happy coding!&lt;/p&gt;

</description>
      <category>githubactions</category>
      <category>s3</category>
      <category>aws</category>
      <category>automaton</category>
    </item>
    <item>
      <title>Automated Kubernetes Governance with Kyverno and Slack Alerts</title>
      <dc:creator>Ravindra Singh</dc:creator>
      <pubDate>Sun, 13 Jul 2025 17:19:41 +0000</pubDate>
      <link>https://dev.to/aws-builders/automated-kubernetes-governance-with-kyverno-and-slack-alerts-a6e</link>
      <guid>https://dev.to/aws-builders/automated-kubernetes-governance-with-kyverno-and-slack-alerts-a6e</guid>
      <description>&lt;p&gt;✨ &lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As &lt;strong&gt;Kubernetes adoption&lt;/strong&gt; increases in production environments, enforcing security, compliance, and operational consistency becomes crucial. Developers move fast, but clusters need guardrails. This is where &lt;strong&gt;Kyverno&lt;/strong&gt; and &lt;strong&gt;Policy Reporter&lt;/strong&gt; come in.&lt;/p&gt;

&lt;p&gt;🏗️ &lt;strong&gt;Kyverno Architecture (Explained Simply)&lt;/strong&gt;&lt;br&gt;
Kyverno works as an Admission Controller inside your Kubernetes cluster.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj7eamf23v1kb21rprfgc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj7eamf23v1kb21rprfgc.png" alt=" " width="800" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whenever you run a command like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f deployment.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Kubernetes API server first checks:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Is the YAML valid?&lt;/strong&gt;&lt;br&gt;
✅ &lt;strong&gt;Is the user authorized?&lt;/strong&gt;&lt;br&gt;
✅ &lt;strong&gt;Are there any policies that should be applied?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is where Kyverno steps in.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🔁 &lt;strong&gt;How it Works (Step-by-Step):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The API server sends the resource to Kyverno via an admission webhook.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Kyverno checks if any policy applies to that resource It checks the resource against all policies stored in its Policy Cache.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Depending on the policy type, Kyverno can:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;1. Validate → Block if not compliant&lt;br&gt;
    2. Mutate → Auto-correct the YAML (e.g., add a label)&lt;br&gt;
    3. Generate → Create supporting resources (like NetworkPolicy)&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Kyverno sends a response back to the API server (allow or deny).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Kyverno also creates a Policy Report and can send an alert via Slack if integrated with Policy Reporter.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;In this blog, we will deploy following resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deploy Kyverno and Policy Reporter&lt;/li&gt;
&lt;li&gt;Write a real policy to protect critical resources&lt;/li&gt;
&lt;li&gt;Trigger a violation and send a Slack alert&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📌 &lt;strong&gt;Why Kyverno?&lt;/strong&gt;&lt;br&gt;
Kyverno is a Kubernetes-native policy engine, which means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No need to learn a new DSL — policies are written in YAML&lt;/li&gt;
&lt;li&gt;Designed for DevOps and platform engineers, not security specialists only&lt;/li&gt;
&lt;li&gt;Supports validation (deny non-compliant resources), mutation (auto-fix), generation (auto-create resources), and cleanup (delete resources)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🚨 &lt;strong&gt;Why Do You Need Kyverno in Your Kubernetes Cluster?&lt;/strong&gt;&lt;br&gt;
As organizations scale their Kubernetes usage, maintaining consistency, security, and compliance across teams and environments becomes a serious challenge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source Git Link&lt;/strong&gt;: [&lt;a href="https://github.com/ravindrasinghh/Kubernetes-Playlist/tree/master/Lesson6" rel="noopener noreferrer"&gt;https://github.com/ravindrasinghh/Kubernetes-Playlist/tree/master/Lesson6&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;🚀 &lt;strong&gt;Step 1: Install Kyverno with Helm&lt;/strong&gt;&lt;br&gt;
Install Kyverno’s admission controllers into your Kubernetes cluster:&lt;br&gt;
&lt;strong&gt;Install it using Helm:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update
helm install kyverno kyverno/kyverno --create-namespace -n kyverno -f kyverno-values.yaml  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz32sonuglx9xceklctvn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz32sonuglx9xceklctvn.png" alt=" " width="800" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📊 &lt;strong&gt;Step 2: Install Policy Reporter with Slack Integration&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Install it using Helm:&lt;/strong&gt;&lt;br&gt;
Install the Policy Reporter UI to visualize Kyverno policies and send alerts to Slack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;helm repo add policy-reporter https://kyverno.github.io/policy-reporter
helm repo update
helm install policy-reporter policy-reporter/policy-reporter --create-namespace -n policy-reporter -f kyverno-ui.yaml 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqgmood52un9i545pozc9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqgmood52un9i545pozc9.png" alt=" " width="800" height="105"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🔧  &lt;strong&gt;Step 3: Install Pre-defned kyverno-policies&lt;/strong&gt;&lt;br&gt;
Install a set of baseline and restricted policies provided by Kyverno:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install it using Helm:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update
helm install kyverno-policies --create-namespace -n kyverno kyverno/kyverno-policies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more details on the predefined policy sets, visit:&lt;br&gt;
&lt;a href="https://github.com/kyverno/kyverno/tree/main/charts/kyverno-policies#kyverno-policies" rel="noopener noreferrer"&gt;https://github.com/kyverno/kyverno/tree/main/charts/kyverno-policies#kyverno-policies&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✨ &lt;strong&gt;Examples of Kyverno in Action&lt;/strong&gt;&lt;br&gt;
✅ &lt;strong&gt;1. Validate Policy — Block containers running as root&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: validate-run-as-non-root
spec:
  validationFailureAction: Enforce
  rules:
    - name: block-root-containers
      match:
        resources:
          kinds:
            - Pod
      validate:
        message: "Running as root is not allowed."
        pattern:
          spec:
            containers:
              - securityContext:
                  runAsNonRoot: true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧠 Use Case: Prevents insecure containers from being deployed.&lt;/p&gt;

&lt;p&gt;✏️ &lt;strong&gt;2. Mutate Policy — Automatically add a label to all Pods&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: add-default-label
spec:
  rules:
    - name: inject-env-label
      match:
        resources:
          kinds:
            - Pod
      mutate:
        patchStrategicMerge:
          metadata:
            labels:
              env: default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧠 Use Case: Ensures every Pod has a required label (e.g., for monitoring, billing, or cost allocation).&lt;/p&gt;

&lt;p&gt;⚙️ &lt;strong&gt;3. Generate Policy — Auto-create a NetworkPolicy in New Namespaces&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: generate-default-network-policy
spec:
  rules:
    - name: auto-create-network-policy
      match:
        resources:
          kinds:
            - Namespace
      generate:
        kind: NetworkPolicy
        apiVersion: networking.k8s.io/v1
        name: default-deny
        namespace: "{{request.object.metadata.name}}"
        data:
          spec:
            podSelector: {}
            policyTypes:
              - Ingress
              - Egress
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧠 Use Case: Ensure every new namespace starts with a default NetworkPolicy to deny all traffic unless explicitly allowed.&lt;/p&gt;

&lt;p&gt;🔐 &lt;strong&gt;4. Preventing Accidental Deletion of Critical Resources (Validate Policy)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: prevent-critical-resource-deletion
spec:
  validationFailureAction: Enforce
  rules:
    - name: block-delete-critical-resources
      match:
        resources:
          kinds:
            - ConfigMap
            - Secret
            - Deployment
            - Service
            - Ingress
            - PersistentVolumeClaim
          namespaces:
            - production
      preconditions:
        all:
          - key: "{{request.operation}}"
            operator: Equals
            value: DELETE
      validate:
        message: "⛔️ Deletion of critical resources is not allowed in production namespace."
        deny: {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🚀 &lt;strong&gt;Let’s Start Implementing These Policies in Our Cluster&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now that we’ve seen practical examples of how Kyverno can validate, mutate, and generate Kubernetes resources, it’s time to apply them in our own environment.&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Step 1: Apply the Policies One by One&lt;/strong&gt;&lt;br&gt;
Use kubectl apply or GitOps practices (e.g., ArgoCD, Flux) to safely introduce each policy into your cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f validate-run-as-non-root.yaml
kubectl apply -f add-default-label.yaml
kubectl apply -f generate-default-network-policy.yaml
kubectl apply -f prevent-critical-resource-deletion.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;💡 Tip: Apply them in a dev/staging cluster first and set validationFailureAction: Audit to test without enforcement.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyan5juyl0zytrbc18afe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyan5juyl0zytrbc18afe.png" alt=" " width="800" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's use kyverno CLI and see , how many current pods or other rsources are passing or failing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get policyreports -A

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7l8op9lt95afn7clhz04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7l8op9lt95afn7clhz04.png" alt=" " width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;-Now let’s test each Kyverno policy to see how it behaves in real-world scenarios.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.validate-run-as-non-root&lt;/strong&gt;**&lt;br&gt;
&lt;code&gt;kubectl apply -f pod-root.yaml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Pod
metadata:
  name: root-pod
spec:
  containers:
    - name: nginx
      image: nginx
      # No securityContext, so will run as root by default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📛 As expected, Kyverno blocks this Pod because it violates the policy that enforces runAsNonRoot: true.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frq2gkh34t4nzovi95awt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frq2gkh34t4nzovi95awt.png" alt=" " width="800" height="128"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.pod-no-label.yaml&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;kubectl apply -f pod-no-label.yaml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Pod
metadata:
  name: test-pod-no-label
spec:
  containers:
    - name: nginx
      image: nginx:latest
      securityContext:
        runAsNonRoot: true  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔄 Thanks to the mutate policy, Kyverno automatically injects the label env: default.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fih8a9kt2mtbb12hp3t3o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fih8a9kt2mtbb12hp3t3o.png" alt=" " width="800" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Auto-create a NetworkPolicy in New Namespaces&lt;/strong&gt;&lt;br&gt;
📦 Kyverno detects the new namespace and creates a default NetworkPolicy in it automatically.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl create namespace test-np&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwdv9rykpfmv1j571mi2q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwdv9rykpfmv1j571mi2q.png" alt=" " width="800" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Preventing Accidental Deletion of Critical Resources&lt;/strong&gt;&lt;br&gt;
Here comes an important one! Let’s try deleting a critical resource (like a Deployment or Service) in the production namespace:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmapo9rslhic8a27i0kzv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmapo9rslhic8a27i0kzv.png" alt=" " width="800" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🔍 &lt;strong&gt;Step 2: Monitor Policy Behavior, View Policy Reports and Slack Alerts&lt;/strong&gt;&lt;br&gt;
Once your Kyverno policies are active, it's important to monitor how they behave and ensure violations don’t go unnoticed. Here's how to track everything using Policy Reporter UI and Slack integration.&lt;/p&gt;

&lt;p&gt;📊 &lt;strong&gt;1. Access the Policy Reporter Dashboard&lt;/strong&gt;&lt;br&gt;
Policy Reporter provides a user-friendly dashboard to visualize all Kyverno policy results.&lt;/p&gt;

&lt;p&gt;📌 To access it via port-forwarding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl port-forward service/policy-reporter-ui 8080:8080 -n policy-reporter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzmvc0rulg1ehd2jdwk4d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzmvc0rulg1ehd2jdwk4d.png" alt=" " width="800" height="246"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🔍 &lt;strong&gt;2. Investigate Non-Compliant Workloads&lt;/strong&gt;&lt;br&gt;
One of the key benefits of &lt;strong&gt;using Kyverno with Policy Reporter&lt;/strong&gt; is the ability to &lt;strong&gt;detect and respond to policy violations in real time.&lt;/strong&gt; Whether it's missing labels, insecure configurations, or critical resource changes—Kyverno helps you enforce best practices, while Policy Reporter ensures you're notified when something goes wrong.&lt;/p&gt;

&lt;p&gt;In this section, let’s create a simple policy that &lt;strong&gt;requires every Pod to have an app label&lt;/strong&gt;, and then test what happens when this rule is violated.&lt;/p&gt;

&lt;p&gt;🛡️ &lt;strong&gt;Example: Require a Label on All Pods&lt;/strong&gt;&lt;br&gt;
Let’s create a ClusterPolicy that audits Pod missing the app label.**&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-label
spec:
  rules:
    - name: check-label
      match:
        resources:
          kinds:
            - Pod
      validate:
        failureAction: Audit
        message: "Labels 'app' is required on every Pod."
        pattern:
          metadata:
            labels:
              app: "?*"

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

&lt;/div&gt;



&lt;p&gt;🔧 &lt;strong&gt;Apply the policy using:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl apply -f require-label.yaml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;🚨 &lt;strong&gt;Trigger a Violation to Test the Policy and Alerts&lt;/strong&gt;&lt;br&gt;
Now, let’s create a Pod that intentionally violates the policy by omitting the app label:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat &amp;lt;&amp;lt;EOF | kubectl apply -n test -f -
apiVersion: v1
kind: Pod
metadata:
  name: violate-pod
spec:
  containers:
    - name: nginx
      image: nginx:latest
EOF
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp51zr7890kkuzkpewnsi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp51zr7890kkuzkpewnsi.png" alt=" " width="800" height="542"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📣 Make sure this policy name is included in your Slack channel filter in values.yaml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;policies:
  include: ["prevent-critical-resource-deletion", "require-label"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔐 Policy applied → Violation triggered → PolicyReport generated → Slack alert sent&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Success! The Pod was created without the required app label, Kyverno generated a PolicyReport, and the Slack alert was triggered as expected.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpqb0cq7krg8pk0oh37mr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpqb0cq7krg8pk0oh37mr.png" alt=" " width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Want to generate a report right now?&lt;/strong&gt;&lt;br&gt;
Click the button and generate a Policy Report and view detailed results—all in a single page, broken down by namespace, policy name, and resource.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6g7fc1q5ku5ge87wwh7m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6g7fc1q5ku5ge87wwh7m.png" alt=" " width="800" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxk4c6v3gov4ee7uz55ic.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxk4c6v3gov4ee7uz55ic.png" alt=" " width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💬 &lt;strong&gt;Thanks for reading!&lt;/strong&gt;&lt;br&gt;
If you found this helpful or face any issues while setting it up, feel free to reach out. I’d be happy to help!&lt;/p&gt;

&lt;p&gt;👉 Drop a comment, connect on LinkedIn, or open an issue on GitHub if you’re using the same setup.&lt;/p&gt;

</description>
      <category>eks</category>
      <category>kyverno</category>
      <category>security</category>
      <category>governance</category>
    </item>
    <item>
      <title>Building a Tetris Game with Python and Pygame</title>
      <dc:creator>Ravindra Singh</dc:creator>
      <pubDate>Sun, 01 Jun 2025 10:50:35 +0000</pubDate>
      <link>https://dev.to/aws-builders/building-a-tetris-game-with-python-and-pygame-40pf</link>
      <guid>https://dev.to/aws-builders/building-a-tetris-game-with-python-and-pygame-40pf</guid>
      <description>&lt;p&gt;Tetris, the timeless puzzle game, has captivated players for decades with its simple yet challenging gameplay. Inspired by this classic, I embarked on a journey to recreate Tetris using Python and Pygame, enhancing it with modern features and visuals.&lt;/p&gt;

&lt;p&gt;🎮 &lt;strong&gt;Project Overview&lt;/strong&gt;&lt;br&gt;
This project is a modern implementation of Tetris, developed in Python using the Pygame library. It offers:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3D-style block rendering:&lt;/strong&gt; Blocks are displayed with light and shadow effects, giving a pseudo-3D appearance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ghost piece preview:&lt;/strong&gt; A translucent piece shows where the current block will land, aiding strategic placement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Smooth animations:&lt;/strong&gt; Line clearing and piece movements are animated for a polished experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Score tracking and level progression:&lt;/strong&gt; Players earn points and advance through levels as they clear lines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User-friendly interface:&lt;/strong&gt; Includes start, pause, and game over screens with clear instructions.&lt;/p&gt;

&lt;p&gt;You can explore the project on GitHub: &lt;a href="https://github.com/ravindrasinghh/tetris-game-amazonq" rel="noopener noreferrer"&gt;https://github.com/ravindrasinghh/tetris-game-amazonq&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🛠️ &lt;strong&gt;Key Features&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Classic Gameplay with Modern Enhancements&lt;/strong&gt;&lt;br&gt;
While preserving the core mechanics of Tetris, this version introduces visual and functional improvements:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next piece preview:&lt;/strong&gt; Displays the upcoming block, allowing players to plan ahead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Responsive controls:&lt;/strong&gt; Smooth and intuitive controls for seamless gameplay.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Intuitive Controls&lt;/strong&gt;&lt;br&gt;
The game utilizes keyboard inputs for control:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;**S:** Start the game

**Left Arrow:** Move piece left

**Right Arrow: **Move piece right

**Down Arrow:** Soft drop (move piece down faster)

**Up Arrow:** Rotate piece

**Spacebar:** Hard drop (instantly drop piece to the bottom)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Game features:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3D-style blocks:&lt;/strong&gt; Blocks are rendered with shading to create a 3D effect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ghost pieces:&lt;/strong&gt; A semi-transparent piece indicates where the current block will land.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Animated transitions:&lt;/strong&gt; Smooth animations for line clears and piece movements enhance the visual appeal.&lt;/p&gt;

&lt;p&gt;🚀 &lt;strong&gt;Getting Started&lt;/strong&gt;&lt;br&gt;
To run the game locally:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clone the repository:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/ravindrasinghh/tetris-game-amazonq.git
cd tetris-game-amazonq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Install dependencies:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ensure you have Python installed. Then, install Pygame:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install pygame
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Run the game:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python tetris.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw1uml7pr8mfcm6z7s153.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw1uml7pr8mfcm6z7s153.png" alt="Image description" width="800" height="1012"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enjoy the game and challenge yourself to achieve high scores!&lt;/p&gt;

&lt;p&gt;📚 &lt;strong&gt;Learnings and Takeaways&lt;/strong&gt;&lt;br&gt;
Developing this Tetris game provided insights into:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Game development fundamentals:&lt;/strong&gt; Understanding game loops, event handling, and rendering.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User interface design:&lt;/strong&gt; Creating intuitive and visually appealing interfaces.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Python and Pygame proficiency&lt;/strong&gt;: Enhancing skills in Python programming and using the Pygame library.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Explore the Project&lt;/strong&gt;&lt;br&gt;
Feel free to explore, fork, and contribute to the project on GitHub: ravindrasinghh/tetris-game-amazonq.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy coding and gaming!&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Install .NET SDK and Runtime on Ubuntu 24.04.2 LTS</title>
      <dc:creator>Ravindra Singh</dc:creator>
      <pubDate>Wed, 23 Apr 2025 08:37:12 +0000</pubDate>
      <link>https://dev.to/aws-builders/install-net-sdk-and-runtime-on-ubuntu-24042-lts-p7p</link>
      <guid>https://dev.to/aws-builders/install-net-sdk-and-runtime-on-ubuntu-24042-lts-p7p</guid>
      <description>&lt;p&gt;If you’re a developer working on a &lt;strong&gt;.NET application **or planning to host one on Ubuntu, you’ll need to install the&lt;/strong&gt; .NET SDK** and &lt;strong&gt;ASP.NET Core Runtime&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This guide is specially written for Ubuntu 24.04.2 LTS users — with every step explained in plain language so even beginners can follow easily.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Why Do We Need to Install This?&lt;/strong&gt;&lt;br&gt;
.NET SDK is needed if you want to build or develop .NET applications.&lt;br&gt;
ASP.NET Core Runtime is required if you only want to run web applications built with ASP.NET Core (for example, hosting on a Linux VM).&lt;/p&gt;

&lt;p&gt;🖥️ &lt;strong&gt;OS Requirement&lt;/strong&gt;&lt;br&gt;
This guide is tested on:&lt;br&gt;
OS: Ubuntu 24.04.2 LTS&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To check your OS version:&lt;/strong&gt;&lt;br&gt;
$ lsb_release -a&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq096j1xjp1rwcbphgira.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq096j1xjp1rwcbphgira.png" alt="Image description" width="534" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🧩 &lt;strong&gt;Step 1: Update Your Package List&lt;/strong&gt;&lt;br&gt;
Before installing anything, always update your system’s package list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Why?&lt;br&gt;
This command makes sure Ubuntu is aware of the latest available software versions. Think of it as refreshing the app store before installing something new.&lt;/p&gt;

&lt;p&gt;📦 &lt;strong&gt;Step 2: Install the .NET SDK 8.0&lt;/strong&gt;&lt;br&gt;
Run this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install -y dotnet-sdk-8.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Why?&lt;br&gt;
This installs the .NET Software Development Kit (SDK), which includes everything you need to build and run .NET 8 apps from the command line.&lt;/p&gt;

&lt;p&gt;The -y flag auto-confirms the installation to save time.&lt;/p&gt;

&lt;p&gt;🌐 &lt;strong&gt;Step 3: Install ASP.NET Core Runtime 8.0&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install -y aspnetcore-runtime-8.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Why?&lt;br&gt;
This installs only the runtime environment for ASP.NET Core web applications. Useful if you’re hosting a web app, not developing it.&lt;/p&gt;

&lt;p&gt;You can install both SDK and Runtime — no issues. The SDK includes a runtime too, but adding aspnetcore-runtime ensures full compatibility for web apps.&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Step 4: Verify the Installation&lt;/strong&gt;&lt;br&gt;
Let’s make sure everything is installed correctly.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check the installed .NET version:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet --version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This shows the version of the SDK currently active.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check where the dotnet CLI is installed:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;which dotnet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This confirms the dotnet command is available in your system's PATH.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;List all installed .NET-related packages:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dpkg -l | grep dotnet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This shows all installed .NET packages using Ubuntu’s package system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz9mh3y4czcvu8plj96gz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz9mh3y4czcvu8plj96gz.png" alt="Image description" width="800" height="164"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🎉 &lt;strong&gt;You’re Ready to Build!&lt;/strong&gt;&lt;br&gt;
You now have the full setup ready to build and run .NET 8.0 and ASP.NET Core apps on Ubuntu 24.04.2 LTS.&lt;/p&gt;

&lt;p&gt;You can now create your first app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
dotnet new console -o HelloApp
cd HelloApp
dotnet run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb6qq2muwndfbchgyick2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb6qq2muwndfbchgyick2.png" alt="Image description" width="800" height="620"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💬 Questions?&lt;br&gt;
If you run into any issues or have questions, feel free to reach out in the comments. Happy coding! 🚀&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Install and Use Amazon Q AI Assistant on Mac</title>
      <dc:creator>Ravindra Singh</dc:creator>
      <pubDate>Wed, 02 Apr 2025 09:23:41 +0000</pubDate>
      <link>https://dev.to/aws-builders/install-and-use-amazon-q-ai-assistant-on-mac-p7k</link>
      <guid>https://dev.to/aws-builders/install-and-use-amazon-q-ai-assistant-on-mac-p7k</guid>
      <description>&lt;p&gt;&lt;strong&gt;Amazon Q&lt;/strong&gt; is a generative AI-powered assistant by AWS designed to help developers boost productivity. It can answer questions, write and review code, debug issues, and even generate documentation.&lt;/p&gt;

&lt;p&gt;Developers should care because it integrates directly into your IDE, understands your codebase, and provides real-time assistance—saving hours of manual effort.&lt;/p&gt;

&lt;p&gt;This blog is a quick guide on how to install and use Amazon Q Developer on macOS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;macOS system&lt;/li&gt;
&lt;li&gt;AWS account with Builder ID or IAM identity&lt;/li&gt;
&lt;li&gt;Internet connection 😄&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Installing Amazon Q on macOS
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Go to the official download page:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line-installing.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line-installing.html&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Download the Mac installer (typically a .dmg file):&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click the download link for macOS under the Amazon Q Developer section.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open the .dmg file once downloaded.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Drag the Amazon Q app into your Applications folder.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fevdsgzs4tbe68goy6ts5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fevdsgzs4tbe68goy6ts5.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable shell integrations  with Amazon Q&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgx84t05w2tcbzpkgiiz4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgx84t05w2tcbzpkgiiz4.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Grant accessibility permissions so Amazon Q can interact with windows and perform actions &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcuyadl3kbe9u6dx3w3f0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcuyadl3kbe9u6dx3w3f0.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After clicking 'Enable', you'll be prompted to activate Amazon Q.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsxva0qqe0uczpkf2ggkm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsxva0qqe0uczpkf2ggkm.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open the app and follow the sign-in process using your AWS Builder ID or IAM identity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ohomywgmq1dp6tk5typ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ohomywgmq1dp6tk5typ.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on 'Allow Access' to grant Amazon Q command line access.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Focal754hivwzq3oiiats.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Focal754hivwzq3oiiats.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After successful installation, you'll be greeted with the Getting Started page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffqmr0u1zzdhcugtw2oq3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffqmr0u1zzdhcugtw2oq3.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now that Amazon Q is installed, let’s make sure everything’s working.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1z8j46rort1b06gqx0xk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1z8j46rort1b06gqx0xk.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To disable Amazon Q from the command line, run the following command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; q inline disable 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;🛠️ Troubleshooting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; Terminal not detecting q command&lt;br&gt;
&lt;strong&gt;Fix:&lt;/strong&gt; Restart your terminal or manually source the shell config file.&lt;br&gt;
&lt;strong&gt;Issue:&lt;/strong&gt; Accessibility permissions not showing&lt;br&gt;
&lt;strong&gt;Fix:&lt;/strong&gt; Go to System Settings → Privacy &amp;amp; Security → Accessibility and manually enable it.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Tip:&lt;/strong&gt; If you’re a developer, also try the Amazon Q extension in your IDE:&lt;br&gt;
&lt;strong&gt;For VS Code:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open Visual Studio Code.&lt;/li&gt;
&lt;li&gt;Go to Extensions.&lt;/li&gt;
&lt;li&gt;Search for Amazon Q.&lt;/li&gt;
&lt;li&gt;Click Install.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftu9pib2wq1quwqjc33gg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftu9pib2wq1quwqjc33gg.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Supercharge Your Development with Amazon Q Developer
&lt;/h1&gt;

&lt;p&gt;🚀 &lt;strong&gt;Now it’s your turn!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Try it out in your favorite IDE or via the desktop app—and let Amazon Q help you build faster and smarter.&lt;/p&gt;

&lt;p&gt;Prefer video tutorials? Check out my step-by-step walkthrough on how to build a Node.js app using Amazon Q CLI!&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/HNb4Ykdufuw"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;If you found this guide helpful, feel free to share it with your developer community or drop your feedback in the comments!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>amazon</category>
    </item>
    <item>
      <title>ECS FinHacks: Scaling Microservices with AWS ECS Fargate and RDS</title>
      <dc:creator>Ravindra Singh</dc:creator>
      <pubDate>Mon, 17 Feb 2025 02:59:59 +0000</pubDate>
      <link>https://dev.to/aws-builders/ecs-finhacks-scaling-microservices-with-aws-ecs-fargate-and-rds-1fnh</link>
      <guid>https://dev.to/aws-builders/ecs-finhacks-scaling-microservices-with-aws-ecs-fargate-and-rds-1fnh</guid>
      <description>&lt;p&gt;If you've ever struggled with questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How do I securely deploy my containerized application on AWS?&lt;/li&gt;
&lt;li&gt;How do I integrate ECS, Fargate, PostgreSQL, and AWS security services?&lt;/li&gt;
&lt;li&gt;How can I ensure high availability while keeping costs under control?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then this blog is for you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fms2rl3p533vhcyk5jzgj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fms2rl3p533vhcyk5jzgj.png" alt="Image description" width="800" height="726"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this blog post, we will explore how to deploy a Node Js Microservice in AWS ECS Fargate with connectivity to Amazon RDS (PostgreSQL). This architecture ensures high availability, security, and scalability while leveraging fully managed AWS services.&lt;/p&gt;

&lt;p&gt;Git Link: &lt;a href="https://github.com/ravindrasinghh/ECS-FinHacks-Scaling-Microservices-with-AWS-ECS-Fargate-and-RDS" rel="noopener noreferrer"&gt;https://github.com/ravindrasinghh/ECS-FinHacks-Scaling-Microservices-with-AWS-ECS-Fargate-and-RDS&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Use AWS ECS?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fully Managed:&lt;/strong&gt; Eliminates the need to manage EC2 instances.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability:&lt;/strong&gt; Supports automatic scaling based on demand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; Integrates with AWS IAM, Security Groups, and VPC.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost Efficiency:&lt;/strong&gt; Pay only for the resources used.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration:&lt;/strong&gt; Works seamlessly with AWS services like RDS, S3, and CloudWatch.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Advanced Architecture Benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ECS Circuit Breaker&lt;/li&gt;
&lt;li&gt;ECS Capacity Provider(ECS Fargate SPOT + ECS Fargate)&lt;/li&gt;
&lt;li&gt;VPC Endpoint&lt;/li&gt;
&lt;li&gt;Route 53 Health check&lt;/li&gt;
&lt;li&gt;AWS Config&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;1. Architecture Overview&lt;/strong&gt;&lt;br&gt;
The architecture follows AWS best practices by leveraging containerized workloads on ECS (Fargate), a multi-AZ database layer (PostgreSQL), and various AWS security and monitoring services.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ECS Fargate: Fully managed container orchestration.&lt;/li&gt;
&lt;li&gt;Amazon RDS (PostgreSQL): Managed relational database service.&lt;/li&gt;
&lt;li&gt;AWS ALB (Application Load Balancer): Distributes traffic among ECS tasks.&lt;/li&gt;
&lt;li&gt;AWS Secrets Manager: Stores database credentials securely.&lt;/li&gt;
&lt;li&gt;AWS CloudWatch: Monitors logs and metrics.&lt;/li&gt;
&lt;li&gt;AWS Route 53: Domain Name System (DNS) for routing traffic.&lt;/li&gt;
&lt;li&gt;AWS WAF (Web Application Firewall): Protects against common web threats.
AWS Config: Tracks and records AWS configuration changes.&lt;/li&gt;
&lt;li&gt;AWS CloudTrail: Logs all API requests for auditing.&lt;/li&gt;
&lt;li&gt;AWS CloudWatch Alarms: Triggers notifications based on metrics.&lt;/li&gt;
&lt;li&gt;VPC Endpoint: Enables secure, private connectivity to AWS services.&lt;/li&gt;
&lt;li&gt;KMS (Key Management Service): Encrypts data at rest and in transit.&lt;/li&gt;
&lt;li&gt;ENI (Elastic Network Interface): Provides network connectivity for ECS tasks.&lt;/li&gt;
&lt;li&gt;Health Check &amp;amp; Route 53 Health Check: Ensures high availability by monitoring service health.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Step-by-Step Breakdown of the AWS Architecture&lt;/strong&gt;&lt;br&gt;
Let's dive deeper into how each AWS service fits into the architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.1 Networking &amp;amp; Security&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;VPC (Virtual Private Cloud):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A private and secure network for hosting all resources.
Contains public and private subnets for better isolation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;AWS WAF (Web Application Firewall):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Protects against common attacks like SQL injection and XSS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;AWS GuardDuty:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detects and alerts on security threats.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;AWS KMS (Key Management Service):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encrypts sensitive data, database records, and API secrets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2.2 Load Balancing &amp;amp; Traffic Routing&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Amazon Route 53:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provides global DNS resolution and failover routing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Application Load Balancer (ALB):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Distributes traffic to ECS containers.&lt;/li&gt;
&lt;li&gt;Performs health checks and ensures high availability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2.3 Compute &amp;amp; Containers&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Amazon ECS (Elastic Container Service):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manages containerized workloads with Fargate &amp;amp; Spot instances.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Fargate (On-demand &amp;amp; Spot):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Serverless compute for containers, reducing management overhead.
Spot pricing optimizes costs by using spare AWS capacity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Task Definitions &amp;amp; IAM Roles:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Defines how containers run within ECS.&lt;/li&gt;
&lt;li&gt;IAM Roles ensure secure communication between services.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2.4 Database Layer&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Amazon RDS (PostgreSQL Multi-AZ):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;High availability using a Master-Replica setup.&lt;/li&gt;
&lt;li&gt;KMS encryption ensures data security.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2.5 Monitoring &amp;amp; Logging&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Amazon CloudWatch:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logs container performance, database health, and API requests.
&lt;strong&gt;AWS Config &amp;amp; CloudTrail:&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Tracks infrastructure changes and compliance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Scalability &amp;amp; High Availability&lt;/strong&gt;&lt;br&gt;
This architecture ensures scalability at multiple levels:&lt;br&gt;
✅ ECS Auto-scaling: Dynamically adjusts the number of running containers based on load.&lt;br&gt;
✅ Database Auto-scaling: Supports read replicas for handling increased query loads.&lt;br&gt;
✅ Multi-AZ Deployment: Ensures uptime even if one availability zone fails.&lt;br&gt;
✅ ALB Health Checks: Automatically reroutes traffic in case of failure.&lt;br&gt;
This combination allows applications to handle traffic spikes without downtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Security Best Practices&lt;/strong&gt;&lt;br&gt;
Security is a top priority, and this architecture follows best practices:&lt;br&gt;
🔐 IAM Roles &amp;amp; Policies: Grant the least privilege access to services.&lt;br&gt;
🔐 WAF &amp;amp; GuardDuty: Blocks malicious requests and detects threats.&lt;br&gt;
🔐 KMS Encryption: Protects database and sensitive data.&lt;br&gt;
🔐 Secrets Manager: Manages database credentials securely.&lt;br&gt;
By implementing these security layers, the architecture remains resilient against cyber threats.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;5. Cost Optimisation Strategies&lt;/strong&gt;&lt;br&gt;
AWS provides multiple ways to reduce costs while maintaining performance.&lt;br&gt;
💰 Fargate Spot: Uses AWS's spare capacity for containerized workloads, reducing costs by up to 70%.&lt;br&gt;
💰 Reserved Instances for PostgreSQL: Locks in lower pricing for predictable workloads.&lt;br&gt;
💰 Auto-scaling Policies: Ensures you only pay for what you use.&lt;br&gt;
💰 EFS Infrequent Access Storage: Saves money on unused storage.&lt;br&gt;
By leveraging these strategies, you can run a cost-efficient architecture without sacrificing performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Troubleshooting Tips&lt;/strong&gt;&lt;br&gt;
👉🏻 To resolve below error.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnrfxld82b88wmem7q96g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnrfxld82b88wmem7q96g.png" alt="Image description" width="800" height="104"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are using a VPC endpoint for ECR, please enable private DNS in the VPC endpoint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5yp9inr92qs5z6vzbnri.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5yp9inr92qs5z6vzbnri.png" alt="Image description" width="800" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use the following command to create the ECR repositories.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws ecr create-repository --repository-name nodejs-api --endpoint-url https://api.ecr.ap-south-1.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;👉🏻 &lt;code&gt;endpoint url will get from https://api.ecr.ap-south-1.amazonaws.com&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Navigate to VPC Endpoints and select the API URL.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuzrc0jpav2myd0bkcptw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuzrc0jpav2myd0bkcptw.png" alt="Image description" width="800" height="293"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉🏻 Amazon ECS tasks hosted on Fargate using platform version 1.4.0 or later require both Amazon ECR VPC endpoints and the Amazon S3 gateway endpoints.&lt;br&gt;
&lt;a href="https://docs.aws.amazon.com/AmazonECR/latest/userguide/vpc-endpoints.html" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Conclusion&lt;/strong&gt;&lt;br&gt;
Building a scalable, secure, and cost-effective AWS architecture doesn't have to be complicated. By integrating ECS, Fargate, PostgreSQL, and AWS security services, you can:&lt;br&gt;
✅ Achieve high availability and fault tolerance&lt;br&gt;
✅ Protect your workloads with advanced security measures&lt;br&gt;
✅ Optimize cloud costs using AWS best practices&lt;br&gt;
This architecture provides a blueprint for running production-grade applications in AWS. Whether you're scaling a startup or managing enterprise workloads, these principles will help you build a robust cloud infrastructure.&lt;/p&gt;

&lt;p&gt;Reference: &lt;br&gt;
If you prefer a video tutorial to help guide you through the setup of Scaling Microservices with AWS ECS Fargate and RDS&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/2XA1E_1TDOk"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
    </item>
    <item>
      <title>EKS &amp; NGINX Load Balancer Monitor with Prometheus, Grafana, and Alerts</title>
      <dc:creator>Ravindra Singh</dc:creator>
      <pubDate>Sat, 14 Dec 2024 08:55:13 +0000</pubDate>
      <link>https://dev.to/aws-builders/eks-nginx-load-balancer-monitor-with-prometheus-grafana-and-alerts-1ikf</link>
      <guid>https://dev.to/aws-builders/eks-nginx-load-balancer-monitor-with-prometheus-grafana-and-alerts-1ikf</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With the growing use of Kubernetes (EKS) and microservices architecture, monitoring your infrastructure has become crucial to ensure that everything runs smoothly. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In this blog, we'll walk through setting up monitoring for NGINX running on an Amazon EKS cluster, utilizing Prometheus and Grafana for monitoring and visualization, and implementing alerting mechanisms to keep you informed about your system's health.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why Monitor EKS and NGINX Load Balancers?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Early Issue Detection:&lt;/strong&gt; Proactive monitoring allows you to identify potential problems before they impact your users, ensuring a seamless experience.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Performance Optimization:&lt;/strong&gt; Monitoring key metrics helps you understand how your EKS cluster and NGINX load balancer are performing, allowing you to fine-tune your configuration for optimal efficiency.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Troubleshooting:&lt;/strong&gt; When issues arise, having detailed metrics and logs readily available makes troubleshooting faster and more effective.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Capacity Planning:&lt;/strong&gt; Analyzing historical data helps you predict future resource needs, ensuring your infrastructure scales seamlessly with your application.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;EKS Cluster Metrics&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EKS Cluster&lt;/li&gt;
&lt;li&gt;Node resource utilization (CPU, memory, disk)&lt;/li&gt;
&lt;li&gt;Pod health and status&lt;/li&gt;
&lt;li&gt;Control plane health&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;NGINX Ingress Controller Metrics&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Request rate and latency&lt;/li&gt;
&lt;li&gt;Error rate&lt;/li&gt;
&lt;li&gt;Upstream server health&lt;/li&gt;
&lt;li&gt;Connection counts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example Alerting Scenarios&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;High NGINX Error Rate:&lt;/strong&gt; Alert when the NGINX error rate exceeds a certain threshold, indicating potential issues with upstream servers or configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Node Resource Exhaustion:&lt;/strong&gt; Alert when CPU or memory utilization on any node approaches critical levels, allowing you to proactively scale your cluster.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pod Failures:&lt;/strong&gt; Alert when pods repeatedly fail to start or crash, signaling potential application or configuration problems.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Let's Begin&lt;/strong&gt;😎&lt;/p&gt;

&lt;p&gt;🚀 &lt;strong&gt;Step-by-Step Guide to install the promethus , grafana and alert manager&lt;/strong&gt;&lt;br&gt;
1️⃣ A running Kubernetes cluster: This can be a self-managed cluster or a managed service like Amazon EKS.&lt;/p&gt;

&lt;p&gt;Refer below video to create the EKS Cluster in AWS&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/vKi6K5ope6c"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;2️⃣ NGINX Ingress on AWS EKS and Deploying Sample Applications&lt;/p&gt;

&lt;p&gt;Refer below video to setup in AWS&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/PYO0OFYNI5A"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;3️⃣ Clone the Repository&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;🧑🏻‍💻git clone https://github.com/ravindrasinghh/Kubernetes-Playlist.git
👨🏻‍💻cd Kubernetes-Playlist/Lesson1/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4️⃣ Please add the below file to install Prometheus, Grafana, and Alertmanager using Helm&lt;br&gt;
👉🏻 prometheus.tf&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "helm_release" "kube-prometheus-stack" {
  name             = "kube-prometheus-stack"
  repository       = "https://prometheus-community.github.io/helm-charts"
  chart            = "kube-prometheus-stack"
  version          = "56.21.3"
  namespace        = "monitoring"
  create_namespace = true

  values = [
    file("./prometheus.yaml")
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉🏻 prometheus.yaml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alertmanager:
  enabled: true
  alertmanagerSpec:
    retention: 24h #This setting specifies the time duration for which Alertmanager will retain alert data. 
    replicas: 1
    resources:
      limits:
        cpu: 600m
        memory: 1024Mi
      requests:
        cpu: 200m
        memory: 356Mi
  config:
    global:
      resolve_timeout: 1s # In this case, it's set to 5 minutes. If an alert is not explicitly resolved by the alert source within 5 minutes, it will be automatically marked as resolved by Alertmanager.
    route:
      group_wait: 20s
      group_interval: 1m
      repeat_interval: 30m
      receiver: "null"
      routes:
      - match:
          alertname: Watchdog
        receiver: "null"
      - match:
          severity: warning
        receiver: "slack-alerts"
        continue: true
      - match:
          severity: critical
        receiver: "slack-alerts"
        continue: true
    receivers:
      - name: "null"
      - name: "slack-alerts"
        slack_configs:
        - api_url: 'https://hooks.slack.com/services/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'
          channel: '#prometheus-alerts'
          send_resolved: true
          title: '[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] Production Monitoring Event Notification'
          text: &amp;gt;-
            {{ range .Alerts }}
              *Alert:* {{ .Annotations.summary }} - `{{ .Labels.severity }}`
              *Description:* {{ .Annotations.description }}
              *Details:*
              {{ range .Labels.SortedPairs }} • *{{ .Name }}:* `{{ .Value }}`
              {{ end }}
            {{ end }}
    templates:
    - "/etc/alertmanager/config/*.tmpl"
additionalPrometheusRulesMap:
 custom-rules:
  groups:
  - name: NginxIngressController
    rules:
    - alert: NginxHighHttp4xxErrorRate
      annotations:
        summary: "High rate of HTTP 4xx errors (instance {{ $labels.ingress }})"
        description: "Too many HTTP requests with status 4xx (&amp;gt; 20 per second) in the last 5 minutes\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"
      expr: nginx_ingress_controller_requests{status="404", ingress="photoapp"} &amp;gt; 5
      for: 5m
      labels:
        severity: critical      
  - name: Nodes
    rules:
    - alert: KubernetesNodeReady
      expr: sum(kube_node_status_condition{condition="Ready", status="false"}) by (node) &amp;gt; 0
      for: 1m
      labels:
        severity: critical
      annotations:
        summary: Kubernetes Node ready (instance {{ $labels.instance }})
        description: "Node {{ $labels.node }} has been unready for a long time\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"         
      # New alert for node deletion
    - alert: InstanceDown
      expr: up == 0
      labels:
        severity: critical
      annotations:
        summary: Kubernetes Node Deleted (instance {{ $labels.instance }})
        description: "Node {{ $labels.node }} has been unready for a long time\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"     
  - name: Pods 
    rules: 
      - alert: Container restarted 
        annotations: 
          summary: Container named {{$labels.container}} in {{$labels.pod}} in {{$labels.namespace}} was restarted 
          description: "\nCluster Name: {{$externalLabels.cluster}}\nNamespace: {{$labels.namespace}}\nPod name: {{$labels.pod}}\nContainer name: {{$labels.container}}\n" 
        expr: | 
          sum(increase(kube_pod_container_status_restarts_total{namespace!="kube-system",pod_template_hash=""}[1m])) by (pod,namespace,container) &amp;gt; 0 
        for: 0m 
        labels: 
          severity: critical            
prometheus:
  enabled: true
  ingress:
    enabled: true
    ingressClassName: nginx
    hosts:
      - prometheus.codedevops.cloud
    paths:  
      - /
  prometheusSpec:
    retention: 48h
    replicas: 2
    resources:
      limits:
        cpu: 800m
        memory: 2000Mi
      requests:
        cpu: 100m
        memory: 200Mi
grafana:
  enabled: true
  adminPassword: admin@123
  replicas: 1
  ingress:
    enabled: true
    ingressClassName: nginx
    hosts:
      - grafana.codedevops.cloud
    path: /

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

&lt;/div&gt;



&lt;p&gt;You can also check the logs of the Prometheus, Grafana, and Alertmanager pods to verify that the setup has been successfully installed.&lt;br&gt;
👉🏻 kubectl get pods -n monitoring&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5305wiykmzm2jfni2nth.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5305wiykmzm2jfni2nth.png" alt="Image description" width="800" height="232"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉🏻 Let's create a record in Route 53 to access prometheus and grafana via a custom domain.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to the Route 53 service, select the hosted zone, and click Create Record.&lt;/li&gt;
&lt;li&gt;Choose Alias, then select the region and the Load Balancer ARN, and click Create.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnv619xy3dsfph67p9622.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnv619xy3dsfph67p9622.png" alt="Image description" width="800" height="529"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgx1at7hpj0a6q3zdte85.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgx1at7hpj0a6q3zdte85.png" alt="Image description" width="800" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉🏻 once the Ingress is configured, you can access the promethues web interface by navigating to &lt;a href="https://prometheus.codedevops.cloud" rel="noopener noreferrer"&gt;https://prometheus.codedevops.cloud&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft9xc1vkgv88tp2mzwwb4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft9xc1vkgv88tp2mzwwb4.png" alt="Image description" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉🏻 once the Ingress is configured, you can access the grafana web interface by navigating to &lt;a href="https://grafana.codedevops.cloud" rel="noopener noreferrer"&gt;https://grafana.codedevops.cloud&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6tqm8rdexibqbglcbype.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6tqm8rdexibqbglcbype.png" alt="Image description" width="800" height="529"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To log in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get the initial password for the admin user:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get secret kube-prometheus-stack-grafana -n monitoring -o jsonpath="{.data.admin-password}" | base64 --decode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;🚀 Step-by-Step Guide to integrate slack with prometheus alerts&lt;br&gt;
Step 1: Create a Slack Incoming Webhook&lt;/strong&gt;&lt;br&gt;
Go to Slack Apps: (Open your Slack workspace and visit the Slack API Apps page.)&lt;/p&gt;

&lt;p&gt;👉🏻Click on Add Apps located at the bottom.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7fm1et5kfeqt3zdtu8qi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7fm1et5kfeqt3zdtu8qi.png" alt="Image description" width="800" height="289"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉🏻 It will open this page, where you need to select Incoming Webhook.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F58s9mqp1zxvl7o2deyu2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F58s9mqp1zxvl7o2deyu2.png" alt="Image description" width="800" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉🏻 click on it and then click on configuration &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Febftmdzzt02dm3tuekz6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Febftmdzzt02dm3tuekz6.png" alt="Image description" width="800" height="219"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉🏻 click on Add to slack&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ga1x3eopj65tfp4dhyq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ga1x3eopj65tfp4dhyq.png" alt="Image description" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉🏻 Choose a channel or an existing channel, then click on Add Incoming Webhooks Integration.After that, copy the Webhook URL and configure it in your Prometheus Helm chart values.yaml file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpg2ywx23q31fx2l217ke.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpg2ywx23q31fx2l217ke.png" alt="Image description" width="800" height="179"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉🏻 click on save buttons and test the configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🚀 Step-by-Step Guide to monitor NGINX ingress Load balancer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;👉🏻Here is the NGINX Ingress YAML file. You can refer to lesson 2 or the previous video for more details.&lt;br&gt;
&lt;a href="https://github.com/ravindrasinghh/Kubernetes-Playlist/blob/master/Lesson2/nginx.yaml" rel="noopener noreferrer"&gt;https://github.com/ravindrasinghh/Kubernetes-Playlist/blob/master/Lesson2/nginx.yaml&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;controller:
  replicaCount: 2
  minAvailable: 1
  resources:
    limits:
      cpu: 500m
      memory: 512Mi
    requests:
      cpu: 100m
      memory: 256Mi
  autoscaling:
    enabled: true
    annotations: {}
    minReplicas: 2
    maxReplicas: 6
    targetCPUUtilizationPercentage: 70
    targetMemoryUtilizationPercentage: 80
    behavior:
      scaleDown:
        stabilizationWindowSeconds: 60
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  metrics:
    port: 10254
    enabled: true
    serviceMonitor:
      enabled: true
      additionalLabels:
        release: "kube-prometheus-stack"
    service:
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "10254"
  service:
    annotations:
      service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
      service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: 'true'
      service.beta.kubernetes.io/aws-load-balancer-type: nlb
      service.beta.kubernetes.io/aws-load-balancer-ssl-ports: https
      service.beta.kubernetes.io/aws-load-balancer-ssl-negotiation-policy: 'ELBSecurityPolicy-TLS13-1-2-2021-06'
      service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
    targetPorts:
      http: http
      https: http

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

&lt;/div&gt;






&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fae9kh35tn83i7vrzc3m9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fae9kh35tn83i7vrzc3m9.png" alt="Image description" width="800" height="625"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In simpler terms:&lt;/strong&gt;&lt;br&gt;
This configuration tells the Ingress Controller to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Expose its internal metrics on port 10254.&lt;/li&gt;
&lt;li&gt;Create a ServiceMonitor object so that Prometheus can automatically find this metrics endpoint.&lt;/li&gt;
&lt;li&gt;Add annotations to the Ingress Controller's Service so Prometheus knows to scrape it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Annotations:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;prometheus.io/scrape: "true": This annotation tells Prometheus that it should scrape the metrics from this service.&lt;/li&gt;
&lt;li&gt;prometheus.io/port: "10254":Specifies the port that Prometheus should use to scrape metrics from this service, matching the metrics.port setting above.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;🚀 Step-by-Step Guide to setup alert in NGINX ingress Load balancer&lt;/strong&gt;&lt;br&gt;
👉🏻add below configuration inside the additionalPrometheusRulesMap:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;additionalPrometheusRulesMap:
 custom-rules:
  groups:
  - name: NginxIngressController
    rules:
    - alert: NginxHighHttp4xxErrorRate
      annotations:
        summary: "High rate of HTTP 4xx errors (instance {{ $labels.ingress }})"
        description: "Too many HTTP requests with status 4xx (&amp;gt; 20 per second) in the last 5 minutes\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"
      expr: nginx_ingress_controller_requests{status="404", ingress="photoapp"} &amp;gt; 5
      for: 5m
      labels:
        severity: critical 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉🏻 Here is the correct url : &lt;br&gt;
&lt;a href="https://myapp.codedevops.cloud/ping" rel="noopener noreferrer"&gt;https://myapp.codedevops.cloud/ping&lt;/a&gt;.&lt;br&gt;
👁️‍🗨️Try accessing the incorrect URL &lt;a href="https://myapp.codedevops.cloud/pingtesting" rel="noopener noreferrer"&gt;https://myapp.codedevops.cloud/pingtesting&lt;/a&gt;. You will see two alerts in the firing state, and the alerts will also appear in Slack.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp4f0ah0hh3vc5zyetlrz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp4f0ah0hh3vc5zyetlrz.png" alt="Image description" width="800" height="319"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉🏻erorr notification in slack&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuuvsxunry0o8psp1sbw4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuuvsxunry0o8psp1sbw4.png" alt="Image description" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉🏻Resolved notification in slack&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fursotqittvrtf9mjon2x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fursotqittvrtf9mjon2x.png" alt="Image description" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🚀 Step-by-Step Guide to monitor Kubernetes cluster, nodes and pods&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The metrics-server is required to collect resource metrics like CPU and memory usage for Kubernetes nodes and pods. It provides data for kubectl top commands and enables the cluster's auto-scaling.&lt;/p&gt;

&lt;p&gt;Please add the below file to install metrics server using helm.&lt;br&gt;
👉🏻 metrics-server.tf&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "helm_release" "metrics_server" {
  name       = "metrics-server"
  repository = "https://kubernetes-sigs.github.io/metrics-server/"
  chart      = "metrics-server"
  version    = "3.12.0"
  namespace  = "kube-system"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🚀 &lt;strong&gt;Step-by-Step Guide to setup alert in Nodes and pods.&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;node is terminating&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;additionalPrometheusRulesMap:
 custom-rules:
  groups:  
  - name: Nodes
    rules:
    - alert: KubernetesNodeReady
      expr: sum(kube_node_status_condition{condition="Ready", status="false"}) by (node) &amp;gt; 0
      for: 1m
      labels:
        severity: critical
      annotations:
        summary: Kubernetes Node ready (instance {{ $labels.instance }})
        description: "Node {{ $labels.node }} has been unready for a long time\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"         
      # New alert for node deletion
    - alert: InstanceDown
      expr: up == 0
      labels:
        severity: critical
      annotations:
        summary: Kubernetes Node Deleted (instance {{ $labels.instance }})
        description: "Node {{ $labels.node }} has been unready for a long time\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}" 
pod is restarting 
additionalPrometheusRulesMap:
 custom-rules:
  groups:
  - name: Pods 
    rules: 
    - alert: Container restarted 
      annotations: 
        summary: Container named {{$labels.container}} in {{$labels.pod}} in {{$labels.namespace}} was restarted 
        description: "\nCluster Name: {{$externalLabels.cluster}}\nNamespace: {{$labels.namespace}}\nPod name: {{$labels.pod}}\nContainer name: {{$labels.container}}\n" 
      expr: | 
        sum(increase(kube_pod_container_status_restarts_total{namespace!="kube-system",pod_template_hash=""}[1m])) by (pod,namespace,container) &amp;gt; 0 
      for: 0m 
      labels: 
       severity: critical
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉🏻erorr notification in slack&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdlfv8xmz532iweg8wlhf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdlfv8xmz532iweg8wlhf.png" alt="Image description" width="800" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉🏻Resolved notification in slack&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu6rz397aw4veta51rm1a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu6rz397aw4veta51rm1a.png" alt="Image description" width="800" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 Step-by-Step Guide to setup Dashboard in Grafana.&lt;br&gt;
Cluster Monitoring: &lt;a href="https://github.com/ravindrasinghh/Kubernetes-Playlist/blob/master/Lesson5/cluster_disk_monitoring.json" rel="noopener noreferrer"&gt;https://github.com/ravindrasinghh/Kubernetes-Playlist/blob/master/Lesson5/cluster_disk_monitoring.json&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldby8ru5az3jt33odh6o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldby8ru5az3jt33odh6o.png" alt="Image description" width="800" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqg2kw5deuuusl897caql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqg2kw5deuuusl897caql.png" alt="Image description" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Prometheus Alert: &lt;a href="https://github.com/ravindrasinghh/Kubernetes-Playlist/blob/master/Lesson5/promethues_alert.json" rel="noopener noreferrer"&gt;https://github.com/ravindrasinghh/Kubernetes-Playlist/blob/master/Lesson5/promethues_alert.json&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Troubleshooting&lt;br&gt;
If you encounter any issues, refer to the Prometheus documentation or raise an issue in this repository.&lt;br&gt;
🏴‍☠️ source link: &lt;a href="https://github.com/ravindrasinghh/Kubernetes-Playlist/tree/master/Lesson5" rel="noopener noreferrer"&gt;https://github.com/ravindrasinghh/Kubernetes-Playlist/tree/master/Lesson5&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you prefer a video tutorial to help guide you to setup EKS &amp;amp; NGINX Load Balancer Monitor with Prometheus, Grafana, and Alerts&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/cww7UHMYOE0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>prometheus</category>
      <category>grafana</category>
      <category>alerting</category>
    </item>
    <item>
      <title>Installing ArgoCD and Securing Access Using Amazon Cognito</title>
      <dc:creator>Ravindra Singh</dc:creator>
      <pubDate>Fri, 27 Sep 2024 11:59:23 +0000</pubDate>
      <link>https://dev.to/aws-builders/installing-argocd-and-securing-access-using-amazon-cognito-3gnn</link>
      <guid>https://dev.to/aws-builders/installing-argocd-and-securing-access-using-amazon-cognito-3gnn</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction:&lt;/strong&gt;&lt;br&gt;
In this blog, we will walk through the steps to install ArgoCD, a powerful GitOps continuous delivery tool, using Helm. We'll also configure access to ArgoCD via an Ingress controller, making it easy to manage Kubernetes deployments from a web interface.&lt;/p&gt;

&lt;p&gt;GIT LINK: &lt;a href="https://github.com/ravindrasinghh/Kubernetes-Playlist" rel="noopener noreferrer"&gt;https://github.com/ravindrasinghh/Kubernetes-Playlist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's Begin&lt;/strong&gt; 😎&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fll4pfwvaerc2d3c8tjns.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fll4pfwvaerc2d3c8tjns.png" alt="Image description" width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Application Controller:&lt;/strong&gt; Manages the state of applications in ArgoCD by continuously monitoring Git repositories and syncing changes to Kubernetes clusters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Repo Server:&lt;/strong&gt; Handles interactions with Git repositories, fetching application manifests and generating Kubernetes manifests in ArgoCD.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ArgoCD Server:&lt;/strong&gt; The web interface and API service for interacting with ArgoCD, where users can view, manage, and control their application deployments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Redis&lt;/strong&gt;: A fast, in-memory key-value store used by ArgoCD for caching and state management.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dex Server:&lt;/strong&gt; An OpenID Connect (OIDC) identity provider used in ArgoCD for integrating with external authentication services (e.g., LDAP, GitHub, etc.).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Let's Begin😎&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🚀 &lt;strong&gt;Step-by-Step Guide&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1️⃣ &lt;strong&gt;A running Kubernetes cluster: This can be a self-managed cluster or a managed service like Amazon EKS.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Refer below video to create the EKS Cluster in AWS&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/vKi6K5ope6c"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;2️⃣ &lt;strong&gt;NGINX Ingress on AWS EKS and Deploying Sample Applications&lt;br&gt;
Refer below video to setup in AWS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/PYO0OFYNI5A"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;3️⃣ &lt;strong&gt;Clone the Repository&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;🧑🏻‍💻git clone https://github.com/ravindrasinghh/Kubernetes-Playlist.git
👨🏻‍💻cd Kubernetes-Playlist/Lesson1/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4️⃣ Please add the below file to install the ArgoCD&lt;br&gt;
👉🏻 argocd.tf&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "helm_release" "argocd" {
  name             = "argocd"
  repository       = "https://argoproj.github.io/argo-helm"
  chart            = "argo-cd"
  namespace        = "argocd"
  create_namespace = true
  version          = "4.0.0"
  values           = [file("./argo.yaml")]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉🏻 argocd.yaml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;global:
  domain: https://argo.codedevops.cloud
repoServer:
  resources:
    requests:
      cpu: 100m
      memory: 128Mi            
server:
  resources:
    requests:
      cpu: 100m
      memory: 128Mi
  config:
    url: "https://argo.codedevops.cloud" 
  extraArgs:
    - --insecure    
  ingress:
    enabled: true
    ingressClassName: nginx
    annotations:
      nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
      nginx.ingress.kubernetes.io/cors-expose-headers: "*, X-CustomResponseHeader"
      nlb.ingress.kubernetes.io/scheme: internet-facing
      nlb.ingress.kubernetes.io/target-type: instance
      nlb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
      nlb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:ap-south-1:434605749312:certificate/50eeb484-0d88-4617-bdf6-1d339f2f3b48"
    hosts:
      - argo.codedevops.cloud
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;You can also view the logs of the ArgoCD pod to verify that ArgoCD has been installed successfully.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;👉🏻 kubectl get pods -n argocd&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmfxj1x26yffay347aw5v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmfxj1x26yffay347aw5v.png" alt="Image description" width="800" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwkgcc71glcurk7vr480k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwkgcc71glcurk7vr480k.png" alt="Image description" width="800" height="92"&gt;&lt;/a&gt;&lt;br&gt;
👉🏻 Let's create a record in Route 53 to access ArgoCD via a custom domain.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to the Route 53 service, select the hosted zone, and click Create Record.&lt;/li&gt;
&lt;li&gt;Choose Alias, then select the region and the Load Balancer ARN, and click Create.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvqysuu3n4iywt0t05ldg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvqysuu3n4iywt0t05ldg.png" alt="Image description" width="800" height="513"&gt;&lt;/a&gt;&lt;br&gt;
👉🏻 once the Ingress is configured, you can access the ArgoCD web interface by navigating to &lt;a href="https://argo.codedevops.cloud" rel="noopener noreferrer"&gt;https://argo.codedevops.cloud&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1er15jbyqdrozpoe5uwt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1er15jbyqdrozpoe5uwt.png" alt="Image description" width="800" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉🏻 To log in:&lt;br&gt;
Get the initial password for the admin user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get secret argocd-initial-admin-secret -n argocd -o jsonpath="{.data.password}" | base64 --decode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉🏻 We can see that we have successfully logged in using the username 'admin' and the password mentioned above.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsyh3mkfavh9sh5o3c5hn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsyh3mkfavh9sh5o3c5hn.png" alt="Image description" width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🚀 Step-by-Step Guide to access via AWS Cognito&lt;/strong&gt;&lt;br&gt;
1️⃣ Navigate to the AWS Cognito console, click on 'Create User Pool,' select 'Username,' and then click 'Next.' You can add additional parameters based on your requirements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14msb3n41mf2wz3xzcur.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14msb3n41mf2wz3xzcur.png" alt="Image description" width="800" height="572"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2️⃣ Set up a password policy to specify the required length and complexity for user passwords, or use the default settings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frtiwi57tmcoj5jingcm5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frtiwi57tmcoj5jingcm5.png" alt="Image description" width="800" height="667"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I selected 'No MFA,' but you can enable it if needed, and then click 'Next.'&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F48aulxzc1k086as26kyn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F48aulxzc1k086as26kyn.png" alt="Image description" width="800" height="689"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3️⃣ For the 'Configure Sign-Up Experience' section, click 'Next' and proceed with the default settings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9bowqbiqa5ckepstjqvg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9bowqbiqa5ckepstjqvg.png" alt="Image description" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4️⃣  Let's use Cognito's default email address temporarily for development to handle emails for sign-up, sign-in, MFA, and account recovery workflows.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff0kv3gtu36sb0nvcuwue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff0kv3gtu36sb0nvcuwue.png" alt="Image description" width="800" height="674"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;5️⃣ Let's integrate with our app and provide the following information:&lt;br&gt;
User Pool Name: ARGOCD&lt;br&gt;
Use the Cognito Hosted UI: Check the box&lt;br&gt;
Use a Cognito Domain: &lt;a href="https://argocodedevops" rel="noopener noreferrer"&gt;https://argocodedevops&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F90hk1b0ffat0f1c70azr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F90hk1b0ffat0f1c70azr.png" alt="Image description" width="800" height="562"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgibfmj7hslr74bmazuml.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgibfmj7hslr74bmazuml.png" alt="Image description" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Set the App Client Name to argo-app-client and click on 'Generate a Client Secret.' For the Allowed Callback URLs, enter &lt;a href="https://argo.codedevops.cloud/auth/callback" rel="noopener noreferrer"&gt;https://argo.codedevops.cloud/auth/callback&lt;/a&gt;, and then click 'Next.'&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0uqyl8lolngkpo8elbpv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0uqyl8lolngkpo8elbpv.png" alt="Image description" width="800" height="729"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Review the settings, and then click 'Create.'&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnblfa3lphdz20rssn8ur.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnblfa3lphdz20rssn8ur.png" alt="Image description" width="800" height="135"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉🏻 &lt;strong&gt;Navigate to users in the userpool and click on Create user.&lt;/strong&gt;&lt;br&gt;
· Creation of user and adding to the Group&lt;br&gt;
· Click on the userpool which has been created&lt;br&gt;
· Navigate to the User tab and click on the create user.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpdydhj702z6i29vdb9i3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpdydhj702z6i29vdb9i3.png" alt="Image description" width="800" height="711"&gt;&lt;/a&gt;&lt;br&gt;
You will also receive the user details in your email.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe1vfmhf5y1kwumesxq8o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe1vfmhf5y1kwumesxq8o.png" alt="Image description" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉🏻 &lt;strong&gt;Navigate to group in the userpool and click on Create group.&lt;/strong&gt;&lt;br&gt;
Add the user to this group, and you can assign them a specific IAM role. Let's keep it as the default.&lt;br&gt;
click on create group.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fev8gnofm9obgzwjnfi28.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fev8gnofm9obgzwjnfi28.png" alt="Image description" width="800" height="743"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the group name and add the newly created user to the group.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg8d9039b9af8sed31pqj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg8d9039b9af8sed31pqj.png" alt="Image description" width="800" height="174"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffkg1rd01py2by2vefawa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffkg1rd01py2by2vefawa.png" alt="Image description" width="800" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;click on add.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjxal379jyr5oi4ooju3h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjxal379jyr5oi4ooju3h.png" alt="Image description" width="800" height="235"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's update the Ingress configuration to enable login to ArgoCD via AWS Cognito, and ensure that the correct values are entered for the OIDC configuration.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉🏻 name: ADMIN # can be anything&lt;br&gt;
👉🏻 issuer: &lt;a href="https://cognito-idp.ap-south-1.amazonaws.com/ap-south-1_i2BlvxmV2" rel="noopener noreferrer"&gt;https://cognito-idp.ap-south-1.amazonaws.com/ap-south-1_i2BlvxmV2&lt;/a&gt; # Replace with your AWS SSO Issuer URL&lt;br&gt;
👉🏻 clientID: 2ulo6uvu1r4o2eesgq9tifiqjq # Replace with your AWS SSO Client ID&lt;br&gt;
👉🏻 clientSecret: 9530gfivef6aoi21e0cj93p41gt7e2gja4b7u0e1ui93pvpv5pu # Replace with your AWS SSO Client Secret&lt;br&gt;
👉🏻 redirectUrI: &lt;a href="https://argo.codedevops.cloud/api/dex/callback" rel="noopener noreferrer"&gt;https://argo.codedevops.cloud/api/dex/callback&lt;/a&gt; # Replace with your ArgoCD URL&lt;br&gt;
👉🏻 requestedScopes: ["email", "openid", "phone"]&lt;br&gt;
👉🏻 requestedIDTokenClaims: {"groups": {"essential": true}}&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can retrieve the values from AWS Cognito. Click on 'App Integration,' navigate to the 'App Client List' section, select argo-app-client, and copy all the client-related information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyoyw0t8k20tjx5nzpr15.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyoyw0t8k20tjx5nzpr15.png" alt="Image description" width="800" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please update the Ingress configuration with AWS Cognito service details to enable login via Cognito.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;global:
  domain: https://argo.codedevops.cloud
configs:
  params:
    "server.insecure": true
  cm:
    create: true        
  rbac:
    create: true
    policy.default: ''
    policy.csv: |
        g, argocd-readonly, role:readonly
        g, argocd-admin, role:admin
    scopes: '[groups]'   
repoServer:
  resources:
    requests:
      cpu: 100m
      memory: 128Mi            
server:
  config:
    url: "https://argo.codedevops.cloud"   
    oidc.config: |
        name: admin
        issuer: https://cognito-idp.ap-south-1.amazonaws.com/ap-south-1_YEwPaQA4Q  # Replace with your AWS SSO Issuer URL
        clientID: 3f8r6j111qidd2c2ft9rmh4vu    # Replace with your AWS SSO Client ID
        clientSecret: 1gpls5t1pm3gjg3rfltsja6b # Replace with your AWS SSO Client Secret
        redirectUrI: https://argo.codedevops.cloud/api/dex/callback
        requestedScopes: ["email", "openid", "phone"]
        requestedIDTokenClaims: {"groups": {"essential": true}}      
  extraArgs:
    - --insecure  
  ingress:
    enabled: true
    ingressClassName: nginx
    annotations:
      nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
      nginx.ingress.kubernetes.io/cors-expose-headers: "*, X-CustomResponseHeader"
      nlb.ingress.kubernetes.io/scheme: internet-facing
      nlb.ingress.kubernetes.io/target-type: instance
      nlb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
      nlb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:ap-south-1:434605749312:certificate/50eeb484-0d88-4617-bdf6-1d339f2f3b48"
    hosts:
      - argo.codedevops.cloud
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉🏻 Run terraform plan to preview the changes, and then use terraform apply to apply them.&lt;br&gt;
👁️‍🗨️Let's try logging in by accessing the URL(&lt;a href="https://argo.codedevops.cloud" rel="noopener noreferrer"&gt;https://argo.codedevops.cloud&lt;/a&gt;) again and signing in through AWS Cognito.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flda1el3zjlqha260xtvh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flda1el3zjlqha260xtvh.png" alt="Image description" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter the username and passsword.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft4e1o2v6zj008wf6w9ah.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft4e1o2v6zj008wf6w9ah.png" alt="Image description" width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb8csgjz75qdw9qfvab4t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb8csgjz75qdw9qfvab4t.png" alt="Image description" width="800" height="564"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fblr6te4t97d9qt0q727h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fblr6te4t97d9qt0q727h.png" alt="Image description" width="800" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Troubleshooting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you encounter any issues, refer to the AWS documentation or raise an issue in this repository.&lt;/p&gt;

&lt;p&gt;🏴‍☠️ &lt;strong&gt;source link:&lt;/strong&gt; &lt;a href="https://github.com/ravindrasinghh/Kubernetes-Playlist/tree/master" rel="noopener noreferrer"&gt;https://github.com/ravindrasinghh/Kubernetes-Playlist/tree/master&lt;/a&gt;&lt;br&gt;
If you prefer a video tutorial to help guide you to Install and Secure ArgoCD access with Amazon Cognito.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/PLBcdL2XSHw"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>eks</category>
      <category>devops</category>
      <category>cognito</category>
    </item>
    <item>
      <title>Integrate API Gateway with AWS EKS NLB</title>
      <dc:creator>Ravindra Singh</dc:creator>
      <pubDate>Sun, 15 Sep 2024 09:45:58 +0000</pubDate>
      <link>https://dev.to/aws-builders/integrate-api-gateway-with-aws-eks-nlb-1bib</link>
      <guid>https://dev.to/aws-builders/integrate-api-gateway-with-aws-eks-nlb-1bib</guid>
      <description>&lt;p&gt;&lt;strong&gt;What is API Gateway&lt;/strong&gt;&lt;br&gt;
API Gateway is a fully managed service and it provides an entry point to your microservices. It helps you innovate faster by handling common functions such as API throttling, request caching, authorization and access control, monitoring, version management, and security.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS PrivateLink&lt;/strong&gt; is a service that allows you to securely access services hosted on AWS in a highly secure and private manner, without exposing your data to the public internet. It enables private connectivity between Virtual Private Clouds (VPCs), AWS services, and on-premises networks, using private IP addresses within your network.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3so05zsqe48ve7nycixx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3so05zsqe48ve7nycixx.jpg" alt="Image description" width="800" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Integrate API Gateway with EKS via NLB?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;For Microservices Architectures:&lt;/strong&gt; When you have multiple microservices in your EKS cluster, and you need a unified API endpoint for client applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security:&lt;/strong&gt; API Gateway offers fine-grained access control and supports authentication and authorization mechanisms, such as AWS IAM and Lambda Authorizers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability and High Availability:&lt;/strong&gt; Combining API Gateway with NLB ensures high availability and automatic scaling of microservices running on your EKS cluster.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Performance:&lt;/strong&gt; NLB offers low latency and can handle millions of requests per second, making it suitable for high-performance applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ease of Management:&lt;/strong&gt; With API Gateway, you can easily manage and expose APIs, track usage, and monitor performance.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By combining API Gateway with an Ingress Load Balancer, you achieve a robust, scalable, and secure architecture for managing API traffic to your backend services in Amazon EKS&lt;/p&gt;

&lt;p&gt;GIT LINK: &lt;a href="https://github.com/ravindrasinghh/Kubernetes-Playlist" rel="noopener noreferrer"&gt;https://github.com/ravindrasinghh/Kubernetes-Playlist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's Begin😎&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🚀 &lt;strong&gt;Step-by-Step Guide&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1️⃣ &lt;strong&gt;A running Kubernetes cluster: This can be a self-managed cluster or a managed service like Amazon EKS.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Refer below video to create the EKS Cluster in AWS&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/vKi6K5ope6c"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;2️⃣ &lt;strong&gt;NGINX Ingress on AWS EKS and Deploying Sample Applications&lt;br&gt;
Refer below video to setup in AWS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/PYO0OFYNI5A"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;3️⃣ &lt;strong&gt;Create a VPC Link for a REST API and Integrate it with the EKS Network Load Balancer (NLB).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiwu2wcugbvlak25samm9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiwu2wcugbvlak25samm9.png" alt="Image description" width="800" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4️⃣ &lt;strong&gt;Creating a VPC private link can take approximately 10 minutes to complete.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;5️⃣ &lt;strong&gt;Create a Private HTTP API using API Gateway with HTTP integrations.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flwh10d1szq9c8bv33y9a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flwh10d1szq9c8bv33y9a.png" alt="Image description" width="800" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;6️⃣ &lt;strong&gt;HTTP integration, API Gateway sends the request to the URL that you specify and returns the response from the URL.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;{proxy}: Single Path Segment Placeholder&lt;/li&gt;
&lt;li&gt;{proxy} is a single path segment placeholder.&lt;/li&gt;
&lt;li&gt;It matches exactly one path segment in the URL&lt;/li&gt;
&lt;li&gt;For example, if your path is /users/{proxy}, it will match:&lt;/li&gt;
&lt;li&gt;/users/123&lt;/li&gt;
&lt;li&gt;/users/abc&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkdo6pjgzbr36t5qzs9eo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkdo6pjgzbr36t5qzs9eo.png" alt="Image description" width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;7️⃣ &lt;strong&gt;{proxy+}: Multi-Segment Path Placeholder&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;{proxy+} is a multi-segment path placeholder (wildcard).&lt;/li&gt;
&lt;li&gt;It matches one or more path segments in the URL.&lt;/li&gt;
&lt;li&gt;For example, if your path is /users/{proxy+}, it will match:&lt;/li&gt;
&lt;li&gt;/users/123&lt;/li&gt;
&lt;li&gt;/users/123/details&lt;/li&gt;
&lt;li&gt;/users/abc/extra/path&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fny80qiquu2o1brza32q7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fny80qiquu2o1brza32q7.png" alt="Image description" width="800" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;8️⃣ &lt;strong&gt;Stages are configurable to enable the deployment of your API.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;9️⃣ &lt;strong&gt;Review the settings and click the "Create" button.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🔟 &lt;strong&gt;Once everything is created, you will see a route defined as {proxy+} with the GET method.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdj0wkh2le65ppenawc6p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdj0wkh2le65ppenawc6p.png" alt="Image description" width="800" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;1️⃣ 1️⃣ &lt;strong&gt;Click on "Stages" on the left side, and select the desired stage. Since auto-deploy is enabled, there is no need to deploy again. Simply copy the URL and make a request to it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwobmpd1o8el3910g0ixv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwobmpd1o8el3910g0ixv.png" alt="Image description" width="800" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Invoke the API URL with the Ingress endpoints.&lt;br&gt;
👉🏻 /&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq4h2y1xj40djaegj88ji.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq4h2y1xj40djaegj88ji.png" alt="Image description" width="800" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉🏻/ping&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fenqzxu5357r026zn2yhy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fenqzxu5357r026zn2yhy.png" alt="Image description" width="800" height="201"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉🏻/metrics&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frw2v3usie6j76qkdqt4b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frw2v3usie6j76qkdqt4b.png" alt="Image description" width="800" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉🏻/erorr&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpayrkxv4c91o5auazivp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpayrkxv4c91o5auazivp.png" alt="Image description" width="800" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👁️‍🗨️ You can use both NLB and ALB with API Gateway HTTP APIs, API Gateway REST APIs whereas only support private integrations using a NLB. If you use NLB, you'll use API Gateway routes to route traffic to distinct services. If you choose to use an ALB to expose your services, you'll use ALB to route traffic to distinct services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configuring a Custom Domain for Your AWS API Gateway&lt;/strong&gt;&lt;br&gt;
Custom domain names are simpler and more intuitive URLs that you can provide to your API users.&lt;/p&gt;

&lt;p&gt;After deploying your API, you (and your customers) can invoke the API using the default base URL of the following format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://api-id.execute-api.region.amazonaws.com/stage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where api-id is generated by API Gateway, region is the AWS Region, and stage is specified by you when deploying the API.&lt;/p&gt;

&lt;p&gt;The hostname portion of the URL, api-id.execute-api.region.amazonaws.com refers to an API endpoint. The default API endpoint name is randomly generated, difficult to recall, and not user-friendly.&lt;/p&gt;

&lt;p&gt;With custom domain names, you can set up your API's hostname, and choose a base path (for example, myservice) to map the alternative URL to your API. For example, a more user-friendly API base URL can become:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://dev.codedevops.cloud/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🚀 Step-by-Step Guide&lt;br&gt;
1️⃣ Click on "Custom Domain" and then click the "Create" button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs89c1k3lrqcvsrzljx7a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs89c1k3lrqcvsrzljx7a.png" alt="Image description" width="800" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2️⃣ Enter the domain name you want to use (e.g., dev.codedevops.cloud), select the appropriate ACM certificate, and click "Create Domain."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff8nyxwmc8dhw6c7art4y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff8nyxwmc8dhw6c7art4y.png" alt="Image description" width="800" height="716"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3️⃣ Click on "Configure API Mapping," select the desired API and stage, and then click "Save."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwh31yzoo4li0xoh38hbm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwh31yzoo4li0xoh38hbm.png" alt="Image description" width="800" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldzkvsxgg8kaabe0eu3g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldzkvsxgg8kaabe0eu3g.png" alt="Image description" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4️⃣ Go to Route 53 and configure the domain api.codedevops.cloud accordingly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzg54sks0jzo9z3y5ycjn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzg54sks0jzo9z3y5ycjn.png" alt="Image description" width="800" height="536"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Invoke the creation of a custom domain name with the Ingress endpoints.&lt;/p&gt;

&lt;p&gt;👉🏻 /&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv22proi5epbma9msetl1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv22proi5epbma9msetl1.png" alt="Image description" width="800" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉🏻/metrics&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8upyxpvgjh0o0q7k51li.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8upyxpvgjh0o0q7k51li.png" alt="Image description" width="800" height="253"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉🏻/error&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F90j84i6xpb3jgcm2im66.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F90j84i6xpb3jgcm2im66.png" alt="Image description" width="800" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Troubleshooting&lt;/strong&gt;&lt;br&gt;
If you encounter any issues, refer to the AWS documentation or raise an issue in this repository.&lt;/p&gt;

&lt;p&gt;🏴‍☠️ source link: &lt;a href="https://github.com/ravindrasinghh/Kubernetes-Playlist/tree/master" rel="noopener noreferrer"&gt;https://github.com/ravindrasinghh/Kubernetes-Playlist/tree/master&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you prefer a video tutorial to help guide you to Integrate API Gateway with AWS EKS NLB&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/GSrNcQzaKe4"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>apigateway</category>
      <category>eks</category>
      <category>aws</category>
      <category>ingress</category>
    </item>
    <item>
      <title>Install NGINX Ingress Controller in AWS EKS</title>
      <dc:creator>Ravindra Singh</dc:creator>
      <pubDate>Sat, 14 Sep 2024 09:38:13 +0000</pubDate>
      <link>https://dev.to/aws-builders/install-nginx-ingress-controller-in-aws-eks-3cf</link>
      <guid>https://dev.to/aws-builders/install-nginx-ingress-controller-in-aws-eks-3cf</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This lesson covers the steps to install and configure an NGINX Ingress Controller in your EKS cluster, enabling you to manage external access to your Kubernetes services.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;What is an Ingress Controller?&lt;/strong&gt;&lt;br&gt;
An Ingress is an API object that defines rules for routing external HTTP and HTTPS traffic to services within your cluster. An Ingress Controller is a software component that implements those rules, acting as a reverse proxy and load balancer for your applications.&lt;/p&gt;

&lt;p&gt;GIT LINK: &lt;a href="https://github.com/ravindrasinghh/Kubernetes-Playlist" rel="noopener noreferrer"&gt;https://github.com/ravindrasinghh/Kubernetes-Playlist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3dodp5wq9jutdw7s0pqx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3dodp5wq9jutdw7s0pqx.png" alt="Image description" width="800" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How nginx ingress controller works ?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ingress Resource Creation:&lt;/strong&gt; You create an Ingress resource in your Kubernetes cluster, specifying how you want to expose your applications to external traffic. This includes details like the hostnames to match, paths to route, and the services to direct traffic to.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Controller Monitoring:&lt;/strong&gt; The Nginx Ingress Controller continuously monitors the Kubernetes API server for changes to Ingress resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Configuration Generation:&lt;/strong&gt; When it detects new or updated Ingress resources, the controller generates an Nginx configuration file based on the specified rules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Configuration Update:&lt;/strong&gt; The controller updates the running Nginx pods with the new configuration file.&lt;br&gt;
Traffic Routing: Nginx acts as a reverse proxy, receiving incoming traffic and routing it to the appropriate backend services based on the Ingress rules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Load Balancing:&lt;/strong&gt; Nginx load balances traffic across multiple pods of the same service, ensuring efficient resource utilization and high availability.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Key points about the Nginx Ingress Controller's operation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Constant Monitoring:&lt;/strong&gt; The controller continuously monitors the Kubernetes API server for changes to Ingress resources, ensuring Nginx's configuration stays up-to-date with your desired state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dynamic Configuration:&lt;/strong&gt; Nginx configuration is generated dynamically based on Ingress rules, allowing for flexible traffic routing and load balancing&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use an ALB when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;You need advanced HTTP/HTTPS routing:&lt;/strong&gt; ALBs operate at Layer 7 (Application Layer), allowing you to route traffic based on various HTTP/HTTPS attributes like host headers, path patterns, query parameters, and even HTTP methods. This makes them ideal for microservices architectures where different services may need to be exposed on the same IP address but with distinct paths or hostnames.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;You need features like WebSockets, HTTP/2, or gRPC:&lt;/strong&gt; ALBs fully support these protocols, making them suitable for applications requiring these advanced features.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use an NLB when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;You need high-performance TCP/UDP load balancing:&lt;/strong&gt; They are a great fit for applications requiring extreme throughput and responsiveness, like gaming servers, streaming services, or real-time communication platforms.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;You need to preserve client source IP addresses:&lt;/strong&gt; NLBs preserve the original client IP address, which can be crucial for applications that need to identify and track individual clients.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Let's Begin😎&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🚀** Prerequisites :**&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Terraform:&lt;/strong&gt; Install Terraform by following the official installation guide.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AWS CLI:&lt;/strong&gt; Install and configure the AWS CLI by following the AWS CLI installation guide.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;kubectl:&lt;/strong&gt; Install kubectl for interacting with your EKS cluster by following the kubectl installation guide.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A running Kubernetes cluster:&lt;/strong&gt; This can be a self-managed cluster or a managed service like Amazon EKS.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Refer below video to create the EKS Cluster in AWS&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/vKi6K5ope6c"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Step1: Clone the Repository&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;🧑🏻‍💻git clone &lt;a href="https://github.com/ravindrasinghh/Kubernetes-Playlist.git" rel="noopener noreferrer"&gt;https://github.com/ravindrasinghh/Kubernetes-Playlist.git&lt;/a&gt;&lt;br&gt;
👨🏻‍💻cd Kubernetes-Playlist/Lesson1/&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Step 2: Please add the below file to NGINX Ingress Controller &lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;👉🏻 nginx.tf&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "helm_release" "ingress-nginx" {
  name             = "ingress-nginx"
  repository       = "https://kubernetes.github.io/ingress-nginx"
  chart            = "ingress-nginx"
  namespace        = "ingress-nginx"
  create_namespace = true
  version          = "4.10.0"
  values           = [file("./nginx.yaml")]
  set {
    name  = "controller.service.annotations.service\\.beta\\.kubernetes\\.io/aws-load-balancer-ssl-cert"
    value = module.acm_backend.acm_certificate_arn
    type  = "string"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉🏻 nginx.yaml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;controller:
  replicaCount: 2
  minAvailable: 1
  resources:
    limits:
      cpu: 500m
      memory: 512Mi
    requests:
      cpu: 100m
      memory: 256Mi
  autoscaling:
    enabled: true
    annotations: {}
    minReplicas: 2
    maxReplicas: 6
    targetCPUUtilizationPercentage: 70
    targetMemoryUtilizationPercentage: 80
    behavior:
     scaleDown:
       stabilizationWindowSeconds: 60
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  service:
    annotations:
      service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
      service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: 'true'
      service.beta.kubernetes.io/aws-load-balancer-type: nlb
      service.beta.kubernetes.io/aws-load-balancer-ssl-ports: https
      service.beta.kubernetes.io/aws-load-balancer-ssl-negotiation-policy: 'ELBSecurityPolicy-TLS13-1-2-2021-06'
      service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
    targetPorts:
      http: http
      https: http
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Initialize Terraform
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;terraform init&lt;/li&gt;
&lt;li&gt;terraform plan&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldzmypufzcd0d3znfnkr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldzmypufzcd0d3znfnkr.png" alt="Image description" width="800" height="691"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;terraform apply&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuozjj4y7r9245ixe9qn5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuozjj4y7r9245ixe9qn5.png" alt="Image description" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Verifying the Installation
&lt;/h2&gt;

&lt;p&gt;After installation, verify that the Nginx Ingress Controller is running correctly. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;kubectl get pods -n ingress-nginx&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fke0xe245kykhtqeap38h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fke0xe245kykhtqeap38h.png" alt="Image description" width="800" height="113"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;kubectl logs ingress-nginx-controller-74fb489d8f-jpvgs -n ingress-nginx&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fapgikybg3ebb6fhwti4t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fapgikybg3ebb6fhwti4t.png" alt="Image description" width="800" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;kubectl get svc -n ingress-nginx&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw38246db0fvqov2gl99i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw38246db0fvqov2gl99i.png" alt="Image description" width="800" height="46"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Access the Load Balancer IP, and if you receive a '404 Not Found' message, that's the expected outcome.&lt;/strong&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu6fslwozrbywgy6cbi2n.png" alt="Image description" width="800" height="144"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step5: Creating an Ingress YAML File
&lt;/h2&gt;

&lt;p&gt;Let's create a basic Ingress resource to expose a service named photoap on the hostname photoapp.codedevops.cloud:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  selector:
    matchLabels:
      app: myapp
  replicas: 1
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - image: ravindrasingh6969/nodeapp:latest
        name: myapp
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  ports:
  - port: 80 #service port  #kubeproxy will open port on worker node to which can route traffic to alb
    targetPort: 8080 #container port
    protocol: TCP
  type: ClusterIP
  selector:
    app: myapp
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp
  annotations:
    # Ingress class to use the NGINX Ingress Controlle
    # AWS-specific annotations for SSL and the load balancer
    alb.ingress.kubernetes.io/scheme: "internet-facing"
    alb.ingress.kubernetes.io/target-type: "ip"
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:ap-south-1:434605749312:certificate/0245c0a5-0867-4372-8206-4a5e4ceda0bd"
    alb.ingress.kubernetes.io/ssl-redirect: '443'
spec:
  ingressClassName: nginx
  rules:
    - host: myapp.codedevops.cloud
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: myapp
                port:
                  number: 80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Additional Paths:&lt;/strong&gt; I added /health, /status, and /api/v1 as additional paths to route traffic to the myapp service on port 80.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Single Host:&lt;/strong&gt; The configuration uses a single host &lt;br&gt;
(myapp.ravindra.tech) to handle multiple paths.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Uniform Backend Service:&lt;/strong&gt; All paths are routed to the same backend service (myapp), which listens on port 80.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This setup will handle requests for the specified paths (/, /ping, /metrics, /health, /status, /api/v1) and route them to the myapp service on port 80, providing flexibility for different endpoints within your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Records in Route 53
&lt;/h2&gt;

&lt;p&gt;To make your application accessible via the hostname specified in the Ingress, you'll need to create a DNS record in Route 53, Amazon's managed DNS service.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Create a Hosted Zone:&lt;/strong&gt; If you don't have one already, create a hosted zone for your domain (e.g., codedevops.cloud) in Route 53.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Create an A Record:&lt;/strong&gt; Create an A record within your hosted zone, pointing the hostname (myapp.codedevops.cloud) to the external IP address of the Nginx Ingress Controller's Service. You can obtain this IP/ARN using kubectl get service -n ingress-nginx.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft41vz0s5q9vwftibgvwh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft41vz0s5q9vwftibgvwh.png" alt="Image description" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Hit Public Domain for the verification
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://myapp.codedevops.cloud/ping" rel="noopener noreferrer"&gt;https://myapp.codedevops.cloud/ping&lt;/a&gt;&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0dp4tsk1hp20k3udlpbf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0dp4tsk1hp20k3udlpbf.png" alt="Image description" width="800" height="230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://myapp.codedevops.cloud/metrics" rel="noopener noreferrer"&gt;https://myapp.codedevops.cloud/metrics&lt;/a&gt;&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhno4l564gz6vmeqsyu9a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhno4l564gz6vmeqsyu9a.png" alt="Image description" width="800" height="537"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://myapp.codedevops.cloud/error" rel="noopener noreferrer"&gt;https://myapp.codedevops.cloud/error&lt;/a&gt;&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuuxn572r1l570quj3olm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuuxn572r1l570quj3olm.png" alt="Image description" width="800" height="198"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Troubleshooting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you encounter any issues, refer to the Nginx ingress documentation or raise an issue in this repository.&lt;/p&gt;

&lt;p&gt;🏴‍☠️ &lt;strong&gt;source link:&lt;/strong&gt; &lt;a href="https://github.com/ravindrasinghh/Kubernetes-Playlist/tree/master" rel="noopener noreferrer"&gt;https://github.com/ravindrasinghh/Kubernetes-Playlist/tree/master&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you prefer a video tutorial to help guide you Install NGINX Ingress Controller in AWS EKS&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/PYO0OFYNI5A"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>ingress</category>
      <category>aws</category>
      <category>eks</category>
      <category>nginx</category>
    </item>
  </channel>
</rss>
