Terraform has become the default way to manage cloud infrastructure. If you’re
provisioning VPCs, IAM roles, DNS records, or database clusters, chances are
you’re writing HCL and running terraform apply. So when it’s time to manage
your API gateway, the instinct is to reach for the same tool.
That instinct makes sense — but it can lead you down a path that adds unnecessary complexity. API gateway configuration is fundamentally different from infrastructure provisioning, and treating route definitions and policy configs the same way you treat a VPC can create more problems than it solves.
This article breaks down the Infrastructure as Code (IaC) landscape for API gateways, explains where Terraform genuinely excels, identifies where it struggles with gateway-specific workloads, and shows when a GitOps-native approach delivers better results.
The IaC Landscape for API Gateways
Teams managing API gateways today have several declarative tooling options, each with different trade-offs.
Terraform is a provider-agnostic infrastructure provisioning tool. You
define resources in HCL, Terraform builds a dependency graph, and plan/apply
cycles reconcile desired state against actual state using a state file. Major
API gateway vendors — including Kong, AWS API Gateway, and Azure API Management
— ship Terraform providers.
Kubernetes CRDs let you define gateway resources as native Kubernetes
objects. If your team already manages everything through kubectl and Helm
charts, CRDs keep API gateway config in the same workflow. Kong’s Gateway
Operator and the Kubernetes Gateway API both take this approach.
Vendor-specific declarative tools like Kong’s decK or Tyk’s tyk-sync let you define gateway config in YAML files and sync them to a running gateway instance. These work well for single-gateway setups but add operational overhead as environments multiply.
GitOps-native platforms treat the Git repository itself as the deployment mechanism. There is no sync step, no state file, and no reconciliation loop. Pushing to a branch deploys the gateway. Reverting a commit rolls it back. The configuration files in your repo are the gateway.
Each approach has a legitimate place. The question is which one fits the operational characteristics of API gateway management — high-frequency config changes, multi-environment deployments, and tight coupling between API routes and application code.
Where Terraform Excels
Terraform is excellent at managing resources that share three characteristics: they change infrequently, they have stable provider APIs, and they represent long-lived infrastructure.
Cloud Infrastructure Provisioning
VPCs, subnets, security groups, load balancers, DNS zones — these resources are
created once and modified rarely. Terraform’s plan/apply cycle is perfectly
suited here because the cost of a full state reconciliation is low when changes
happen weekly or monthly.
Identity Provider Configuration
Setting up Auth0 tenants, Cognito user pools, or Okta applications involves creating interconnected resources that rarely change after initial setup. Terraform’s dependency graph handles the creation order cleanly.
Cross-Provider Orchestration
Need to provision an AWS RDS instance, configure a Cloudflare DNS record pointing to it, and create a monitoring dashboard in Datadog? Terraform handles all three in a single plan, with proper dependency ordering and rollback semantics.
The common thread: these are infrastructure resources that exist at the platform level, change on a slow cadence, and benefit from centralized state tracking.
Where Terraform Struggles with API Gateways
API gateway configuration doesn’t fit neatly into Terraform’s model. Here’s why.
High-Churn Configuration
API routes, policies, and authentication rules change frequently — often
multiple times per day on active teams. Every change triggers a full
terraform plan that must diff the entire state against the desired
configuration. As the number of managed resources grows, plan times increase and
the blast radius of each apply expands.
Compare this to application code, where deploying a change to one endpoint doesn’t require re-evaluating every other endpoint in the system.
State File Complexity
Terraform tracks every managed resource in a state file. For API gateways with hundreds of routes, dozens of policies, and multiple environments, that state file becomes a liability. State locking, remote backend configuration, and state migration all add operational burden that doesn’t exist when your configuration lives directly in Git.
Teams often discover this when two developers try to apply gateway changes simultaneously and run into state lock conflicts — a problem that simply doesn’t occur with Git-based workflows where branches provide natural isolation.
Drift in Fast-Moving Teams
Terraform assumes it is the sole manager of resources it creates. But API
gateways often sit at the intersection of multiple teams: platform engineers
configure global policies, backend developers add routes, and security teams
update authentication rules. When someone makes a change through a dashboard or
CLI outside of Terraform, the next plan shows unexpected drift that must be
manually reconciled.
Plugin and Policy Configuration Sprawl
Traditional API gateways like Kong manage behavior through plugins, each with
its own configuration block. In Terraform, this means defining kong_plugin
resources with JSON-encoded configuration strings embedded in HCL. The result is
configuration that’s hard to read, hard to review in a pull request, and
impossible to test in isolation.
The Kong/Konnect Terraform Approach
Kong’s investment in Terraform illustrates both the appeal and the challenges.
Kong ships two Terraform providers:
terraform-provider-konnect
(GA, with over 300,000 installs) for their Konnect SaaS platform, and
terraform-provider-kong-gateway (beta) for self-hosted deployments.
The Konnect provider exists because Kong’s platform has significant surface area beyond gateway routing. Konnect manages control planes, mesh planes, API products, developer portals, teams, roles, and runtime groups. These organizational resources are a natural fit for Terraform — they’re created once, modified rarely, and benefit from centralized state management.
Kong also supports Kubernetes CRDs through the Kong Gateway Operator, giving Kubernetes-native teams a way to manage Konnect resources from within their existing cluster workflows.
The challenge appears at the boundary between platform infrastructure and
day-to-day gateway configuration. Route definitions, plugin configurations, and
consumer groups change frequently. Managing them through Terraform’s
plan/apply cycle introduces friction that Kong’s own declarative tool, decK,
was designed to avoid. Many Kong users end up using Terraform for control plane
provisioning and decK for route and plugin management — splitting their
configuration across two tools with different state models.
GitOps-Native API Management
A GitOps-native API gateway takes a different architectural approach: the gateway configuration lives in your application repository, deploys through your existing Git workflow, and requires no external state management or reconciliation tools.
Zuplo was built this way from the ground up. Every aspect of the gateway — routes, policies, custom logic, and OpenAPI specifications — is stored as files in a Git repository. There is no imperative API to call, no state file to manage, and no sync tool to run.
Here’s what that looks like in practice:
Configuration as Code
Routes are defined in config/routes.oas.json, a standard
OpenAPI specification file. Policies attach to routes
declaratively. Custom request and response handling is written in TypeScript and
lives alongside the configuration:
Every file is human-readable, diffable, and reviewable in a standard pull request. There’s no HCL-encoded JSON, no state file, and no resource graph to debug.
Branch-Based Preview Environments
This is where GitOps-native platforms provide something Terraform fundamentally cannot: automatic preview environments for every branch.
When a developer creates a feature branch and pushes a change, Zuplo automatically deploys a fully functional preview environment with its own URL. Reviewers can send real HTTP requests to test authentication, rate limiting, and routing behavior before any change reaches production.
With Terraform, creating a preview environment means provisioning a complete infrastructure stack — which can take minutes to hours — and destroying it afterward. With a GitOps-native gateway, the preview exists as long as the branch exists, with zero infrastructure overhead.
Atomic Deployments with Zero Drift
Every Zuplo deployment is atomic: the entire configuration either deploys successfully or the previous version remains in place. There are no partial states, no half-applied changes, and no drift between what’s in your repository and what’s running in production.
Rollback is a git revert followed by a push. No terraform destroy, no state
surgery, no manual cleanup.
Programmable Policies in Code
Instead of configuring plugins through JSON blobs in HCL, Zuplo’s policies are either selected from a catalog of built-in options or written as TypeScript functions:
This code is version-controlled, testable, and reviewable in a pull request — the same workflow your team already uses for application code.
When to Use What: A Decision Framework
The right tool depends on what you’re managing. Here’s a practical framework:
Use Terraform For
- Cloud infrastructure: VPCs, subnets, security groups, load balancers, CDN configuration
- Identity providers: Auth0 tenants, Cognito user pools, Okta applications and authorization servers
- DNS and certificates: Route 53 hosted zones, Cloudflare DNS records, ACM certificates
- Secrets backends: Vault configuration, AWS Secrets Manager setup
- Network policy: Firewall rules, VPN configuration, private link setup
- Monitoring infrastructure: Datadog dashboards, PagerDuty services, alerting rules
These resources change infrequently, benefit from dependency graphs, and are naturally managed at the infrastructure level.
Use GitOps-Native For
- API routes and endpoints: Path definitions, HTTP method configuration, upstream targets
- Gateway policies: Rate limiting, authentication, request validation, response transformation
- OpenAPI specifications: The contract between your API and its consumers
- Custom gateway logic: Request/response handlers, middleware, data transformation
- Developer portal content: API documentation, getting-started guides, changelogs
These resources change frequently, are tightly coupled to application behavior, and benefit from the same review and deployment workflow as application code.
Combine Both
The most effective pattern is using Terraform and GitOps together, each managing the layer it’s best suited for:
- Terraform provisions the platform: identity providers, DNS records, secrets backends, and monitoring infrastructure
- GitOps drives day-2 gateway configuration: routes, policies, custom logic, and API documentation deploy through Git
This separation is clean because the two layers have different change cadences. Infrastructure changes happen weekly or monthly. Gateway configuration changes happen daily. Using the right tool for each cadence eliminates friction without sacrificing control.
Practical Example: Terraform + GitOps Together
Here’s how a real team might combine Terraform for infrastructure with a GitOps-native gateway for API management.
Terraform manages the identity layer:
The GitOps-native gateway consumes that identity provider in
config/routes.oas.json:
Environment variables bridge the two layers:
Terraform outputs — like the Auth0 domain and client ID — are stored as environment variables in Zuplo, where gateway policies reference them at runtime. The infrastructure layer and the gateway configuration layer are cleanly separated, each managed by the tool best suited to its change cadence.
Moving Beyond Terraform for API Configuration
If your team currently manages API gateway configuration through Terraform and you’re feeling the friction — long plan times, state conflicts, drift after manual changes — the path forward doesn’t require abandoning Terraform entirely.
Keep Terraform for what it does best. Your VPCs, IAM roles, DNS records, and identity provider configuration should stay in Terraform. These resources are stable, change infrequently, and benefit from Terraform’s dependency management.
Move gateway configuration to Git. Routes, policies, authentication rules,
and custom logic belong in a repository where changes are reviewed in pull
requests, deployed automatically on merge, and rolled back with git revert.
This is the workflow your developers already know — there’s no new tool to
learn.
Use preview environments to test safely. Instead of provisioning a full Terraform stack for every feature branch, use a gateway that creates preview environments automatically. Reviewers can verify API behavior with real HTTP requests before changes reach production.
The IaC landscape for API gateways isn’t one-size-fits-all. Terraform is the
right tool for infrastructure provisioning. For the fast-moving, high-churn
world of API routes and policies, a
GitOps-native approach is simpler,
faster, and less prone to the drift and state management headaches that come
with managing everything through terraform apply.
Zuplo’s GitOps-native architecture eliminates the need for a separate Terraform provider, CRD controller, or sync tool. Your API configuration lives in your repository, deploys on push, and runs at the edge across 300+ data centers — no infrastructure management required. Get started and see how a GitOps-native gateway simplifies your API management workflow.