<?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: sanjay yadav</title>
    <description>The latest articles on DEV Community by sanjay yadav (@sanjay_yadav_).</description>
    <link>https://dev.to/sanjay_yadav_</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%2F3902053%2Ff2660aca-b937-4ed0-aa7c-c58c559b48b0.jpg</url>
      <title>DEV Community: sanjay yadav</title>
      <link>https://dev.to/sanjay_yadav_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sanjay_yadav_"/>
    <language>en</language>
    <item>
      <title>Most Teams Don't Move to Amazon RDS for Performance</title>
      <dc:creator>sanjay yadav</dc:creator>
      <pubDate>Fri, 29 May 2026 05:19:50 +0000</pubDate>
      <link>https://dev.to/sanjay_yadav_/most-teams-dont-move-to-amazon-rds-for-performance-41l8</link>
      <guid>https://dev.to/sanjay_yadav_/most-teams-dont-move-to-amazon-rds-for-performance-41l8</guid>
      <description>&lt;p&gt;You’ve decided to move your applications from on-premises to AWS and are looking at the cloud services that best meet your needs. When moving an application with a relational database like Oracle, MySQL, or SQL Server to the cloud, you'll face the choice between Amazon RDS and AWS EC2.&lt;/p&gt;

&lt;p&gt;You need to decide whether to:&lt;/p&gt;

&lt;p&gt;Use AWS’s Relational Database Service (RDS)&lt;br&gt;
Host a database server on an AWS EC2 (Elastic Compute) instance&lt;/p&gt;

&lt;h2&gt;
  
  
  What is AWS RDS?
&lt;/h2&gt;

&lt;p&gt;Amazon Relational Database Service (Amazon RDS) is a managed Database-as-a-Service (DBaaS) that helps IT administrators easily set up, run, and scale relational databases in the cloud. RDS supports popular database engines like MySQL, MariaDB, PostgreSQL, Oracle, and Microsoft SQL Server.&lt;/p&gt;

&lt;p&gt;When moving to the cloud, most applications using these databases can switch to Amazon RDS without much hassle. You can choose different database instance types based on your needs for CPU, memory, storage, and networking. With Amazon RDS, Amazon takes care of tasks like provisioning, setup, patching, backup, recovery, and failure repair, saving your team from these time-consuming tasks.&lt;/p&gt;

&lt;p&gt;Amazon RDS automatically backs up your databases every 24 hours, ensuring that in the worst case, you can recover data for up to 24 hours. With a multi-region active-active strategy, you can achieve near-zero data loss and minimal recovery time. Routine patching is also automated with set maintenance windows for security. On top of this it also supports PITR recovery so you can get back your database to any particular timestamp in last 7 days. &lt;/p&gt;

&lt;p&gt;RDS allows you to have read replicas in zones closer to your users, which increases read capacity and reduces the load on production servers by routing read queries to the replicas. You can also send heavy queries to read replicas to lessen the burden on your main servers.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Amazon EC2?
&lt;/h2&gt;

&lt;p&gt;Amazon Elastic Compute Cloud (EC2) is a web service that gives you secure access to server instances when you need them. It's easy to get and set up capacity – just use the Amazon EC2 web service interface to add capacity as needed.&lt;/p&gt;

&lt;p&gt;You have full control over your computing resources and can scale up or down based on your needs. To provide database services for your application, you can set up EC2 instances and install the necessary database engines yourself.&lt;/p&gt;

&lt;p&gt;Next, let’s look at the pros and cons of choosing between Amazon RDS and EC2 for your database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Administration
&lt;/h2&gt;

&lt;p&gt;When it comes to administration, Amazon RDS is easy to set up because AWS automates the entire process of management, maintenance, and security, allowing you to focus on essential tasks instead of routine maintenance. You can access its capabilities through the AWS Management Console, AWS RDS command-line interface, or simple REST API calls. &lt;/p&gt;

&lt;p&gt;AWS EC2 gives you full control over the OS, database version, configuration, and other software components, but you are responsible for all routine maintenance activities, including patches, upgrades, backups, replication, and clustering.&lt;/p&gt;

&lt;h2&gt;
  
  
  High Availability
&lt;/h2&gt;

&lt;p&gt;Amazon RDS has built-in high availability. It automatically creates a primary database instance and replicates the data to a standby instance in a different Amazon Availability Zone. This ensures that if there is an outage in one zone, you can recover your database from the other zone.&lt;/p&gt;

&lt;p&gt;On the other hand, with AWS EC2, you are responsible for configuring the database server in a highly available cluster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Backups
&lt;/h2&gt;

&lt;p&gt;With Amazon RDS, you can set up automated backups. AWS CloudWatch can notify you about backup failures, completions, and more. You can also get database snapshots on-demand and keep them as long as you need. &lt;/p&gt;

&lt;p&gt;With AWS EC2, you have to enable backups yourself and set up separate monitoring to ensure regular backups. You cannot use AWS CloudWatch for this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scalability
&lt;/h2&gt;

&lt;p&gt;Amazon RDS easily integrates with Amazon’s scaling tools for both vertical and horizontal scaling. You can scale up to a larger instance in a few clicks, and you can automate the creation of additional read replicas to handle increased read-only workloads. &lt;/p&gt;

&lt;p&gt;With AWS EC2, you have to set up a scalable architecture manually, which includes setting up multiple EC2 instances, load balancing, configuring Availability Groups, and Sharding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance
&lt;/h2&gt;

&lt;p&gt;With Amazon RDS, you can configure your instance with a specific number of provisioned IOPS for fast and consistent performance, though it can be expensive. RDS integrates with Amazon CloudWatch for monitoring database performance. &lt;/p&gt;

&lt;p&gt;With AWS EC2, you need to choose the right storage volume for the IOPS and latency you need. Since the database server is not AWS-managed, you cannot use AWS CloudWatch for performance monitoring and need to use third-party tools instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Storage
&lt;/h2&gt;

&lt;p&gt;With Amazon RDS, you have three storage options:&lt;/p&gt;

&lt;p&gt;General-purpose SSD: Cost-effective, delivers single-digit millisecond latencies, and handles up to 3,000 IOPS.&lt;br&gt;
Provisioned IOPS: Ideal for database-intensive workloads needing low latency and very high IOPS throughput.&lt;br&gt;
Magnetic: Supports magnetic storage for backward compatibility.&lt;br&gt;
With AWS EC2, the IOPS and latency depend on the instance type. You can get up to 16,000 IOPS and 2,000 Mbps with the right EBS-optimized instance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Support and Control
&lt;/h2&gt;

&lt;p&gt;With Amazon RDS, you are limited to the database engines and versions supported by Amazon. Amazon manages upgrades and patches, so you don't handle the database server directly. You have access to database administration tools for necessary tasks.&lt;/p&gt;

&lt;p&gt;With AWS EC2, you can install any database engine and version you want, without being limited by AWS's RDS support. You have full control over the operating system and the database server. You can apply updates and patches, set maintenance windows, run multiple instances on the same EC2 instance, and control the ports used.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security
&lt;/h2&gt;

&lt;p&gt;Amazon RDS offers encryption both at rest and in transit. This means the storage for database instances, read replicas, automated backups, and snapshots are all encrypted while stored. &lt;/p&gt;

&lt;p&gt;In AWS EC2, encryption is handled at the EBS volume level, and you can also configure encryption at the database level.&lt;/p&gt;

&lt;h2&gt;
  
  
  Licensing
&lt;/h2&gt;

&lt;p&gt;Amazon RDS offers both “License Included” and “Bring-Your-Own-License (BYOL)” models, depending on the database engine. &lt;/p&gt;

&lt;p&gt;For example, Oracle RDS allows you to bring your license, but Amazon RDS for SQL Server only supports the “License Included” model. You cannot bring your SQL licenses to RDS, as SQL Server is licensed through AWS.&lt;/p&gt;

&lt;p&gt;With AWS EC2, you can bring your database licenses regardless of the database engine.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cost
&lt;/h3&gt;

&lt;p&gt;Spending depends on the instance type, and you can use the AWS Cost Calculator to get detailed costs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Amazon RDS:
&lt;/h3&gt;

&lt;p&gt;Usually more expensive because Amazon handles routine management tasks for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS EC2:
&lt;/h3&gt;

&lt;p&gt;Generally cheaper since you manage the database server yourself.&lt;br&gt;
You are responsible for tasks like backup, recovery, patching, and load management.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Choose Between AWS RDS and Amazon EC2
&lt;/h2&gt;

&lt;p&gt;Choosing between a database on an EC2 instance and RDS means deciding between managing everything yourself and using a managed service where AWS handles routine tasks. With RDS, a simple API call gives you control over deployment, backups, snapshots, restores, sizing, high availability, and replicas.&lt;/p&gt;

&lt;p&gt;In contrast, using EC2 means you need to manually set up, configure, manage, and tune components like EC2 instances, storage, scalability, networking, and security.&lt;/p&gt;

&lt;p&gt;Using RDS reduces management overhead and increases flexibility and automation. You can use automated CI/CD systems with AWS CLI, CDK, and CloudFormation to deploy the database with minimal manual work. Managed services let you control the infrastructure and design services that are easy to deploy, replicate, and have auto-healing features.&lt;/p&gt;

&lt;p&gt;However, cost is a key factor. Amazon RDS can be slightly more expensive than EC2 for the same configuration. If you have a tight budget or need a database engine or version not supported by RDS, you might have to use an EC2-hosted database.&lt;/p&gt;

&lt;p&gt;At KuebOps Consulting, we highly recommend using RDS instances over EC2 for database to our clients. The additional cost that you pay almost always saves a lot more money than what you would spend on managing and scaling the database yourself on an EC2 instance. &lt;/p&gt;

&lt;h2&gt;
  
  
  Read More
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.kubeblogs.com/route-53-dns-firewall-aws-egress-security/" rel="noopener noreferrer"&gt;Route 53 DNS Firewall: Block Malware Across Your VPC&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.kubeblogs.com/fixing-504-errors-in-gke-load-balancer-how-backendconfig-solved-our-30-second-timeout-problem/" rel="noopener noreferrer"&gt;Fix 504 Errors in GKE Load Balancer (BackendConfig Guide)&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.kubeblogs.com/how-we-use-airflow-to-optimize-our-devops-workflow/" rel="noopener noreferrer"&gt;How We Use Airflow to Optimize Our DevOps Workflow&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>database</category>
      <category>devops</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Database Performance Discussions Usually Change Once Infrastructure Costs Start Scaling</title>
      <dc:creator>sanjay yadav</dc:creator>
      <pubDate>Thu, 28 May 2026 04:47:03 +0000</pubDate>
      <link>https://dev.to/sanjay_yadav_/database-performance-discussions-usually-change-once-infrastructure-costs-start-scaling-48j</link>
      <guid>https://dev.to/sanjay_yadav_/database-performance-discussions-usually-change-once-infrastructure-costs-start-scaling-48j</guid>
      <description>&lt;p&gt;At smaller scale, managed databases usually feel interchangeable.&lt;/p&gt;

&lt;p&gt;The application works.&lt;br&gt;
Queries run.&lt;br&gt;
Everything seems fine.&lt;/p&gt;

&lt;p&gt;But once workloads grow and infrastructure costs start increasing, database discussions become much more operational than people initially expect.&lt;/p&gt;

&lt;p&gt;Storage performance.&lt;br&gt;
IOPS limits.&lt;br&gt;
Latency.&lt;br&gt;
Cost scaling.&lt;/p&gt;

&lt;p&gt;That’s usually where infrastructure tradeoffs start becoming impossible to ignore.&lt;/p&gt;

&lt;p&gt;The pricing usually looks straightforward until higher performance tiers start becoming unavoidable.&lt;/p&gt;

&lt;p&gt;In practice, performance discussions usually turn into infrastructure efficiency discussions pretty quickly.&lt;/p&gt;

&lt;p&gt;I found this benchmark useful because it compares AWS RDS and Civo Postgres from both the performance and operational cost perspective instead of only comparing monthly cost numbers:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.kubeblogs.com/aws-rds-vs-civo-postgres-benchmark/" rel="noopener noreferrer"&gt;https://www.kubeblogs.com/aws-rds-vs-civo-postgres-benchmark/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>devops</category>
      <category>cloud</category>
      <category>aws</category>
    </item>
    <item>
      <title>Kubernetes Observability Usually Gets More Complicated Before It Gets Better</title>
      <dc:creator>sanjay yadav</dc:creator>
      <pubDate>Mon, 25 May 2026 05:08:11 +0000</pubDate>
      <link>https://dev.to/sanjay_yadav_/kubernetes-observability-usually-gets-more-complicated-before-it-gets-better-2eje</link>
      <guid>https://dev.to/sanjay_yadav_/kubernetes-observability-usually-gets-more-complicated-before-it-gets-better-2eje</guid>
      <description>&lt;p&gt;Logs are easy at the beginning.&lt;/p&gt;

&lt;p&gt;Production observability usually isn’t.&lt;/p&gt;

&lt;p&gt;One pattern that shows up often in Kubernetes environments is teams adding more monitoring components over time and slowly ending up with more complexity than expected.&lt;/p&gt;

&lt;p&gt;More agents.&lt;br&gt;
More pipelines.&lt;br&gt;
More moving parts.&lt;/p&gt;

&lt;p&gt;Collecting telemetry is usually not the hard part.&lt;/p&gt;

&lt;p&gt;Keeping observability systems manageable as infrastructure grows is where things get difficult.&lt;/p&gt;

&lt;p&gt;That’s why tooling discussions usually become much more operational than feature comparisons.&lt;/p&gt;

&lt;p&gt;Especially once infrastructure starts growing and operational overhead becomes harder to ignore.&lt;/p&gt;

&lt;p&gt;I found this breakdown useful because it compares Fluent Bit and Grafana Alloy from a Kubernetes observability perspective instead of treating it as only a tooling comparison:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.kubeblogs.com/fluent-bit-vs-grafana-alloy-kubernetes-observability-2026/" rel="noopener noreferrer"&gt;https://www.kubeblogs.com/fluent-bit-vs-grafana-alloy-kubernetes-observability-2026/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>Terraform with AI: Build AWS Infra (Cursor + MCP)</title>
      <dc:creator>sanjay yadav</dc:creator>
      <pubDate>Sat, 23 May 2026 05:21:24 +0000</pubDate>
      <link>https://dev.to/sanjay_yadav_/terraform-with-ai-build-aws-infra-cursor-mcp-4hga</link>
      <guid>https://dev.to/sanjay_yadav_/terraform-with-ai-build-aws-infra-cursor-mcp-4hga</guid>
      <description>&lt;h2&gt;
  
  
  Why Terraform with AI Matters in Modern DevOps
&lt;/h2&gt;

&lt;p&gt;Writing Terraform for anything beyond a small setup quickly becomes tedious.&lt;br&gt;
Once you start dealing with multiple modules, cross-resource dependencies, and AWS-specific quirks, the workflow slows down. Most of the time isn’t spent writing code — it’s spent checking documentation, fixing edge cases, and rerunning terraform apply.&lt;br&gt;
Many teams are now experimenting with Terraform with AI to speed this up.&lt;br&gt;
In practice, that only works partially — unless the AI has proper context.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;&lt;a href="https://www.youtube.com/watch?v=XlZfgCC5vcI" rel="noopener noreferrer"&gt;Build Complete AWS Infrastructure with Terraform MCP Server and Cursor AI - Full Tutorial&lt;/a&gt;&lt;/strong&gt;
&lt;/h2&gt;
&lt;h2&gt;
  
  
  How Terraform workflows traditionally worked
&lt;/h2&gt;

&lt;p&gt;A typical workflow looks like this:&lt;br&gt;
Read Terraform docs&lt;br&gt;
Write modules and resources manually&lt;br&gt;
Run terraform plan&lt;br&gt;
Fix errors&lt;br&gt;
Repeat&lt;br&gt;
For small setups, this is manageable.&lt;br&gt;
For production infrastructure, it becomes repetitive and slow. Most engineers end up switching between Terraform registry docs, AWS docs, and their codebase constantly.&lt;/p&gt;
&lt;h2&gt;
  
  
  Limitations of Using Terraform with AI Without Context
&lt;/h2&gt;

&lt;p&gt;The obvious idea is to use AI to generate Terraform.&lt;br&gt;
In most cases, it starts like this:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Generate Terraform for a VPC with public and private subnets”&lt;/em&gt;&lt;br&gt;
You do get output. But:&lt;/p&gt;

&lt;p&gt;It may use outdated arguments&lt;br&gt;
It ignores your module structure&lt;br&gt;
Dependencies are incomplete&lt;br&gt;
It often fails during terraform apply&lt;br&gt;
👉 The core issue: &lt;strong&gt;AI does not understand your infrastructure context&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Our First Attempt (RAG Failure) (Late 2024 - before advent of modern agents)
&lt;/h2&gt;

&lt;p&gt;To solve this, we built an internal tool using:&lt;/p&gt;

&lt;p&gt;Vector database&lt;br&gt;
RAG (Retrieval-Augmented Generation)&lt;br&gt;
The idea was to fetch Terraform documentation and index it in a vector database and provide it to an agent&lt;br&gt;
It helped slightly — but failed in practice:&lt;/p&gt;

&lt;p&gt;Iteration was difficult - terraform plan and apply loop - fix errors&lt;br&gt;
Context size limitations&lt;br&gt;
No awareness of project structure&lt;br&gt;
Could not refine outputs&lt;br&gt;
It generated code, but only for simple infrastructure. For complex ones it used to fail after a few iterations.&lt;/p&gt;

&lt;p&gt;We didn't try to optimise it further because while we were in middle of it - cursor agents became extremely powerful and they pretty much solved this iteration problem.&lt;/p&gt;
&lt;h2&gt;
  
  
  What changed with MCP Server + Cursor
&lt;/h2&gt;

&lt;p&gt;The behavior changed once we introduced Terraform MCP Server and used it with Cursor.&lt;br&gt;
Instead of generating code blindly, the system now had access to:&lt;/p&gt;

&lt;p&gt;Terraform module documentation&lt;br&gt;
Input/output structures&lt;br&gt;
Resource relationships&lt;br&gt;
The difference was noticeable.&lt;br&gt;
The output was not perfect — but much closer to something usable.&lt;/p&gt;
&lt;h2&gt;
  
  
  How MCP actually changes the workflow
&lt;/h2&gt;

&lt;p&gt;At a high level, MCP acts as a bridge between the editor (Cursor) and Terraform context.&lt;br&gt;
Instead of guessing, the AI can:&lt;/p&gt;

&lt;p&gt;Look up module definitions&lt;br&gt;
Understand required inputs&lt;br&gt;
Follow dependencies across resources&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%2Fmb3f5jlrakd2005c48wd.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%2Fmb3f5jlrakd2005c48wd.png" alt=" " width="800" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the key difference from standard AI usage.&lt;/p&gt;
&lt;h2&gt;
  
  
  ⚙️ What MCP Server Actually Does Internally
&lt;/h2&gt;

&lt;p&gt;The improvement with MCP is not just better prompting — it’s access to structured Terraform knowledge.&lt;br&gt;
The MCP server exposes tools that allow the AI to query real Terraform data:&lt;/p&gt;
&lt;h3&gt;
  
  
  Key MCP Capabilities:
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Provider Documentation Lookup
&lt;/h4&gt;

&lt;p&gt;Fetches full documentation for resources, data sources, and functions&lt;/p&gt;
&lt;h4&gt;
  
  
  Module Discovery
&lt;/h4&gt;

&lt;p&gt;Finds Terraform modules from the registry with usage examples&lt;/p&gt;
&lt;h4&gt;
  
  
  Module Details
&lt;/h4&gt;

&lt;p&gt;Retrieves inputs, outputs, and configuration patterns&lt;/p&gt;
&lt;h4&gt;
  
  
  Policy Search
&lt;/h4&gt;

&lt;p&gt;Helps identify best practices and security policies&lt;br&gt;
👉 In simple terms:&lt;br&gt;
Instead of guessing, the AI can &lt;strong&gt;look things up like an engineer would&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Terraform with AI vs Manual vs MCP (Comparison)
&lt;/h2&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%2F74yzya09v8ew48jxd46a.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%2F74yzya09v8ew48jxd46a.png" alt=" " width="772" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In practice, most teams try AI first, then realize that without context, results are unreliable. MCP fixes that gap.&lt;/p&gt;
&lt;h2&gt;
  
  
  A practical example: building AWS infrastructure
&lt;/h2&gt;

&lt;p&gt;Let’s take a realistic setup:&lt;/p&gt;

&lt;p&gt;VPC with public and private subnets&lt;br&gt;
NAT Gateway and Internet Gateway&lt;br&gt;
Application Load Balancer&lt;br&gt;
Auto Scaling group (EC2)&lt;br&gt;
CloudFront distribution&lt;br&gt;
Cloudflare DNS&lt;br&gt;
Jump box for access&lt;br&gt;
This is a typical production-style setup.&lt;br&gt;
Writing this manually takes time — especially when wiring dependencies correctly.&lt;/p&gt;
&lt;h3&gt;
  
  
  How we approached it
&lt;/h3&gt;

&lt;p&gt;Instead of writing everything manually, we broke the problem into smaller steps and guided the AI.&lt;/p&gt;
&lt;h2&gt;
  
  
  🧠 Full Prompt Used for Infrastructure Generation
&lt;/h2&gt;

&lt;p&gt;Instead of vague prompts, we used a structured, step-by-step approach to guide the AI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start code generation. Do it step by step. Move to next step only after the current step is complete.

Step: Create VPC and Network Infrastructure - use vpc module
- Create VPC with appropriate CIDR block
- Create public and private subnets across 2 AZs
- Set up Internet Gateway
- Configure NAT Gateways in public subnets
- Configure route tables for public/private subnets

Step: Create Security Groups
- ALB security group (allow HTTP/HTTPS inbound)
- EC2 security group 
    - allow traffic from ALB
    - allow ssh from the vpc
- Allow all outbound traffic

Step: Create Auto Scaling Group - use autoscaling module
- Create launch template for EC2 instances
- Use ubuntu ami for the instances
- Configure ASG across private subnets
- Use keypair named "vikas-aws"
- Add a user data script to install nginx and create a simple html page

Step: Create a jumpbox
- Create a jumpbox in the public subnet
- Ensure it has a public IP
- Allow SSH from internet

Step: Create Application Load Balancer - use alb module
- Create ALB in public subnets
- Configure HTTP listener
- Attach to autoscaling group

Step: CloudFront Distribution
- Configure CloudFront with ALB as origin
- Set caching TTL to 0

Step: DNS Configuration
- DNS handled via Cloudflare (no route53)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In practice, breaking the problem into steps like this improves output quality significantly compared to single prompts.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the generated Terraform looked like
&lt;/h2&gt;

&lt;p&gt;A simplified example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="s2"&gt;"vpc"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"terraform-aws-modules/vpc/aws"&lt;/span&gt;
  &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"5.0.0"&lt;/span&gt;

  &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"demo-vpc"&lt;/span&gt;
  &lt;span class="nx"&gt;cidr&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.0/16"&lt;/span&gt;

  &lt;span class="nx"&gt;azs&lt;/span&gt;             &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1b"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;public_subnets&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"10.0.1.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"10.0.2.0/24"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;private_subnets&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"10.0.3.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"10.0.4.0/24"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="nx"&gt;enable_nat_gateway&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;single_nat_gateway&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This wasn’t perfect out of the box, but:&lt;/p&gt;

&lt;p&gt;Structure was correct&lt;br&gt;
Inputs were mostly valid&lt;br&gt;
Dependencies were aligned&lt;br&gt;
That already saves a significant amount of time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually improved (based on usage)
&lt;/h2&gt;

&lt;p&gt;From real usage:&lt;/p&gt;

&lt;h4&gt;
  
  
  Before:
&lt;/h4&gt;

&lt;p&gt;2–4 hours to assemble infra&lt;br&gt;
Multiple documentation lookups&lt;br&gt;
Several failed applies&lt;/p&gt;

&lt;h4&gt;
  
  
  After:
&lt;/h4&gt;

&lt;p&gt;Initial setup generated in minutes&lt;br&gt;
Fewer structural errors&lt;br&gt;
Faster iteration&lt;br&gt;
In most teams, the biggest gain is reduced context switching.&lt;/p&gt;

&lt;h2&gt;
  
  
  Operational considerations
&lt;/h2&gt;

&lt;p&gt;This approach still requires discipline:&lt;/p&gt;

&lt;p&gt;Always run terraform plan&lt;br&gt;
Review changes carefully&lt;br&gt;
Do not trust generated code blindly&lt;br&gt;
IAM policies and security configurations must always be reviewed manually.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Terraform with AI Works Best
&lt;/h2&gt;

&lt;p&gt;In most teams, this approach works well when:&lt;/p&gt;

&lt;p&gt;You are building new infrastructure&lt;br&gt;
You need to scaffold modules quickly&lt;br&gt;
You want to reduce repetitive work&lt;br&gt;
It is less effective when used blindly or without validation.&lt;/p&gt;

&lt;h2&gt;
  
  
  When not to use this approach
&lt;/h2&gt;

&lt;p&gt;Avoid relying on it when:&lt;/p&gt;

&lt;p&gt;Infrastructure requires strict compliance&lt;br&gt;
You don’t understand the generated code&lt;br&gt;
You need deterministic, audited configurations&lt;br&gt;
This is not a replacement for Terraform expertise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this fits in a DevOps workflow
&lt;/h2&gt;

&lt;p&gt;This approach integrates naturally with:&lt;/p&gt;

&lt;p&gt;Git-based workflows&lt;br&gt;
CI/CD pipelines&lt;br&gt;
Infrastructure reviews&lt;br&gt;
The deployment process does not change — only the way code is written.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h4&gt;
  
  
  What is Terraform with AI?
&lt;/h4&gt;

&lt;p&gt;Terraform with AI refers to using AI tools to generate and manage infrastructure code more efficiently.&lt;/p&gt;

&lt;h4&gt;
  
  
  What is Terraform MCP Server?
&lt;/h4&gt;

&lt;p&gt;It provides AI tools with Terraform context, including modules and documentation.&lt;/p&gt;

&lt;h4&gt;
  
  
  Is AI-generated Terraform safe for production?
&lt;/h4&gt;

&lt;p&gt;Yes, but only after proper validation and review.&lt;/p&gt;

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

&lt;p&gt;Terraform itself hasn’t changed.&lt;br&gt;
What’s changing is how engineers interact with it.&lt;br&gt;
Using Terraform with AI + MCP Server reduces friction in writing infrastructure — especially for repetitive setups.&lt;br&gt;
It doesn’t replace engineering judgment, but it does make the workflow more efficient.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related reading
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.kubeblogs.com/how-civo-kubernetes-routes-pod-traffic-single-egress-ip-explained/" rel="noopener noreferrer"&gt;https://www.kubeblogs.com/how-civo-kubernetes-routes-pod-traffic-single-egress-ip-explained/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.kubeblogs.com/gp3-vs-gp2-ebs-volume-aws/" rel="noopener noreferrer"&gt;https://www.kubeblogs.com/gp3-vs-gp2-ebs-volume-aws/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>aws</category>
      <category>devops</category>
      <category>ai</category>
    </item>
    <item>
      <title>K3s vs Kubernetes (K8s): Performance, Architecture, Use Cases and When to Choose Each</title>
      <dc:creator>sanjay yadav</dc:creator>
      <pubDate>Fri, 22 May 2026 04:50:47 +0000</pubDate>
      <link>https://dev.to/sanjay_yadav_/k3s-vs-kubernetes-k8s-performance-architecture-use-cases-and-when-to-choose-each-ekh</link>
      <guid>https://dev.to/sanjay_yadav_/k3s-vs-kubernetes-k8s-performance-architecture-use-cases-and-when-to-choose-each-ekh</guid>
      <description>&lt;p&gt;K3s and Kubernetes (K8s) are often compared, but they are not direct competitors. They solve different infrastructure problems.&lt;br&gt;
K3s can run in under 200MB of RAM, while a standard Kubernetes cluster can exceed 800MB. This makes the choice highly dependent on your environment and workload.&lt;/p&gt;

&lt;p&gt;This guide explains the key differences between K3s and Kubernetes, focusing on architecture, performance, and real-world DevOps use cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Kubernetes (K8s)
&lt;/h2&gt;

&lt;p&gt;Kubernetes is a container orchestration platform designed to manage large-scale distributed systems.&lt;br&gt;
It provides:&lt;/p&gt;

&lt;p&gt;Automated deployment and scaling&lt;br&gt;
Self-healing infrastructure&lt;br&gt;
Service discovery and load balancing&lt;br&gt;
Kubernetes is widely used in production environments where scalability and reliability are critical.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is K3s
&lt;/h2&gt;

&lt;p&gt;K3s is a lightweight Kubernetes distribution designed for environments with limited resources.&lt;/p&gt;

&lt;p&gt;It simplifies Kubernetes by:&lt;/p&gt;

&lt;p&gt;Packaging components into a single binary&lt;br&gt;
Using lightweight storage (SQLite by default)&lt;br&gt;
Reducing operational complexity&lt;br&gt;
K3s is commonly used in edge computing, IoT, and development environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  K3s vs Kubernetes: Key Differences
&lt;/h2&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%2Fwpqir34qgfprblf5yz1c.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%2Fwpqir34qgfprblf5yz1c.png" alt=" " width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  K3s vs Kubernetes Architecture Comparison
&lt;/h2&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%2Fw1gr33vvhp7n3x4qw8bl.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%2Fw1gr33vvhp7n3x4qw8bl.png" alt=" " width="799" height="628"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  K3s vs Kubernetes Performance Comparison
&lt;/h2&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%2F2nixvrp2r1t08z6khj38.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%2F2nixvrp2r1t08z6khj38.png" alt=" " width="800" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From practical testing, K3s consistently performs better on small instances (1–2GB RAM), while Kubernetes starts showing its strength as workload complexity and scale increase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Observation
&lt;/h2&gt;

&lt;p&gt;In a test cluster:&lt;/p&gt;

&lt;p&gt;K3s used approximately 200MB RAM&lt;br&gt;
Kubernetes used more than 800MB RAM&lt;br&gt;
K3s performs better in constrained environments, while Kubernetes handles high-scale workloads more effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  K3s vs Kubernetes Use Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  When to Use K3s
&lt;/h3&gt;

&lt;p&gt;Edge computing&lt;br&gt;
IoT deployments&lt;br&gt;
CI/CD environments&lt;br&gt;
Local development&lt;/p&gt;

&lt;h3&gt;
  
  
  When to Use Kubernetes
&lt;/h3&gt;

&lt;p&gt;Production systems&lt;br&gt;
Microservices architecture&lt;br&gt;
Multi-cloud deployments&lt;br&gt;
High-traffic applications&lt;br&gt;
A common mistake is adopting full Kubernetes too early. For many small projects or internal tools, K3s can handle the workload with significantly less operational overhead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decision Guide
&lt;/h2&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%2F770cl5vhjm5d5w57jb5y.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%2F770cl5vhjm5d5w57jb5y.png" alt=" " width="799" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  K3s Installation
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;curl -sfL https://get.k3s.io | sh -&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Kubernetes Installation (kubeadm)
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;kubeadm init&lt;/code&gt;&lt;br&gt;
Pros and Cons&lt;/p&gt;

&lt;h2&gt;
  
  
  K3s
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;p&gt;Lightweight&lt;br&gt;
Fast setup&lt;br&gt;
Low resource usage&lt;/p&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;p&gt;Limited scalability&lt;br&gt;
Fewer enterprise features&lt;/p&gt;

&lt;h2&gt;
  
  
  Kubernetes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;p&gt;Highly scalable&lt;br&gt;
Rich ecosystem&lt;br&gt;
Production-grade&lt;/p&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;p&gt;Complex setup&lt;br&gt;
Higher resource usage&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is K3s production ready
&lt;/h3&gt;

&lt;p&gt;K3s is production ready for lightweight workloads, especially in edge and constrained environments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is K3s faster than Kubernetes
&lt;/h3&gt;

&lt;p&gt;K3s has faster startup time and lower resource consumption compared to standard Kubernetes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can K3s replace Kubernetes
&lt;/h3&gt;

&lt;p&gt;K3s is not a replacement for Kubernetes in enterprise environments. It is designed for specific use cases like edge and development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read More
&lt;/h2&gt;

&lt;p&gt;Continue learning with these in-depth guides:&lt;br&gt;
&lt;a href="https://www.kubeblogs.com/kubernetes-architecture-explained" rel="noopener noreferrer"&gt;Kubernetes Architecture Deep Dive (Components Explained)&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.kubeblogs.com/k8s-vs-docker" rel="noopener noreferrer"&gt;K8s vs Docker: Complete Comparison Guide&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.kubeblogs.com/kubernetes-monitoring-tools" rel="noopener noreferrer"&gt;Best Kubernetes Monitoring Tools for DevOps&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;There is no one-size-fits-all choice here, but in most early-stage or resource-constrained setups, K3s is often the more practical starting point.&lt;br&gt;
K3s and Kubernetes are designed for different types of environments, and choosing the right one depends on your specific use case.&lt;br&gt;
K3s is ideal for lightweight workloads, edge computing, and development environments where simplicity and low resource usage are important.&lt;br&gt;
Kubernetes, on the other hand, is built for large-scale, production-grade systems that require high availability, scalability, and a mature ecosystem.&lt;br&gt;
In most modern DevOps workflows, both are used together:&lt;/p&gt;

&lt;p&gt;K3s for development, testing, and edge deployments&lt;br&gt;
Kubernetes for production and high-scale applications&lt;br&gt;
Selecting the right platform is less about features and more about aligning with your infrastructure needs and long-term scalability goals.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>k3s</category>
      <category>kubeblogs</category>
    </item>
    <item>
      <title>Jenkins or GitHub Actions? Deciding the Right CI/CD Tool for Your Workflow</title>
      <dc:creator>sanjay yadav</dc:creator>
      <pubDate>Thu, 21 May 2026 05:27:22 +0000</pubDate>
      <link>https://dev.to/sanjay_yadav_/jenkins-or-github-actions-deciding-the-right-cicd-tool-for-your-workflow-1cc8</link>
      <guid>https://dev.to/sanjay_yadav_/jenkins-or-github-actions-deciding-the-right-cicd-tool-for-your-workflow-1cc8</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Continuous Integration and Delivery is a key part of any software application. Be it a mobile app, a backend app or a website - everything requires CI/CD to make things easier for everyone. From testing and building code to deploying it across environments, CI/CD tools help simplify workflows, reduce manual tasks, and maintain consistency across the development process.&lt;/p&gt;

&lt;p&gt;There are tons of options available in the market when it comes to CICD. Among the many available, Jenkins and GitHub Actions stand out as two of the most popular and effective options. Jenkins has been there for a very long time, is mature and is being used by thousands of teams across the globe.&lt;/p&gt;

&lt;p&gt;On the other hand, GitHub Actions is designed to work naturally within GitHub, is comparatively newer and is tightly bound to Github (which can be a deal breaker for some folks).&lt;/p&gt;

&lt;p&gt;While both are great - which one do you choose? At KubeNine we are inclined towards Github Actions and we’ll tell you why!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Jenkins?
&lt;/h2&gt;

&lt;p&gt;Jenkins is a widely used open-source automation server that helps developers build, test, and deploy applications efficiently. For over a decade, it has been a cornerstone of CI/CD workflows, providing teams with the tools needed to automate repetitive tasks.&lt;/p&gt;

&lt;p&gt;Supported by a massive community, Jenkins offers an extensive plugin library with over 1,800 plugins, allowing it to integrate with a wide range of open-source and enterprise tools to handle diverse automation needs.&lt;/p&gt;

&lt;p&gt;Despite the rise of CI/CD tools like GitLab CI and GitHub Actions, Jenkins is a popular choice among organizations due to its flexibility and extensive capabilities.&lt;/p&gt;

&lt;p&gt;According to the Developer Ecosystem Report, 54% of developers rely on Jenkins for their CI/CD needs, showcasing its enduring relevance in the industry.&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%2Fwvbu8lblq0o3d50ino7y.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%2Fwvbu8lblq0o3d50ino7y.png" alt=" " width="614" height="792"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Below is the architectural diagram of Jenkins:
&lt;/h2&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%2F3o0ed6uvgguytuk8yzfc.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%2F3o0ed6uvgguytuk8yzfc.png" alt=" " width="779" height="794"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is GitHub Actions?
&lt;/h2&gt;

&lt;p&gt;GitHub Actions is an automation tool built directly into GitHub, allowing developers to create workflows for building, testing, and deploying applications.&lt;/p&gt;

&lt;p&gt;It simplifies the process of setting up Continuous Integration (CI) and Continuous Delivery (CD) by using YAML-based configuration files stored in the same repository as the code. Also, its completely managed so the users do not have to worry about setting up and managing any instance. This makes it particularly attractive.&lt;/p&gt;

&lt;p&gt;One of the key strengths of GitHub Actions is its flexibility. Developers can choose from a vast marketplace of pre-built actions that connect with various tools and services, enabling efficient automation without needing to start from scratch.&lt;/p&gt;

&lt;p&gt;GitHub Actions is quickly gaining popularity in the CI/CD space. According to the Developer Ecosystem Report, 51% of developers use GitHub Actions regularly for CI/CD tasks, making it the second most widely adopted tool after Jenkins. Its adoption is especially prominent in personal projects, where 37% of developers rely on it. The simplicity of its setup and its native connection with GitHub repositories make it a go-to choice for many developers and small teams.&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%2Fnk53hltwsldukgm1szkw.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%2Fnk53hltwsldukgm1szkw.png" alt=" " width="601" height="797"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub Actions also plays a significant role in the Software Development Life Cycle (SDLC) by automating repetitive tasks like testing and deployment. This not only saves time but also helps developers maintain focus on coding.&lt;/p&gt;

&lt;h3&gt;
  
  
  Below is the architectural diagram of GitHub Actions, which shows how it operates in a CI/CD pipeline setup:
&lt;/h3&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%2Fce426anor4r6bs5c3vfh.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%2Fce426anor4r6bs5c3vfh.png" alt=" " width="800" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Building and Pushing a Docker Image: Jenkins vs. GitHub Actions
&lt;/h2&gt;

&lt;p&gt;Let’s walk through the process of setting up a pipeline for both Jenkins and GitHub Actions to build a Docker image and push it to a Docker repository. By comparing the steps, we can better understand the ease of use, setup complexity, and overall user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Jenkins: Build and Push Pipeline
&lt;/h2&gt;

&lt;p&gt;We will use Helm to install Jenkins on a Kubernetes cluster and create a pipeline for building and pushing a Docker image.&lt;/p&gt;

&lt;h3&gt;
  
  
  Steps to Install and Configure Jenkins:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Install Jenkins Using Helm
&lt;/h4&gt;

&lt;p&gt;Add the Jenkins Helm repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm repo add jenkins https://charts.jenkins.io helm repo update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install Jenkins on your Kubernetes cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm &lt;span class="nb"&gt;install &lt;/span&gt;jenkins jenkins/jenkins &lt;span class="nt"&gt;--namespace&lt;/span&gt; jenkins &lt;span class="nt"&gt;--create-namespace&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Retrieve the admin password:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;--namespace&lt;/span&gt; jenkins &lt;span class="nt"&gt;-it&lt;/span&gt; svc/jenkins &lt;span class="nt"&gt;-c&lt;/span&gt; jenkins &lt;span class="nt"&gt;--&lt;/span&gt; /bin/cat /run/secrets/chart-admin-password

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

&lt;/div&gt;



&lt;p&gt;Access Jenkins at http://:8080 and log in using the admin credentials.&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%2Fk6nnwavayva19hmp7abo.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%2Fk6nnwavayva19hmp7abo.png" alt=" " width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Install Required Plugins
&lt;/h3&gt;

&lt;p&gt;Go to Manage Jenkins &amp;gt; Plugins and install the required plugins, such as Pipeline and Docker Pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set Up Docker on Jenkins Node
&lt;/h3&gt;

&lt;p&gt;Ensure Docker is installed on the Jenkins agent node.&lt;br&gt;
Add the Jenkins user to the Docker group:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; docker jenkins

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create a Pipeline for Docker Build and Push
&lt;/h3&gt;

&lt;p&gt;In Jenkins, create a new Pipeline item.&lt;br&gt;
Add the following script to your pipeline configuration (replace placeholders with your values):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt;
    &lt;span class="n"&gt;environment&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;DOCKER_USERNAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'docker-username'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;DOCKER_PASSWORD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'docker-password'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;stages&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Checkout'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="nl"&gt;url:&lt;/span&gt; &lt;span class="s1"&gt;'https://github.com/your-username/your-repo.git'&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Build Docker Image'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;sh&lt;/span&gt; &lt;span class="s1"&gt;'docker build -t your-username/your-image:latest .'&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Push to Docker Hub'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;sh&lt;/span&gt; &lt;span class="s1"&gt;'docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD'&lt;/span&gt;
                &lt;span class="n"&gt;sh&lt;/span&gt; &lt;span class="s1"&gt;'docker push your-username/your-image:latest'&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Run the Pipeline
&lt;/h4&gt;

&lt;p&gt;Save the pipeline and click Build Now to execute the steps. Jenkins will:&lt;br&gt;
Pull the source code from your repository.&lt;br&gt;
Build a Docker image.&lt;br&gt;
Push the image to your Docker repository.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting Up GitHub Actions: Build and Push Workflow
&lt;/h2&gt;

&lt;p&gt;GitHub Actions makes it easier to define workflows directly in the repository using YAML files.&lt;/p&gt;
&lt;h3&gt;
  
  
  Steps to Configure GitHub Actions:
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Add a Workflow File
&lt;/h4&gt;

&lt;p&gt;In your repository, create a folder .github/workflows if it doesn’t exist.&lt;br&gt;
Add a file named docker-build-push.yml.&lt;/p&gt;
&lt;h4&gt;
  
  
  Define the Workflow
&lt;/h4&gt;

&lt;p&gt;Add the following workflow to the file (replace placeholders with your values):&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;Build and Push Docker Image&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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;main"&lt;/span&gt; &lt;span class="pi"&gt;]&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;build-and-push&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;Check out the 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@v2&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;Log in to Docker Hub&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;docker/login-action@v2&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;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DOCKER_USERNAME }}&lt;/span&gt;
          &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DOCKER_PASSWORD }}&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;Build and Push Docker Image&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;docker build -t your-username/your-image:latest .&lt;/span&gt;
          &lt;span class="s"&gt;docker push your-username/your-image:latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Add Secrets
&lt;/h4&gt;

&lt;p&gt;Go to your repository’s Settings &amp;gt; Secrets and variables &amp;gt; Actions.&lt;br&gt;
Add two secrets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DOCKER_USERNAME (your Docker Hub username)&lt;/li&gt;
&lt;li&gt;DOCKER_PASSWORD (your Docker Hub password)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Commit and Push Changes
&lt;/h4&gt;

&lt;p&gt;Push your changes to the main branch.&lt;br&gt;
GitHub Actions will automatically run the workflow, building the Docker image and pushing it to Docker Hub.&lt;br&gt;
From a practical perspective and based on our experience, we’ve worked extensively with both Jenkins and GitHub Actions, offering services to set up and manage both tools for different teams and projects. What we’ve observed is that there’s nothing wrong with choosing either tool—it all comes down to your unique requirements. The question is:&lt;/p&gt;

&lt;h2&gt;
  
  
  Which One Is Better: Jenkins or GitHub Actions?
&lt;/h2&gt;

&lt;p&gt;There’s no such thing as a universally “better” tool in the world of CI/CD. However at KubeNine we are inclined more towards Github Actions. The right choice entirely depends on your team’s requirements, project scale, and infrastructure needs&lt;/p&gt;

&lt;h3&gt;
  
  
  When Jenkins Might Be the Better Option
&lt;/h3&gt;

&lt;p&gt;Jenkins is ideal if you need a self-hosted solution where everything is completely under your control. You can install Jenkins from scratch and configure it to suit your exact requirements.&lt;/p&gt;

&lt;p&gt;It has a rich ecosystem of over 1,800 plugins, allowing integration with countless tools and services. Whether you need advanced pipeline customization, on-premises hosting, or compliance with strict organizational policies, Jenkins gives you the flexibility to achieve it all.&lt;/p&gt;

&lt;p&gt;However, it’s worth noting that the support for plugins in Jenkins has seen a decline in recent years.&lt;/p&gt;

&lt;p&gt;Some plugins are not actively maintained, and keeping them updated can become a challenge. Additionally, the manual setup and maintenance required for Jenkins can be time-consuming, especially for teams that are new to CI/CD. &lt;/p&gt;

&lt;h2&gt;
  
  
  When GitHub Actions Might Be the Better Option
&lt;/h2&gt;

&lt;p&gt;GitHub Actions is a great choice if you’re looking for something simple and fast. Unlike Jenkins, it doesn’t require a complex setup process. As we demonstrated in the pipeline example above, all you need is a YAML file in your repository.&lt;/p&gt;

&lt;p&gt;You simply define the steps, like building a Docker image or running tests, and GitHub handles the rest for you.&lt;/p&gt;

&lt;p&gt;For instance, in our example, setting up a pipeline in GitHub Actions was as easy as writing a few lines of YAML. Want to build a Docker image? Just add one line to specify the Docker build action.&lt;/p&gt;

&lt;p&gt;Need to push the image to Docker Hub? Add another action for Docker login and push. It’s all optimized for simplicity and speed, making it especially appealing for small to medium-sized teams or personal projects.&lt;/p&gt;

&lt;p&gt;If you need more control, GitHub Actions also supports self-hosted runners. This allows you to host your workflows on dedicated virtual machines or servers, ensuring enhanced security and compliance.&lt;/p&gt;

&lt;p&gt;For example, in sensitive environments like banking or healthcare, where dedicated VMs are required for better isolation and control, self-hosted runners provide a strong alternative to Jenkins.&lt;/p&gt;

&lt;p&gt;Key Considerations:&lt;br&gt;
Factor&lt;/p&gt;

&lt;p&gt;Jenkins&lt;/p&gt;

&lt;p&gt;GitHub Actions&lt;/p&gt;

&lt;p&gt;Ease of Use&lt;/p&gt;

&lt;p&gt;Requires manual setup and maintenance, making it more complex for new users.&lt;/p&gt;

&lt;p&gt;Minimal setup; simple YAML-based workflows that are ready to use out of the box.&lt;/p&gt;

&lt;p&gt;Infrastructure Control&lt;/p&gt;

&lt;p&gt;Fully self-hosted; everything from updates to security patches is in your hands.&lt;/p&gt;

&lt;p&gt;Offers GitHub-hosted runners for convenience but also supports self-hosted runners for more control.&lt;/p&gt;

&lt;p&gt;Security&lt;/p&gt;

&lt;p&gt;Full control over servers, suitable for environments with strict compliance requirements.&lt;/p&gt;

&lt;p&gt;Self-hosted runners provide similar security, while GitHub-hosted runners are maintained by GitHub.&lt;/p&gt;

&lt;p&gt;Customization&lt;/p&gt;

&lt;p&gt;Highly customizable with plugins and Groovy pipelines, but requires expertise to configure.&lt;/p&gt;

&lt;p&gt;Simple to customize using pre-built actions or by creating your own custom actions.&lt;/p&gt;

&lt;p&gt;Speed and Simplicity&lt;/p&gt;

&lt;p&gt;Slower setup due to manual configurations and plugin management.&lt;/p&gt;

&lt;p&gt;Faster setup; optimized for GitHub-hosted repositories with minimal effort required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Choose Jenkins if:&lt;br&gt;
You require complete control over your CI/CD environment.&lt;br&gt;
Your workflows are highly complex and need extensive customization.&lt;br&gt;
Your organization has the infrastructure to maintain Jenkins servers and manage plugin updates.&lt;br&gt;
Choose GitHub Actions if:&lt;br&gt;
You want a quick and straightforward CI/CD solution.&lt;br&gt;
Your projects are hosted on GitHub, and you prefer everything in one ecosystem.&lt;br&gt;
You’re looking for a scalable solution without the burden of managing infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do You Really Need to Switch from Jenkins to GitHub Actions?
&lt;/h2&gt;

&lt;p&gt;Github Actions might look cool and enticing but don’t switch to just because it looks cool. If your CI/CD pipelines are already fully set up in Jenkins, running smoothly, and your team is comfortable with the tool, there’s no strong reason to switch just for the sake of it. Based on what we’ve discussed so far, such a move may be unnecessary and could lead to additional effort without significant benefits.&lt;/p&gt;

&lt;p&gt;However, if you’re starting fresh—whether in a new company or a new project—and your code is hosted on GitHub, GitHub Actions becomes an obvious choice. It’s easy to set up, integrates natively with GitHub repositories, and provides modern features that align well with today’s DevOps workflows. For teams just getting started, GitHub Actions is undoubtedly the more convenient and efficient option.&lt;/p&gt;

&lt;p&gt;Ultimately, the need to switch depends on your specific situation. If Jenkins is working well for your team, stick with it. But if you’re looking for a simpler, GitHub-centric solution for new projects, GitHub Actions is the way to go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Are There Alternatives to Jenkins and GitHub Actions?
&lt;/h2&gt;

&lt;p&gt;Yes, there are several other CI/CD tools available, each designed for different workflows and requirements. Here are four popular alternatives:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. GitLab CI/CD
&lt;/h4&gt;

&lt;p&gt;Built into GitLab, this tool helps automate builds, tests, and deployments for projects hosted on GitLab.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Azure DevOps Pipelines
&lt;/h4&gt;

&lt;p&gt;Microsoft’s CI/CD solution that integrates well with Azure services and supports multiple repositories.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. CircleCI
&lt;/h4&gt;

&lt;p&gt;A cloud-based CI/CD tool known for its simplicity and support for Docker-based workflows.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Bitbucket Pipelines
&lt;/h4&gt;

&lt;p&gt;Atlassian’s CI/CD solution for Bitbucket repositories, tightly integrated with other Atlassian tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h4&gt;
  
  
  1. Which is better: Jenkins or GitHub Actions?
&lt;/h4&gt;

&lt;p&gt;It depends on your use case. Jenkins is more flexible and customizable for complex CI/CD pipelines, while GitHub Actions is easier to set up and integrates seamlessly with GitHub repositories.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Is Jenkins outdated compared to GitHub Actions?
&lt;/h4&gt;

&lt;p&gt;No, Jenkins is still widely used in production environments. However, GitHub Actions is gaining popularity due to its simplicity and native GitHub integration.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. When should I use GitHub Actions instead of Jenkins?
&lt;/h4&gt;

&lt;p&gt;Use GitHub Actions if you want:&lt;/p&gt;

&lt;p&gt;Quick setup&lt;br&gt;
Tight GitHub integration&lt;br&gt;
Minimal maintenance&lt;br&gt;
It’s ideal for small to medium projects.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. When is Jenkins a better choice than GitHub Actions?
&lt;/h4&gt;

&lt;p&gt;Jenkins is better when you need:&lt;/p&gt;

&lt;p&gt;Advanced customization&lt;br&gt;
Complex pipelines&lt;br&gt;
On-premise CI/CD setup&lt;/p&gt;

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

&lt;p&gt;Choosing the right CI/CD tool depends entirely on your team’s requirements and project needs. Both Jenkins and GitHub Actions have unique strengths—Jenkins offers unmatched control and customization, while GitHub Actions provides simplicity and speed, especially for GitHub-hosted projects.&lt;/p&gt;

&lt;p&gt;Along with alternatives like GitLab CI/CD, Azure DevOps Pipelines, CircleCI, and Bitbucket Pipelines, there are plenty of options to fit various workflows.&lt;/p&gt;

&lt;p&gt;At Kubenine, we provide services to help you set up infrastructure, automate CI/CD pipelines, and manage cloud-native environments.&lt;/p&gt;

&lt;p&gt;Our mission is to handle these technical complexities so you can focus entirely on your product. Whether you need a Jenkins-based solution, GitHub Actions workflows, or support with other tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read More from KubeBlogs
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.kubeblogs.com/run-streamlit-reliably-in-production-using-supervisor/" rel="noopener noreferrer"&gt;Run Streamlit Reliably in Production using Supervisor&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.kubeblogs.com/gcp-permissions-and-scopes-for-compute-engine-vms/" rel="noopener noreferrer"&gt;Fix GCP 403 Permission Errors in Compute Engine VMs&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.kubeblogs.com/enhance-cloud-security-audits-with-prowler/" rel="noopener noreferrer"&gt;Enhance Cloud Security Audits with Prowler (Step-by-Step Guide)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>devops</category>
      <category>jenkins</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Managing Terraform State Locking in S3 Without DytnamoDB</title>
      <dc:creator>sanjay yadav</dc:creator>
      <pubDate>Wed, 20 May 2026 05:38:33 +0000</pubDate>
      <link>https://dev.to/sanjay_yadav_/managing-terraform-state-locking-in-s3-without-dytnamodb-3fpn</link>
      <guid>https://dev.to/sanjay_yadav_/managing-terraform-state-locking-in-s3-without-dytnamodb-3fpn</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you’ve worked with Terraform, you’ve probably followed the standard setup:&lt;/p&gt;

&lt;p&gt;S3 for storing Terraform state&lt;br&gt;
DynamoDB for state locking&lt;br&gt;
It’s widely recommended, and most teams implement it without questioning why.&lt;/p&gt;

&lt;p&gt;But Terraform has evolved.&lt;/p&gt;

&lt;p&gt;Today, Terraform S3 backend locking can handle state locking without DynamoDB. This introduces a simpler alternative — but also raises an important question:&lt;/p&gt;

&lt;p&gt;Do you actually need DynamoDB for Terraform state locking anymore?&lt;br&gt;
In this guide, we’ll break this down from a real-world DevOps perspective — not just configuration, but actual decision-making.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Terraform State Locking
&lt;/h2&gt;

&lt;p&gt;Terraform state is the single source of truth for your infrastructure.&lt;/p&gt;

&lt;p&gt;Whenever you run terraform apply, Terraform reads and updates this state file.&lt;/p&gt;

&lt;p&gt;Without proper state locking:&lt;/p&gt;

&lt;p&gt;Multiple users or pipelines can run changes at the same time&lt;br&gt;
State files can become corrupted&lt;br&gt;
Infrastructure becomes inconsistent&lt;br&gt;
Terraform state locking ensures that only one operation modifies the state at a time.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Terraform Locking Works
&lt;/h2&gt;

&lt;p&gt;At a high level:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Terraform attempts to acquire a lock&lt;/li&gt;
&lt;li&gt;If a lock exists → execution stops&lt;/li&gt;
&lt;li&gt;If no lock exists → execution proceeds&lt;/li&gt;
&lt;li&gt;After completion → lock is released&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The difference is in implementation:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Terraform DynamoDB locking
&lt;/h4&gt;

&lt;p&gt;→ lock stored as a database record&lt;/p&gt;

&lt;h4&gt;
  
  
  Terraform S3 backend locking
&lt;/h4&gt;

&lt;p&gt;→ lock stored as a .tflock file&lt;/p&gt;

&lt;h2&gt;
  
  
  Terraform S3 Backend Architecture
&lt;/h2&gt;

&lt;p&gt;In a typical Terraform S3 backend setup:&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%2Frjgmea4g81axxszeh1a6.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%2Frjgmea4g81axxszeh1a6.png" alt=" " width="800" height="563"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Terraform CLI interacts with the S3 bucket&lt;br&gt;
Reads terraform.tfstate (state file)&lt;br&gt;
Creates .tflock file to acquire a lock&lt;br&gt;
Executes infrastructure changes&lt;br&gt;
Deletes the lock after completion&lt;br&gt;
This removes the dependency on DynamoDB entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Terraform S3 Locking (Modern Approach)
&lt;/h2&gt;

&lt;p&gt;Using Terraform S3 backend locking without DynamoDB simplifies your infrastructure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Benefits
&lt;/h3&gt;

&lt;p&gt;No additional AWS service required&lt;br&gt;
Lower operational cost&lt;br&gt;
Easier setup and maintenance&lt;br&gt;
Faster onboarding for teams&lt;br&gt;
For small teams and low-concurrency environments, this approach works well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Terraform DynamoDB Locking (Traditional Approach)
&lt;/h2&gt;

&lt;p&gt;The traditional setup uses DynamoDB for Terraform state locking.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why DynamoDB Was Used
&lt;/h3&gt;

&lt;p&gt;Strong consistency guarantees&lt;br&gt;
Better handling of concurrent operations&lt;br&gt;
Automatic lock management&lt;br&gt;
This makes DynamoDB more reliable in complex or high-scale environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  S3 vs DynamoDB Locking (Key Differences)
&lt;/h2&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%2Fcwauwgh2wrzfpbgqnrwx.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%2Fcwauwgh2wrzfpbgqnrwx.png" alt=" " width="761" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use Terraform S3 Locking
&lt;/h2&gt;

&lt;p&gt;Use Terraform S3 backend locking without DynamoDB if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have a small team&lt;/li&gt;
&lt;li&gt;Infrastructure changes are controlled&lt;/li&gt;
&lt;li&gt;CI/CD pipelines are not running in parallel&lt;/li&gt;
&lt;li&gt;You want to reduce cost and complexity
This approach is ideal for startups and smaller environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When NOT to Use S3 Locking
&lt;/h2&gt;

&lt;p&gt;Avoid S3-only locking in the following scenarios:&lt;/p&gt;

&lt;h4&gt;
  
  
  High Concurrency CI/CD Pipelines
&lt;/h4&gt;

&lt;p&gt;Multiple pipelines running simultaneously can create conflicts.&lt;/p&gt;

&lt;h4&gt;
  
  
  Large Teams
&lt;/h4&gt;

&lt;p&gt;More engineers increase the risk of concurrent operations.&lt;/p&gt;

&lt;h4&gt;
  
  
  Production-Critical Systems
&lt;/h4&gt;

&lt;p&gt;Critical infrastructure requires stronger consistency guarantees.&lt;/p&gt;

&lt;p&gt;In these cases, Terraform DynamoDB locking is the safer option.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Failure Scenario
&lt;/h2&gt;

&lt;p&gt;One common issue with S3 locking occurs when Terraform crashes before releasing the lock.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Happens
&lt;/h3&gt;

&lt;p&gt;The .tflock file remains in S3&lt;br&gt;
All future Terraform runs fail&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3 &lt;span class="nb"&gt;rm &lt;/span&gt;s3://your-bucket/path/.tflock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This manual cleanup is something every team using S3 locking should be prepared for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices for Terraform S3 Backend
&lt;/h2&gt;

&lt;p&gt;To safely use Terraform S3 backend locking, follow these best practices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable S3 versioning to protect state&lt;/li&gt;
&lt;li&gt;Use KMS encryption for security&lt;/li&gt;
&lt;li&gt;Separate state files for each environment&lt;/li&gt;
&lt;li&gt;Restrict IAM permissions (least privilege)&lt;/li&gt;
&lt;li&gt;Monitor state access and changes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Migration from DynamoDB to S3 Locking
&lt;/h2&gt;

&lt;p&gt;Migrating from DynamoDB to S3 locking is straightforward.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Enable Locking
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;use_lockfile = true&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Migrate State
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;terraform init -migrate-state&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Validate
&lt;/h3&gt;

&lt;p&gt;Test concurrency scenarios before using this setup in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decision Guide
&lt;/h2&gt;

&lt;p&gt;If you're unsure which approach to choose, use this simple rule:&lt;/p&gt;

&lt;p&gt;Small team → S3 locking&lt;br&gt;
Low concurrency → S3 locking&lt;br&gt;
Large team → DynamoDB locking&lt;br&gt;
High CI/CD activity → DynamoDB locking&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Is DynamoDB required for Terraform state locking?
&lt;/h4&gt;

&lt;p&gt;No, Terraform S3 backend locking can replace DynamoDB in many cases.&lt;/p&gt;

&lt;h4&gt;
  
  
  Is Terraform S3 locking safe for production?
&lt;/h4&gt;

&lt;p&gt;Yes for small setups, but not ideal for high-concurrency environments.&lt;/p&gt;

&lt;h4&gt;
  
  
  What is the biggest risk of S3 locking?
&lt;/h4&gt;

&lt;p&gt;Concurrency issues and stuck .tflock files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read More
&lt;/h2&gt;

&lt;p&gt;If you're working on Terraform and cloud automation, you might also find these useful:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.kubeblogs.com/gcp-billing-kill-switch-with-terraform/" rel="noopener noreferrer"&gt;https://www.kubeblogs.com/gcp-billing-kill-switch-with-terraform/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.kubeblogs.com/fluent-bit-vs-grafana-alloy/" rel="noopener noreferrer"&gt;https://www.kubeblogs.com/fluent-bit-vs-grafana-alloy/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.kubeblogs.com/how-civo-kubernetes-routes-pod-traffic/" rel="noopener noreferrer"&gt;https://www.kubeblogs.com/how-civo-kubernetes-routes-pod-traffic/&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Terraform S3 backend locking provides a simpler alternative to DynamoDB.&lt;/p&gt;

&lt;p&gt;For small and medium setups, it reduces complexity and cost significantly.&lt;/p&gt;

&lt;p&gt;However, for high-scale environments with frequent concurrent deployments, DynamoDB remains the more reliable option.&lt;/p&gt;

&lt;p&gt;The key is choosing the right approach based on your workload — not blindly following defaults.&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>devops</category>
      <category>aws</category>
      <category>cloud</category>
    </item>
    <item>
      <title>How to Avoid GitHub Token Rate Limiting Issues | Complete Guide for DevOps Teams</title>
      <dc:creator>sanjay yadav</dc:creator>
      <pubDate>Tue, 19 May 2026 05:05:03 +0000</pubDate>
      <link>https://dev.to/sanjay_yadav_/how-to-avoid-github-token-rate-limiting-issues-complete-guide-for-devops-teams-1i56</link>
      <guid>https://dev.to/sanjay_yadav_/how-to-avoid-github-token-rate-limiting-issues-complete-guide-for-devops-teams-1i56</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Your CI/CD pipeline was working fine until suddenly every build started failing with a GitHub API 403 error.&lt;/p&gt;

&lt;p&gt;I faced this exact issue during a production deployment. Everything looked fine—no code changes, no infrastructure issues—but pipelines kept failing.&lt;/p&gt;

&lt;p&gt;At first, we thought it was a bug in the pipeline, but nothing pointed to the actual issue.&lt;/p&gt;

&lt;p&gt;After debugging for hours, it became clear that the problem was not the code, but GitHub API rate limiting.&lt;/p&gt;

&lt;p&gt;If you are facing GitHub API rate limit exceeded errors in CI/CD pipelines, this guide will help you fix them effectively.&lt;/p&gt;

&lt;p&gt;Quick Fix (TL;DR for busy DevOps engineers): Use authenticated tokens, reduce unnecessary API calls, implement caching, and switch to GitHub Apps for scalable systems.&lt;br&gt;
What is GitHub API Rate Limiting?&lt;br&gt;
GitHub API rate limiting restricts how many API requests you can make within a specific time window. This ensures fair usage and prevents abuse.&lt;/p&gt;

&lt;p&gt;In real-world DevOps workflows, this limit can quickly become a bottleneck.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why GitHub API Rate Limit Errors Happen in CI/CD
&lt;/h2&gt;

&lt;p&gt;In most DevOps setups, pipelines frequently interact with GitHub APIs:&lt;/p&gt;

&lt;p&gt;Fetching repositories&lt;br&gt;
Triggering workflows&lt;br&gt;
Checking build statuses&lt;br&gt;
Managing pull requests&lt;br&gt;
Common causes include:&lt;/p&gt;

&lt;p&gt;Frequent API polling&lt;br&gt;
Multiple services making requests at the same time&lt;br&gt;
Unauthenticated API usage&lt;br&gt;
This is where GitHub API rate limit exceeded errors typically occur.&lt;/p&gt;
&lt;h2&gt;
  
  
  GitHub API Rate Limits Explained (Token Types)
&lt;/h2&gt;

&lt;p&gt;Unauthenticated Requests: 60 requests per hour&lt;br&gt;
Personal Access Token (PAT): 5000 requests per hour&lt;br&gt;
GitHub Actions Token: approximately 1000 requests per hour&lt;br&gt;
Using authenticated requests significantly increases your available limits.&lt;/p&gt;
&lt;h2&gt;
  
  
  Token Management Strategies
&lt;/h2&gt;

&lt;p&gt;Use GitHub Apps Instead of Personal Tokens&lt;br&gt;
GitHub Apps provide higher rate limits and better security.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# .github/workflows/deploy.yml
name: Deploy with GitHub App
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          token: ${{ secrets.GITHUB_APP_TOKEN }}

      - name: Deploy
        run: |
          # Your deployment logic here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Implement Token Rotation
&lt;/h3&gt;

&lt;p&gt;Rotate tokens regularly to avoid hitting limits:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash
# token-rotation.sh
OLD_TOKEN=$1
NEW_TOKEN=$2
# Update secrets in repository
gh secret set GITHUB_TOKEN --body "$NEW_TOKEN"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Use Repository-Specific Tokens
&lt;/h3&gt;

&lt;h1&gt;
  
  
  Different tokens for different purposes
&lt;/h1&gt;

&lt;p&gt;env:&lt;br&gt;
  DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}&lt;br&gt;
  NOTIFY_TOKEN: ${{ secrets.NOTIFY_TOKEN }}&lt;br&gt;
  BACKUP_TOKEN: ${{ secrets.BACKUP_TOKEN }}&lt;/p&gt;
&lt;h2&gt;
  
  
  Rate Limit Handling in Code
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Implement Exponential Backoff
&lt;/h3&gt;

&lt;p&gt;This function retries API calls when rate limits are hit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import time
import random
from functools import wraps

def retry_with_backoff(max_retries=3, base_delay=1):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            for attempt in range(max_retries):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    if "rate limit" in str(e).lower() and attempt &amp;lt; max_retries - 1:
                        delay = base_delay * (2 ** attempt) + random.uniform(0, 1)
                        time.sleep(delay)
                        continue
                    raise
            return None
        return wrapper
    return decorator

@retry_with_backoff(max_retries=5, base_delay=2)
def make_github_request(url, headers):
    response = requests.get(url, headers=headers)
    if response.status_code == 429:
        retry_after = int(response.headers.get('Retry-After', 60))
        time.sleep(retry_after)
        raise Exception("Rate limited")
    return response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Check Rate Limit Headers
&lt;/h2&gt;

&lt;p&gt;Always monitor rate limit headers in your requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def check_rate_limit(response):
    remaining = int(response.headers.get('X-RateLimit-Remaining', 0))
    reset_time = int(response.headers.get('X-RateLimit-Reset', 0))

    if remaining &amp;lt; 100:  # Warning threshold
        print(f"Warning: Only {remaining} requests remaining")
        print(f"Rate limit resets at: {reset_time}")

    return remaining, reset_time
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  GitHub API Rate Limit Architecture (CI/CD Flow)
&lt;/h2&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%2Fo54zov1ek3i42hghiayr.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%2Fo54zov1ek3i42hghiayr.png" alt=" " width="800" height="139"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CI/CD Pipeline Optimization&lt;br&gt;
Batch API Requests&lt;br&gt;
Combine multiple operations into single requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Instead of multiple individual requests
- name: Get PR details
  run: |
    # Bad: Multiple API calls
    gh pr view ${{ github.event.pull_request.number }} --json title
    gh pr view ${{ github.event.pull_request.number }} --json body
    gh pr view ${{ github.event.pull_request.number }} --json files

    # Good: Single API call
    gh pr view ${{ github.event.pull_request.number }} --json title,body,files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Cache API Responses
&lt;/h2&gt;

&lt;p&gt;Use GitHub Actions cache to reduce API calls:&lt;/p&gt;

&lt;p&gt;``- name: Cache API response&lt;br&gt;
  uses: actions/cache@v3&lt;br&gt;
  with:&lt;br&gt;
    path: ~/.cache/github-api&lt;br&gt;
    key: ${{ runner.os }}-api-cache-${{ github.sha }}&lt;br&gt;
    restore-keys: |&lt;br&gt;
      ${{ runner.os }}-api-cache-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;name: Use cached data
run: |
if [ -f ~/.cache/github-api/data.json ]; then
  echo "Using cached data"
else
  echo "Fetching fresh data"
  gh api repos/${{ github.repository }}/commits &amp;gt; ~/.cache/github-api/data.json
fi`&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimize Workflow Triggers
&lt;/h2&gt;

&lt;p&gt;Reduce unnecessary workflow runs:&lt;/p&gt;

&lt;h1&gt;
  
  
  Only run on specific paths
&lt;/h1&gt;

&lt;p&gt;on:&lt;br&gt;
  push:&lt;br&gt;
    branches: [main]&lt;br&gt;
    paths:&lt;br&gt;
      - 'src/&lt;strong&gt;'&lt;br&gt;
      - 'package.json'&lt;br&gt;
      - '.github/workflows/&lt;/strong&gt;'&lt;/p&gt;

&lt;h1&gt;
  
  
  Skip workflows for draft PRs
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;name: Skip for draft PRs
if: github.event.pull_request.draft == true
run: exit 0&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Monitoring and Alerting
&lt;/h2&gt;

&lt;p&gt;Set Up Rate Limit Monitoring&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;name: Monitor rate limits&lt;br&gt;
run: |&lt;br&gt;
response=$(gh api rate_limit)&lt;br&gt;
remaining=$(echo $response | jq '.rate.remaining')&lt;/p&gt;

&lt;p&gt;if [ $remaining -lt 100 ]; then&lt;br&gt;
  echo ":⚠️:Rate limit low: $remaining requests remaining"&lt;br&gt;
fi&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Create Rate Limit Dashboard
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
import requests&lt;br&gt;
import json&lt;br&gt;
from datetime import datetime&lt;/p&gt;

&lt;p&gt;def monitor_rate_limits(token):&lt;br&gt;
    headers = {'Authorization': f'token {token}'}&lt;br&gt;
    response = requests.get('&lt;a href="https://api.github.com/rate_limit" rel="noopener noreferrer"&gt;https://api.github.com/rate_limit&lt;/a&gt;', headers=headers)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data = response.json()
rate = data['rate']

print(f"Remaining: {rate['remaining']}")
print(f"Reset time: {datetime.fromtimestamp(rate['reset'])}")

if rate['remaining'] &amp;lt; 100:
    # Send alert to Slack/Teams
    send_alert(f"GitHub rate limit low: {rate['remaining']} remaining")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Token Types Comparison
&lt;/h2&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%2Fiyabdxfp7f9hwlaw7mw6.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%2Fiyabdxfp7f9hwlaw7mw6.png" alt=" " width="766" height="261"&gt;&lt;/a&gt;&lt;br&gt;
Choosing the right authentication method directly impacts pipeline stability.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Happens When Rate Limit is Exceeded?
&lt;/h2&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%2Fhuazt48e2z62ihya5ajh.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%2Fhuazt48e2z62ihya5ajh.png" alt=" " width="800" height="211"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices Summary
&lt;/h2&gt;

&lt;p&gt;Use GitHub Apps for higher rate limits&lt;br&gt;
Implement exponential backoff&lt;br&gt;
Monitor API headers&lt;br&gt;
Cache API responses&lt;br&gt;
Batch API requests&lt;br&gt;
Optimize workflows&lt;br&gt;
Rotate tokens regularly&lt;/p&gt;

&lt;h2&gt;
  
  
  Read More
&lt;/h2&gt;

&lt;p&gt;If you are working with cloud and DevOps setups, these guides may help:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.kubeblogs.com/k3s-vs-kubernetes/" rel="noopener noreferrer"&gt;https://www.kubeblogs.com/k3s-vs-kubernetes/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.kubeblogs.com/aws-t2-vs-t3-vs-t4g/" rel="noopener noreferrer"&gt;https://www.kubeblogs.com/aws-t2-vs-t3-vs-t4g/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.kubeblogs.com/aws-gp2-vs-gp3/" rel="noopener noreferrer"&gt;https://www.kubeblogs.com/aws-gp2-vs-gp3/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.kubeblogs.com/s3-security-best-practices/" rel="noopener noreferrer"&gt;https://www.kubeblogs.com/s3-security-best-practices/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ:
&lt;/h2&gt;

&lt;h4&gt;
  
  
  What is GitHub API rate limiting?
&lt;/h4&gt;

&lt;p&gt;GitHub API rate limiting restricts how many API requests you can make within a defined time window.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why do I get a 403 error in GitHub API?
&lt;/h4&gt;

&lt;p&gt;You get a 403 error when you exceed your API rate limit or use unauthenticated requests.&lt;/p&gt;

&lt;h4&gt;
  
  
  How can I fix GitHub API rate limit exceeded errors?
&lt;/h4&gt;

&lt;p&gt;Use authenticated tokens, reduce unnecessary API calls, and implement caching strategies.&lt;/p&gt;

&lt;h4&gt;
  
  
  Can GitHub Actions hit rate limits?
&lt;/h4&gt;

&lt;p&gt;Yes, GitHub Actions can hit rate limits, especially in workflows that make frequent API calls.&lt;/p&gt;

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

&lt;p&gt;GitHub API rate limiting is a common issue in DevOps workflows, but it is predictable once you understand how it works.&lt;/p&gt;

&lt;p&gt;By using authenticated tokens, reducing API calls, implementing caching, and leveraging GitHub Apps, you can prevent unexpected failures in your CI/CD pipelines.&lt;/p&gt;

&lt;p&gt;Handling API limits properly is essential for building stable and scalable automation systems.&lt;/p&gt;

</description>
      <category>github</category>
      <category>devops</category>
      <category>cicd</category>
      <category>automation</category>
    </item>
    <item>
      <title>The Simplest AWS Security Hack I've Shipped in a Decade</title>
      <dc:creator>sanjay yadav</dc:creator>
      <pubDate>Mon, 18 May 2026 07:02:29 +0000</pubDate>
      <link>https://dev.to/sanjay_yadav_/the-simplest-aws-security-hack-ive-shipped-in-a-decade-2imi</link>
      <guid>https://dev.to/sanjay_yadav_/the-simplest-aws-security-hack-ive-shipped-in-a-decade-2imi</guid>
      <description>&lt;p&gt;DNS based firewalls are one of the easiset and fastest ways to secure your network. They have been around for decades and have been widely adopted for network security. They simply block DNS queries to malicious domains before they can even start to communicate with the internet.&lt;/p&gt;

&lt;p&gt;When I work with our customers, I often find out that they implement all sorts of security controls like security groups, network policies, etc. but they almost always miss out on the simplest and most effective one - DNS based firewalls. DNS based firewalls are not a replacement for these other controls, but they are a powerful addition.&lt;/p&gt;

&lt;p&gt;AWS has a very simple mechanism to achieve this on your VPC DNS resolver. It's called Route 53 Resolver DNS Firewall. It's a simple rule based firewall that sits in front of the DNS resolver your VPC already uses. When something inside the VPC asks "where is evil-c2.ru?", the firewall checks the domain against AWS's managed threat lists and returns NXDOMAIN if it's bad. The connection dies before a single packet leaves the network. That's the whole idea. Nothing runs on the host. Nothing sits in the packet path. No application has to change. It covers every EC2, Fargate task, Lambda, and EKS pod in the VPC the moment you turn it on, and most setups cost under $30 a month.&lt;/p&gt;

&lt;p&gt;I've been in platform work for almost a decade now. I have never seen a security primitive with this effort-to-outcome ratio. AWS shipped it in 2021. Very few teams I have audited run it.&lt;/p&gt;

&lt;h3&gt;
  
  
  What you actually ship - a Terraform module
&lt;/h3&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%2Fz7hsmy41377h8u3akg6y.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%2Fz7hsmy41377h8u3akg6y.png" alt=" " width="800" height="109"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You create five things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A rule group pointing at AWS's four managed threat lists: AWSManagedDomainsMalwareDomainList, AWSManagedDomainsBotnetCommandandControl, AWSManagedDomainsAmazonGuardDutyThreatList, AWSManagedDomainsAggregateThreatList&lt;/li&gt;
&lt;li&gt;A rule group with your own policy-forbidden domains (webhook.site, transfer.sh, pastebin mirrors, crypto miners)&lt;/li&gt;
&lt;li&gt;Rule group associations to each VPC you want covered&lt;/li&gt;
&lt;li&gt;A Resolver query log config writing every DNS query to CloudWatch&lt;/li&gt;
&lt;li&gt;A metric filter, alarm, and SNS topic for notifications on blocked queries
Under 200 lines of Terraform.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Terraform implementation&lt;/p&gt;

&lt;p&gt;Here's the shape of it:&lt;/p&gt;

&lt;p&gt;`&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
data "aws_route53_resolver_firewall_domain_list" "botnet" {&lt;br&gt;
  name = "AWSManagedDomainsBotnetCommandandControl"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_route53_resolver_firewall_rule_group" "managed" {&lt;br&gt;
  name = "managed-threat-blocks"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_route53_resolver_firewall_rule" "botnet" {&lt;br&gt;
  name                    = "block-botnet-c2"&lt;br&gt;
  firewall_rule_group_id  = aws_route53_resolver_firewall_rule_group.managed.id&lt;br&gt;
  firewall_domain_list_id = data.aws_route53_resolver_firewall_domain_list.botnet.id&lt;br&gt;
  priority                = 10&lt;br&gt;
  action                  = "BLOCK"&lt;br&gt;
  block_response          = "NXDOMAIN"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_route53_resolver_firewall_rule_group_association" "managed" {&lt;br&gt;
  firewall_rule_group_id = aws_route53_resolver_firewall_rule_group.managed.id&lt;br&gt;
  vpc_id                 = var.vpc_id&lt;br&gt;
  priority               = 101&lt;br&gt;
  name                   = "managed-block"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_route53_resolver_query_log_config" "vpc" {&lt;br&gt;
  name            = "vpc-dns-logs"&lt;br&gt;
  destination_arn = aws_cloudwatch_log_group.dns.arn&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_route53_resolver_query_log_config_association" "vpc" {&lt;br&gt;
  resolver_query_log_config_id = aws_route53_resolver_query_log_config.vpc.id&lt;br&gt;
  resource_id                  = var.vpc_id&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;br&gt;
`&lt;br&gt;
Three things to be careful about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Association priority ordering. Allowlist rule groups need a lower number than blocklists, or the block wins. I use 50 for allow, 101+ for block. The priority lives on the association, not the rule group.&lt;/li&gt;
&lt;li&gt;block_response = "NXDOMAIN", not NODATA. NXDOMAIN makes the client fail cleanly. NODATA can leave some resolvers hanging in a retry loop.&lt;/li&gt;
&lt;li&gt;Query logging is a separate resource. The firewall decides whether to block. The query log config is what actually writes entries. You need both, and both need VPC associations.
### What you get back, immediately&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Malware C2 communication is blocked for every workload, automatically.
&lt;/h4&gt;

&lt;p&gt;EC2, ECS, Fargate, Lambda, EKS pods. Anything using the VPC resolver, which is almost everything by default. When a compromised container tries to phone home to evil-c2.ru, the resolver returns NXDOMAIN. The connection dies at the DNS layer. No packet leaves your VPC.&lt;/p&gt;
&lt;h4&gt;
  
  
  You get a complete DNS audit trail in CloudWatch.
&lt;/h4&gt;

&lt;p&gt;Every query, every VPC, every source IP. When something goes sideways — supply chain compromise, malicious npm package, leaked credential being abused — you can answer "what did it try to talk to?" in minutes.&lt;/p&gt;

&lt;p&gt;You enforce egress policy without asking app teams to do anything&lt;br&gt;
. Want to block webhook.site, transfer.sh, and anonymous file upload services? Add them to a domain list. Done. No config change in any app. No proxy PAC file. No VPN rules.&lt;/p&gt;
&lt;h3&gt;
  
  
  Safety against DNS-over-HTTPS bypass attempts
&lt;/h3&gt;
&lt;h4&gt;
  
  
  DNS Firewall catches DNS-over-HTTPS bypass attempts.
&lt;/h4&gt;

&lt;p&gt;Modern malware increasingly uses DoH to talk to 1.1.1.1, dns.google, or attacker-controlled resolvers, routing around traditional egress proxies that can't see inside TLS. But the first step of DoH is still resolving the DoH endpoint. If that endpoint is in a threat list, the lookup fails before the HTTPS tunnel ever opens.&lt;/p&gt;
&lt;h3&gt;
  
  
  How do I suggest rolling this out?
&lt;/h3&gt;

&lt;p&gt;Deploy in ALERT mode. Do not enable BLOCK mode in the beginning to avoid unexpected blockages. Wait two weeks. Run this CloudWatch Insights query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
fields query_name, firewall_domain_list_id
| filter firewall_rule_action = "ALERT"
| stats count(*) as hits by query_name
| sort hits desc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Flip to BLOCK one managed list at a time. Start with BotnetCommandandControl (highest confidence, fewest false positives). End with AggregateThreatList (broadest, highest false-positive rate). Wait a week between flips. If something breaks, you know which list did it.&lt;/p&gt;

&lt;p&gt;The cost math&lt;/p&gt;

&lt;p&gt;For a typical setup:&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%2Fvyx2kutx2le11ye1j80v.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%2Fvyx2kutx2le11ye1j80v.png" alt=" " width="404" height="155"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  "It's not a complete egress solution.
&lt;/h3&gt;

&lt;p&gt;" Correct. It doesn't inspect payloads. It doesn't block IP-literal traffic from malware that hardcodes IPs. It doesn't replace security groups or NAT gateways with fixed egress IPs.&lt;/p&gt;

&lt;p&gt;However, it's a great addition to your egress security posture. It's a simple and effective way to block malicious domains before they can even start to communicate with the internet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frequently Asked Questions
&lt;/h3&gt;

&lt;h4&gt;
  
  
  What is Route 53 DNS Firewall?
&lt;/h4&gt;

&lt;p&gt;Route 53 DNS Firewall is an AWS service that filters outbound DNS queries at the VPC resolver level, allowing you to block malicious domains, command-and-control (C2) traffic, and unwanted destinations before any connection is established.&lt;/p&gt;

&lt;h4&gt;
  
  
  How does Route 53 DNS Firewall work?
&lt;/h4&gt;

&lt;p&gt;Route 53 DNS Firewall evaluates DNS queries against managed and custom domain lists. If a domain is flagged, it returns an NXDOMAIN response, stopping communication before traffic leaves your VPC.&lt;/p&gt;

&lt;h4&gt;
  
  
  Does Route 53 DNS Firewall require agents?
&lt;/h4&gt;

&lt;p&gt;No, Route 53 DNS Firewall is completely agentless. It works at the VPC DNS resolver level and automatically protects EC2, Lambda, Fargate, and EKS workloads without any application changes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Can Route 53 DNS Firewall block malware?
&lt;/h4&gt;

&lt;p&gt;Yes, it blocks malware by preventing DNS resolution of malicious domains, including botnet command-and-control servers, using AWS managed threat intelligence lists.&lt;/p&gt;

&lt;h4&gt;
  
  
  Does Route 53 DNS Firewall support Lambda and EKS?
&lt;/h4&gt;

&lt;p&gt;Yes, it works automatically with Lambda, EKS, EC2, and Fargate as long as they use the default VPC DNS resolver.&lt;/p&gt;

&lt;h4&gt;
  
  
  What is the cost of Route 53 DNS Firewall?
&lt;/h4&gt;

&lt;p&gt;Pricing depends on DNS query volume and rule groups. Most small to mid-sized setups typically cost between $15 and $70 per month.&lt;/p&gt;

&lt;h4&gt;
  
  
  Should I enable BLOCK mode immediately?
&lt;/h4&gt;

&lt;p&gt;No, it’s recommended to start in ALERT mode, monitor DNS queries for false positives, and gradually move to BLOCK mode to avoid breaking production workloads.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Route 53 DNS Firewall is one of those rare AWS features that’s simple to set up but makes a real difference. With just a bit of configuration, you can block malicious domains, reduce risk from compromised workloads, and finally get visibility into what your systems are trying to reach outside your VPC.&lt;/p&gt;

&lt;p&gt;It’s not meant to replace everything else in your security stack, but it solves a problem that a lot of teams don’t even realize they have—uncontrolled outbound traffic.&lt;/p&gt;

&lt;p&gt;If you haven’t tried it yet, start in alert mode, watch what shows up, and then move to blocking step by step. You’ll likely catch things you didn’t expect.&lt;/p&gt;

&lt;p&gt;For the effort involved, it’s easily one of the highest-impact security improvements you can make in AWS.&lt;/p&gt;

&lt;p&gt;Ship it or get in touch with KubeNine on (&lt;a href="https://kubenine.com" rel="noopener noreferrer"&gt;https://kubenine.com&lt;/a&gt;) to understand it further.&lt;/p&gt;

&lt;h3&gt;
  
  
  Read More on KubeBlogs
&lt;/h3&gt;

&lt;p&gt;If you're exploring DevOps, Kubernetes, and cloud infrastructure, these guides will help you go deeper:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.kubeblogs.com/how-civo-kubernetes-routes-pod-traffic-single-egress-ip-explained/" rel="noopener noreferrer"&gt;How Kubernetes Routes Pod Traffic with a Single Egress IP&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.kubeblogs.com/gp3-vs-gp2-ebs-volume-aws/" rel="noopener noreferrer"&gt;GP3 vs GP2 EBS Volumes: Performance and Cost Comparison&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.kubeblogs.com/self-hosted-github-actions-runner/" rel="noopener noreferrer"&gt;How to Set Up a Self-Hosted GitHub Actions Runner&lt;/a&gt;&lt;br&gt;
These articles cover Kubernetes networking, AWS storage optimization, and CI/CD infrastructure — useful when scaling beyond local development environments.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>security</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Docker Image Re-Tagging in AWS ECR Is More Inefficient Than Most Teams Realize</title>
      <dc:creator>sanjay yadav</dc:creator>
      <pubDate>Fri, 15 May 2026 04:54:55 +0000</pubDate>
      <link>https://dev.to/sanjay_yadav_/docker-image-re-tagging-in-aws-ecr-is-more-inefficient-than-most-teams-realize-3370</link>
      <guid>https://dev.to/sanjay_yadav_/docker-image-re-tagging-in-aws-ecr-is-more-inefficient-than-most-teams-realize-3370</guid>
      <description>&lt;p&gt;At small scale, Docker image tagging feels pretty straightforward.&lt;/p&gt;

&lt;p&gt;But once larger CI/CD pipelines and multiple environments get involved, re-tagging images inside AWS ECR starts becoming pretty inefficient.&lt;/p&gt;

&lt;p&gt;A lot of teams still:&lt;/p&gt;

&lt;p&gt;pull large images locally&lt;br&gt;
re-tag them&lt;br&gt;
push them again&lt;/p&gt;

&lt;p&gt;even when the image itself never actually changed.&lt;/p&gt;

&lt;p&gt;The inefficient part is that the image itself usually hasn’t changed at all.&lt;/p&gt;

&lt;p&gt;In many cases, re-tagging is really just a metadata operation, but traditional workflows still end up moving large image layers around unnecessarily.&lt;/p&gt;

&lt;p&gt;At larger scale, this starts becoming less of a Docker problem and more of a CI/CD workflow problem.&lt;/p&gt;

&lt;p&gt;That’s usually where API-based workflows or tools like Skopeo start making much more sense for image promotion between environments and registries.&lt;/p&gt;

&lt;p&gt;This breakdown explains some practical ways teams handle ECR re-tagging more efficiently:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.kubeblogs.com/docker-image-re-tagging-limitations-aws-ecr-solutions-alternatives-2025/" rel="noopener noreferrer"&gt;https://www.kubeblogs.com/docker-image-re-tagging-limitations-aws-ecr-solutions-alternatives-2025/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>docker</category>
      <category>cicd</category>
      <category>containers</category>
    </item>
    <item>
      <title>Host a Static Website on AWS S3 in Minutes</title>
      <dc:creator>sanjay yadav</dc:creator>
      <pubDate>Thu, 14 May 2026 07:02:40 +0000</pubDate>
      <link>https://dev.to/sanjay_yadav_/host-a-static-website-on-aws-s3-in-minutes-36ac</link>
      <guid>https://dev.to/sanjay_yadav_/host-a-static-website-on-aws-s3-in-minutes-36ac</guid>
      <description>&lt;p&gt;Amazon S3 (Simple Storage Service) lets you host static websites. Static websites are made up of HTML, CSS, JavaScript, and media files — no server-side code is needed.&lt;/p&gt;

&lt;p&gt;This guide will walk you through the steps to set up and publish a static website using an S3 bucket.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Create an S3 Bucket
&lt;/h2&gt;

&lt;p&gt;Go to the S3 Console in AWS.&lt;br&gt;
Click Create bucket.&lt;br&gt;
Enter a unique name for your bucket. For website hosting, the bucket name should match your domain name (e.g., example.com).&lt;br&gt;
Choose a region.&lt;br&gt;
Uncheck Block all public access (you'll make the bucket public for web access).&lt;br&gt;
Acknowledge the warning and click Create bucket.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2: Upload Your Website Files
&lt;/h2&gt;

&lt;p&gt;Open your new bucket.&lt;br&gt;
Click Upload.&lt;br&gt;
Add your HTML, CSS, JS, and other static files.&lt;br&gt;
Click Upload.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 3: Set Permissions to Make Files Public
&lt;/h2&gt;

&lt;p&gt;You need to make your files publicly readable:&lt;/p&gt;

&lt;p&gt;Go to the &lt;/p&gt;
&lt;h3&gt;
  
  
  Permissions tab
&lt;/h3&gt;

&lt;p&gt;.&lt;br&gt;
Scroll to &lt;/p&gt;
&lt;h3&gt;
  
  
  Bucket Policy
&lt;/h3&gt;

&lt;p&gt;.&lt;br&gt;
Add a policy like this:&lt;br&gt;
&lt;/p&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;Replace your-bucket-name with the actual name of your bucket.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Enable Static Website Hosting
&lt;/h2&gt;

&lt;p&gt;Go to the Properties tab of the bucket.&lt;br&gt;
Scroll to Static website hosting.&lt;br&gt;
Click Edit.&lt;br&gt;
Choose Enable.&lt;br&gt;
Enter the name of your index document (e.g., index.html). You can also add an error document (e.g., error.html).&lt;br&gt;
Save changes.&lt;br&gt;
After saving, you'll see a Bucket website endpoint. This is the URL of your website.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: (Optional) Use a Custom Domain with Route 53
&lt;/h2&gt;

&lt;p&gt;If you have a domain name, you can use Amazon Route 53 to point it to your S3 site:&lt;/p&gt;

&lt;p&gt;Create a hosted zone for your domain.&lt;br&gt;
Add an Alias record pointing to the S3 website endpoint.&lt;br&gt;
Make sure your S3 bucket name matches your domain exactly (e.g., example.com) for this to work.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQs
&lt;/h2&gt;

&lt;h4&gt;
  
  
  What is Amazon S3 static website hosting?
&lt;/h4&gt;

&lt;p&gt;Amazon S3 static website hosting allows developers to host HTML, CSS, JavaScript, and media files directly from an S3 bucket without managing servers.&lt;/p&gt;

&lt;h4&gt;
  
  
  Can I host a website on AWS S3 for free?
&lt;/h4&gt;

&lt;p&gt;Yes. Small static websites may fit within the AWS Free Tier limits depending on storage, requests, and bandwidth usage.&lt;/p&gt;

&lt;h4&gt;
  
  
  Do I need EC2 to host a static website on AWS?
&lt;/h4&gt;

&lt;p&gt;No. Static websites can be hosted directly on Amazon S3 without using EC2 instances or backend servers.&lt;/p&gt;

&lt;h4&gt;
  
  
  Can I use a custom domain with S3 website hosting?
&lt;/h4&gt;

&lt;p&gt;Yes. You can connect a custom domain using Amazon Route 53 and point it to the S3 website endpoint.&lt;/p&gt;

&lt;h4&gt;
  
  
  Does Amazon S3 support HTTPS for static websites?
&lt;/h4&gt;

&lt;p&gt;S3 website endpoints do not directly support HTTPS. AWS CloudFront is commonly used to enable HTTPS and CDN support.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Hosting a static website with Amazon S3 is simple and doesn't require a server. You just upload your files, set public access, and turn on website hosting. You can also link a custom domain if you have one.&lt;/p&gt;

&lt;p&gt;Let me know if you need help with custom error pages or adding HTTPS using CloudFront.&lt;/p&gt;

&lt;p&gt;Read More Section&lt;br&gt;
&lt;a href="https://dev.toReduce%20AWS%20Costs%20by%20Rightsizing%20Resources"&gt;Learn practical cloud rightsizing strategies to reduce AWS costs and optimize infrastructure usage.&lt;/a&gt;&lt;br&gt;
&lt;a&gt;Compare ECS EC2 and AWS Fargate for scalability, pricing, and operational overhead.&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.toAWS%20Config%20Compliance%20Policies%20Explained"&gt;Use AWS Config to monitor infrastructure drift and enforce cloud governance policies.&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.toMonitor%20Subnet%20IP%20Exhaustion%20Using%20AWS%20Lambda"&gt;Prevent deployment failures by monitoring available subnet IPs with AWS Lambda and CloudWatch.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>s3</category>
      <category>devops</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Authentication in Kubernetes Gets Complicated Faster Than Most Teams Expect</title>
      <dc:creator>sanjay yadav</dc:creator>
      <pubDate>Wed, 13 May 2026 04:37:34 +0000</pubDate>
      <link>https://dev.to/sanjay_yadav_/authentication-in-kubernetes-gets-complicated-faster-than-most-teams-expect-20d2</link>
      <guid>https://dev.to/sanjay_yadav_/authentication-in-kubernetes-gets-complicated-faster-than-most-teams-expect-20d2</guid>
      <description>&lt;p&gt;One thing I keep noticing in Kubernetes environments is how quickly authentication becomes difficult to manage once multiple internal services and dashboards are involved.&lt;/p&gt;

&lt;p&gt;At first, exposing applications through Ingress feels straightforward.&lt;/p&gt;

&lt;p&gt;But as clusters grow, teams usually end up solving authentication separately for different applications, which slowly turns into duplicated configuration and inconsistent access control across environments.&lt;/p&gt;

&lt;p&gt;The part that makes this setup useful is that authentication gets handled closer to the ingress layer instead of inside every application separately.&lt;/p&gt;

&lt;p&gt;Using OAuth2 Proxy with NGINX Ingress makes it possible to centralize authentication using providers like GitHub or Google while keeping internal services much simpler.&lt;/p&gt;

&lt;p&gt;I came across a useful walkthrough covering this setup here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.kubeblogs.com/authentication-with-oauth2-proxy-and-nginx-ingress-on-kubernetes/" rel="noopener noreferrer"&gt;https://www.kubeblogs.com/authentication-with-oauth2-proxy-and-nginx-ingress-on-kubernetes/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>devops</category>
      <category>security</category>
      <category>nginx</category>
    </item>
  </channel>
</rss>
