Kellton LogoHome
Contact

Migrating from NGINX to AWS CloudFront Functions. Benefits, use cases, and DevOps insights

Serverless edge computing: How to migrate NGINX traffic to CloudFront Functions with Terragrunt.

Maciej Piesio
5 min read
Two people are working at computers in an office. A person on the right is looking at a monitor displaying code in a dark theme text editor.

NGINX vs. CloudFront Functions

If you’ve ever managed edge traffic with NGINX, you know the drill: endless CVE patches, container rebuilds, and delayed deployments. While NGINX is a powerful tool, maintaining it at scale can drain time and resources. In this article, we’ll walk you through what NGINX does, what CloudFront Functions bring to the table, and how the migration simplified our DevOps workflows with Terraform and Terragrunt. By the end, you’ll see why shifting from containers to serverless edge computing might be the upgrade your infrastructure needs.


What was our previous NGINX setup?

What is NGINX? NGINX is an open-source web server and reverse proxy widely used for load balancing, caching, and request routing. It’s extremely fast and flexible, but requires ongoing patching and maintenance. In our previous setup, NGINX was containerized and deployed either:

  • As part of a Docker Compose stack on Docker Swarm running on EC2
  • As a service on an AWS Fargate-powered ECS cluster.

Infrastructure was managed using Terragrunt, allowing us to keep configurations in code and deploy across multiple environments consistently.

NGINX was responsible for all the little – but vital – things that happen before a request hits the application server: path rewrites (like swapping /old-path/ for /new-path/), redirects for old API endpoints, host-based routing, and header manipulation. It worked, sure, but it felt like pushing a heavy cart uphill. The downsides were glaring:

While effective, this approach had several downsides:

  • Security: Frequent CVE alerts flagged our NGINX version
  • Operational Overhead: Managing Docker images, container orchestration, and rolling updates
  • Deployment Delays: Changes required container rebuilds and ECS/Fargate task redeployments

Why migrate to AWS CloudFront Functions?

The goal was to migrate all edge logic managed by NGINX to AWS CloudFront Functions to achieve:

  • Easier management of rewrite/redirect logic
  • Quicker deployments using Terraform and Terragrunt
  • Improved security posture by removing the need to patch and manage NGINX.

CloudFront Functions let you run lightweight JavaScript at the CDN edge, during the viewer request or viewer response phase. This enables ultra-low-latency routing and transformation without managing servers or containers.

The benefits are clear as a bell: no infrastructure to manage, global propagation in seconds, and it's fully integrated with your existing CloudFront distributions. It’s a real game-changer for simple edge use cases.


Managing CloudFront Functions with Terraform and Terragrunt

Just like with NGINX, we kept everything in infrastructure-as-code. Using Terraform and Terragrunt, we can:

  • Version-control every single one of our CloudFront Functions.
  • Deploy consistently across development, staging, and production environments.
  • Roll back quickly if something goes sideways.

This setup makes sure we treat the edge logic itself as code. It ensures complete traceability – you always know who changed what and when – and it drastically cuts down on human errors.

Our Terragrunt structure looks something like this:

# terragrunt.hcl  
inputs = {  
  cloudfront_functions = [  
    {  
      name       = "rewrite_old_path"  
      runtime    = "cloudfront-js-1.0"  
      handler    = "handler"  
      code       = file("../functions/rewrite_old_path.js")  
      trigger    = "viewer-request"  
    }  
  ]  
}

Practical use cases: Migrating common NGINX rules to CloudFront Functions

Let’s break down how some of the most common NGINX configurations translate into CloudFront Functions. This will give you a clear picture of what the migration looks like in practice.

Use Case 1: Path Rewrite

This is arguably the most common task. NGINX lets you use a powerful, if sometimes cryptic, rewrite directive.

Previous NGINX Configuration:

location /old-path/ {  
  rewrite ^/old-path/(.*)$ /new-path/$1 permanent;  
}

Equivalent CloudFront Function:

function handler(event) {
  const request = event.request;
  if (request.uri.startsWith('/old-path/')) {
    request.uri = request.uri.replace(/^\/old-path\/(.*)/, '/new-path/$1');
  }
  return request;
}

Use Case 2: API Version Redirect

You often need to send users from an old API version to a new one, telling the browser the change is permanent.

Previous NGINX Configuration:

location /api/v1/ {  
  return 301 /api/v2/$request_uri;  
}

Equivalent CloudFront Function:

function handler(event) {
  const { uri } = event.request;
  if (uri.startsWith('/api/v1/')) {
    return {
      statusCode: 301,
      statusDescription: 'Moved Permanently',
      headers: {
        location: { value: uri.replace(/^\/api\/v1\/(.*)/, '/api/v2/$1') },
      },
    };
  }
  return event.request;
}

Use Case 3: Host-Based Routing

NGINX handles this with multiple server_name and proxy_pass blocks. It’s a fine approach, but it keeps that complexity locked inside your container.

Equivalent CloudFront Function:

function handler(event) {
  const request = event.request;
  const host = request.headers['host'].value;

  if (host === 'us.example.com') {
    request.origin = {
      s3: { domainName: 'us-bucket.s3.amazonaws.com', region: 'us-east-1' },
    };
  } else if (host === 'eu.example.com') {
    request.origin = {
      s3: {
        domainName: 'eu-bucket.s3.eu-west-1.amazonaws.com',
        region: 'eu-west-1',
      },
    };
  }
  return request;
}

Benefits observed after NGINX migration

After migrating to CloudFront Functions, the results were immediate and substantial. We got a huge boost in operational effectiveness.

  • Faster deployments – Edge logic updates now take mere seconds. We completely eliminated the wait time for container builds and image pushes.
  • Lower maintenance – We no longer spend time patching containers or keeping NGINX versions up to date. That's a zero-cost win for the team.
  • Improved security – Our security scans are clean. We removed the entire NGINX attack surface, eliminating alerts related to its CVEs.
  • Infrastructure simplification – We were able to decommission several old NGINX services. Less running means less to worry about.
  • Unified IaC – Every routing rule is now version-controlled and deployed consistently using Terraform. This makes our entire edge architecture repeatable and traceable.

From heavy containers to lightweight edge logic

Migrating NGINX responsibilities to CloudFront Functions has streamlined our operations, improved security, and accelerated deployment cycles. By managing everything in Terraform and Terragrunt, we achieved a repeatable, trackable, and low-maintenance edge architecture. If your stack still relies on NGINX for edge routing and rewrites, this approach could simplify your setup significantly while eliminating common maintenance and security headaches.

At Kellton Europe, we help organizations modernize their cloud infrastructure with scalable, secure, and cost-efficient architectures. Get in touch with our cloud experts and let’s design an edge solution that works for your business.

FAQ

  • Why migrate from NGINX to AWS CloudFront Functions?

    CloudFront Functions eliminate the need to manage NGINX servers, improving deployment speed, scalability, and security – all while running lightweight JavaScript at the edge.
  • What are the main advantages of CloudFront Functions over NGINX?

    They remove infrastructure overhead, deploy globally within seconds, and integrate seamlessly with AWS services. No container patching or maintenance required.
  • How do CloudFront Functions improve DevOps workflows?

    By combining Terraform and Terragrunt, teams can manage configurations as code, automate deployments, and make edge updates faster and more reliable.
  • Can CloudFront Functions replace all NGINX use cases?

    Not entirely. They’re ideal for routing, redirects, and header rewrites, but for complex reverse proxy logic or caching strategies, Lambda@Edge or NGINX on EC2/Fargate may still be needed.

Maciej Piesio

DevOps Engineer

Maciej Piesio is a DevOps engineer focused on AWS and Kubernetes. With roots in Linux administration and experience across multiple cloud platforms, he builds scalable, reliable systems through automation and clean infrastructure design.

A man standing in the office in front of the Kellton sign, wearing a black shirt and glasses.

Sebastian Spiegel

Backend Development Director

Inspired by our insights? Let's connect!

You've read what we can do. Now let's turn our expertise into your project's success!

Get in touch with us

0 / 3000
Let us know you're human
By submitting this form you acknowledge that you have read Kellton's Privacy Policy and agree to its terms.

Get to know us

Learn about our team, values, and commitment to delivering high-quality, tailored solutions for your business.

Tell us about your needs

Share your project requirements and objectives so we can craft a customized plan.

Free consultation

Make the most of our free consultation to discover the optimal strategies and solutions tailored to your business challenges.