top of page

How we built an AIOps agent – and let it perform root cause analysis

On March 13th, we had a service that was down.






Nothing strange in itself, things like that happen. In a complex environment, there can be multiple reasons for this, many systems to validate, and it can be time-consuming to troubleshoot.


  • Github (Manifest repo)

  • Kubernetes (AWS EKS)

  • ArgoCD

  • Amazon ECR

  • AWS Load Balancers


There was no clear root cause, and starting to troubleshoot each system individually could be a time-consuming process.



We did something simple: we let an AI troubleshoot

Instead of starting to search manually, we put an AI on the problem.

A prompt. No back and forth dialogue. Just: “find out what’s wrong, can’t reach application X”.



The result? 4 errors across three systems


On a run, the agent found:


1. Wrong selector in load balancer (misconfigured kubernetes manifest)

loadbalancer.yaml referenced devsecops-lab-appp (three p).

Result: no healthy NLB targets.


2. Image tag that did not exist (misconfigured kubernetes manifest)

Deployment.yaml used v0.0.99, but ECR only had v0.0.7.Pod got stuck in ImagePullBackOff.


3. Port mismatch (misconfigured kubernetes manifest)

ContainerPort 4999 was configured, while service and load balancer pointed to 5000. All requests were denied.


4. Security group blocked health checks

NodePort 30992 was used, but the security group only allowed 31000–31100. Health checks were silently dropped.


Four small errors. Together: a service that didn't work.



Here comes the important part: how we built it


This didn't work because we "prompted well". It worked because we built the right structure around the AI.


Let me show you how we did it.



Step 1: we built an agent that can actually do the job

We didn't start with prompts. We started with what the agent can actually do.

We set up a local MCP server and gave the agent three simple tools:

  • list – show available code (to avoid re-generating)

  • write – to generate code

  • execute – to run what it created itself


Then we made a conscious choice. We didn't build any ready-made integrations. (This method is specifically called "Code execution with MCP").


Instead, we let the agent himself:


  • write scripts to read Kubernetes resources

  • retrieve information from AWS (e.g. security groups, load balancers)

  • compare configuration against GitHub


The first run took a little longer, but after that it was able to reuse its own “skills”.


The result?

An agent who not only responds, but actually drives the troubleshooting.


Step 2: We defined the troubleshooting flow upfront

Next problem: where should the agent start?


AI is good at execution, but not at choosing the right path.

So we removed that choice completely.


We created infra-context.md and defined a clear routing:

“App unreachable” →ArgoCD → Deployments → Pods → Services → Manifests


This is nothing advanced. It's just our collective experience written down.


The difference is that the agent:

  • follows every step

  • doesn't skip anything

  • run everything in the same flow


This is where we went from “AI testing a few things” to a reproducible troubleshooting process.


Step 3: we controlled the behavior, not just the input

The final part was to get the agent to behave consistently.

We did that in CLAUDE.md .


There we described specifically:

  • when to use the MCP server

  • how workflows should be built (code structure)

  • how results should be structured in a report

  • which files to read for context ( infra-context.md )


We were very clear here.


For example:

  • “always read infra-context.md first”

  • “build a workflow that runs all checks in one run”

  • “return a structured response with identified errors and suggested actions”


This was crucial.


Without it, we got different answers in different formats based on what the prompt looked like. With the structure, we got an agent that:


  • works methodically

  • run the entire analysis in one step

  • delivers something we can actually use right away



What we learned

This is what actually made a difference:


Structure optimizes the AI model

Today's LLMs are powerful, but can tend to hallucinate and go in the wrong direction if structure and rules are not in place.


AI is good at writing code

Since LLMs are more trained to generate code than to use various “tools”, it is advantageous to let them do that, instead of asking them to debug “freehand”. This keeps the context “clean”, which reduces the risk of hallucinations and saves on tokens.


Clear context between runs

Since an agent without structure has no knowledge of the environment (we would have needed to prompt it how to reach each system), it probably won't find all errors after one run and needs to be prompted again to continue debugging (costs more tokens and is not deterministic). This can also lead to context bloating which tends to create problems for the agent to achieve its original task.


It is possible to make it reproducible

One run → one answer → same result every time.


What this means in practice

Most environments today consist of several different systems, such as Kubernetes, cloud (AWS/Azure), some form of Git, CI/CD, VMs, etc.


When something goes wrong, it is often necessary to:

  • multiple tools

  • several people

  • manual correlation


This is exactly what we address with AIOps. Not more dashboards, but a way to actually get to the root cause faster.


Download the full case


See the entire setup behind the solution. How the flow is set up, how the agent executes and how you can apply it in your own environment.






Would you like to see how this can work in your environment?


This started as a demo case, but the pattern is directly applicable in production.


We help you to:

  • set up AIOps flows

  • connect Kubernetes, cloud and CI/CD

  • automate troubleshooting and reduce time to root cause


Get in touch and we'll show you what it could look like for you.





Or contact our colleague Ronnie Qvist , and he will help you further.


📲 +46 791 04 70 00


 
 
 

Comments


bottom of page