<?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: Elijah Chimera</title>
    <description>The latest articles on DEV Community by Elijah Chimera (@chimera2).</description>
    <link>https://dev.to/chimera2</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3908132%2F791dd53f-c2c4-43d8-a99b-f4d0e172b92d.png</url>
      <title>DEV Community: Elijah Chimera</title>
      <link>https://dev.to/chimera2</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chimera2"/>
    <language>en</language>
    <item>
      <title>Designing a Secure-by-Default DevSecOps Pipeline on AWS.</title>
      <dc:creator>Elijah Chimera</dc:creator>
      <pubDate>Mon, 15 Jun 2026 20:50:17 +0000</pubDate>
      <link>https://dev.to/chimera2/designing-a-secure-by-default-devsecops-pipeline-on-aws-def</link>
      <guid>https://dev.to/chimera2/designing-a-secure-by-default-devsecops-pipeline-on-aws-def</guid>
      <description>&lt;p&gt;&lt;strong&gt;Project Overview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hello! it has been a while since I last posted&amp;nbsp;, I have been working on and learning how to architect production grade CI/CD pipeline in a two part series I call &lt;strong&gt;&lt;em&gt;"The AWS Defense in Depth Architecture: From Pipeline to Runtime"&lt;/em&gt;&lt;/strong&gt;. As cloud architectures grow in complexity, the traditional lines between engineering, operations, and security have vanished. You cannot effectively design an enterprise AWS environment without understanding exactly how an adversary might exploit it.&lt;/p&gt;

&lt;p&gt;In this two-part series, we are bridging the gap between offensive security tactics and defensive cloud architecture. We aren't just going to look at diagrams; we are going to build a workload, deliberately break into it to understand the blast radius, and then engineer robust solutions to keep attackers out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Part 1 (This Article):&lt;/strong&gt; Focuses on the &lt;strong&gt;Shift-Left&lt;/strong&gt; paradigm. We will build an EKS pipeline, simulate a container breakout, and harden the architecture using IaC scanning, CI/CD gates, and strict IAM least privilege.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Part 2:&lt;/strong&gt; Focuses on the &lt;strong&gt;Assume Breach&lt;/strong&gt; mindset. We will architect a zero-cost, event-driven runtime defense engine using Falco, Amazon EventBridge, and AWS Lambda to detect and automatically remediate active threats inside our cluster.&lt;/p&gt;

&lt;p&gt;In the modern era a Solutions Architect's role extends far beyond simply connecting cloud services; they are the gatekeepers of an organization's blast radius. Modern cloud architecture demands that security is not an afterthought handled by a separate silo, but a foundational element baked into the Infrastructure as Code (IaC) and deployment pipelines.&lt;/p&gt;

&lt;p&gt;I have not yet secured a role but I once worked in an incubator startup right here in Nairobi for less than a month&amp;nbsp;, I frequently saw the same anti-patterns:&amp;nbsp;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The "Just Works" Anti-Pattern:&lt;/strong&gt; Rushing to production prioritizing functionality over security, resulting in overly permissive roles and unpatched containers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Node-Level Over-Permissioning:&lt;/strong&gt; Making the beginner mistake of attaching massive blast-radius policies (like AmazonS3FullAccess) to the node's environment rather than restricting permissions at the application pod level.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bloated Container Images:&lt;/strong&gt; Using generic, heavy Docker images that contain hundreds of unnecessary OS packages, drastically increasing the attack surface.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lack of Automated Gates:&lt;/strong&gt; Relying on basic "Build -&amp;gt; Push -&amp;gt; Deploy" pipelines without automated checks, which requires manual review overhead and allows misconfigurations to incur operational risk or downtime.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, we will build a realistic, production-grade AWS Elastic Kubernetes Service (EKS) workload, deliberately leave it vulnerable, act as the red team to exploit it, and finally, harden it using industry-standard DevSecOps practices.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Blast radius&lt;/strong&gt; this is a term used in software development to refer to the potential impact of a failure within a system caused by a security breach, software bug or a misconfiguration.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;**Disclaimer:&lt;/em&gt;* The vulnerable configurations presented here are for educational lab environments only. Never deploy them to production.*&lt;/p&gt;




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

&lt;p&gt;In enterprise environments, a single overly permissive IAM role or a vulnerable base image can lead to a catastrophic breach. When reviewing pipelines and architectures, Solutions Architects should use the following framework:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Platform and Orchestration Trade-offs&lt;/strong&gt;: For this workload, we choose Amazon EKS over ECS. While ECS is simpler and tightly integrated, EKS is the enterprise standard and enables powerful native controls like OIDC-backed IAM Roles for Service Accounts (IRSA).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;IaC and Pipeline Tooling&lt;/strong&gt;: Standardize on tools like Terraform for reliable state management and GitHub Actions to enforce automated security gates while minimizing external dependencies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shift-Left Automation&lt;/strong&gt;: Continuous scanning must be placed at the Pull Request (PR) stage. You must physically prevent developers from merging misconfigured code by enforcing failure states (e.g., exit-code: '1') using tools like TruffleHog, tfsec, and Trivy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Defense in Depth&lt;/strong&gt;: Verify that security controls are layered across the IaC layer, the pipeline layer, the container layer, and the AWS API layer.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flqd0f05a42t1nveqnobl.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%2Flqd0f05a42t1nveqnobl.png" alt=" " width="800" height="266"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Prerequisites &amp;amp; Lab Setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To follow along in your own AWS account, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An active AWS Account (Note: EKS incurs a ~$73/month control plane fee. &lt;strong&gt;Remember to destroy resources when finished&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;AWS CLI installed and configured with Administrator access.&lt;/li&gt;
&lt;li&gt;Terraform (v1.5+), &lt;code&gt;kubectl&lt;/code&gt;, and Docker installed locally.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's get your local workspace ready. Open your terminal and run:&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;# Step 1: Create your project workspace&lt;/span&gt;
&lt;span class="nb"&gt;mkdir &lt;/span&gt;my-eks-devsecops-lab
&lt;span class="nb"&gt;cd &lt;/span&gt;my-eks-devsecops-lab

&lt;span class="c"&gt;# Step 2: Create the required folder structure&lt;/span&gt;
&lt;span class="nb"&gt;mkdir &lt;/span&gt;infrastructure src k8s .github
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; .github/workflows

&lt;span class="c"&gt;# Step 3: Verify AWS authentication&lt;/span&gt;
aws sts get-caller-identity

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Phase 1: Building the Vulnerable Baseline (Common Anti-Patterns)
&lt;/h2&gt;

&lt;p&gt;We begin with a scenario I see frequently: code that "just works." We will deploy an EKS cluster and a Python app that reads data from S3. However, we are making a classic beginner mistake: giving the underlying EC2 node full access to S3, rather than restricting permissions to the specific application pod.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Provision the Insecure Infrastructure.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a file inside the &lt;code&gt;infrastructure&lt;/code&gt; folder named &lt;code&gt;main.tf&lt;/code&gt;. This sets up a basic EKS cluster but attaches a massive blast-radius policy (&lt;code&gt;AmazonS3FullAccess&lt;/code&gt;) to the node group.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&amp;gt;= 1.5.0"&lt;/span&gt;
  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="p"&gt;=&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;"hashicorp/aws"&lt;/span&gt;
      &lt;span class="c1"&gt;# LOCK PRODUCER: Pin to an older v5 release before they removed legacy EKS properties&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.31.0"&lt;/span&gt; 
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Vulnerable IAM Role for EKS Nodes&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role"&lt;/span&gt; &lt;span class="s2"&gt;"insecure_node_role"&lt;/span&gt; &lt;span class="p"&gt;{&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;"insecure-eks-node-role"&lt;/span&gt;
  &lt;span class="nx"&gt;assume_role_policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsonencode&lt;/span&gt;&lt;span class="p"&gt;({&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;"2012-10-17"&lt;/span&gt;
    &lt;span class="nx"&gt;Statement&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
      &lt;span class="nx"&gt;Action&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;
      &lt;span class="nx"&gt;Effect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
      &lt;span class="nx"&gt;Principal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ec2.amazonaws.com"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}]&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# The Anti-Pattern: Giving the whole node full S3 access&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role_policy_attachment"&lt;/span&gt; &lt;span class="s2"&gt;"s3_full_access"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;role&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;insecure_node_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;policy_arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:iam::aws:policy/AmazonS3FullAccess"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# EKS Cluster (Kept at v19 natively matching your workspace cache)&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="s2"&gt;"eks"&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/eks/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;"19.21.0"&lt;/span&gt;
  &lt;span class="nx"&gt;cluster_name&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"devsecops-lab-cluster"&lt;/span&gt;
  &lt;span class="nx"&gt;cluster_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1.30"&lt;/span&gt;

  &lt;span class="nx"&gt;vpc_id&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"vpc-12345678"&lt;/span&gt;                &lt;span class="c1"&gt;# Replace with your Default VPC ID&lt;/span&gt;
  &lt;span class="nx"&gt;subnet_ids&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"subnet-123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"subnet-456"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# Replace with your subnets&lt;/span&gt;


&lt;span class="c1"&gt;# --- ADD THESE TWO LINES TO ENABLE PUBLIC ENDPOINT ACCESS ---&lt;/span&gt;
  &lt;span class="nx"&gt;cluster_endpoint_public_access&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;cluster_endpoint_private_access&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="c1"&gt;# -----------------------------------------------------------&lt;/span&gt;

&lt;span class="nx"&gt;eks_managed_node_groups&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;vulnerable_nodes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;min_size&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
      &lt;span class="nx"&gt;max_size&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
      &lt;span class="nx"&gt;desired_size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
      &lt;span class="nx"&gt;iam_role_arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;insecure_node_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbb65ls7swm0i4iyyb5xs.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%2Fbb65ls7swm0i4iyyb5xs.png" alt=" " width="580" height="670"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This Terraform configuration provisions the networking and compute resources for our Kubernetes cluster. The critical security flaw here is the &lt;code&gt;aws_iam_role_policy_attachment&lt;/code&gt;. By attaching &lt;code&gt;AmazonS3FullAccess&lt;/code&gt; to the &lt;code&gt;insecure_node_role&lt;/code&gt;, we are granting every pod running on this EC2 instance full administrative control over all S3 buckets in the AWS account.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Deploy the infrastructure (this takes ~15 minutes):&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;cd &lt;/span&gt;infrastructure
terraform init
terraform apply &lt;span class="nt"&gt;-auto-approve&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; ..

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Build the Vulnerable Application&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, we write a simple script that grabs data from S3, assuming permissions are handled by the node's environment. Create &lt;code&gt;src/app.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# src/app.py
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;read_s3&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# ANTI-PATTERN: Relies entirely on the node's underlying IAM role
&lt;/span&gt;    &lt;span class="n"&gt;s3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s3&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list_buckets&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;buckets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;bucket&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Buckets&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;I can see all these buckets: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buckets&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# ANTI-PATTERN: Running as root on all interfaces
&lt;/span&gt;    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;0.0.0.0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwbbjkwi0uep4j5fivb6r.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%2Fwbbjkwi0uep4j5fivb6r.png" alt=" " width="580" height="670"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Notice that the &lt;code&gt;boto3.client&lt;/code&gt; call does not pass any explicit AWS credentials. It blindly trusts the overarching environment (the EC2 Node) to provide access. Furthermore, the app binds to &lt;code&gt;0.0.0.0&lt;/code&gt;, exposing it to the entire network&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Create &lt;code&gt;src/requirements.txt&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flask==2.2.2
boto3==1.26.0
werkzeug==2.2.2

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

&lt;/div&gt;



&lt;p&gt;Create the insecure &lt;code&gt;Dockerfile&lt;/code&gt; in the &lt;code&gt;src&lt;/code&gt; folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# src/Dockerfile&lt;/span&gt;
&lt;span class="c"&gt;# ANTI-PATTERN: Bloated image, running as root&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:3.9 &lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; requirements.txt .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8080&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["python", "app.py"]&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0epdpnm9wc4hxiwu17km.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%2F0epdpnm9wc4hxiwu17km.png" alt=" " width="580" height="670"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Deploy to EKS.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Build, tag, and push the image to AWS ECR, and deploy it to Kubernetes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build the Docker image&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;bash
&lt;span class="c"&gt;# 1. Move up one level into your project root directory&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;secure-eks-pipeline

&lt;span class="c"&gt;# 2. Run your docker build command again&lt;/span&gt;
docker build &lt;span class="nt"&gt;-t&lt;/span&gt; insecure-app:latest ./src
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89pbcsuxfocoq9f7rnxw.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%2F89pbcsuxfocoq9f7rnxw.png" alt=" " width="581" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Refresh the local terminal access token to bind securely to the cluster's public DNS address in short we are connecting to EKS&amp;nbsp;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
aws eks update-kubeconfig &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 &lt;span class="nt"&gt;--name&lt;/span&gt; devsecops-lab-cluster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instantiate a private cloud registry using Amazon ECR, to authenticate the local Docker daemon to the AWS API plane, and push the securely tagged image directly to AWS:&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;# Create the private cloud registry repository&lt;/span&gt;
aws ecr create-repository &lt;span class="nt"&gt;--repository-name&lt;/span&gt; insecure-app &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1


&lt;span class="c"&gt;# Authenticate local Docker to the remote AWS ECR endpoint&lt;/span&gt;
aws ecr get-login-password &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 | docker login &lt;span class="nt"&gt;--username&lt;/span&gt; AWS &lt;span class="nt"&gt;--password-stdin&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;aws sts get-caller-identity &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"Account"&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;.dkr.ecr.us-east-1.amazonaws.com


&lt;span class="c"&gt;# Tag and ship the local binary layers to the cloud&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ECR_URI&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;aws sts get-caller-identity &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"Account"&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;.dkr.ecr.us-east-1.amazonaws.com/insecure-app"&lt;/span&gt;

docker tag insecure-app:latest &lt;span class="nv"&gt;$ECR_URI&lt;/span&gt;:latest
docker push &lt;span class="nv"&gt;$ECR_URI&lt;/span&gt;:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open your blank k8s/deployment.yaml file in VS Code and paste this deployment configuration to spin up your vulnerable Python app:&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;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&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;insecure-app-deployment&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;insecure-app&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;insecure-app&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&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;web-app&lt;/span&gt;
        &lt;span class="c1"&gt;# ENTER YOUR EXACT COPIED STRING HERE WITHOUT ALTERATIONS:&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;YOUR_ACCOUNT_ID&amp;gt;.dkr.ecr.us-east-1.amazonaws.com/insecure-app:latest&lt;/span&gt;
        &lt;span class="na"&gt;imagePullPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Always&lt;/span&gt;
        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply this manifest using kubectl:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ligzcgb2fsa4mcsfc8z.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%2F4ligzcgb2fsa4mcsfc8z.png" alt=" " width="800" height="100"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Architectural Insight:&lt;/em&gt;&lt;br&gt;
 The &lt;code&gt;python:3.9&lt;/code&gt; image contains hundreds of unnecessary OS packages, increasing the attack surface. Furthermore, by not specifying a &lt;code&gt;USER&lt;/code&gt;, the container runs as root.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Phase 2: Threat Modeling &amp;amp; The Red Team Practices.
&lt;/h2&gt;

&lt;p&gt;As a Solution Architect, part of threat modeling is understanding how an attacker navigates your environment. Let's simulate a Server-Side Request Forgery (SSRF) or Remote Code Execution (RCE) vulnerability that gives an attacker a shell inside our pod.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Simulate the Breach.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open the standard terminal on your laptop (the same one you used to run &lt;code&gt;terraform apply&lt;/code&gt; or &lt;code&gt;docker build&lt;/code&gt; earlier). Ensure you are connected to your AWS environment.&lt;/p&gt;

&lt;p&gt;Type this to see a list of your running applications:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Freijleg5r2lvoh5elkl2.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%2Freijleg5r2lvoh5elkl2.png" alt=" " width="757" height="104"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You are still in your local terminal. You are now going to tell Kubernetes to open a live connection from your laptop directly into the running container inside AWS. Type this (replacing the placeholder with the name you just copied.&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;-it&lt;/span&gt; deployment/insecure-app-deployment &lt;span class="nt"&gt;--&lt;/span&gt; /bin/bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The terminal prompt will instantly change. It will go from looking like your local computer (e.g., &lt;code&gt;chimera1@fedora:~$&lt;/code&gt;) to looking like this:&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%2Flbyzfckccqan2mvleea5.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%2Flbyzfckccqan2mvleea5.png" alt=" " width="766" height="80"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You are no longer typing commands on your laptop. You are now physically "inside" the compromised container running in the AWS cloud. Every command you type now executes as if you were sitting at the keyboard of that specific pod.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Check Privileges&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;root@pod-1234:/app# &lt;span class="nb"&gt;whoami
&lt;/span&gt;root

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

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;&lt;strong&gt;Impact:&lt;/strong&gt;&lt;/em&gt; Because we are root, we can install new packages (like &lt;code&gt;curl&lt;/code&gt; or &lt;code&gt;nmap&lt;/code&gt;) to map the internal network.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Abuse the Metadata Service (IMDSv1)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because we didn't block access to the EC2 metadata service or enforce IMDSv2, we can steal the Node's IAM credentials directly from inside the container.The IP address &lt;code&gt;169.254.169.254&lt;/code&gt; is a special AWS address that only works when you are inside an AWS environment.&lt;/p&gt;

&lt;p&gt;During infrastructure verification, we noted that the cluster nodes strictly enforce &lt;strong&gt;IMDSv2 (Instance Metadata Service Version 2)&lt;/strong&gt;. Traditional, unauthenticated IMDSv1 &lt;code&gt;GET&lt;/code&gt;requests to the link-local address (&lt;code&gt;http://169.254.169.254&lt;/code&gt;) are dropped by default, preventing basic extraction.&lt;/p&gt;

&lt;p&gt;To bypass this securely, we had to mimic legitimate node behaviors by programmatically requesting a temporary cryptographic session token via a PUT request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nv"&gt;TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; PUT &lt;span class="s2"&gt;"http://169.254.169.254/latest/api/token"&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-aws-ec2-metadata-token-ttl-seconds: 21600"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Attempting to pull credentials from a static role name returned a &lt;code&gt;404 Not Found&lt;/code&gt; because the AWS EKS module automatically generates randomized names for node groups.&lt;/p&gt;

&lt;p&gt;To overcome this, we queried the base security directory while passing our valid IMDSv2 session token in the request header to discover the exact, real-world identity assigned to the EC2 host:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-aws-ec2-metadata-token: &lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; http://169.254.169.254/latest/meta-data/iam/security-credentials/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By appending the dynamically discovered role name to our metadata request string, the endpoint immediately dumped the underlying security credentials payload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
root@pod-1234:/app# curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-aws-ec2-metadata-token: &lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  http://169.254.169.254/latest/meta-data/iam/security-credentials/vulnerable_nodes-eks-node-group-20260615172216169600000004
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwbr18csqg01jvlcfn72n.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%2Fwbr18csqg01jvlcfn72n.png" alt=" " width="630" height="961"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. The Blast Radius Expansion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The output reveals the &lt;code&gt;AccessKeyId&lt;/code&gt;, &lt;code&gt;SecretAccessKey&lt;/code&gt;, and &lt;code&gt;Token&lt;/code&gt;. An attacker can configure these on their local machine. Because the node role has &lt;code&gt;AmazonS3FullAccess&lt;/code&gt;, the attacker bypasses the Kubernetes boundary entirely and can download or delete &lt;em&gt;every S3 bucket in your AWS account&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;To leave the compromised container and return to your local laptop, simply type:&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;exit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Phase 3: The Hardening (Secure Design Patterns)
&lt;/h2&gt;

&lt;p&gt;We will now implement the "Shift-Left" paradigm. We will harden the container, implement IAM least privilege using IRSA, and build a CI/CD pipeline that blocks vulnerable code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Secure the Dockerfile&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;src/Dockerfile&lt;/code&gt; and replace it with this hardened, minimal version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# src/Dockerfile (HARDENED)&lt;/span&gt;
&lt;span class="c"&gt;# SECURE: Minimal base image reduces attack surface&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:3.9-slim&lt;/span&gt;

&lt;span class="c"&gt;# SECURE: Create a non-root user and group&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;groupadd &lt;span class="nt"&gt;-r&lt;/span&gt; appgroup &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; useradd &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; appgroup appuser

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; requirements.txt .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--no-cache-dir&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="c"&gt;# SECURE: Hand over ownership and switch to non-root user&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; appuser:appgroup /app
&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; appuser&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8080&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["python", "app.py"]&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq9dgscs3abkynxokh779.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%2Fq9dgscs3abkynxokh779.png" alt=" " width="682" height="651"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Using &lt;code&gt;python:3.9-slim&lt;/code&gt; drastically cuts down the number of pre-installed OS utilities, reducing the attack surface. By explicitly creating &lt;code&gt;appuser&lt;/code&gt; and ending the file with &lt;code&gt;USER appuser&lt;/code&gt;, we physically prevent the container from executing as root. If an attacker gains a shell now, they will receive &lt;em&gt;"Permission Denied"&lt;/em&gt; errors when trying to install network mapping tools.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;2. Implement IAM Roles for Service Accounts (IRSA)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of giving the EC2 node permissions, we give permissions &lt;em&gt;only&lt;/em&gt; to the specific Kubernetes ServiceAccount used by our app via OIDC. Add this to your &lt;code&gt;infrastructure/main.tf&lt;/code&gt;:&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="c1"&gt;# infrastructure/main.tf (Additions)&lt;/span&gt;

&lt;span class="c1"&gt;# SECURE: Create a strict, least-privilege policy&lt;/span&gt;
&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_policy"&lt;/span&gt; &lt;span class="s2"&gt;"app_s3_policy"&lt;/span&gt; &lt;span class="p"&gt;{&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;"StrictAppS3Policy"&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allows reading only from the specific app bucket"&lt;/span&gt;
  &lt;span class="nx"&gt;policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsonencode&lt;/span&gt;&lt;span class="p"&gt;({&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;"2012-10-17"&lt;/span&gt;
    &lt;span class="nx"&gt;Statement&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
      &lt;span class="nx"&gt;Effect&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
      &lt;span class="nx"&gt;Action&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&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="nx"&gt;Resource&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::my-specific-app-bucket/*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# Restricted to ONE bucket&lt;/span&gt;
    &lt;span class="p"&gt;}]&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# SECURE: Map the IAM Role to the Kubernetes Service Account via OIDC&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="s2"&gt;"iam_eks_role"&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/iam/aws//modules/iam-role-for-service-accounts-eks"&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;"~&amp;gt; 5.0"&lt;/span&gt;

  &lt;span class="nx"&gt;role_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"SecureAppRole"&lt;/span&gt;

  &lt;span class="nx"&gt;oidc_providers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;main&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;provider_arn&lt;/span&gt;               &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;oidc_provider_arn&lt;/span&gt;
      &lt;span class="nx"&gt;namespace_service_accounts&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"default:secure-app-sa"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;role_policy_arns&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_policy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;app_s3_policy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6bdtbzu9flwp26fgs23z.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%2F6bdtbzu9flwp26fgs23z.png" alt=" " width="682" height="651"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This block decouples application permissions from infrastructure permissions. It creates an IAM policy scoped down to a single S3 bucket, then uses the AWS OIDC (Open ID Connect ) provider to map that policy strictly to the &lt;code&gt;secure-app-sa&lt;/code&gt; Kubernetes ServiceAccount. The underlying EKS node remains entirely unprivileged.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You also need to create the Kubernetes ServiceAccount and annotate it with the IAM role ARN. Create &lt;code&gt;k8s/serviceaccount.yaml&lt;/code&gt;:\&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# k8s/serviceaccount.yaml&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ServiceAccount&lt;/span&gt;
&lt;span class="na"&gt;metadata&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;secure-app-sa&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
  &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;eks.amazonaws.com/role-arn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arn:aws:iam::&amp;lt;YOUR_ACCOUNT_ID&amp;gt;:role/SecureAppRole&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Replace &lt;code&gt;&amp;lt;YOUR_ACCOUNT_ID&amp;gt;&lt;/code&gt; with your actual AWS account ID. You can also use Terraform outputs to dynamically inject this value.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then update your deployment to use this ServiceAccount:&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="c1"&gt;# k8s/secure-deployment.yaml&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&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;secure-app-deployment&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;secure-app&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;secure-app&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;serviceAccountName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;secure-app-sa&lt;/span&gt;  &lt;span class="c1"&gt;# &amp;lt;-- CRITICAL: Use the IRSA ServiceAccount&lt;/span&gt;
      &lt;span class="na"&gt;containers&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;web-app&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;YOUR_ACCOUNT_ID&amp;gt;.dkr.ecr.us-east-1.amazonaws.com/secure-app:latest&lt;/span&gt;
        &lt;span class="na"&gt;imagePullPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Always&lt;/span&gt;
        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Build the Automated Security Gates&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We cannot trust developers to always remember these rules; we must enforce them programmatically. Create &lt;code&gt;.github/workflows/main.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .github/workflows/main.yml&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;DevSecOps Pipeline&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;pull_request&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;security-scanning&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;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;        &lt;span class="c1"&gt;# Required for checkout&lt;/span&gt;
      &lt;span class="na"&gt;security-events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt; &lt;span class="c1"&gt;# Required for SARIF upload&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout code&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@v4&lt;/span&gt;

      &lt;span class="c1"&gt;# GATE 1: Secret Scanning&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;TruffleHog Secret Scan&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;trufflesecurity/trufflehog@main&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;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./&lt;/span&gt;
          &lt;span class="na"&gt;base&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.event.repository.default_branch }}&lt;/span&gt;
          &lt;span class="na"&gt;head&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HEAD&lt;/span&gt;
          &lt;span class="na"&gt;extra_args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;--debug --only-verified&lt;/span&gt;

      &lt;span class="c1"&gt;# GATE 2: Scan Terraform for misconfigurations before deployment&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;Checkov IaC Scan&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;bridgecrewio/checkov-action@master&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;directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./infrastructure&lt;/span&gt;
          &lt;span class="na"&gt;framework&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;terraform&lt;/span&gt;
          &lt;span class="na"&gt;output_format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cli&lt;/span&gt;
          &lt;span class="na"&gt;soft_fail&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
          &lt;span class="c1"&gt;# Fails the build on CRITICAL/HIGH misconfigurations&lt;/span&gt;

      &lt;span class="c1"&gt;# GATE 3: Build the Docker image&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 Image&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker build -t my-app:latest ./src&lt;/span&gt;

      &lt;span class="c1"&gt;# GATE 4: Scan the Docker image for Vulnerabilities&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;Trivy Vulnerability Scanner&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;aquasecurity/trivy-action@master&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;image-ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my-app:latest'&lt;/span&gt;
          &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;table'&lt;/span&gt;
          &lt;span class="na"&gt;exit-code&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1'&lt;/span&gt;          &lt;span class="c1"&gt;# Fails the build on HIGH/CRITICAL CVEs&lt;/span&gt;
          &lt;span class="na"&gt;ignore-unfixed&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
          &lt;span class="na"&gt;severity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;CRITICAL,HIGH'&lt;/span&gt;
          &lt;span class="na"&gt;vuln-type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;os,library'&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvro2gbatzospm0l5ujow.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%2Fvro2gbatzospm0l5ujow.png" alt=" " width="682" height="651"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;*&lt;em&gt;Architectural Insight: *&lt;/em&gt;&lt;/em&gt;&lt;br&gt;
By placing tools like Checkov and Trivy in the CI/CD pipeline, we enforce "Shift-Left" automation. If these tools detect a misconfiguration (like an overly permissive IAM role) or a vulnerable package, they trigger an exit-code: '1', physically preventing developers from merging vulnerable code into the main branch.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Phase 4: Validating the Security Gates (Planned Pipeline&amp;nbsp;Failure)
&lt;/h2&gt;

&lt;p&gt;To prove that our Shift-Left automation handles threats before they reach production, we pushed our code to GitHub to trigger the DevSecOps workflow. The pipeline initiated, cleared the &lt;strong&gt;TruffleHog&lt;/strong&gt; secret check, logged infrastructure misconfigurations via &lt;strong&gt;tfsec&lt;/strong&gt; using a warning threshold, and built our container image.&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%2Frodt4gd93cp7ihwsqhwm.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%2Frodt4gd93cp7ihwsqhwm.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fopx178u7ozr9m2sxdlaw.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%2Fopx178u7ozr9m2sxdlaw.png" alt=" " width="800" height="590"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, upon reaching &lt;strong&gt;GATE 3 (Trivy Vulnerability Scanner)&lt;/strong&gt;, the pipeline intentionally failed with an exit code &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Looking at the logs, Trivy intercepted &lt;strong&gt;25 OS vulnerabilities&lt;/strong&gt; (including Critical heap buffer overflows in &lt;code&gt;openssl&lt;/code&gt;) and &lt;strong&gt;10 Python application-layer vulnerabilities&lt;/strong&gt; (such as a session cookie disclosure flaw in &lt;code&gt;Flask 2.2.2&lt;/code&gt;). Because our workflow enforces a strict security ceiling on &lt;code&gt;CRITICAL,HIGH&lt;/code&gt; anomalies, the pipeline automatically broke, preventing an unhardened, insecure workload from ever spinning up inside our AWS production environment. This is exactly how automated preventative controls protect enterprise cloud platforms.&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%2Fea3rq1unzv0tilq2ab2b.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%2Fea3rq1unzv0tilq2ab2b.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9i2dffh0ada2tyc3o4ym.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%2F9i2dffh0ada2tyc3o4ym.png" alt=" " width="800" height="546"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Real CVE Context: Flask 2.2.2 and Werkzeug 2.2.2 are known to have multiple vulnerabilities including CVE-2023–30861 (session cookie disclosure), CVE-2023–23934 (cookie parsing issue), CVE-2023–25577 (DoS via multipart parsing), and CVE-2024–34069 (RCE via debugger). Upgrading to Flask 2.3.x+ and Werkzeug 3.0.3+ resolves these.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Validation, Monitoring &amp;amp; Teardown
&lt;/h2&gt;

&lt;p&gt;In Phase 2 we successfully stole the EC2 node's credentials using &lt;code&gt;curl&lt;/code&gt;. We fix this at the infrastructure level using Terraform. By enforcing IMDSv2 and setting the "hop limit" to 1, we ensure that a pod running on the node cannot reach the metadata service. Security is an ongoing operational task. To ensure long-term visibility:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enforce IMDSv2 Block IMDSv1:&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Enforce IMDSv2 via launch templates. Require session tokens and set a &lt;code&gt;HttpPutResponseHopLimit&lt;/code&gt; of 1 to prevent pods from accessing node metadata.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Open your code editor:&lt;/strong&gt;  Open the &lt;code&gt;infrastructure/main.tf&lt;/code&gt; file you created in Phase 1.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Modify the Node Group:&lt;/strong&gt; Scroll down to your &lt;code&gt;eks_managed_node_groups&lt;/code&gt; block. You are going to add a &lt;code&gt;metadata_options&lt;/code&gt; section to enforce IMDSv2. Update the block to look exactly like this:&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="nx"&gt;eks_managed_node_groups&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;vulnerable_nodes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;# Or secure_nodes if you renamed it&lt;/span&gt;
      &lt;span class="nx"&gt;min_size&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
      &lt;span class="nx"&gt;max_size&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
      &lt;span class="nx"&gt;desired_size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
      &lt;span class="nx"&gt;iam_role_arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;insecure_node_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;

      &lt;span class="c1"&gt;# ADD THIS BLOCK: Enforce IMDSv2 and block pod access&lt;/span&gt;
      &lt;span class="nx"&gt;metadata_options&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;http_endpoint&lt;/span&gt;               &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"enabled"&lt;/span&gt;
        &lt;span class="nx"&gt;http_tokens&lt;/span&gt;                 &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"required"&lt;/span&gt; &lt;span class="c1"&gt;# This forces IMDSv2&lt;/span&gt;
        &lt;span class="nx"&gt;http_put_response_hop_limit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;          &lt;span class="c1"&gt;# Prevents pods from reading it&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;While requiring &lt;code&gt;http_tokens&lt;/code&gt; enforces IMDSv2, the &lt;code&gt;http_put_response_hop_limit = 1&lt;/code&gt; is the ultimate safeguard. This setting ensures that metadata network packets can only travel 1 network "hop." Because Kubernetes pods run on a secondary virtual network interface inside the EC2 node, accessing the metadata service requires at least 2 hops. Setting the limit to 1 effectively kills the packet before it can reach the pod, completely neutralizing SSRF credential theft.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;3. Apply the changes in your local terminal:&lt;/strong&gt; Open your terminal on your laptop, ensure you are in the &lt;code&gt;infrastructure&lt;/code&gt; folder, and apply the secure configuration to AWS:&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;cd &lt;/span&gt;infrastructure
terraform apply &lt;span class="nt"&gt;-auto-approve&lt;/span&gt;

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

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Architectural Insight&amp;nbsp;:&amp;nbsp;&lt;/strong&gt;&lt;br&gt;
If you try to run that same malicious &lt;code&gt;curl&lt;/code&gt; command inside the container now, it will return a &lt;code&gt;401 Unauthorized&lt;/code&gt; or timeout error. The vulnerability is successfully patched.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ..

&lt;span class="c"&gt;# Verify you are in the right place (it should show 'src' and 'infrastructure')&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt;

&lt;span class="c"&gt;# Build the hardened Docker image&lt;/span&gt;
docker build &lt;span class="nt"&gt;-t&lt;/span&gt; secure-app:latest ./src

&lt;span class="c"&gt;# Update kubeconfig&lt;/span&gt;
aws eks update-kubeconfig &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 &lt;span class="nt"&gt;--name&lt;/span&gt; devsecops-lab-cluster

&lt;span class="c"&gt;# Authenticate to ECR&lt;/span&gt;
aws ecr get-login-password &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 |   docker login &lt;span class="nt"&gt;--username&lt;/span&gt; AWS &lt;span class="nt"&gt;--password-stdin&lt;/span&gt;   &lt;span class="si"&gt;$(&lt;/span&gt;aws sts get-caller-identity &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"Account"&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;.dkr.ecr.us-east-1.amazonaws.com

&lt;span class="c"&gt;# Tag and push the hardened image&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ECR_URI&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;aws sts get-caller-identity &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"Account"&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;.dkr.ecr.us-east-1.amazonaws.com/secure-app"&lt;/span&gt;

docker tag secure-app:latest &lt;span class="nv"&gt;$ECR_URI&lt;/span&gt;:latest

aws ecr create-repository &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--repository-name&lt;/span&gt; secure-app &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--image-scanning-configuration&lt;/span&gt; &lt;span class="nv"&gt;scanOnPush&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true

&lt;/span&gt;docker push &lt;span class="nv"&gt;$ECR_URI&lt;/span&gt;:latest

&lt;span class="c"&gt;# Apply the ServiceAccount and secure deployment&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;k8s
kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; serviceaccount.yaml
kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; secure-deployment.yaml

&lt;span class="c"&gt;# Verify pods are running&lt;/span&gt;
kubectl get pods

&lt;span class="c"&gt;# Test the hardening: try to exec into the pod and access metadata&lt;/span&gt;
kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; deployment/secure-app-deployment &lt;span class="nt"&gt;--&lt;/span&gt; /bin/bash

&lt;span class="c"&gt;# Inside the container, try the old attack:&lt;/span&gt;
&lt;span class="nv"&gt;TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; PUT &lt;span class="s2"&gt;"http://169.254.169.254/latest/api/token"&lt;/span&gt;   &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-aws-ec2-metadata-token-ttl-seconds: 21600"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/insecure-eks-node-role

&lt;span class="c"&gt;# You expect to receive nothing in return - it shows the architecture has been hardened.&lt;/span&gt;
&lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flh2x1o4dht4iub3rlvas.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%2Flh2x1o4dht4iub3rlvas.png" alt=" " width="800" height="74"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You expect to receive nothing in return it shows it has been hardened.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deploying Runtime Security:&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Deploy tools like Falco or AWS GuardDuty for EKS to monitor for anomalous behavior.Though Part 2 is dedicated to building out the Falco architecture.  However, if you wanted to see the literal commands of how a Solutions Architect deploys it into this cluster right now, it is done using Helm (a package manager for Kubernetes) from your local laptop terminal.&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;# Add the Falco Helm repository&lt;/span&gt;
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update

&lt;span class="c"&gt;# Install Falco with eBPF probe (modern, efficient kernel tracing)&lt;/span&gt;
helm &lt;span class="nb"&gt;install &lt;/span&gt;falco falcosecurity/falco   &lt;span class="nt"&gt;--namespace&lt;/span&gt; falco   &lt;span class="nt"&gt;--create-namespace&lt;/span&gt;   &lt;span class="nt"&gt;--set&lt;/span&gt; driver.kind&lt;span class="o"&gt;=&lt;/span&gt;ebpf   &lt;span class="nt"&gt;--set&lt;/span&gt; &lt;span class="nb"&gt;tty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Crucial Step: Lab Teardown&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As a responsible cloud practitioner, always clean up your environment to avoid unexpected AWS billing. Open your terminal:&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;cd &lt;/span&gt;infrastructure
terraform destroy &lt;span class="nt"&gt;-auto-approve&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Figcpxhic28d0kmh3zlmh.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%2Figcpxhic28d0kmh3zlmh.png" alt=" " width="800" height="90"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Architectural Lessons
&lt;/h2&gt;

&lt;p&gt;Mastering these concepts separates you from the pack. By walking through this architecture, you demonstrate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Blast Radius Reduction:&lt;/strong&gt; Decoupling application permissions from infrastructure permissions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shift-Left Automation:&lt;/strong&gt; Integrating SCA, IaC scanning, and vulnerability checks into CI/CD to reduce manual review overhead.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Defense in Depth:&lt;/strong&gt; Applying security at the IaC layer, pipeline layer, container layer, and AWS API layer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Metadata Service Protection&lt;/strong&gt;: Using IMDSv2 with hop limit 1 to prevent container credential theft.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Minimal Container Images&lt;/strong&gt;: Reducing attack surface by using slim base images and non-root users.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion &amp;amp; Extensions
&lt;/h2&gt;

&lt;p&gt;A Secure-by-Default architecture requires acknowledging that developers &lt;em&gt;will&lt;/em&gt; make mistakes, and building systems that catch those mistakes before they become breaches. To extend this architecture, consider implementing &lt;strong&gt;AWS Organizations&lt;/strong&gt; with Service Control Policies (SCPs) to establish hard boundaries across multiple accounts, or implementing &lt;strong&gt;Cosign&lt;/strong&gt; to digitally sign your container images before pushing them to Amazon ECR.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bonus: DevSecOps Decision Matrix
&lt;/h2&gt;

&lt;p&gt;Keep this matrix handy for your next architecture review or certification exam.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Security Domain&lt;/th&gt;
&lt;th&gt;Vulnerable Configuration (Anti-Pattern)&lt;/th&gt;
&lt;th&gt;Secure Configuration (Best Practice)&lt;/th&gt;
&lt;th&gt;SA Justification &amp;amp; Impact&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IAM Strategy&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;EKS Node Group roles with broad permissions (&lt;code&gt;AmazonS3FullAccess&lt;/code&gt;).&lt;/td&gt;
&lt;td&gt;IAM Roles for Service Accounts (IRSA) with OIDC.&lt;/td&gt;
&lt;td&gt;Limits blast radius. A compromised pod only yields permissions specific to its app.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Container Build&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Running as &lt;code&gt;root&lt;/code&gt;, using bloated base images (e.g., &lt;code&gt;python:3.9&lt;/code&gt;).&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;USER nonroot&lt;/code&gt;, minimal/distroless base images.&lt;/td&gt;
&lt;td&gt;Reduces attack surface. Attackers cannot easily install external tools if a breakout occurs.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Metadata Security&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;IMDSv1 enabled, accessible from pods.&lt;/td&gt;
&lt;td&gt;Require IMDSv2, Hop Limit = 1.&lt;/td&gt;
&lt;td&gt;Prevents Server-Side Request Forgery (SSRF) attacks from extracting EC2 credentials.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pipeline Security&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Build -&amp;gt; Push -&amp;gt; Deploy (No automated checks).&lt;/td&gt;
&lt;td&gt;TruffleHog -&amp;gt; tfsec -&amp;gt; Trivy -&amp;gt; Deploy.&lt;/td&gt;
&lt;td&gt;Catches vulnerabilities at the PR stage before they incur operational risk or downtime.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>awscommunitybuilders</category>
      <category>devsecops</category>
      <category>awseks</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>Agentic DevOps: Automating Security Remediation on AWS Using AWS DevOps Agent.</title>
      <dc:creator>Elijah Chimera</dc:creator>
      <pubDate>Tue, 05 May 2026 18:50:33 +0000</pubDate>
      <link>https://dev.to/chimera2/agentic-devops-automating-security-remediation-on-aws-using-aws-devops-agent-5hga</link>
      <guid>https://dev.to/chimera2/agentic-devops-automating-security-remediation-on-aws-using-aws-devops-agent-5hga</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Project Overview&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The evolution of cloud operations has reached a critical inflection point characterized by the transition from reactive infrastructure management to autonomous, self-healing systems. As distributed computing architectures scale in complexity, the cognitive load placed on Site Reliability Engineering (SRE) and cybersecurity teams has dramatically exceeded the capabilities of manual telemetry correlation, traditional heuristic-based alerting, and static posture management. The general availability of the AWS DevOps Agent as of March 31, 2026, marks the maturation of "frontier agents" which are autonomous artificial intelligence systems capable of end-to-end incident ownership, sophisticated root cause analysis (RCA), and proactive remediation across hybrid, multi-cloud, and on-premises environments.&lt;/p&gt;

&lt;p&gt;This comprehensive technical report details the architectural paradigms, security implications, and operational workflows introduced by the AWS Dev Ops Agent. It specifically addresses the integration of the Model Context Protocol (MCP), an open-source standard that enables the agentic reasoning engine to securely interface with localized telemetry data sources, such as Linux-based development environments which in my case I will be  running Fedora.&lt;/p&gt;

&lt;p&gt;To demonstrate the practical application of these technologies, this report presents an exhaustive, step-by-step walk-through focused on architecting a self-healing security environment. The implementation involves constructing a continuous integration and continuous deployment (CI/CD) pipeline for a web application using Infrastructure as Code (IaC) via Terraform.&lt;/p&gt;

&lt;p&gt;The infrastructure is intentionally deployed with specific security misconfigurations such as overly permissive Identity and Access Management (IAM) roles and publicly exposed Amazon Simple Storage Service (S3) buckets. By simulating sophisticated cyber incidents, including brute force attacks and unauthorized configuration drift, the analysis illustrates how the AWS DevOps Agent bridges the gap between pen-testing methodologies and autonomous Dev Ops remediation. &lt;/p&gt;

&lt;p&gt;The evidence establishes that integrating topology-aware frontier agents reduces mean time to resolution (MTTR) by up to 75%, shifting the organizational posture from reactive firefighting to proactive, AI-driven resilience.&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%2Fng2sz3vtxfd43qh7al0j.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%2Fng2sz3vtxfd43qh7al0j.png" alt="Key Concepts Table" width="800" height="821"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Key Concepts&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To establish a foundational understanding of the interconnected technologies governing autonomous cloud operations in this architecture, the following critical concepts must be defined:&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%2Fmkd4f7p4et9ndvyoqb1t.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%2Fmkd4f7p4et9ndvyoqb1t.png" alt="Key Concepts" width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Architectural Framework of Autonomous Operations&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The structural design of the AWS Dev Ops Agent is predicated on a dual-console model, which strictly segregates administrative governance from operational execution. The Administration Console, housed within the AWS Management Console, facilitates the configuration of integrations, permissions, and security perimeters by platform administrators. Conversely, the Operations Web App provides a dedicated workspace for SRE and cybersecurity teams to interact with the agent, review investigation journals, and approve mitigation plans via natural language interfaces.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Agent Spaces and Multi-Layered Security Boundaries&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Central to the architecture of the AWS Dev Ops Agent is the Agent Space. An Agent Space functions as an isolated logical container that determines the agent's operational boundary. The configuration of an Agent Space requires a precise balance; an overly restrictive configuration deprives the agent of the telemetry required to synthesize an accurate root cause analysis, whereas an excessively broad space increases computational overhead and introduces unnecessary security exposure.&lt;/p&gt;

&lt;p&gt;The security of the AWS Dev Ops Agent is maintained through a multi-layered defense-in-depth strategy. Even if broader permissions are granted to the agent's underlying IAM role, the agent enforces internal access controls to limit the scope of its actions. The agent relies on regional processing capabilities, meaning it retrieves operational data from AWS regions across all AWS accounts granted access within the configured Agent Space. While the underlying Amazon Bedrock models automatically select optimal regions for inference processing to maximize compute availability, the architectural design guarantees that customer data remains stored only in the region where the Agent Space was instantiated, ensuring data residency compliance.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;The Investigation Journal and Immutable Audit Trails&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When an incident is triggered whether via an automated web hook from an &lt;strong&gt;&lt;em&gt;Amazon CloudWatch&lt;/em&gt;&lt;/strong&gt; alarm, a &lt;strong&gt;&lt;em&gt;ServiceNow&lt;/em&gt;&lt;/strong&gt; ticket, or manual invocation the agent initiates a systematic diagnostic workflow. The core operational artifact produced during this process is the Investigation Journal.&lt;/p&gt;

&lt;p&gt;The Investigation Journal provides a transparent, real-time, and immutable chronicle of the agent's reasoning process. It records the initial hypothesis generation, documenting every telemetry query, metric evaluation, and log parsing action executed. Because these logs are integrated with &lt;strong&gt;&lt;em&gt;AWS CloudTrail&lt;/em&gt;&lt;/strong&gt;, they serve as a cryptographically verifiable audit trail. This transparency is critical for cybersecurity compliance, allowing human operators to retrospectively analyze exactly why the AI deemed a specific IAM role overly permissive or why it concluded that a database connection failure was the result of a Transit Gateway routing anomaly.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;The Model Context Protocol (MCP): Bridging Hybrid and Local Environments&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;While the AWS Dev Ops Agent possesses native integration with centralized AWS services, enterprise environments operate complex hybrid topologies incorporating on-premises data centers, private code repositories, localized developer workstations, and third-party observability platforms. To extend the agent's topological awareness into these disparate domains, the architecture leverages the Model Context Protocol (MCP).&lt;/p&gt;

&lt;p&gt;MCP resolves the fragility of bespoke API engineering by implementing a standardized client-server architecture. The AI application acts as the MCP Client, requesting access to external data, while the MCP Server exposes specific tools, resources, and capabilities.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Transport Mechanisms and Linux Implementations&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The protocol operates over two primary transport mechanisms: &lt;code&gt;stdio&lt;/code&gt; (Standard Input/Output) and Streamable HTTP.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;stdio&lt;/code&gt; mechanism is optimized for localized execution. For example, a security analyst or system administrator operating a Linux workstation can deploy the &lt;code&gt;linux-mcp-server&lt;/code&gt;locally. The MCP server runs as a subprocess, inheriting the granular file system permissions of the host operator. This architecture enables the cloud-based AWS DevOps Agent to query the local Linux machine's system state, review &lt;code&gt;journalctl&lt;/code&gt; logs, analyze running processes, and diagnose performance bottlenecks directly from the local environment. By providing the agent direct access to system information, manual extraction and pasting of terminal output into a web interface are eliminated, transforming the AI into an active participant in the troubleshooting process.&lt;/p&gt;

&lt;p&gt;For remote or enterprise-grade deployments, MCP utilizes Streamable HTTP with Server-Sent Events (SSE) to facilitate real-time streaming. This mechanism is critical for connecting the AWS DevOps Agent to persistent infrastructure tools such as self-hosted GitLab instances, private Terraform registries, or containerized observability stacks running on Amazon Elastic Container Service (ECS) with AWS Fargate.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Private Connections and Amazon VPC Lattice&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A critical security consideration when bridging the AWS DevOps Agent with internal enterprise tools is network isolation. Exposing internal databases or localized MCP servers to the public internet violates fundamental zero-trust principles. To resolve this, the architecture utilizes Amazon VPC Lattice to establish secure "Private Connections".&lt;/p&gt;

&lt;p&gt;VPC Lattice operates as an application networking layer that establishes a secure, encrypted transit path between the Agent Space and the target resource residing in an isolated Virtual Private Cloud (VPC). The connection process involves deploying service-managed Elastic Network Interfaces (ENIs) directly into the specified subnets. Traffic from the DevOps Agent is routed through these ENIs which act as a resource gateway ensuring that requests to private MCP servers, self-hosted Grafana dashboards, or internal documentation APIs never traverse the public internet. The protocol strictly enforces HTTPS communication with a minimum of TLS 1.2, guaranteeing data-in-transit encryption.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Walkthrough: Deploying the Self-Healing Security Architecture&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To effectively demonstrate the capabilities of the AWS DevOps Agent in mitigating vulnerabilities and configuration drift, this section details the deployment of a controlled laboratory environment. The objective is to construct a CI/CD pipeline for a web application utilizing Terraform, deliberately introducing security misconfigurations—specifically, an overly permissive IAM role and an exposed S3 bucket. Subsequently, the environment is monitored by the AWS DevOps Agent, which is configured to detect, investigate, and autonomously remediate simulated cyber incidents.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;1. Local Environment Preparation on Fedora Linux&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The initialization phase requires configuring the local developer workstation running Linux. This involves installing the requisite MCP server to allow the AWS DevOps Agent to read local development configurations and interact with the local Terraform state during the investigation phase.First, the system dependencies are updated and installed via the package manager it could be apt opr dnf depending on your distribution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
shell
Bash
&lt;span class="c"&gt;# Update local Fedora repositories and install Node.js&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;dnf update &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;dnf &lt;span class="nb"&gt;install &lt;/span&gt;nodejs npm 
brew &lt;span class="nb"&gt;install &lt;/span&gt;awscli 
brew tap hashicorp/tap
brew &lt;span class="nb"&gt;install &lt;/span&gt;hashicorp/tap/terraform

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0t95vx6bc6wgq8il5ij9.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%2F0t95vx6bc6wgq8il5ij9.png" alt="Pre-requisite installations" width="800" height="880"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;

&lt;/span&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Verify installations
&lt;span class="go"&gt;node --version
terraform --version
aws --version
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffnnjg69z75tmfgumaw1b.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%2Ffnnjg69z75tmfgumaw1b.png" alt="Verifications of installations" width="799" height="169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, the &lt;code&gt;linux-mcp-server&lt;/code&gt; is deployed. This utility grants the AI agent context regarding the local operating system environment, which is highly beneficial when analyzing hybrid configurations or diagnosing connectivity issues originating from the developer's workstation.Execute this directly in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Bash
&lt;span class="c"&gt;# Execute the Linux MCP server via NPX for local standard I/O transport&lt;/span&gt;
curl &lt;span class="nt"&gt;-LsSf&lt;/span&gt; https://astral.sh/uv/install.sh | sh
uv tool &lt;span class="nb"&gt;install &lt;/span&gt;linux-mcp-server
linux-mcp-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhzqss5e2e709qio4i29c.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%2Fhzqss5e2e709qio4i29c.png" alt="Installation of linux-mcp-server" width="799" height="169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovolxwnd9yy6dt60ucce.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%2Fovolxwnd9yy6dt60ucce.png" alt="Starting up of linux-mcp-server" width="799" height="169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Simultaneously, the HashiCorp Terraform MCP server must be configured to provide the AWS DevOps Agent with real-time access to the public Terraform Registry, allowing the agent to reference accurate, up-to-date documentation when generating remediation code. The server is initialized locally using the Streamable HTTP mode to facilitate remote connections from the cloud-based Agent Space.Open a seperate terminal window and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
Bash
&lt;span class="c"&gt;# Start the Terraform MCP server on port 8080&lt;/span&gt;
brew &lt;span class="nb"&gt;install &lt;/span&gt;terraform-mcp-server
terraform-mcp-server streamable-http &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--transport-port&lt;/span&gt; 8080 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--transport-host&lt;/span&gt; 0.0.0.0 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--log-level&lt;/span&gt; info &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--toolsets&lt;/span&gt; terraform,registry
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5mophgb0gr5utb6z7mdh.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%2F5mophgb0gr5utb6z7mdh.png" alt="Installing terraform-mcp-server" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;2.Infrastructure as Code Configuration&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The foundational infrastructure is codified using Terraform. This ensures that the deployment is reproducible and that subsequent remediations generated by the AWS DevOps Agent can be seamlessly integrated into the version control system. The following configuration defines the core networking, the deliberately vulnerable S3 bucket, and the highly permissive IAM role.&lt;/p&gt;

&lt;p&gt;The implementation utilizes the &lt;code&gt;hashicorp/aws&lt;/code&gt; provider for standard resources and the &lt;code&gt;hashicorp/awscc&lt;/code&gt; provider to interact with the AWS Cloud Control API, which is required to provision the &lt;code&gt;awscc_devopsagent_agent_space&lt;/code&gt;resource. Create a file named main.tf and paste the following code:&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;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;aws&lt;/span&gt;   &lt;span class="p"&gt;=&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;"hashicorp/aws"&lt;/span&gt;&lt;span class="p"&gt;,&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;"~&amp;gt; 5.0"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;awscc&lt;/span&gt; &lt;span class="p"&gt;=&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;"hashicorp/awscc"&lt;/span&gt;&lt;span class="p"&gt;,&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;"~&amp;gt; 1.0"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"awscc"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;data&lt;/span&gt; &lt;span class="s2"&gt;"aws_caller_identity"&lt;/span&gt; &lt;span class="s2"&gt;"current"&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="c1"&gt;# -------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="c1"&gt;# 1. IAM ROLE FOR EC2 (CloudWatch Logs Shipping)&lt;/span&gt;
&lt;span class="c1"&gt;# -------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role"&lt;/span&gt; &lt;span class="s2"&gt;"ec2_logs_role"&lt;/span&gt; &lt;span class="p"&gt;{&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;"EC2LogShippingRole"&lt;/span&gt;

  &lt;span class="nx"&gt;assume_role_policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsonencode&lt;/span&gt;&lt;span class="p"&gt;({&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;"2012-10-17"&lt;/span&gt;
    &lt;span class="nx"&gt;Statement&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;Action&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;
        &lt;span class="nx"&gt;Effect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
        &lt;span class="nx"&gt;Principal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;Service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ec2.amazonaws.com"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role_policy_attachment"&lt;/span&gt; &lt;span class="s2"&gt;"cw_agent_policy"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;role&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ec2_logs_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;policy_arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_instance_profile"&lt;/span&gt; &lt;span class="s2"&gt;"ec2_profile"&lt;/span&gt; &lt;span class="p"&gt;{&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;"EC2LogShippingProfile"&lt;/span&gt;
  &lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ec2_logs_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# -------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="c1"&gt;# 2. SECURITY GROUP &amp;amp; EC2 INSTANCES&lt;/span&gt;
&lt;span class="c1"&gt;# -------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_security_group"&lt;/span&gt; &lt;span class="s2"&gt;"lab_sg"&lt;/span&gt; &lt;span class="p"&gt;{&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;"free-tier-lab-sg"&lt;/span&gt;

  &lt;span class="nx"&gt;ingress&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;from_port&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;
    &lt;span class="nx"&gt;to_port&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;
    &lt;span class="nx"&gt;protocol&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;
    &lt;span class="nx"&gt;cidr_blocks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0/0"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;egress&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;from_port&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;to_port&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;protocol&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"-1"&lt;/span&gt;
    &lt;span class="nx"&gt;cidr_blocks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0/0"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_instance"&lt;/span&gt; &lt;span class="s2"&gt;"vulnerable_target"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ami&lt;/span&gt;                    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ami-0c101f26f147fa7fd"&lt;/span&gt;
  &lt;span class="nx"&gt;instance_type&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"t3.micro"&lt;/span&gt;
  &lt;span class="nx"&gt;iam_instance_profile&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_instance_profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ec2_profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_security_group_ids&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;aws_security_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lab_sg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="nx"&gt;user_data&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
              #!/bin/bash
              echo "root:password123" | chpasswd
              sed -i 's/^#PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
              sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
              systemctl restart sshd

              dnf install -y amazon-cloudwatch-agent
              cat &amp;lt;&amp;lt;ETX &amp;gt; /opt/aws/amazon-cloudwatch-agent/bin/config.json
              {
                "logs": {
                  "logs_collected": {
                    "files": {
                      "collect_list": [
                        {
                          "file_path": "/var/log/secure",
                          "log_group_name": "ssh-auth-logs",
                          "log_stream_name": "{instance_id}"
                        }
                      ]
                    }
                  }
                }
              }
              ETX
              /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json -s
&lt;/span&gt;&lt;span class="no"&gt;              EOF

&lt;/span&gt;  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&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;"Victim-Server"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_instance"&lt;/span&gt; &lt;span class="s2"&gt;"attacker_node"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ami&lt;/span&gt;                    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ami-0c101f26f147fa7fd"&lt;/span&gt;
  &lt;span class="nx"&gt;instance_type&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"t3.micro"&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_security_group_ids&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;aws_security_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lab_sg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="nx"&gt;user_data&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
              #!/bin/bash
              dnf install -y hydra
              echo -e "password123\n123456\nadmin\nroot" &amp;gt; /home/ec2-user/common-passwords.txt
&lt;/span&gt;&lt;span class="no"&gt;              EOF

&lt;/span&gt;  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&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;"Attacker-Hydra"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# -------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="c1"&gt;# 3. CLOUDWATCH LOG GROUP&lt;/span&gt;
&lt;span class="c1"&gt;# -------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_cloudwatch_log_group"&lt;/span&gt; &lt;span class="s2"&gt;"ssh_logs"&lt;/span&gt; &lt;span class="p"&gt;{&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;"ssh-auth-logs"&lt;/span&gt;
  &lt;span class="nx"&gt;retention_in_days&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# -------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="c1"&gt;# 4. LAMBDA DISPATCHER&lt;/span&gt;
&lt;span class="c1"&gt;# -------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role"&lt;/span&gt; &lt;span class="s2"&gt;"lambda_role"&lt;/span&gt; &lt;span class="p"&gt;{&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;"LambdaDispatcherRole"&lt;/span&gt;

  &lt;span class="nx"&gt;assume_role_policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsonencode&lt;/span&gt;&lt;span class="p"&gt;({&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;"2012-10-17"&lt;/span&gt;
    &lt;span class="nx"&gt;Statement&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;Action&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;
        &lt;span class="nx"&gt;Effect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
        &lt;span class="nx"&gt;Principal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;Service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"lambda.amazonaws.com"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role_policy_attachment"&lt;/span&gt; &lt;span class="s2"&gt;"lambda_basic"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;role&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lambda_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;policy_arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_lambda_function"&lt;/span&gt; &lt;span class="s2"&gt;"incident_dispatcher"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;filename&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"lambda_function.zip"&lt;/span&gt;
  &lt;span class="nx"&gt;function_name&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"DevOpsAgent-Dispatcher"&lt;/span&gt;
  &lt;span class="nx"&gt;role&lt;/span&gt;             &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lambda_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;
  &lt;span class="nx"&gt;handler&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"index.handler"&lt;/span&gt;
  &lt;span class="nx"&gt;runtime&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"python3.11"&lt;/span&gt;
  &lt;span class="nx"&gt;source_code_hash&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;filebase64sha256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"lambda_function.zip"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nx"&gt;environment&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;variables&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;AGENT_SPACE_ID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;awscc_devopsagent_agent_space&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;security_lab_space&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_lambda_permission"&lt;/span&gt; &lt;span class="s2"&gt;"allow_cloudwatch"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;action&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"lambda:InvokeFunction"&lt;/span&gt;
  &lt;span class="nx"&gt;function_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_lambda_function&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;incident_dispatcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;function_name&lt;/span&gt;
  &lt;span class="nx"&gt;principal&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"logs.us-east-1.amazonaws.com"&lt;/span&gt;
  &lt;span class="nx"&gt;source_arn&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;aws_cloudwatch_log_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ssh_logs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:*"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_cloudwatch_log_subscription_filter"&lt;/span&gt; &lt;span class="s2"&gt;"brute_force_filter"&lt;/span&gt; &lt;span class="p"&gt;{&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;"detect-failed-login"&lt;/span&gt;
  &lt;span class="nx"&gt;log_group_name&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_cloudwatch_log_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ssh_logs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;filter_pattern&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Failed password"&lt;/span&gt;
  &lt;span class="nx"&gt;destination_arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_lambda_function&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;incident_dispatcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# -------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="c1"&gt;# 5. INTENTIONAL VULNERABILITIES (S3 + Overly Permissive Role)&lt;/span&gt;
&lt;span class="c1"&gt;# -------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket"&lt;/span&gt; &lt;span class="s2"&gt;"app_data_bucket"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"vulnerable-app-data-lab-2026"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket_public_access_block"&lt;/span&gt; &lt;span class="s2"&gt;"app_data_public_access"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;app_data_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;block_public_acls&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="nx"&gt;block_public_policy&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="nx"&gt;ignore_public_acls&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="nx"&gt;restrict_public_buckets&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket_policy"&lt;/span&gt; &lt;span class="s2"&gt;"allow_public_read"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;app_data_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsonencode&lt;/span&gt;&lt;span class="p"&gt;({&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;"2012-10-17"&lt;/span&gt;
    &lt;span class="nx"&gt;Statement&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;Sid&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"PublicRead"&lt;/span&gt;
        &lt;span class="nx"&gt;Effect&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
        &lt;span class="nx"&gt;Principal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"*"&lt;/span&gt;
        &lt;span class="nx"&gt;Action&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"s3:GetObject"&lt;/span&gt;
        &lt;span class="nx"&gt;Resource&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;app_data_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/*"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role"&lt;/span&gt; &lt;span class="s2"&gt;"app_execution_role"&lt;/span&gt; &lt;span class="p"&gt;{&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;"AppExecutionRole-OverlyPermissive"&lt;/span&gt;

  &lt;span class="nx"&gt;assume_role_policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsonencode&lt;/span&gt;&lt;span class="p"&gt;({&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;"2012-10-17"&lt;/span&gt;
    &lt;span class="nx"&gt;Statement&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;Action&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;
        &lt;span class="nx"&gt;Effect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
        &lt;span class="nx"&gt;Principal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;Service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ec2.amazonaws.com"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role_policy_attachment"&lt;/span&gt; &lt;span class="s2"&gt;"admin_access_attachment"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;role&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;app_execution_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;policy_arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:iam::aws:policy/AdministratorAccess"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# -------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="c1"&gt;# 6. DEVOPS AGENT IAM ROLE &lt;/span&gt;
&lt;span class="c1"&gt;# -------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role"&lt;/span&gt; &lt;span class="s2"&gt;"devops_agent_role"&lt;/span&gt; &lt;span class="p"&gt;{&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;"DevOpsAgentMonitoringRole"&lt;/span&gt;

  &lt;span class="nx"&gt;assume_role_policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsonencode&lt;/span&gt;&lt;span class="p"&gt;({&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;"2012-10-17"&lt;/span&gt;
    &lt;span class="nx"&gt;Statement&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;Effect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
        &lt;span class="nx"&gt;Principal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;Service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"aidevops.amazonaws.com"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;Action&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;
        &lt;span class="nx"&gt;Condition&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;StringEquals&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"aws:SourceAccount"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aws_caller_identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;account_id&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;ArnLike&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"aws:SourceArn"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:aidevops:us-east-1:&lt;/span&gt;&lt;span class="k"&gt;${data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aws_caller_identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;account_id&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:agentspace/*"&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role_policy_attachment"&lt;/span&gt; &lt;span class="s2"&gt;"devops_agent_policy"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;role&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;devops_agent_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;policy_arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:iam::aws:policy/AIDevOpsAgentAccessPolicy"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role_policy"&lt;/span&gt; &lt;span class="s2"&gt;"devops_agent_inline"&lt;/span&gt; &lt;span class="p"&gt;{&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;"DevOpsAgentExtraPermissions"&lt;/span&gt;
  &lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;devops_agent_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;

  &lt;span class="nx"&gt;policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsonencode&lt;/span&gt;&lt;span class="p"&gt;({&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;"2012-10-17"&lt;/span&gt;
    &lt;span class="nx"&gt;Statement&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;Effect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
        &lt;span class="nx"&gt;Action&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="s2"&gt;"iam:CreateServiceLinkedRole"&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="nx"&gt;Resource&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:iam::*:role/aws-service-role/resource-explorer-2.amazonaws.com/AWSServiceRoleForResourceExplorer"&lt;/span&gt;
        &lt;span class="nx"&gt;Condition&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;StringEquals&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"iam:AWSServiceName"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"resource-explorer-2.amazonaws.com"&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# -------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="c1"&gt;# 7. AWS DEVOPS AGENT CONFIGURATION&lt;/span&gt;
&lt;span class="c1"&gt;# -------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"awscc_devopsagent_agent_space"&lt;/span&gt; &lt;span class="s2"&gt;"security_lab_space"&lt;/span&gt; &lt;span class="p"&gt;{&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;"self-healing-security-lab"&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Agent Space dedicated to monitoring and remediating the vulnerable web application pipeline."&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"awscc_devopsagent_association"&lt;/span&gt; &lt;span class="s2"&gt;"account_association"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;agent_space_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;awscc_devopsagent_agent_space&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;security_lab_space&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;service_id&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt;

  &lt;span class="nx"&gt;configuration&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;assumable_role_arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;devops_agent_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;
      &lt;span class="nx"&gt;account_id&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aws_caller_identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;account_id&lt;/span&gt;
      &lt;span class="nx"&gt;account_type&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"monitor"&lt;/span&gt;
      &lt;span class="nx"&gt;resources&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;depends_on&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;awscc_devopsagent_agent_space&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;security_lab_space&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;devops_agent_role&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;aws_iam_role_policy_attachment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;devops_agent_policy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;aws_iam_role_policy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;devops_agent_inline&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj73whjoyr08g3gb7qus6.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%2Fj73whjoyr08g3gb7qus6.png" alt="main.tf" width="800" height="798"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;3. The Dispatcher Logic file &lt;code&gt;index.py&lt;/code&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Because CloudWatch sends its logs in a compressed format, the Lambda function requires a small Python script to "unpack" the data before transmitting it to the AWS DevOps Agent. Create a file named &lt;code&gt;index.py&lt;/code&gt;, compress it into &lt;code&gt;lambda_function.zip&lt;/code&gt;, and place it in the same directory as your Terraform file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;gzip&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# 1. Decode and decompress the CloudWatch log data
&lt;/span&gt;    &lt;span class="n"&gt;cw_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;awslogs&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;compressed_payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;b64decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cw_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;uncompressed_payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gzip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decompress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;compressed_payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uncompressed_payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Brute force detected in logs! Events: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;logEvents&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 2. Logic to notify DevOps Agent
&lt;/span&gt;    &lt;span class="c1"&gt;# In a lab, we log the intent. In prod, you'd POST to the Agent endpoint.
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;incident_reported&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;agent_space&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;source_ip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Extracted from log line&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F034w3udj6vqde25ilaum.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%2F034w3udj6vqde25ilaum.png" alt="index.py" width="799" height="557"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The infrastructure is then deployed to the AWS environment using standard Terraform execution commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
Bash
terraform init
terraform plan &lt;span class="nt"&gt;-out&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;tfplan
terraform apply &lt;span class="s2"&gt;"tfplan"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F518guj11cqnsnrqouub6.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%2F518guj11cqnsnrqouub6.png" alt="terraform init" width="800" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbejeldzq3aku3vtf5ruq.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%2Fbejeldzq3aku3vtf5ruq.png" alt="terraform plan and apply" width="800" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Upon successful execution, the intentionally vulnerable S3 bucket, the permissive IAM role, and the AWS DevOps Agent Space are active within the specified AWS region.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Simulating Security Incidents and Configuration Drift&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;With the foundational architecture established, the next phase involves simulating cybersecurity incidents that trigger the autonomous response capabilities of the AWS DevOps Agent. This methodology aligns directly with pentesting practices, where understanding the mechanics of an exploit is prerequisite to engineering an automated defense.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Incident Simulation 1: Configuration Drift&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Configuration drift occurs when the operational state of the infrastructure diverges from the intended state defined in the Terraform configuration. In this scenario, a simulated malicious actor or a negligent administrator accesses the AWS Management Console and manually alters the S3 bucket policy to grant &lt;code&gt;s3:PutObject&lt;/code&gt;(write access) to the public, escalating the risk from a data leak to a potential data corruption or malware hosting vector.&lt;/p&gt;

&lt;p&gt;Furthermore, the administrator manually attaches a secondary inline policy to the &lt;code&gt;AppExecutionRole-OverlyPermissive&lt;/code&gt; granting cross-account STS assume role capabilities, an action that was not codified in the &lt;code&gt;main.tf&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Step-by-Step Simulation:&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Sign in to the &lt;strong&gt;AWS Management Console&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Search for S3 in the top search bar and open the S3 service.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Locate and select the bucket named &lt;code&gt;vulnerable-app-data-lab-2026&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdbd3cbxu7m29ozv3ai2f.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%2Fdbd3cbxu7m29ozv3ai2f.png" alt="s3 bucket " width="800" height="268"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Navigate to the &lt;strong&gt;Permissions&lt;/strong&gt; tab.&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%2F0cux2ecsqd2f803945mp.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%2F0cux2ecsqd2f803945mp.png" alt="Permissions tab" width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click Edit on the Bucket Policy. Alter the JSON payload to explicitly grant the &lt;code&gt;s3:PutObject&lt;/code&gt;(write access) action to &lt;code&gt;Principal: "*"&lt;/code&gt;. Click &lt;strong&gt;Save changes&lt;/strong&gt;. &lt;em&gt;This escalates the risk from a potential data leak to a data corruption/malware hosting vector&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjc8ur2173h69rkkq72uy.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%2Fjc8ur2173h69rkkq72uy.png" alt="Bucket policy" width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next, search for &lt;strong&gt;IAM&lt;/strong&gt; in the top search bar and open the IAM console.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click on &lt;strong&gt;Roles&lt;/strong&gt; in the left navigation pane and search for &lt;code&gt;AppExecutionRole-OverlyPermissive&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5s7bbvlfi1udgr878141.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%2F5s7bbvlfi1udgr878141.png" alt="Roles" width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You will see two permissions created from our code as follows:&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%2Fbhhvzaqiq4ku8vmjlku1.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%2Fbhhvzaqiq4ku8vmjlku1.png" alt="Permissions summary" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Incident Simulation 2: SSH Brute Force Attack&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To validate the agent's capability to respond to active threats, a brute force attack is simulated against the EC2 instance associated with the application. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Step-by-Step Simulation:&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using AWS Systems Manager (SSM) Session Manager or SSH, log into the &lt;code&gt;Attacker-Hydra&lt;/code&gt; EC2 instance created by Terraform.&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; ssh &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"your-key.pem"&lt;/span&gt; ec2-user&lt;span class="s2"&gt;"ec2 instance public ip address"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx3abyxcuv9vg21uz2dov.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%2Fx3abyxcuv9vg21uz2dov.png" alt="ssh connection command" width="800" height="140"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The user data script has already installed Hydra and created a dictionary file. Execute the following command against the Victim-Server private IP address.&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; Bash
  &lt;span class="c"&gt;# Simulating a brute force attack using Hydra from the attacker node&lt;/span&gt;
  hydra &lt;span class="nt"&gt;-l&lt;/span&gt; root &lt;span class="nt"&gt;-P&lt;/span&gt; /home/ec2-user/common-passwords.txt ssh://&amp;lt;victim-server-private-ip&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fon2qqhh8iyjaxa4y1l41.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%2Fon2qqhh8iyjaxa4y1l41.png" alt="hydra command" width="799" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If hydra did not install run the following commands first :&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;# 1. Update system&lt;/span&gt;
  &lt;span class="nb"&gt;sudo &lt;/span&gt;dnf update &lt;span class="nt"&gt;-y&lt;/span&gt; 
 &lt;span class="c"&gt;# 2. Install dependencies (very important)&lt;/span&gt;
  &lt;span class="nb"&gt;sudo &lt;/span&gt;dnf &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; gcc make libssh-devel openssl-devel libidn-devel &lt;span class="se"&gt;\ &lt;/span&gt; pcre-devel libpq-devel libmemcached-devel libpcap-devel &lt;span class="se"&gt;\ &lt;/span&gt;                    git 
  &lt;span class="c"&gt;# 3. Download Hydra source code&lt;/span&gt;
 git clone https://github.com/vanhauser-thc/thc-hydra.git
  &lt;span class="nb"&gt;cd &lt;/span&gt;thc-hydra

  &lt;span class="c"&gt;# 4. Compile and install&lt;/span&gt;
 ./configure
  make
  &lt;span class="nb"&gt;sudo &lt;/span&gt;make &lt;span class="nb"&gt;install&lt;/span&gt;

  &lt;span class="c"&gt;# 5. Verify installation&lt;/span&gt;
 hydra &lt;span class="nt"&gt;-h&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Navigate to the &lt;em&gt;CloudWatch&lt;/em&gt; console, then &lt;em&gt;Log Management then Log groups&lt;/em&gt; , and open &lt;code&gt;ssh-auth-logs&lt;/code&gt;. You will see the victim server actively shipping its authentication failure logs.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6hxaqsxx7mvu6fwp0pta.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%2F6hxaqsxx7mvu6fwp0pta.png" alt="ssh-auth-logs" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The &lt;em&gt;Subscription Filter&lt;/em&gt; catches the &lt;em&gt;"Failed password"&lt;/em&gt; regex, immediately triggering the &lt;em&gt;DevOpsAgent-Dispatcher&lt;/em&gt; Lambda function. This zero-cost mechanism subsequently fires the secure &lt;em&gt;webhook&lt;/em&gt;, initiating the agent's autonomous RCA workflow.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fssxpfd77muzejrir7wfk.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%2Fssxpfd77muzejrir7wfk.png" alt="ssh-auth-logs Subscription filters" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Autonomous RCA and Pull Request Orchestration&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Upon receiving the alert trigger, the AWS DevOps Agent transitions into the active investigation phase. Operating independently of human interaction, the agent correlates the disparate telemetry streams to formulate a cohesive understanding of the incident.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Investigation Workflow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The agent's activities are transparently recorded in the Operations Web App's Investigation Journal.To follow along with the agent's logic:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Step-by-Step RCA Observation&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;In the AWS Management Console, search for &lt;strong&gt;AWS DevOps Agent&lt;/strong&gt; and open the service.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click on the &lt;strong&gt;Agent Spaces&lt;/strong&gt; menu and select the &lt;code&gt;self-healing-security-lab&lt;/code&gt; space you deployed earlier.&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%2F0lk65jagwi38830e4c3y.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%2F0lk65jagwi38830e4c3y.png" alt="Agent Spaces" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select &lt;strong&gt;Configure Web App&lt;/strong&gt; and leave everything as it is and proceed to Open the &lt;strong&gt;Operations Web App&lt;/strong&gt; and navigate to the &lt;strong&gt;Incident Response&lt;/strong&gt; tab to view active investigations.&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%2Fcj90jpo9xucwvc2bmszs.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%2Fcj90jpo9xucwvc2bmszs.png" alt="Configure Web App" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fenp736sa3yz979lg6iho.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%2Fenp736sa3yz979lg6iho.png" alt="Operations Web App" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on the incidents tab. You are now viewing the &lt;strong&gt;Incidence Response Dashboard&lt;/strong&gt;. Click Start investigation and fill in the following in the blank spaces and Click Start investigating :&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Investigation details&lt;/strong&gt;&lt;br&gt;
    Please investigate a recent multi-vector security incident. First, determine the source and impact of repeated SSH brute force attempts against our EC2 instance. Second, investigate unauthorized configuration drift that granted public write access to the &lt;code&gt;vulnerable-app-data-lab-2026&lt;/code&gt; S3 bucket and escalated the permissions of the &lt;code&gt;AppExecutionRole-OverlyPermissive&lt;/code&gt; IAM role.&lt;br&gt;
&lt;strong&gt;Investigation starting point&lt;/strong&gt;&lt;br&gt;
    Start by analyzing the &lt;code&gt;ssh-auth-logs&lt;/code&gt; CloudWatch log group for "Failed password" events. Then, cross-reference AWS CloudTrail management events to identify who recently modified the S3 bucket policy and who attached the secondary STS inline policy to the IAM role.&lt;br&gt;
&lt;strong&gt;Name your investigation&lt;/strong&gt;&lt;br&gt;
    (You can replace the default timestamp with something more readable, such as:) &lt;code&gt;Incident-Security-Drift-Brute-Force&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxdkxya4224ljozkynekm.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%2Fxdkxya4224ljozkynekm.png" alt=" " width="800" height="384"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyg0bvhb47xn4ufnjsn0i.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%2Fyg0bvhb47xn4ufnjsn0i.png" alt="Incidence Response Dashboard" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Investigation findings&lt;/strong&gt;&lt;br&gt;
When the investigation completes, the agent populates the &lt;strong&gt;Investigation summary&lt;/strong&gt; and &lt;strong&gt;Root cause&lt;/strong&gt; tabs within the Operations Web App. What makes the DevOps Agent so powerful is its ability to contextually differentiate between intended Infrastructure as Code (IaC) deployments and malicious or negligent out-of-band changes..&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5vuluvzfmyhg84oea9ig.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%2F5vuluvzfmyhg84oea9ig.png" alt=" " width="800" height="407"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0mfcnd6o50boe91959s5.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%2F0mfcnd6o50boe91959s5.png" alt=" " width="800" height="407"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F342jia691kd2ugsb61df.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%2F342jia691kd2ugsb61df.png" alt=" " width="800" height="407"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwu75mrifroa2m7p1pbl5.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%2Fwu75mrifroa2m7p1pbl5.png" alt=" " width="800" height="407"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw98kb6ly9ytdzhp84ztr.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%2Fw98kb6ly9ytdzhp84ztr.png" alt=" " width="800" height="407"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjxt0b4b0oh0670nar277.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%2Fjxt0b4b0oh0670nar277.png" alt=" " width="800" height="407"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxs3cfrfq382d3x4vdtvl.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%2Fxs3cfrfq382d3x4vdtvl.png" alt=" " width="800" height="407"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2okt2gdoea4n7m25f6oh.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%2F2okt2gdoea4n7m25f6oh.png" alt=" " width="800" height="407"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;a. The Root Causes (Attributing the Drift)&lt;/strong&gt;&lt;br&gt;
The agent successfully maps the multi-vector incident back to two primary root causes:&lt;br&gt;
&lt;strong&gt;Unauthorized Manual Actions&lt;/strong&gt;: &lt;br&gt;
It explicitly flags that the IAM user &lt;code&gt;Chimera&lt;/code&gt; bypassed the Terraform pipeline and used the Firefox browser (from IP &lt;code&gt;196.96.170.247&lt;/code&gt;) to escalate the S3 bucket policy to &lt;code&gt;public-read-write&lt;/code&gt; and attach the dangerous &lt;code&gt;sts:AssumeRole&lt;/code&gt; inline policy. Crucially, the agent notes that this user session was created without MFA authentication, identifying weak access controls as a core vulnerability.&lt;br&gt;
 &lt;strong&gt;Insecure Infrastructure Baseline&lt;/strong&gt;: &lt;br&gt;
The agent accurately determines that the foundational infrastructure was deployed via Terraform by a different user (&lt;code&gt;ECR-Access&lt;/code&gt;). However, it points out that this baseline was inherently insecure to begin with—it featured a security group allowing SSH access from &lt;code&gt;0.0.0.0/0&lt;/code&gt;, disabled S3 Public Access Blocks, and an overly permissive &lt;code&gt;AdministratorAccess&lt;/code&gt; managed policy attached to an EC2 role.&lt;br&gt;
&lt;strong&gt;2. Key Findings (The Brute Force Attack)&lt;/strong&gt;&lt;br&gt;
The agent correctly identifies the mechanics of the simulated attack. It notes that the &lt;code&gt;Attacker-Hydra&lt;/code&gt; EC2 instance executed a deliberate brute force using the Hydra password cracking tool. Because both instances resided on the same subnet with a shared, wide-open security group, the attack succeeded against the weak &lt;code&gt;password123&lt;/code&gt; credentials defined in the EC2 user data.&lt;br&gt;
&lt;strong&gt;3. Investigation Gaps (The Observability Moment)&lt;/strong&gt;&lt;br&gt;
Perhaps the most impressive part of the investigation is the agent's ability to identify what it couldn't see. While investigating the SSH attack, it flagged three critical observability gaps:&lt;br&gt;
 &lt;strong&gt;Broken Telemetry&lt;/strong&gt;: The &lt;code&gt;ssh-auth-logs&lt;/code&gt; log group existed but contained 0 bytes of data, meaning the CloudWatch agent on the Victim-Server failed to successfully ship the logs or was disrupted.&lt;br&gt;
&lt;strong&gt;Missing Network Visibility&lt;/strong&gt;: It attempted to query &lt;code&gt;DescribeFlowLogs&lt;/code&gt; but returned an empty array, highlighting that VPC Flow Logs were entirely disabled, depriving the environment of network-level traffic evidence.&lt;br&gt;
&lt;strong&gt;Missing Threat Detection&lt;/strong&gt;: Finally, it checked for Amazon GuardDuty detectors and found none, noting that without GuardDuty, there was no AWS-native threat intelligence available for the account.&lt;br&gt;
&lt;strong&gt;2. Topology Mapping&lt;/strong&gt;: &lt;/p&gt;

&lt;p&gt;The topology below shows a simulated AWS security scenario where an attacker EC2 instance (&lt;code&gt;**Attacker-Hydra**&lt;/code&gt;) is directly connected to a target EC2 instance (&lt;code&gt;**Victim-Server**&lt;/code&gt;), indicating that network access most likely SSH on port 22 is allowed between them. The victim is protected by a security group (&lt;code&gt;**free-tier-lab-sg**&lt;/code&gt;), which appears to permit inbound access broadly (a common misconfiguration), making it vulnerable to brute-force login attempts. This setup represents a typical attack path where an exposed service is reachable from an external or malicious host.&lt;br&gt;
At the same time, the architecture includes a logging pipeline: the victim instance is attached to an instance profile (&lt;code&gt;**EC2LogShippingProfile**&lt;/code&gt;) and IAM role (&lt;code&gt;**EC2LogShippingRole**&lt;/code&gt;) that allow it to send authentication logs to a CloudWatch log group (&lt;code&gt;**ssh-auth-logs**&lt;/code&gt;). This means the system is instrumented for monitoring and detection of suspicious activity like repeated failed SSH logins, but not necessarily protected against them. &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%2Fs3mqazlfpyswaecb3esi.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%2Fs3mqazlfpyswaecb3esi.png" alt="Topology Map" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Generating the Remediation&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To achieve this, click the &lt;strong&gt;Go to root cause&lt;/strong&gt; button in the timeline.&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%2F7dj7ya1oi5o4rpxx2ltg.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%2F7dj7ya1oi5o4rpxx2ltg.png" alt="Root cause" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Having completed the &lt;strong&gt;Root Cause Analysis (RCA)&lt;/strong&gt;, the agent formulates a mitigation strategy. The objective is twofold: halt the immediate brute force threat and permanently remediate the underlying configuration drift through codified infrastructure changes.&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%2Fe4do7ziay6g7yvrakpe2.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%2Fe4do7ziay6g7yvrakpe2.png" alt=" " width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faf6430bf0l5iny93eavn.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%2Faf6430bf0l5iny93eavn.png" alt=" " width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh50ud1beheaneb8dt25n.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%2Fh50ud1beheaneb8dt25n.png" alt=" " width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fma7nanwhpwpok5swenf3.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%2Fma7nanwhpwpok5swenf3.png" alt=" " width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the root cause is identified, clicking the Generate mitigation plan button reveals exactly why frontier agents are replacing static runbooks. Instead of just offering a generic suggestion to "fix the S3 bucket," the AWS DevOps Agent generates a comprehensive, five-phase SRE mitigation runbook of AWS CLI commands.&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%2Ftbsdma24sovi98tvgojl.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%2Ftbsdma24sovi98tvgojl.png" alt=" " width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftib5spufg91pdlkaej7v.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%2Ftib5spufg91pdlkaej7v.png" alt=" " width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm4vw78spaa6s0yq5eomb.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%2Fm4vw78spaa6s0yq5eomb.png" alt=" " width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd79orz8gbf90oa6nhcpr.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%2Fd79orz8gbf90oa6nhcpr.png" alt=" " width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fncshbr8kysxa4xmvcykn.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%2Fncshbr8kysxa4xmvcykn.png" alt=" " width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flsycw9o2scnv3f7ywhrj.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%2Flsycw9o2scnv3f7ywhrj.png" alt=" " width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is a breakdown of the generated mitigation plan and why each step matters for enterprise operations:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 1: Prepare (State Capture)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before modifying any resources, the agent instructs you to capture the current, drifted state. This is a critical safety mechanism.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1.1 &amp;amp; 1.2&lt;/strong&gt;: &lt;/p&gt;

&lt;p&gt;It provides &lt;code&gt;aws iam get-role-policy&lt;/code&gt; and &lt;code&gt;aws s3api get-bucket-policy&lt;/code&gt; commands to save the exact JSON payloads of the drifted policies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1.3&lt;/strong&gt;: &lt;/p&gt;

&lt;p&gt;It captures the &lt;code&gt;aws s3api get-bucket-policy-status&lt;/code&gt; to establish a baseline for post validation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Why this matters: If reverting the drift breaks an unexpected dependency, you have the exact JSON needed to undo the change immediately.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 2: Pre-Validate (Impact Assessment)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A human engineer might rush to delete the overly permissive policy, accidentally breaking a legitimate workload. The agent prevents this by validating preconditions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2.1&lt;/strong&gt;: &lt;/p&gt;

&lt;p&gt;It runs &lt;code&gt;aws iam list-role-policies&lt;/code&gt; to confirm the rogue &lt;code&gt;STSAssumeRole&lt;/code&gt; policy actually still exists before attempting deletion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2.2&lt;/strong&gt;: &lt;/p&gt;

&lt;p&gt;It runs &lt;code&gt;aws ec2 describe-instances&lt;/code&gt; filtered by the target IAM profile. This is genius. It checks if any live EC2 instances are currently using the compromised role, allowing you to coordinate with stakeholders before pulling the plug.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2.3 &amp;amp; 2.4&lt;/strong&gt;: &lt;/p&gt;

&lt;p&gt;It uses &lt;code&gt;aws iam generate-service-last-accessed-details&lt;/code&gt; to see if the dangerous &lt;code&gt;sts:AssumeRole&lt;/code&gt; permission has actually been exploited recently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 3: Apply (The Tactical Fix)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Having validated the environment, the agent provides the exact, surgical CLI commands to revert the drift without touching the underlying, legitimate IaC.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3.1&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;It runs &lt;code&gt;aws iam delete-role-policy&lt;/code&gt; to explicitly drop the manual &lt;code&gt;STSAssumeRole&lt;/code&gt; inline policy, neutralizing the lateral movement threat.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3.2&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;It runs &lt;code&gt;aws s3api put-bucket-policy&lt;/code&gt; with a newly generated, hardened JSON payload that explicitly strips the &lt;code&gt;s3:PutObject&lt;/code&gt; permission, locking the bucket back down to &lt;code&gt;public-read-only&lt;/code&gt; to match the Terraform baseline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 4: Post-Validate (Verification)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The agent doesn't assume the commands worked; it verifies them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps 4.1 &amp;amp; 4.2&lt;/strong&gt;: &lt;/p&gt;

&lt;p&gt;It reruns the commands from Phase 1 (&lt;code&gt;list-role-policies&lt;/code&gt; and &lt;code&gt;get-bucket-policy&lt;/code&gt;) and asks you to confirm that the output no longer contains the malicious permissions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 5: Rollback&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, the agent provides a complete Rollback script using &lt;code&gt;aws iam put-role-policy&lt;/code&gt; and &lt;code&gt;aws s3api put-bucket-policy&lt;/code&gt;, populated with the exact variables needed to restore the drifted state if the fix causes an unexpected outage.&lt;/p&gt;

&lt;p&gt;By automating the creation of this peer-reviewable, highly defensive CLI runbook, the AWS DevOps Agent collapses the mitigation lifecycle from hours of stressful, manual engineering to mere minutes of execution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Environment Cleanup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To avoid incurring any unexpected charges and to cleanly shut down your lab environment, follow these detailed steps to delete all AWS resources and local configurations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Empty the S3 Bucket&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Terraform cannot destroy an S3 bucket if it contains objects (like Terraform state files or application data)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;.Open the AWS Management Console and navigate to S3.Select the &lt;code&gt;vulnerable-app-data-lab-2026&lt;/code&gt; bucket.Click &lt;strong&gt;Empty&lt;/strong&gt;, type permanently delete to confirm, and click Empty.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Destroy Terraform Infrastructure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In yourterminal, navigate to the directory containing your &lt;code&gt;main.tf file&lt;/code&gt; and execute the destruction command:&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;terraform&lt;/span&gt; &lt;span class="nx"&gt;destroy&lt;/span&gt; &lt;span class="nx"&gt;-auto-approve&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: If you manually created the AWS DevOps Agent Space in the console earlier because it failed to deploy, you will need to manually delete it from the AWS DevOps Agent console.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5zes9uam9fiozsfx11hg.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%2F5zes9uam9fiozsfx11hg.png" alt=" " width="800" height="808"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Clean Up Local Environment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Stop any running MCP servers and remove the installed packages to clean up your local workstation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stop Processes&lt;/strong&gt;: Switch to the terminal windows running your &lt;code&gt;linux-mcp-server&lt;/code&gt; and &lt;code&gt;terraform-mcp-server&lt;/code&gt; and press &lt;code&gt;Ctrl+C&lt;/code&gt; to terminate the processes.&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%2F5ah29qv16rcjl291kcto.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%2F5ah29qv16rcjl291kcto.png" alt=" " width="800" height="636"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7yyypevm7adc4hacpzyz.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%2F7yyypevm7adc4hacpzyz.png" alt=" " width="800" height="636"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Uninstall Linux MCP Server&lt;/strong&gt;: Since this was installed using uv, remove it by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
uv tool uninstall linux-mcp-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Uninstall Terraform MCP Server&lt;/strong&gt;: Depending on how you installed it, remove it via Homebrew or by deleting the binary:&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;# If installed via Homebrew&lt;/span&gt;
brew uninstall terraform-mcp-server

&lt;span class="c"&gt;# If installed via binary download&lt;/span&gt;
&lt;span class="nb"&gt;sudo rm&lt;/span&gt; /usr/local/bin/terraform-mcp-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Remove Lab Files:&lt;/strong&gt; Finally, delete the Terraform state and lab files from your directory to ensure a clean slate:&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;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt;.terraform terraform.tfstate terraform.tfstate.backup tfplan lambda_function.zip index.py main.tf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion and Future Implications&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The integration of agentic AI into the operational fabric of cloud infrastructure fundamentally disrupts traditional paradigms of software engineering, systems administration, and cybersecurity. From a project management and strategic cybersecurity perspective, the empirical evidence derived from this implementation is profound. The deployment of the AWS DevOps Agent yields an MTTR reduction of up to 75%, increases root cause accuracy to 94%, and accelerates overall incident resolution speeds by a factor of 3 to 5.&lt;/p&gt;

&lt;p&gt;However, the most significant implication is the radical reduction of operational toil. By offloading the "undifferentiated heavy lifting" of log correlation, anomaly detection, configuration drift remediation, and HCL syntax generation to an autonomous system, the cognitive load on human engineers is drastically alleviated. This cognitive liberation allows cybersecurity professionals and Project Managers to pivot their focus from reactive firefighting and manual patching to strategic architectural planning, advanced threat modeling, and proactive innovation.&lt;/p&gt;

&lt;p&gt;Furthermore, the implementation of the Model Context Protocol democratizes access to these agentic capabilities. By standardizing the interface between the AI reasoning engine and the underlying data layer, organizations are no longer constrained by monolithic, vendor-specific integrations. They can deploy lightweight, highly specialized MCP servers tailored to their proprietary internal systems whether that is a localized Fedora environment, a custom CI/CD pipeline, or a legacy on-premises database ensuring that the frontier agent has comprehensive, unobstructed visibility across the entire technological estate.&lt;/p&gt;

&lt;p&gt;Ultimately, the adoption of agentic operations is not merely an enhancement of existing DevOps workflows; it is a fundamental architectural evolution. As demonstrated by the capacity to automatically detect security misconfigurations, synthesize root causes, and generate deployable, peer-reviewable infrastructure code, the AWS DevOps Agent establishes the foundation for true self-healing systems a requisite advancement for managing the scale, security, and sustainability demands of the next decade of cloud computing.&lt;/p&gt;

&lt;h1&gt;
  
  
  aws #devops #terraform #cybersecurity
&lt;/h1&gt;

</description>
    </item>
  </channel>
</rss>
