<?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>Forem: Edwin Jonathan</title>
    <description>The latest articles on Forem by Edwin Jonathan (@edwindevops).</description>
    <link>https://forem.com/edwindevops</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3910450%2F83277dda-3c32-4a62-973e-26d0f74c3356.png</url>
      <title>Forem: Edwin Jonathan</title>
      <link>https://forem.com/edwindevops</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/edwindevops"/>
    <language>en</language>
    <item>
      <title>How I Used OIDC to Eliminate Static AWS Keys from GitHub Actions (Real Pipeline Walkthrough)</title>
      <dc:creator>Edwin Jonathan</dc:creator>
      <pubDate>Wed, 06 May 2026 11:45:58 +0000</pubDate>
      <link>https://forem.com/edwindevops/how-i-used-oidc-to-eliminate-static-aws-keys-from-github-actions-real-pipeline-walkthrough-4dpo</link>
      <guid>https://forem.com/edwindevops/how-i-used-oidc-to-eliminate-static-aws-keys-from-github-actions-real-pipeline-walkthrough-4dpo</guid>
      <description>&lt;p&gt;Static AWS access keys in GitHub Actions secrets is how &lt;br&gt;
production environments get breached.&lt;/p&gt;

&lt;p&gt;Here's how I replaced every static key with OIDC federation &lt;br&gt;
for the Damolak Technologies DevOps challenge — &lt;br&gt;
and why you should too.&lt;/p&gt;




&lt;p&gt;The Problem With Static Keys&lt;/p&gt;

&lt;p&gt;When you do this:&lt;br&gt;
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}&lt;br&gt;
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}&lt;br&gt;
 You have a long-lived credential sitting in GitHub that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Never rotates automatically&lt;/li&gt;
&lt;li&gt;Has blast radius if the repo is compromised&lt;/li&gt;
&lt;li&gt;Violates least-privilege by existing at all&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;The Fix: OIDC&lt;/p&gt;

&lt;p&gt;GitHub Actions supports OIDC token exchange with AWS.&lt;br&gt;
Your pipeline requests a short-lived token. AWS validates it &lt;br&gt;
against a trust policy. No stored credentials.&lt;/p&gt;

&lt;p&gt;Step 1 — IAM OIDC Provider&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
hcl
resource "aws_iam_openid_connect_provider" "github" {
  url             = "https://token.actions.githubusercontent.com"
  client_id_list  = ["sts.amazonaws.com"]
  thumbprint_list = ["6938fd4d98bab03faadb97b34396831e3780aea1"]
}

Step 2 — Trust Policy (scoped to YOUR repo):
{
  "Condition": {
    "StringLike": {
      "token.actions.githubusercontent.com:sub": 
        "repo:EdwinJdevops/damolak-challenge:ref:refs/heads/main"
    }
  }
}

This means ONLY your main branch can assume this role.
A fork cannot. A PR branch cannot. Exact scope.

Step 3 — GitHub Actions Workflow
permissions:
  id-token: write
  contents: read

- name: Configure AWS credentials
  uses: aws-actions/configure-aws-credentials@v4
  with:
    role-to-assume: arn:aws:iam::ACCOUNT_ID:role/github-actions-role
    aws-region: us-east-1
That's it. No secrets stored. Token lives for 15 minutes.

**The Full Pipeline I Shipped
**
OIDC auth → ECR login → Docker build + push →
ECS Fargate rolling deploy → ALB health check
33 AWS resources provisioned by Terraform.
Live endpoint behind ALB.
Zero static credentials anywhere in the stack.
Full repo: github.com/EdwinJdevops/damolak-challenge.

Connect:https://hashnode.com/@jonathandevops
Connect:https://www.linkedin.com/in/edwin-jonathan-1094093b0
Connect:https://x.com/TheCloudDeveng
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>devops</category>
      <category>aws</category>
      <category>githubactions</category>
      <category>terraform</category>
    </item>
    <item>
      <title>I Built a Production-Grade Internal Developer Platform at 17 — Full Architecture</title>
      <dc:creator>Edwin Jonathan</dc:creator>
      <pubDate>Sun, 03 May 2026 15:23:10 +0000</pubDate>
      <link>https://forem.com/edwindevops/i-built-a-production-grade-internal-developer-platform-at-17-full-architecture-id6</link>
      <guid>https://forem.com/edwindevops/i-built-a-production-grade-internal-developer-platform-at-17-full-architecture-id6</guid>
      <description>&lt;p&gt;The Problem&lt;/p&gt;

&lt;p&gt;Most engineers deploy to Kubernetes by clicking buttons in a UI. &lt;br&gt;
That's not DevOps. That's manual labor with extra steps.&lt;/p&gt;

&lt;p&gt;I built Archnet — a fully automated Internal Developer Platform &lt;br&gt;
that handles deployments, secrets, observability, and self-healing &lt;br&gt;
with zero human intervention after setup.&lt;/p&gt;

&lt;p&gt;What is an Internal Developer Platform?&lt;/p&gt;

&lt;p&gt;An IDP is the infrastructure layer that sits between your code &lt;br&gt;
and your cloud. It handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How code gets deployed&lt;/li&gt;
&lt;li&gt;How secrets are managed&lt;/li&gt;
&lt;li&gt;How the system monitors itself&lt;/li&gt;
&lt;li&gt;How failures get detected and fixed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most companies pay Humanitec or Backstage $50k+/month for this.&lt;br&gt;
I built it from scratch.&lt;/p&gt;

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

&lt;p&gt;Developer pushes code to GitHub&lt;br&gt;
↓&lt;br&gt;
GitHub Actions builds + scans the image&lt;br&gt;
↓&lt;br&gt;
Docker image pushed to registry&lt;br&gt;
↓&lt;br&gt;
ArgoCD detects manifest change in Git&lt;br&gt;
↓&lt;br&gt;
ArgoCD syncs to k3s Kubernetes cluster&lt;br&gt;
↓&lt;br&gt;
Prometheus scrapes metrics from all pods&lt;br&gt;
↓&lt;br&gt;
Grafana visualizes — AlertManager fires on anomalies&lt;br&gt;
↓&lt;br&gt;
Loki aggregates all logs&lt;/p&gt;

&lt;p&gt;Tech Stack &amp;amp; Why&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;k3s over kubeadm&lt;/strong&gt;&lt;br&gt;
Single binary. Boots in under 5 minutes. &lt;br&gt;
Full Kubernetes API. Production-proven by Rancher.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ArgoCD over Flux&lt;/strong&gt;&lt;br&gt;
Better UI for drift visibility. Multi-cluster support. &lt;br&gt;
Stronger RBAC controls. Built-in auto-remediation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sealed-Secrets over HashiCorp Vault&lt;/strong&gt;&lt;br&gt;
No external dependencies. Secrets live encrypted in Git.&lt;br&gt;
Only the cluster can decrypt. Zero operational overhead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prometheus + Grafana over Datadog&lt;/strong&gt;&lt;br&gt;
Full data ownership. No per-host billing.&lt;br&gt;
Custom retention. Industry standard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub Actions over Jenkins&lt;/strong&gt;&lt;br&gt;
No server to maintain. Native Git integration.&lt;br&gt;
YAML pipelines. Free for public repos.&lt;/p&gt;

&lt;h2&gt;
  
  
  The GitOps Model
&lt;/h2&gt;

&lt;p&gt;Everything is declarative. No imperative commands in production.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You commit a change to Git&lt;/li&gt;
&lt;li&gt;ArgoCD detects the drift between Git and cluster state&lt;/li&gt;
&lt;li&gt;ArgoCD automatically syncs — no human needed&lt;/li&gt;
&lt;li&gt;If a pod crashes, ArgoCD detects and resyncs&lt;/li&gt;
&lt;li&gt;Prometheus fires an alert, Grafana shows the anomaly&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is self-healing infrastructure.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Network policies: default deny all, explicit allow per service&lt;/li&gt;
&lt;li&gt;RBAC: least-privilege service accounts per workload&lt;/li&gt;
&lt;li&gt;Sealed-Secrets: no plaintext secrets anywhere&lt;/li&gt;
&lt;li&gt;Trivy: scans every image before it touches the cluster&lt;/li&gt;
&lt;li&gt;Audit logging: every API call recorded&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Observability Stack
&lt;/h2&gt;

&lt;p&gt;Three pillars:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Metrics&lt;/strong&gt; — Prometheus collects from every pod&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logs&lt;/strong&gt; — Loki aggregates from every container&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alerts&lt;/strong&gt; — AlertManager fires to Slack on anomalies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dashboards track: cluster health, pod restarts, &lt;br&gt;
deployment status, ArgoCD sync state, node memory/CPU.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;Real DevOps is not about knowing commands.&lt;br&gt;
It's about designing systems that run themselves.&lt;/p&gt;

&lt;p&gt;Observability is not optional — if you can't see it, &lt;br&gt;
you can't fix it.&lt;/p&gt;

&lt;p&gt;Security must be designed in from day one.&lt;br&gt;
Not bolted on after.&lt;/p&gt;

&lt;p&gt;Git is not just version control. &lt;br&gt;
In GitOps, Git is your deployment engine.&lt;/p&gt;

&lt;p&gt;The Repo&lt;/p&gt;

&lt;p&gt;Full open source: github.com/EdwinJdevops/ARCHNET&lt;/p&gt;

&lt;p&gt;Architecture docs, tech decisions, security model, &lt;br&gt;
CI/CD pipeline, Terraform IaC — all documented.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who I Am
&lt;/h2&gt;

&lt;p&gt;17-year-old self-taught DevOps Engineer from Nigeria.&lt;br&gt;
Building infrastructure that enterprises pay millions for.&lt;/p&gt;

&lt;p&gt;Available for DevOps, Cloud, and Platform Engineering roles globally.&lt;/p&gt;




&lt;p&gt;If this helped you — share it. &lt;br&gt;
If you're hiring — let's talk.&lt;/p&gt;

&lt;p&gt;Originally published on Hashnode: [&lt;a href="https://edwinjonathand-devops.hashnode.dev/" rel="noopener noreferrer"&gt;https://edwinjonathand-devops.hashnode.dev/&lt;/a&gt;]&lt;/p&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>gitops</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
