DevOps · Infrastructure automation

Complex systems.
Clear thinking.

I’m James Jenkins. I turn cloud infrastructure, delivery pipelines, and operational workflows into systems that are easier to build, understand, and run.

Based in Utah / Jenkins Cloud Solutions

THE ENGINEER BEHIND THE SYSTEMS01 / JJ
James Jenkins smiling
James JenkinsDevOps + AI Engineer Contractor

Build it deliberately.
Make it repeatable.
Leave a clear path for the next person.

IN THE TOOLKIT
AWSAzureGoogle CloudKubernetesPulumiTerraformAWS CDKGitLab CI/CDisCOBOLPuppeteerPython

01 / Practice

Infrastructure with
an operating plan.

I work across the lifecycle: provision the environment, ship the application, and make the next change easier to reason about.

01

Cloud foundations

Infrastructure as code with Pulumi, Terraform, and AWS CDK. Repeatable environments, clear boundaries, and configurations people can review.

AWS · IaC · Serverless
02

Delivery & operations

Kubernetes, EKS, Helm, and GitLab pipelines. Deployment workflows that connect a source change to an identifiable release and a recovery path.

Kubernetes · Helm · CI/CD
03

Useful automation

Python services, AWS Lambda, API Gateway, and AI-assisted workflows. Reduce repetitive work while keeping decisions and results inspectable.

Python · APIs · AI workflows

Selected engineering work

From complex workflows
to repeatable systems.

Two examples of my contribution. Client identities and internal implementation details are omitted.

Public repositories / Workbench

Practical projects.
Ideas you can inspect.

All public repositories
Identity & accessReference implementation

Multi-cloud Kubernetes RBAC

A shared namespace access policy for existing EKS, AKS, and GKE clusters, with Terraform identity mappings and automated allow/deny checks on a local kind cluster.

  • Terraform
  • EKS / AKS / GKE
  • Kubernetes RBAC
  • Python
multi-cloud-kubernetes-rbac
Cloud deliveryReference implementation

GitLab OIDC cloud deployments

GitLab-to-cloud OIDC federation with scoped trust, temporary credentials, separate dev/prod storage, and rejection tests. Cloud deployment jobs are disabled until federation and storage are configured.

  • GitLab CI/CD
  • OIDC
  • Terraform
  • AWS / Azure / Google Cloud
gitlab-oidc-cloud-deployments
Reliability & diagnosisLocal lab

Kubernetes SRE observability

A local Kubernetes and Docker Compose lab connecting an instrumented Python API to Prometheus SLOs, Grafana dashboards, OpenTelemetry traces, and controlled fault injection.

  • Kubernetes
  • Prometheus
  • Grafana
  • OpenTelemetry
  • Python
kubernetes-sre-observability
Infrastructure as codePublic example

AWS CDK → EKS

A Python/AWS CDK example for an EKS cluster and Helm-deployed NGINX application, including ALB ingress and CI configuration.

  • Python
  • AWS CDK
  • Kubernetes
  • Helm
aws-cdk-python-eks-cluster

Descriptions reflect the public source and README. Each repository documents its setup, scope, and validation; the examples are available to explore and adapt.

Part of the delivery / Documentation

Leave good documentation.
Make the next step clear.

I leave clear, practical documentation alongside my work, so another engineer can set it up, understand the decisions, troubleshoot a problem, and carry it forward.

  • A clear starting point

    Prerequisites, setup, validation, limitations, and cleanup.

  • Commands with context

    Explain what to run, which signals matter, and how to interpret the result.

  • A way to verify recovery

    Define healthy behavior and the checks that confirm it.

  • A useful handoff

    Record evidence, decisions, and follow-up actions for the next engineer.

docs/runbook.mdPublic local-lab example

An incident runbook someone else can follow

A public guide to investigating error-budget burn and missing telemetry in my local Kubernetes SRE lab, with commands, interpretation, recovery checks, and a postmortem handoff.

  1. Confirm the symptom

    Identify the service and SLO, compare user-facing request signals, and inspect both alert windows.

  2. Follow the evidence

    Correlate logs with a trace ID and inspect the request and dependency spans in Grafana and Tempo.

  3. Recover and verify

    Stop the local fault traffic, supply healthy baseline traffic, then confirm successful requests and alert recovery.

One documented check · local Compose lab

docker compose logs --since=10m app otel-collector tempo

02 / Architecture & standards

Draw the system.
Explain the decisions.

Architecture is a set of decisions you can explain: who can act, where traffic flows, what gets deployed, and how the system recovers.

Explore compute patterns for AWS, Azure, and Google Cloud, alongside delivery, access, and engineering standards. These illustrative designs make the boundaries and decisions visible.

AWS reference design with a public Application Load Balancer, private EC2 Auto Scaling workers across two Availability Zones, and an RDS Multi-AZ primary and standby.
  1. Enter through a public load balancer

    An Application Load Balancer accepts HTTPS and forwards application requests to its registered targets.

  2. Run the app across Availability Zones

    An EC2 Auto Scaling group places application instances in private subnets across two Availability Zones.

  3. Scale and replace deliberately

    Use demand metrics for scaling and configure load-balancer health checks for instance replacement.

  4. Keep the database connection private

    The application connects to the RDS primary through its database endpoint, with network access scoped to the application tier.

  5. Provide a database recovery path

    An RDS Multi-AZ DB instance synchronously replicates to a standby in another Availability Zone. That standby supports failover; it does not serve reads.

AWS compute reference: public ingress, private application instances, and a database failover boundary.
Open full-size diagram
01

Separate the tiers

Public ingress, private compute, and database access have distinct network boundaries.

02

Spread the application

Multiple Availability Zones and health-based replacement reduce dependence on one instance.

03

Choose the right resilience

Application scale-out and database failover solve different problems.

A small example / RBAC

Make the boundary
visible.

A useful permission model explains what an identity can do—and gives you a way to check where that access ends.

Try this policy sketch: a service account can read Pods in the observability namespace.

Read the RBAC guide
permission-check / example
IDENTITY

system:serviceaccount:observability:reader

CHECK
$ kubectl auth can-i get pods
  -n observability
  --as=system:serviceaccount:observability:reader
yes

The Role grants read access to Pods in this namespace.

Illustrative policy · runs entirely in your browser

03 / Engineering notes

The reasoning
behind the work.

Practical guides on access, diagnosis, and delivery. Written to be useful at the terminal, with links to the source documentation.

04 / Engineering community

Help another engineer
get unstuck.

I share what I learn on Stack Overflow: answering questions, investigating the details, and following up when the first explanation leaves something unresolved.

13+years on Stack Overflow

Member since

Behind every technical question is someone trying to move a project forward. I aim to leave them with a clearer explanation and a concrete next step.

See my Stack Overflow contributions

Find me as jdj333

A real troubleshooting exchangeKeycloak · Bash · OIDC

Getting a Keycloak setup script past a 401

An engineer wanted to provision Keycloak realms from a local script, but getting and using an administrator token was blocking the setup.

Explain the path

I explained how to use the built-in admin-cli client with bootstrap administrator credentials, and why the administrator’s permissions determine what the token can do.

Follow the evidence

When the edited script still returned 401, I reproduced it on Keycloak 26.8.2. The token extracted with jq kept its JSON quotes; raw extraction with jq -r removed them, and the same realm-creation request returned 201. I also pointed out the password-variable mismatch and checking HTTP errors before continuing.

401 quoted token201 raw token
Read my answer and the follow-up

05 / About James

Engineer.
Problem solver.
Always learning.

Full background on LinkedIn

I’m a DevOps and infrastructure automation engineer based in Utah.

Through Jenkins Cloud Solutions, I work across AWS infrastructure as code, serverless services, Kubernetes, and automated delivery. My focus is making complex environments repeatable, improving developer workflows, and building systems teams can understand and operate with confidence.

My background spans frontend and Java development, DevOps engineering, and cloud consulting. That mix keeps me interested in both the infrastructure and the people who depend on it.

2023 — present

Jenkins Cloud Solutions LLCDevOps + AI Engineer Contractor

2022 — 2023

Amazon Web ServicesDevOps Consultant

2019 — 2022

bioMérieuxSenior DevOps Engineer

2011 — 2019

Enterprise software engineeringFrontend & Java development → DevOps engineering

Background drawn from my LinkedIn profile; repository descriptions reflect their public documentation.

Keep the conversation going

Good systems start
with good questions.

Connect on LinkedIn