<?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: Renato Mendoza</title>
    <description>The latest articles on DEV Community by Renato Mendoza (@rmendoza).</description>
    <link>https://dev.to/rmendoza</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%2F3423234%2Fe0b15b22-e0f0-43ae-84cb-464546f0f212.png</url>
      <title>DEV Community: Renato Mendoza</title>
      <link>https://dev.to/rmendoza</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rmendoza"/>
    <language>en</language>
    <item>
      <title>One-Click Deployments #2: AWS EKS Fargate Cluster Using Terraform and Helm</title>
      <dc:creator>Renato Mendoza</dc:creator>
      <pubDate>Wed, 24 Sep 2025 03:05:02 +0000</pubDate>
      <link>https://dev.to/rmendoza/one-click-deployments-2-aws-eks-fargate-cluster-with-applications-using-terraform-16bk</link>
      <guid>https://dev.to/rmendoza/one-click-deployments-2-aws-eks-fargate-cluster-with-applications-using-terraform-16bk</guid>
      <description>&lt;p&gt;Welcome to my &lt;strong&gt;One-Click AWS EKS Deployment&lt;/strong&gt; tutorial. This is a complete guide to deploying a production-ready EKS Fargate cluster.&lt;/p&gt;

&lt;p&gt;In this post, you'll deploy a &lt;strong&gt;complete EKS Fargate infrastructure with sample application&lt;/strong&gt; using a single Terraform command. No more spending hours setting up VPCs, EKS clusters, RBAC, load balancers, and applications separately. We use &lt;strong&gt;Terraform modules + Helm charts&lt;/strong&gt; to provision everything from network infrastructure to a running nginx website with load balancer automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  What You Get
&lt;/h2&gt;

&lt;p&gt;A single &lt;code&gt;terraform apply&lt;/code&gt; command creates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;🌐 Complete networking infrastructure&lt;/strong&gt; across 2 availability zones

&lt;ul&gt;
&lt;li&gt;VPC with public/private subnets&lt;/li&gt;
&lt;li&gt;Internet Gateway, NAT Gateway with EIP (cost-optimized single NAT)&lt;/li&gt;
&lt;li&gt;Security groups with least-privilege access&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;🚀 Production-ready EKS Fargate cluster&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Managed control plane with Fargate-only execution (no EC2 management)&lt;/li&gt;
&lt;li&gt;AWS Load Balancer Controller for native ALB/NLB integration&lt;/li&gt;
&lt;li&gt;Comprehensive RBAC with IAM Groups (devops, developers, viewers)&lt;/li&gt;
&lt;li&gt;CloudWatch logging and monitoring ready&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;📦 Nginx sample application deployed automatically&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Custom HTML content and health check endpoints&lt;/li&gt;
&lt;li&gt;Kubernetes deployment, service, and ingress resources&lt;/li&gt;
&lt;li&gt;Application Load Balancer with optional custom domain/SSL&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;🔧 Multi-environment support&lt;/strong&gt; for dev, staging, and production configurations&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;Building a production-ready EKS cluster from scratch is complex and time-consuming. You need to understand AWS networking, EKS configuration, Kubernetes RBAC, load balancing, security best practices, and how all these components work together.&lt;/p&gt;

&lt;p&gt;Most tutorials only show you isolated pieces - how to create a VPC, or how to set up EKS, or how to deploy an app. But getting everything to work together securely and reliably? That's where the real challenge lies.&lt;/p&gt;

&lt;p&gt;This solution eliminates the complexity by providing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Proven architecture&lt;/strong&gt; that follows AWS best practices&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Complete automation&lt;/strong&gt; - no manual steps or configuration gaps&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Production-ready security&lt;/strong&gt; with proper RBAC and network isolation&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Working example&lt;/strong&gt; you can immediately extend with your own applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of spending weeks learning and debugging, you get a solid foundation in minutes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Repository Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;one-click-aws-eks/
├── infra/
│   └── envs/              # Root module with environment configs
│       ├── dev/           # Development environment settings
│       ├── staging/       # Staging environment settings
│       └── prod/          # Production environment settings
├── modules/
│   ├── network/           # VPC, subnets, NAT gateway, security groups
│   ├── eks/              # EKS cluster, Fargate profiles, RBAC, Load Balancer Controller
│   └── applications/     # Helm charts for nginx sample application
└── scripts/              # Cleanup and utility scripts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Architecture Overview
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────────────────────────┐
│                                    AWS VPC                                      │
│                                 (10.0.0.0/16)                                  │
│                                                                                 │
│  ┌─────────────────────┐                      ┌─────────────────────┐         │
│  │   Public Tier       │                      │   Public Tier       │         │
│  │  (us-east-1a)       │                      │  (us-east-1b)       │         │
│  │ ┌─────────────────┐ │                      │ ┌─────────────────┐ │         │
│  │ │ Public Subnet   │ │  ┌─────────────────┐ │ │ Public Subnet   │ │         │
│  │ │ 10.0.0.0/20     │◄┼──┤ Internet Gateway ├─┤ 10.0.16.0/20    │ │         │
│  │ └─────────────────┘ │  └─────────────────┘ │ └─────────────────┘ │         │
│  │         │           │                      │                     │         │
│  │    ┌────▼────┐      │                      │                     │         │
│  │    │ ALB     │      │                      │                     │         │
│  │    │(nginx)  │      │                      │                     │         │
│  │    └─────────┘      │                      │                     │         │
│  └─────────────────────┘                      └─────────────────────┘         │
│              │                                                                 │
│  ┌───────────▼─────────┐                               ┌─────────────────────┐ │
│  │   Private App Tier  │                               │   Private App Tier  │ │
│  │    (us-east-1a)     │                               │    (us-east-1b)     │ │
│  │ ┌─────────────────┐ │     ┌─────────────────────┐   │ ┌─────────────────┐ │ │
│  │ │ Private Subnet  │ │     │                     │   │ │ Private Subnet  │ │ │
│  │ │ 10.0.32.0/20    │ │     │      EKS Cluster    │   │ │ 10.0.48.0/20    │ │ │
│  │ └─────────────────┘ │     │   (Control Plane)   │   │ └─────────────────┘ │ │
│  │                     │     │                     │   │                     │ │
│  │ ┌─────────────────┐ │     │   ┌─────────────┐   │   │ ┌─────────────────┐ │ │
│  │ │   EKS Fargate   │◄┼─────┼───┤ API Server  │   │   │ │   EKS Fargate   │ │ │
│  │ │     Pods        │ │     │   └─────────────┘   │   │ │     Pods        │ │ │
│  │ │                 │ │     └─────────────────────┘   │ │                 │ │ │
│  │ │ • nginx-sample  │ │                               │ │ • apps namespace│ │ │
│  │ │ • custom HTML   │ │                               │ │ • ready for     │ │ │
│  │ │ • /health       │ │                               │ │   more apps     │ │ │
│  │ └─────────────────┘ │                               │ └─────────────────┘ │ │
│  └─────────────────────┘                               └─────────────────────┘ │
│                                                                                 │
│  ┌─────────────────────┐                               ┌─────────────────────┐ │
│  │   Private DB Tier   │                               │   Private DB Tier   │ │
│  │    (us-east-1a)     │                               │    (us-east-1b)     │ │
│  │ ┌─────────────────┐ │                               │ ┌─────────────────┐ │ │
│  │ │ Private Subnet  │ │        (Ready for RDS,        │ │ Private Subnet  │ │ │
│  │ │ 10.0.64.0/20    │ │         ElastiCache)         │ │ 10.0.80.0/20    │ │ │
│  │ └─────────────────┘ │                               │ └─────────────────┘ │ │
│  └─────────────────────┘                               └─────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;p&gt;&lt;strong&gt;Required setup:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS account with EKS permissions&lt;/li&gt;
&lt;li&gt;Terraform installed locally&lt;/li&gt;
&lt;li&gt;kubectl installed locally (for post-deployment testing)&lt;/li&gt;
&lt;li&gt;AWS CLI configured with appropriate credentials&lt;/li&gt;
&lt;li&gt;Terraform backend with S3 + DynamoDB (optional but recommended)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Manual Deployment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Clone and setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/rnato35/one-click-aws-eks.git
&lt;span class="nb"&gt;cd &lt;/span&gt;one-click-aws-eks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Configure your environment
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Edit development configuration&lt;/span&gt;
&lt;span class="c"&gt;# Modify infra/envs/dev/terraform.tfvars with your settings:&lt;/span&gt;

&lt;span class="c"&gt;# Basic settings&lt;/span&gt;
region      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;  &lt;span class="c"&gt;# Your preferred AWS region&lt;/span&gt;
aws_profile &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"your-aws-profile"&lt;/span&gt;  &lt;span class="c"&gt;# AWS CLI profile to use&lt;/span&gt;

&lt;span class="c"&gt;# Optional: For public load balancer with custom domain&lt;/span&gt;
nginx_sample_domain_name     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"demo.yourdomain.com"&lt;/span&gt;  &lt;span class="c"&gt;# Your domain&lt;/span&gt;
nginx_sample_certificate_arn &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:acm:us-east-1:ACCOUNT:certificate/YOUR-CERT-ID"&lt;/span&gt;  &lt;span class="c"&gt;# ACM certificate&lt;/span&gt;

&lt;span class="c"&gt;# Or leave these unset for local port-forwarding access&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Deploy with Terraform
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Navigate to infrastructure directory&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;infra/envs

&lt;span class="c"&gt;# Initialize Terraform (with optional remote backend)&lt;/span&gt;
terraform init
&lt;span class="c"&gt;# terraform init -backend-config="bucket=YOUR_BUCKET" -backend-config="key=eks-dev/terraform.tfstate" -backend-config="region=us-east-1"&lt;/span&gt;

&lt;span class="c"&gt;# Deploy everything with one command!&lt;/span&gt;
terraform apply &lt;span class="nt"&gt;-var-file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"dev/terraform.tfvars"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens during deployment (5-15 minutes):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure phase&lt;/strong&gt; (3-8 min): VPC, subnets, EKS cluster, RBAC, Load Balancer Controller&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Applications phase&lt;/strong&gt; (4-8 min): nginx sample app with Kubernetes resources and ingress&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verification&lt;/strong&gt;: Health checks and load balancer readiness&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;All in one Terraform configuration&lt;/strong&gt; - No need to manage separate infrastructure and application deployments!&lt;/p&gt;




&lt;h2&gt;
  
  
  What Gets Deployed in Detail
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🌐 Networking Infrastructure
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;VPC&lt;/strong&gt;: 10.0.0.0/16 with DNS support across 2 availability zones&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public subnets&lt;/strong&gt;: For load balancers (10.0.0.0/20, 10.0.16.0/20)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private subnets&lt;/strong&gt;: For EKS Fargate workloads (10.0.32.0/20, 10.0.48.0/20)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Single NAT Gateway&lt;/strong&gt;: Cost-optimized outbound internet access (~50% cost reduction)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security Groups&lt;/strong&gt;: Least-privilege firewall rules for EKS and load balancers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Route Tables&lt;/strong&gt;: Proper routing for public/private subnet traffic&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🚀 EKS Cluster Components
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Managed control plane&lt;/strong&gt;: High availability, managed by AWS across multiple AZs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fargate profiles&lt;/strong&gt;: Serverless container execution for default, kube-system, and apps namespaces&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OIDC provider&lt;/strong&gt;: For secure Kubernetes service account authentication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EKS add-ons&lt;/strong&gt;: VPC CNI, CoreDNS, kube-proxy (auto-managed versions)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Load Balancer Controller&lt;/strong&gt;: Native integration with ALB/NLB via Helm deployment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudWatch logging&lt;/strong&gt;: API server and audit logs with configurable retention&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔒 Security &amp;amp; RBAC
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Comprehensive IAM Groups-based access control&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;🔴 &lt;strong&gt;eks-devops&lt;/strong&gt;: Full cluster administration access (platform team)&lt;/li&gt;
&lt;li&gt;🟡 &lt;strong&gt;eks-developers&lt;/strong&gt;: Namespace-scoped access with read/write in apps, read-only elsewhere&lt;/li&gt;
&lt;li&gt;🟢 &lt;strong&gt;eks-viewers&lt;/strong&gt;: Read-only cluster access for monitoring and troubleshooting&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Assumable IAM roles&lt;/strong&gt;: Team members assume roles based on group membership&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Service accounts&lt;/strong&gt;: Secure pod-level AWS permissions using OIDC&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Network isolation&lt;/strong&gt;: Private subnets with no direct internet access&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Encryption&lt;/strong&gt;: EKS secrets encryption and secure communication&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  📦 Sample Nginx Application (Automatically Deployed)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Custom HTML content&lt;/strong&gt;: Professional landing page with architecture information&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health endpoint&lt;/strong&gt;: &lt;code&gt;/health&lt;/code&gt; for application monitoring and load balancer health checks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production-ready Kubernetes resources&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Deployment with configurable replicas and resource limits&lt;/li&gt;
&lt;li&gt;Service for internal load balancing&lt;/li&gt;
&lt;li&gt;Ingress for external access with SSL termination&lt;/li&gt;
&lt;li&gt;ConfigMaps for HTML content and nginx configuration&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Load balancer options&lt;/strong&gt;: Public ALB with custom domain/SSL OR local port-forwarding&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Post-Deployment: Access Your Website &amp;amp; Cluster
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Set up cluster access (for admins)
&lt;/h3&gt;

&lt;p&gt;Add your IAM user to the appropriate IAM Group, then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Assume the cluster admin role&lt;/span&gt;
aws sts assume-role &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--role-arn&lt;/span&gt; arn:aws:iam::ACCOUNT:role/one-click-dev-eks-cluster-admins &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--role-session-name&lt;/span&gt; admin-session

&lt;span class="c"&gt;# Export the temporary credentials, then configure kubectl&lt;/span&gt;
aws eks update-kubeconfig &lt;span class="nt"&gt;--name&lt;/span&gt; one-click-dev-eks &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1

&lt;span class="c"&gt;# Verify cluster access&lt;/span&gt;
kubectl get nodes
kubectl get namespaces
kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; apps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Access your website
&lt;/h3&gt;

&lt;p&gt;There are &lt;strong&gt;two options&lt;/strong&gt; to visualize the nginx sample application:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 1: Public ALB with Custom Domain (Production-ready)&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Configure a certificate and put its ARN in the &lt;code&gt;nginx_sample_certificate_arn&lt;/code&gt; variable&lt;/li&gt;
&lt;li&gt;Set your custom domain in the &lt;code&gt;nginx_sample_domain_name&lt;/code&gt; variable&lt;/li&gt;
&lt;li&gt;Access via your custom domain over HTTPS&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Option 2: Local Port Forwarding (Development/Testing)&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Don't define the certificate and domain variables&lt;/li&gt;
&lt;li&gt;Use kubectl port forwarding to access the service locally:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Forward local port to the nginx service&lt;/span&gt;
kubectl port-forward &lt;span class="nt"&gt;-n&lt;/span&gt; apps service/nginx-sample 8080:80

&lt;span class="c"&gt;# Visit your website locally&lt;/span&gt;
curl http://localhost:8080/architecture
curl http://localhost:8080/health
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;For Option 1 (Public ALB):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Get the load balancer URL&lt;/span&gt;
kubectl get ingress &lt;span class="nt"&gt;-n&lt;/span&gt; apps

&lt;span class="c"&gt;# Visit your website&lt;/span&gt;
curl http://&amp;lt;your-alb-dns-name&amp;gt;/architecture

&lt;span class="c"&gt;# Test health endpoint&lt;/span&gt;
curl http://&amp;lt;your-alb-dns-name&amp;gt;/health
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Test RBAC with different roles
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# For developers (namespace-scoped access)&lt;/span&gt;
aws sts assume-role &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--role-arn&lt;/span&gt; arn:aws:iam::ACCOUNT:role/one-click-dev-eks-developers &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--role-session-name&lt;/span&gt; dev-session

&lt;span class="c"&gt;# Test permissions&lt;/span&gt;
kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; apps              &lt;span class="c"&gt;# ✅ Allowed  &lt;/span&gt;
kubectl get nodes                     &lt;span class="c"&gt;# ✅ Allowed (read-only)&lt;/span&gt;
kubectl delete namespace kube-system  &lt;span class="c"&gt;# ❌ Forbidden&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Deployment Process Explained
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Unified Deployment Process
&lt;/h3&gt;

&lt;p&gt;This project uses &lt;strong&gt;a single Terraform configuration&lt;/strong&gt; that handles everything:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Infrastructure deployment&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VPC, subnets, EKS cluster, load balancer controller&lt;/li&gt;
&lt;li&gt;All networking components and security groups&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Applications deployment&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;nginx sample app and all Kubernetes resources&lt;/li&gt;
&lt;li&gt;Deployed automatically after infrastructure is ready&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Environment Management
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Terraform workspaces&lt;/strong&gt;: Isolate state for different environments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separate tfvars files&lt;/strong&gt;: Environment-specific configurations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sequential deployment&lt;/strong&gt;: Infrastructure first, then applications automatically&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Environment Isolation
&lt;/h3&gt;

&lt;p&gt;Each environment uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Separate tfvars files (&lt;code&gt;dev/&lt;/code&gt;, &lt;code&gt;staging/&lt;/code&gt;, &lt;code&gt;prod/&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Different cluster names and configurations&lt;/li&gt;
&lt;li&gt;Isolated AWS resources and namespaces&lt;/li&gt;
&lt;li&gt;Terraform workspace isolation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  IAM Groups Integration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Automatic creation&lt;/strong&gt;: IAM Groups are created for each cluster&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User management&lt;/strong&gt;: Add IAM users to groups for appropriate access&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Role assumption&lt;/strong&gt;: Users assume roles based on group membership&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MFA support&lt;/strong&gt;: Optional MFA requirements for role assumption&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Advanced Features
&lt;/h2&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fargate pricing&lt;/strong&gt;: Pay-per-pod, no idle EC2 instances&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource limits&lt;/strong&gt;: Prevent resource waste in containers&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Production Readiness
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multi-AZ deployment&lt;/strong&gt;: High availability by default&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health checks&lt;/strong&gt;: Application-aware load balancer probes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto scaling&lt;/strong&gt;: Horizontal Pod Autoscaler ready&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring&lt;/strong&gt;: CloudWatch integration ready for extension&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extensibility
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Modular design&lt;/strong&gt;: Add applications via additional Helm charts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RBAC foundation&lt;/strong&gt;: Easy to add users to IAM Groups&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 Call to Action
&lt;/h2&gt;

&lt;p&gt;Deploy your own production-ready EKS Fargate cluster with &lt;strong&gt;one command&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔗 &lt;a href="https://github.com/rnato35/one-click-aws-eks" rel="noopener noreferrer"&gt;GitHub Repository: one-click-aws-eks&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This Terraform solution gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Complete EKS infrastructure in 10-15 minutes&lt;/li&gt;
&lt;li&gt;✅ Working nginx application with load balancer&lt;/li&gt;
&lt;li&gt;✅ Comprehensive RBAC ready for your team&lt;/li&gt;
&lt;li&gt;✅ Multi-environment support (dev/staging/prod)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Perfect starting point for your next Kubernetes project on AWS!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Found this helpful? ⭐ Star the repository and let me know what you'd like to see deployed with one click next!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>kubernetes</category>
      <category>terraform</category>
      <category>devops</category>
    </item>
    <item>
      <title>Building Production-Ready AWS Three-Tier Architecture with Terraform and GitOps</title>
      <dc:creator>Renato Mendoza</dc:creator>
      <pubDate>Sun, 21 Sep 2025 20:19:43 +0000</pubDate>
      <link>https://dev.to/rmendoza/building-production-ready-aws-three-tier-architecture-with-terraform-and-gitops-1kfn</link>
      <guid>https://dev.to/rmendoza/building-production-ready-aws-three-tier-architecture-with-terraform-and-gitops-1kfn</guid>
      <description>&lt;p&gt;Modern web applications demand scalable, secure, and maintainable infrastructure. This project demonstrates how to deploy a complete three-tier architecture on AWS using Terraform with professional CI/CD workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You'll Build
&lt;/h2&gt;

&lt;p&gt;A production-ready architecture featuring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Web Tier&lt;/strong&gt;: Application Load Balancer with SSL termination and Auto Scaling Groups&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application Tier&lt;/strong&gt;: EC2 instances running PHP web application in private subnets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database Tier&lt;/strong&gt;: RDS MySQL with Multi-AZ support and encrypted storage&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🔒 Security First
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Private subnets for application and database tiers&lt;/li&gt;
&lt;li&gt;AWS Secrets Manager integration for database credentials&lt;/li&gt;
&lt;li&gt;OIDC authentication (no long-term AWS keys)&lt;/li&gt;
&lt;li&gt;Security groups with least-privilege access&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🚀 GitOps Workflow
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Environment-specific branches (&lt;code&gt;env/dev&lt;/code&gt;, &lt;code&gt;env/staging&lt;/code&gt;, &lt;code&gt;env/prod&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Automated Terraform validation and planning on PRs&lt;/li&gt;
&lt;li&gt;Manual approval gates for production deployments&lt;/li&gt;
&lt;li&gt;Safe destroy workflows with confirmation requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📊 Infrastructure as Code
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Modular Terraform design for reusability&lt;/li&gt;
&lt;li&gt;Remote state management with S3 and DynamoDB&lt;/li&gt;
&lt;li&gt;Environment-specific configurations&lt;/li&gt;
&lt;li&gt;Comprehensive output values&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws-three-tier-terraform-cicd/
├── .github/workflows/
│   └── terraform.yaml         # CI/CD pipeline
├── docs/
│   └── MANUAL_WORKFLOWS.md    # Manual workflow documentation
├── infra/envs/
│   ├── dev/                   # Development environment config
│   │   └── terraform.tfvars   # Dev-specific variables
│   ├── staging/               # Staging environment config
│   │   └── terraform.tfvars   # Staging-specific variables
│   ├── prod/                  # Production environment config
│   │   └── terraform.tfvars   # Production-specific variables
│   ├── main.tf                # Main infrastructure configuration
│   ├── variables.tf           # Input variables
│   ├── locals.tf              # Local values
│   └── versions.tf            # Terraform and provider versions
├── modules/
│   ├── application/           # Application tier module
│   │   ├── main.tf            # Application module implementation
│   │   ├── variables.tf       # Application module variables
│   │   └── outputs.tf         # Application module outputs
│   └── network/               # Network tier module
│       ├── main.tf            # Network module implementation
│       ├── variables.tf       # Network module variables
│       └── outputs.tf         # Network module outputs
└── scripts/                   # Helper scripts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fork the repository&lt;/strong&gt; and configure GitHub secrets:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   DB_PASSWORD          # Database password
   AWS_ROLE_ARN         # OIDC role ARN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For detailed instructions on setting up OIDC authentication and configuring the Terraform backend, see: &lt;a href="https://github.com/rnato35/one-click-aws-terraform-backend-gitops-oidc" rel="noopener noreferrer"&gt;one-click-aws-terraform-backend-gitops-oidc&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Set GitHub variables&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   AWS_REGION           # Target AWS region
   TF_BACKEND_*         # Terraform backend config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Configure environment&lt;/strong&gt; by copying &lt;code&gt;terraform.tfvars.example&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;   &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-west-2"&lt;/span&gt;
   &lt;span class="nx"&gt;env_name&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"dev"&lt;/span&gt;
   &lt;span class="nx"&gt;certificate_arn&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:acm:..."&lt;/span&gt;
   &lt;span class="nx"&gt;domain_name&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"yourdomain.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Deploy using GitOps&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Create PR to environment branches → Terraform format check, validation, and plan&lt;/li&gt;
&lt;li&gt;Merge to &lt;code&gt;env/dev&lt;/code&gt; → Deploy to development&lt;/li&gt;
&lt;li&gt;Merge to &lt;code&gt;env/staging&lt;/code&gt; → Deploy to staging&lt;/li&gt;
&lt;li&gt;Merge to &lt;code&gt;env/prod&lt;/code&gt; → Deploy to production (with manual approval)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  CI/CD Pipeline Highlights
&lt;/h2&gt;

&lt;p&gt;The GitHub Actions workflow provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Automated Planning&lt;/strong&gt;: Terraform plans run on every PR with results commented&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Environment Isolation&lt;/strong&gt;: Separate workspaces for dev/staging/prod&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security Gates&lt;/strong&gt;: Manual approval required for production changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safe Destruction&lt;/strong&gt;: Multi-step confirmation for infrastructure teardown&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Credentials are handled through multiple security layers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Secrets&lt;/strong&gt; store the master password&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Secrets Manager&lt;/strong&gt; receives the password via CI/CD&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IAM Roles&lt;/strong&gt; allow EC2 instances to retrieve credentials&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Hardcoding&lt;/strong&gt; - passwords never appear in code or state&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Production Considerations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Configure DNS manually (project doesn't create Route53 records)&lt;/li&gt;
&lt;li&gt;Enable VPC Flow Logs for network monitoring&lt;/li&gt;
&lt;li&gt;Use remote state backend for team collaboration&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why This Approach Works
&lt;/h2&gt;

&lt;p&gt;This architecture pattern provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: Auto Scaling Groups handle traffic spikes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: Multi-layered security with private networking&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliability&lt;/strong&gt;: Multi-AZ deployment with load balancing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintainability&lt;/strong&gt;: Modular Terraform with GitOps workflows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost Efficiency&lt;/strong&gt;: Environment-specific scaling configurations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ready to deploy enterprise-grade infrastructure? Check out the &lt;a href="https://github.com/rnato35/aws-three-tier-terraform-cicd" rel="noopener noreferrer"&gt;full repository&lt;/a&gt; for complete implementation details.&lt;/p&gt;




</description>
      <category>architecture</category>
      <category>aws</category>
      <category>terraform</category>
      <category>devops</category>
    </item>
    <item>
      <title>One-Click Deployments #1: Bootstrap a GitOps-Ready AWS Terraform Backend with GitHub Actions (OIDC)</title>
      <dc:creator>Renato Mendoza</dc:creator>
      <pubDate>Tue, 12 Aug 2025 18:23:52 +0000</pubDate>
      <link>https://dev.to/rmendoza/-one-click-deployments-1-bootstrap-a-gitops-ready-aws-terraform-backend-with-github-actions-49n2</link>
      <guid>https://dev.to/rmendoza/-one-click-deployments-1-bootstrap-a-gitops-ready-aws-terraform-backend-with-github-actions-49n2</guid>
      <description>&lt;p&gt;Welcome to the first post in my &lt;strong&gt;One-Click Deployments&lt;/strong&gt; series. In this series, we build infrastructure with as little manual setup as possible.&lt;/p&gt;

&lt;p&gt;In this post, you will bootstrap a &lt;strong&gt;secure AWS Terraform backend in one command&lt;/strong&gt;. No more storing &lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt; and &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt; in GitHub secrets. We use &lt;strong&gt;GitHub Actions + OpenID Connect (OIDC)&lt;/strong&gt; to assume an AWS IAM role at runtime, avoiding long-lived credentials entirely.&lt;/p&gt;




&lt;h2&gt;
  
  
  What You Get
&lt;/h2&gt;

&lt;p&gt;A single &lt;code&gt;terraform apply&lt;/code&gt; in &lt;code&gt;infra/bootstrap&lt;/code&gt; creates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;S3 bucket&lt;/strong&gt; for Terraform state

&lt;ul&gt;
&lt;li&gt;Versioning enabled, SSE-KMS with a customer-managed key, bucket key enabled
&lt;/li&gt;
&lt;li&gt;Public access blocked, TLS-only bucket policy
&lt;/li&gt;
&lt;li&gt;Lifecycle to expire noncurrent versions after 365 days
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;DynamoDB table&lt;/strong&gt; for state locking on-demand
&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;KMS key&lt;/strong&gt; with rotation enabled, alias created
&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;GitHub OIDC provider&lt;/strong&gt; in AWS
&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;IAM role&lt;/strong&gt; for GitHub Actions with least-privilege backend access
&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;backend.generated.hcl&lt;/code&gt; written for you&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;Setting up a secure Terraform backend is usually tedious:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create and secure an S3 bucket
&lt;/li&gt;
&lt;li&gt;Add DynamoDB for state locking
&lt;/li&gt;
&lt;li&gt;Provision and wire a KMS key
&lt;/li&gt;
&lt;li&gt;Write and distribute backend config
&lt;/li&gt;
&lt;li&gt;Create an IAM role with correct trust
&lt;/li&gt;
&lt;li&gt;Configure OIDC
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This template does it in &lt;strong&gt;one go&lt;/strong&gt; and wires your GitOps workflow on branches &lt;code&gt;env/dev&lt;/code&gt;, &lt;code&gt;env/staging&lt;/code&gt;, &lt;code&gt;env/prod&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Repository Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;one-click-aws-terraform-backend-gitops-oidc/
├── infra/
│   ├── bootstrap/      # Creates S3, DynamoDB, KMS, OIDC, IAM role
│   └── envs/           # Root stack using the generated backend
└── .github/
    └── workflows/
        └── terraform.yaml  # GitOps workflow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;ul&gt;
&lt;li&gt;AWS account and credentials locally with permissions for IAM, S3, DynamoDB, and KMS
&lt;/li&gt;
&lt;li&gt;AWS CLI configured
&lt;/li&gt;
&lt;li&gt;Terraform 1.6 or newer
&lt;/li&gt;
&lt;li&gt;A GitHub repo with environments: dev, staging, prod
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Clone the repository&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/rnato35/one-click-aws-terraform-backend-gitops-oidc.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Initialize and apply Terraform&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ./one-click-aws-terraform-backend-gitops-oidc/infra/bootstrap &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; terraform init
terraform apply &lt;span class="nt"&gt;-var&lt;/span&gt; &lt;span class="s1"&gt;'github_org=&amp;lt;your-gh-org-or-user&amp;gt;'&lt;/span&gt; &lt;span class="nt"&gt;-var&lt;/span&gt; &lt;span class="s1"&gt;'github_repo=&amp;lt;your-github-repo&amp;gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


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

&lt;ul&gt;
&lt;li&gt;The current trust policy matches &lt;code&gt;repo:&amp;lt;org&amp;gt;/&amp;lt;repo&amp;gt;:*&lt;/code&gt; by default.&lt;/li&gt;
&lt;li&gt;Branch filtering is enforced by GitHub Environments and branch protections.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Copy outputs to GitHub variables and secrets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repository variables:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;TF_BACKEND_BUCKET&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;bucket_name&amp;gt;&lt;/span&gt;
&lt;span class="py"&gt;TF_BACKEND_REGION&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;region&amp;gt;&lt;/span&gt;
&lt;span class="py"&gt;TF_BACKEND_DDB_TABLE&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;dynamodb_table_name&amp;gt;&lt;/span&gt;
&lt;span class="py"&gt;TF_BACKEND_KMS_KEY_ID&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;kms_key_arn&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;strong&gt;Environment secrets (dev, staging, prod):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;AWS_ROLE_ARN&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;github_role_arn_from_outputs&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  GitOps Flow Explained
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Branch Mapping
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;env/dev&lt;/code&gt; → GitHub environment &lt;code&gt;dev&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;env/staging&lt;/code&gt; → GitHub environment &lt;code&gt;staging&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;env/prod&lt;/code&gt; → GitHub environment &lt;code&gt;prod&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pull requests&lt;/strong&gt; targeting &lt;code&gt;env/*&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;plan&lt;/code&gt; only
&lt;/li&gt;
&lt;li&gt;Selects workspace based on PR base branch
&lt;/li&gt;
&lt;li&gt;Uses per-env tfvars (dev, staging, prod)
&lt;/li&gt;
&lt;li&gt;Posts plan in logs
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pushes&lt;/strong&gt; to &lt;code&gt;env/*&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;apply&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Selects workspace and env tfvars automatically
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Production (&lt;code&gt;env/prod&lt;/code&gt;)&lt;/strong&gt; requires a manual approval step before apply  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Approvers can be changed in:
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="err"&gt;.github/workflows/terraform.yaml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Credentials
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Uses OIDC to assume &lt;code&gt;AWS_ROLE_ARN&lt;/code&gt; from the target GitHub environment
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Backend Wiring
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;terraform init&lt;/code&gt; receives &lt;code&gt;-backend-config&lt;/code&gt; values from repository variables &lt;code&gt;TF_BACKEND_*&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The same remote state is used locally via &lt;code&gt;backend.generated.hcl&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Recommended Guardrails
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Protect &lt;code&gt;env/staging&lt;/code&gt; and &lt;code&gt;env/prod&lt;/code&gt; branches
&lt;/li&gt;
&lt;li&gt;Require reviewers in GitHub Environments &lt;code&gt;staging&lt;/code&gt; and &lt;code&gt;prod&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Scope the IAM role to least privilege only the resources your infra needs
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What the Bootstrap Creates in Detail
&lt;/h2&gt;

&lt;h3&gt;
  
  
  KMS Key
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;enable_key_rotation = true&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;7-day deletion window
&lt;/li&gt;
&lt;li&gt;Alias: &lt;code&gt;alias/&amp;lt;name_prefix&amp;gt;-tfstate&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  S3 Bucket for State
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Versioning on
&lt;/li&gt;
&lt;li&gt;SSE-KMS using the CMK, bucket key enabled
&lt;/li&gt;
&lt;li&gt;Public access block on
&lt;/li&gt;
&lt;li&gt;TLS-only bucket policy
&lt;/li&gt;
&lt;li&gt;Lifecycle to expire noncurrent versions after 365 days
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  DynamoDB Table for Locks
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;PAY_PER_REQUEST
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  backend.generated.hcl Content
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;bucket&lt;/code&gt;, &lt;code&gt;key = global/terraform.tfstate&lt;/code&gt;, &lt;code&gt;region&lt;/code&gt;, &lt;code&gt;encrypt&lt;/code&gt;, &lt;code&gt;kms_key_id&lt;/code&gt;, &lt;code&gt;dynamodb_table&lt;/code&gt;, &lt;code&gt;acl = private&lt;/code&gt;, &lt;code&gt;workspace_key_prefix = envs&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  GitHub OIDC Provider and IAM Role
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Trust: &lt;code&gt;repo:&amp;lt;org&amp;gt;/&amp;lt;repo&amp;gt;:*&lt;/code&gt; with &lt;code&gt;aud = sts.amazonaws.com&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Inline policy for backend access: S3 objects + List, DynamoDB lock item CRUD, KMS use for state
&lt;/li&gt;
&lt;li&gt;Managed policy attachments via &lt;code&gt;github_oidc_managed_policy_arns&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Inline policies loaded from &lt;code&gt;Policy/*.json&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Important default:&lt;/strong&gt; All JSON policies found in &lt;code&gt;infra/bootstrap/Policy&lt;/code&gt; are attached as inline policies. The repository includes a couple of &lt;strong&gt;example&lt;/strong&gt; policies you can adapt to your needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Policy/TerraformAdminNoBilling.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Policy/TerraformBillingAccess.json&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Review and remove or replace these files to meet your least-privilege needs before applying in production.&lt;/p&gt;




&lt;h2&gt;
  
  
  Call to Action
&lt;/h2&gt;

&lt;p&gt;Try the repo and deploy your backend in &lt;strong&gt;one click&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/rnato35/one-click-aws-terraform-backend-gitops-oidc" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>aws</category>
      <category>terraform</category>
      <category>githubactions</category>
    </item>
  </channel>
</rss>
