How We Migrated an AWS Amplify GraphQL Backend to CDK (Without a Rewrite)

Published: (December 30, 2025 at 05:29 AM EST)
4 min read
Source: Dev.to

Source: Dev.to

AWS Amplify AppSync migration diagram

How we moved from Amplify to CDK without rewriting business logic, why we did it, and what we learned.

Note: This isn’t an anti‑Amplify post. It’s about understanding where Amplify shines — and where it stops scaling.

When Amplify Works Well

Amplify is a great choice when:

  • You’re early in a project.
  • You want fast, schema‑driven development.
  • You’re happy with Amplify‑managed CloudFormation.
  • You don’t need fine‑grained IAM or custom pipelines.

We used Amplify exactly this way at the start. Using directives like @model, @auth, and connections, Amplify generated:

  • An AppSync GraphQL API
  • DynamoDB tables
  • VTL resolvers
  • IAM roles
  • Lambda data sources (when needed)

For a long time, this worked perfectly.

The Problems We Eventually Hit

As the backend grew, a few issues became increasingly hard to ignore.

1. Limited Control and Visibility

Amplify abstracts away a lot of infrastructure:

  • IAM permissions are auto‑generated.
  • CloudFormation stacks are hidden.
  • Resource naming is opaque.

This makes:

  • Code reviews harder
  • Security reviews painful
  • Debugging deployments difficult

2. Difficult Multi‑Environment & Platform Integration

We wanted:

  • Explicit dev / staging / prod environments
  • Integration with an existing CDK‑based platform
  • Predictable diffs and rollbacks

Amplify’s CLI‑driven workflow didn’t fit well with these requirements.

3. A Hard CloudFormation Scaling Limit

AWS CloudFormation enforces a hard limit of 500 resources per stack.
Amplify deploys most GraphQL backends into one (or a very small number of) stacks. As schemas grow, the number of generated resources quickly approaches that limit:

  • Resolvers
  • Functions
  • IAM roles & policies
  • DynamoDB tables & GSIs

When you near the 500‑resource limit:

  • Deployments become fragile
  • Adding new models or resolvers can fail
  • Amplify provides no supported way to split or refactor the generated stacks

At that point, backend evolution effectively stalls.

Why We Didn’t Rewrite Everything

By the time we hit these limits we already had:

  • A large GraphQL schema
  • Custom VTL resolvers
  • Lambda‑based business logic
  • Production data in DynamoDB

A full rewrite would have been:

  • Risky
  • Time‑consuming
  • Unnecessary

Instead we asked a different question:

What if Amplify was only used to generate the initial artifacts — and not to own the backend forever?

Migration Steps

Step 1 – Use Amplify Once, as a Scaffolding Tool

Treat Amplify as a compiler, while CDK becomes the deployment engine.
Amplify generated:

  • schema.graphql
  • .vtl resolver templates
  • Build artifacts:
    • build/cloudformation-template.json
    • build/stacks/*.json
    • build/resolvers/*.vtl
  • Auth logic embedded in resolvers

At this stage Amplify did its job well.

Step 2 – Extract the Durable Assets

From the Amplify backend output we kept only what was durable and valuable:

  • GraphQL schema
  • Resolver templates
  • Table definitions
  • Auth rules & logic

We did not keep:

  • Amplify CLI files
  • Amplify Console configuration
  • Auto‑generated CloudFormation stacks

Those are implementation details, not architecture.

Step 3 – Rebuild Explicitly in AWS CDK

Each Amplify‑generated resource was reimplemented explicitly in CDK. CDK now owns:

  • AppSync API + data sources
  • Function configurations
  • Pipeline resolvers
  • IAM roles / policies
  • DynamoDB tables (optional)
  • Lambda data sources (optional)

Instead of deploying Amplify stacks directly, we extracted the intent into CDK code and redeployed from there. This removed Amplify “magic” and made behavior predictable.

Step 4 – Split the Backend into Multiple CDK Stacks

Unlike Amplify’s monolithic stacks, CDK allowed us to:

  • Split AppSync, DynamoDB, Lambda, and IAM into separate stacks
  • Control resource boundaries
  • Avoid CloudFormation’s 500‑resource limit entirely

This single change removed a major long‑term scalability risk.

Step 5 – Config‑Driven, Environment‑Aware Design

We replaced CLI‑driven configuration with:

  • YAML‑based config files
  • Environment‑specific definitions (dev, staging, prod)
  • Deterministic naming

Now we get reviewable diffs via cdk diff:

cdk diff -c env=staging
cdk deploy -c env=staging

CDK became the only source of truth.

Step 6 – Remove Amplify Completely

Once parity was verified:

  • The Amplify project was deleted
  • Amplify Console was disconnected
  • No more amplify push

From that point on:

  • Infrastructure changes are code‑reviewed
  • Deployments are predictable
  • Scaling is no longer capped by stack limits

What We Learned

  • Amplify is excellent for scaffolding.
  • It is not designed for large, long‑lived backends.
  • The CloudFormation 500‑resource limit is a real constraint.
  • Migration is safer than a full rewrite.
  • Explicit CDK ownership pays off quickly at scale.

Want the Full Setup?

We packaged this approach into a reusable bundle that includes:

  • A production‑grade CDK AppSync backend
  • Config‑driven resolver and Lambda implementations
  • Example CI/CD pipelines

👉 Grab the repo on GitHub

Feel free to open issues or submit PRs if you run into any snags!

bda wiring

  • Migration checklist and hard‑earned lessons
  • Real‑world examples (not toy demos)

👉 Gumroad:

Final Thoughts

This migration wasn’t about rejecting Amplify. It was about using the right tool at the right stage.

  • Amplify helped us move fast early.
  • CDK helped us move safely at scale.

If you’re approaching the same limits, there is a clean exit — without a rewrite.

Back to Blog

Related posts

Read more »

Terraform Stacks

Overview A collection of production‑ready Terraform Stacks that showcase enterprise patterns across full applications, multi‑region fan‑out, and Kubernetes pla...

Cómo solucionarlo con Terraform?

markdown !Forem Logohttps://media2.dev.to/dynamic/image/width=65,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2...