Insights - Cloud Engineering

From a Third-Party WAF to AWS WAF: The Engineering Decisions That Changed More Than Our Architecture

From a Third-Party WAF to AWS WAF: The Engineering Decisions That Changed More Than Our Architecture
Chandramani

Chandramani

DevOps Engineer

Updated18 Aug 2026
Published18 Jun 2026
TagAWS
Reading time6 min read

Gist

What began as a false-positive investigation revealed a deeper problem: years of accumulated WAF rules with no clear owner, no documented purpose, and no one willing to remove them. The real migration wasn't moving rules from one platform to another β€” it was separating intentional security controls from historical baggage and rebuilding ownership from the ground up.

For years, every request to our applications followed the same path.

A user clicked Login, searched for a record, or downloaded a document. Before that request ever reached our application running on AWS, it first travelled to a third-party Web Application Firewall hosted outside our cloud environment. The request was inspected there, and only then was it forwarded back into AWS to reach the application.

It worked. In fact, it had worked for years.

Like many production systems, the architecture had gradually become something nobody questioned β€” because it continued doing its job. But engineering teams don't usually revisit systems because they're broken. They revisit them when something starts feeling unnecessarily difficult.

For us, that moment came during what should have been a straightforward false-positive investigation.

Why We Started Asking Questions

A legitimate customer request had been blocked. The logs existed. AWS had its view of the request, and the WAF vendor had theirs. Yet understanding what had actually happened meant moving between two different platforms, correlating timestamps, comparing rule IDs, and piecing together a story that no single system could explain.

The problem wasn't the blocked request.

The problem was that we had lost operational visibility into one of the most critical layers of our platform.

As we dug deeper, more questions surfaced.

Why does this regex exist? Who added this allowlist? Why is this endpoint excluded from inspection? Is this rule still protecting us, or has it simply survived every migration because nobody wanted to remove it?

None of those questions had immediate answers.

That was the moment we realized this project wasn't really about replacing one WAF with another. It was about regaining ownership of our security platform.

The Migration Didn't Start With AWS

When people think about migrations, they usually imagine new infrastructure β€” provisioning services, deploying code, updating DNS records.

Our migration looked very different.

Long before we created an AWS WAF WebACL or configured CloudFront, we spent weeks understanding what already existed. We exported every active security rule, every regex pattern, every IP allowlist, every rate-limiting policy, and every exception that had accumulated over the years. The goal wasn't simply to inventory them β€” we wanted to understand why each one existed in the first place.

That exercise became the foundation of the entire migration.

Some rules were immediately recognizable because they addressed well-known security threats. Others reflected specific business requirements or incidents that had occurred years earlier. But there was another category that surprised us β€” rules with no clear owner, no documented purpose, rules that everyone assumed were important simply because they were still running in production.

The audit forced us to ask questions that had been overlooked for years: Does this control still provide value? Is it already covered by modern managed rule groups? Would anyone notice if we removed it?

By the end of the inventory, something became obvious. The migration wasn't about moving rules from one platform to another. It was about separating intentional security controls from historical baggage.

Looking back, the most important lesson from the project can be summarized in one sentence.

The audit wasn't preparation for the migration. The audit was the migration.

Everything that followed became easier because we finally understood what we were protecting.

Rebuilding Instead of Replicating

One of the easiest ways to approach a migration is to recreate the existing environment exactly as it is. At first, that sounds like the safest option. In reality, it often means carrying yesterday's decisions into tomorrow's architecture.

We deliberately chose a different path. Instead of treating every legacy rule as something that deserved to be preserved, we treated every rule as something that had to justify its existence.

Some controls were retired because AWS Managed Rule Groups already provided equivalent protection. Others had been created as temporary responses to incidents that no longer reflected the current application landscape. A few were simply duplicates introduced over years of incremental changes.

Rather than aiming for a one-to-one migration, we rebuilt the rule set around how the applications actually behaved today.

The result was a smaller, cleaner, and more maintainable security policy. More importantly, every rule that moved into production had a clear purpose, a documented owner, and a reason to exist.

That change may not have been visible to end users. For the engineers responsible for operating the platform, it changed everything.

The Decisions That Changed Everything

Every engineering project has a few decisions that seem insignificant when they're made but become defining moments in hindsight. This migration had several.

The first was surprisingly simple: no WAF rule would ever be created, modified, or deleted directly through the AWS Console. Every change had to go through a GitHub Pull Request, be reviewed by another engineer, and carry the context needed to explain why the change was being made.

Initially, it felt like additional process. As the migration progressed, it became one of the strongest engineering controls we introduced. Reviewing pull requests caught configuration mistakes before they reached production. Every security rule developed a traceable history. SOC 2 evidence became a by-product of the engineering workflow instead of a separate documentation exercise. Months later, when someone asked why a particular rule existed, the answer was no longer hidden inside someone's memory β€” it was recorded alongside the change itself.

Another decision proved equally valuable: every newly designed rule would spend time observing production traffic before enforcing it. Instead of immediately blocking requests, we allowed the rules to operate in Count mode, giving us an opportunity to understand real user behaviour before making enforcement decisions.

At the time, it felt like a cautious approach. Later, it prevented legitimate enterprise users from being blocked because hundreds of employees shared the same public IP address behind a corporate network.

Engineering projects often celebrate the technologies they adopt. Looking back, the technologies mattered. But the decisions mattered more β€” because those decisions gave us something we didn't have before.

Confidence. Not just in the platform we were building, but in our ability to explain every security control that protected it.

Coming in Part 2: where AI genuinely accelerated the migration, why it never replaced engineering judgment, the measurable outcomes of the project, and the lessons we'll carry into every future cloud security migration.

Where AI Actually Helped

Whenever AI becomes part of an engineering project, the conversation usually shifts in one direction: how much of the work can AI do?

That wasn't the question we were trying to answer. Our focus was simpler β€” which parts of the migration were repetitive enough for AI to accelerate, while keeping every engineering decision in human hands?

That distinction shaped how we used AI throughout the project.

One of the first opportunities appeared during the inventory phase. We had exported hundreds of legacy rules, regex patterns, and configuration snippets accumulated over several years. Understanding each of them manually would have taken days.

AI became a useful engineering assistant. It translated undocumented regex into plain English, summarized legacy rule behavior, highlighted rules that appeared to overlap with AWS Managed Rule Groups, and helped transform engineering notes into structured documentation.

What it never did was decide whether a rule should stay or go.

Every recommendation was reviewed. Every rule was validated. Every production decision belonged to the engineering team.

Later in the migration, AI helped accelerate rule translation by suggesting AWS WAF equivalents for legacy controls and organizing application-specific rule structures for review. It also supported operational monitoring by classifying blocked requests into likely false positives, potential attacks, or cases requiring further investigation β€” allowing engineers to focus their attention where it mattered most.

Looking back, we realized something interesting.

AI never became the engineer.

It became the teammate that handled repetitive analysis so engineers could spend more time making architectural decisions. That's where it delivered the most value.

What We Learned

Every migration teaches technical lessons. The valuable ones, however, usually have very little to do with technology. This project was no different.

The first lesson was that migrations rarely fail because of infrastructure. They struggle because of accumulated operational debt. By the time we completed our inventory, we had discovered duplicated controls, outdated incident rules, and configurations that no longer reflected how the applications actually behaved. Understanding those decisions took far longer than deploying new infrastructure.

The second lesson was that managed security services aren't "set and forget." AWS Managed Rule Groups provided a strong foundation, but they still required tuning around application behaviour. One search endpoint, for example, legitimately generated request patterns that resembled SQL injection attempts. Rather than disabling protection entirely, we scoped the exception to that specific endpoint while preserving protection everywhere else. That balance only came from understanding the application itself.

The third lesson reinforced why engineering discipline matters.

Every security change went through GitHub. Every exception had a reason. Every decision had a reviewer.

Months later, nobody had to ask why a rule existed, because the answer travelled with the code itself.

Perhaps the biggest lesson, though, came from observing production traffic.

Rules that looked perfect on paper behaved differently under real user activity. Running them in Count mode before enforcement gave us the confidence to adjust them without impacting customers. One enterprise customer with hundreds of users behind a shared corporate NAT gateway could easily have been blocked on day one if we had skipped that validation period. Instead, we redesigned the rate-limiting strategy before enabling enforcement.

That single incident justified every extra day we spent validating the platform.

The Results

The migration delivered measurable improvements across both operational efficiency and security management.

Eighteen production domains were migrated over twelve weeks without downtime. Security controls were consolidated from 147 production rules to 96, removing redundant configurations while improving visibility and maintainability. False positives dropped significantly, and the average time required to investigate blocked requests reduced from hours to minutes because engineers no longer had to correlate information across multiple platforms. Domain onboarding also became substantially faster through reusable WebACL configurations.

The impact extended beyond the migration itself.

Today, approximately 2 million requests are inspected every day at the AWS edge, with nearly 200,000 malicious or unwanted requests blocked daily before reaching the application layer. Security monitoring has evolved from reactive troubleshooting into a structured operational process supported by CloudWatch, GitHub workflows, and AI-assisted triage.

These numbers matter. But they don't tell the whole story.

The real success wasn't reducing latency or retiring legacy rules. It was building a platform the engineering team could confidently understand, operate, and improve.

Looking Back

When we started this migration, we thought we were replacing a Web Application Firewall.

Looking back, that's only a small part of what actually happened.

We rebuilt ownership.

Every production rule now has a documented purpose. Every security decision has a recorded history. Every change follows an engineering workflow instead of depending on tribal knowledge or vendor support. The platform has become easier to explain, easier to audit, and easier to evolve β€” because the knowledge now lives with the engineers who operate it.

AI certainly helped us move faster. AWS provided the cloud-native capabilities we needed. GitHub strengthened our engineering governance.

But none of those technologies made the migration successful on their own.

The success came from asking difficult questions, challenging long-standing assumptions, and treating the migration as an opportunity to simplify rather than replicate.

That's the lesson we'll carry into every future modernization project.

Technology can change your architecture.

Engineering ownership changes how confidently you operate it.

Planning AI transformation?

Design a future-ready AI strategyβ€”connect vision to execution with a roadmap built for speed, impact, and long-term growth.