AWS Transform at 1 Year: Agentic Legacy Modernization in Production
Listen to article
generated on playGenerated only on first play
AWS Transform arrived promising AI-agent-driven legacy modernization — after one year, it's worth examining what it actually delivers, where it falls short, and what the real adoption cost is in critical systems. This analysis is grounded in concrete technical evidence, not marketing.
After sixteen years helping financial organizations migrate systems nobody wants to touch — COBOL on mainframe, Java EE 5 on bare-metal servers, PL/SQL with business logic buried in triggers — I've learned that the hardest part of modernization isn't the target technology: it's understanding what the legacy code actually does. AWS Transform arrived in 2024 with an audacious proposition: use AI agents to automate exactly that analysis and transformation step. One year later, with the service gaining support for custom transformations, it's time for an honest assessment — what works, what doesn't, and what a senior architect needs to know before putting this into a financial production pipeline.
Numbers that matter after one year
What AWS Transform actually is — and what it isn't
AWS Transform is not a magic modernization button. It is an agentic orchestration platform that coordinates static code analysis, transformation generation via language models (primarily through Amazon Bedrock), automated test execution, and a feedback loop for iterative refinement. The internal architecture resembles a Step Functions workflow with specialized agents: an analysis agent that builds a dependency graph of the source code, a transformation agent that generates target code, and a validation agent that runs test suites and interprets failures.
The primary use case at launch was Java 8/11 to Java 17/21 migration, with Maven and Gradle support. That is deliberately narrow — and that narrowness is an engineering virtue, not a marketing limitation. Systems with well-defined scope, known toolchain, and reasonable test coverage are exactly where agentic automation delivers real value. The problem starts when organizations try to extrapolate this to more complex scenarios: COBOL to Java, PL/SQL to Aurora, or monoliths with circular dependencies and zero tests.
The custom transformations support added at the one-year mark changes the game in an interesting way: it is now possible to define your own transformation recipes — refactoring rules, API substitution patterns, naming policies — that the agent applies as constraints during generation. This moves Transform closer to a modernization governance framework, not just a migration tool.
AWS Transform Agentic Pipeline — Modernization Flow
Internal AWS Transform flow from legacy code to modernized artifact, showing specialized agents, validation loops, and integration points with underlying AWS services.
- Legacy Repo · Git / S3 upload
- Build Manifest · pom.xml / build.gradle
- Analysis Agent · dependency graph + AST
- Custom Transform Rules · recipes / guardrails
- Amazon Bedrock · Claude / Titan
- Transform Agent · code generation + patch
- Build Runner · Maven / Gradle exec
- Validation Agent · test suite + failure triage
- Feedback Loop · max N iterations
- Diff Report · human review gate
- CloudWatch Logs · agent reasoning traces
- Modernized Repo · PR / branch
Where Transform shines: the Java case and the logic of agentic automation
The Java 8/11 to Java 17/21 migration is a structurally well-suited problem for agentic automation for three reasons: the transformation space is finite and well-documented (removed APIs, JPMS module changes, new language patterns), the build toolchain is deterministic (Maven/Gradle produces reproducible results), and validation is objective (the code either compiles or it doesn't, tests either pass or they don't). This triangle — finite space, deterministic build, objective validation — is the ideal profile for a transformation agent.
In projects with test coverage above 70% and well-managed dependencies (no proprietary third-party JARs without a modern equivalent), Transform can process the migration with minimal human intervention. The internal feedback loop — where the validation agent interprets compilation failures and passes context back to the transformation agent — is genuinely useful for common migration errors such as sun.misc.Unsafe usage, removed reflection APIs, and serialization incompatibilities.
The custom transformations support adds a governance layer that makes a real difference in financial environments: you can codify policies like 'never use java.util.Date, always replace with java.time.LocalDate' or 'every call to library X must be replaced by library Y with this specific API mapping'. This turns Transform into an architectural standards enforcement vehicle during migration — something that normally requires extensive manual review in code reviews.
Real strengths of AWS Transform
Real limits: where Transform fails in financial environments
The fundamental problem with Transform in mission-critical financial systems is not technical — it is epistemic. The agent has no way of knowing what the legacy code should do when the original intent has been lost. In core banking systems with 15 years of accumulated patches, there is often critical business logic — compound interest calculations, credit eligibility rules, regulatory exception handling — that is correct not because it follows a recognizable pattern, but because it was manually fixed after production incidents and never properly documented.
In this scenario, Transform can produce code that compiles, passes existing tests, and is still wrong — because the existing tests don't cover the edge cases discovered in production. This is not a failure of Transform specifically; it is a failure of the modernization process without adequate test coverage. But it is a failure that the service's marketing tends to gloss over.
Another critical limit is the handling of proprietary dependencies. In banking environments, it is common to have HSM (Hardware Security Module) SDKs, connectivity libraries for clearing systems (SWIFT, SPB, CIP), and mainframe system adapters that have no documented modern equivalent. The agent cannot transform what it doesn't know — and has no mechanism to clearly signal 'this dependency has no known mapping' in a way that integrates with a structured human review workflow. The custom transformations documentation for this case is still insufficient.
Finally, the agent's iteration model has a configurable attempt limit. In projects with high cyclomatic complexity and cross-cutting dependencies, the agent may exhaust the iteration budget without converging — and the intermediate state left behind is not easily resumable by a human engineer.
Critical trap: passing tests ≠ correct behavior
In financial systems, never use automated test pass rates as the sole acceptance criterion for Transform-generated code. Existing tests reflect the known behavior of the system, not the correct behavior. Before any Transform migration, invest in mutation testing (PIT for Java) and contract tests based on historical production data. Without this, you are validating that the agent faithfully reproduced historical bugs — which is not modernization.
Custom Transformations: governance as modernization code
The custom transformations feature is, in my assessment, the most architecturally significant addition of the first year. The core idea is that you can define a set of transformation rules — in a format that Transform interprets as generation constraints — and the agent applies them consistently across the entire codebase. This solves a real problem that any modernization architect knows: pattern drift over a long migration.
In an 18-month migration with 50 developers, it is practically impossible to ensure that everyone applies the same refactoring decisions consistently. Custom transformations let you codify those decisions once and apply them automatically. Concrete examples of use in financial environments: systematic replacement of java.util.logging with SLF4J with MDC configured for correlation IDs (mandatory for traceability in payment systems), migration of checked exception handling patterns to unchecked with standardized wrappers, and replacement of direct cryptography API calls with AWS KMS SDK calls with specific key policy configuration.
The rule application mechanism still has limitations: there is no native support for complex conditional rules (if class implements interface X, apply transformation Y, else apply Z), and the documentation of how rules interact with the analysis agent's dependency graph is insufficient. For advanced use cases, you will need a dedicated engineer to iterate on transformation recipes — which is an operational cost that must be factored into planning.
How to adopt AWS Transform in financial environments: a defensive sequence
- 1
1. Qualify the portfolio before any execution
Run static analysis (SonarQube, Checkstyle, Dependency-Check) on the source code to map: current test coverage, proprietary dependencies without a modern equivalent, cyclomatic complexity per module, and usage of APIs removed in the target version. Projects with coverage < 40% or unmapped dependencies should be excluded from the initial Transform scope.
- 2
2. Build the contract test suite before migration
Use historical production data (anonymized per LGPD/GDPR) to create contract tests that capture the real behavior of the system. Tools like Pact or parameterized tests with JUnit 5 are appropriate. These tests are your real acceptance criterion — not the existing unit tests.
- 3
3. Configure custom transformation rules before the first run
Codify the migration's architectural decisions as transformation recipes: logging patterns, encryption policies (KMS key ARNs, approved algorithms), third-party library substitutions, and exception handling patterns. This ensures the agent applies your design decisions, not its own inferences.
- 4
4. Run on isolated modules, not the entire monolith
Start with modules that have the highest test coverage and fewest external dependencies. Use feature flags to activate migrated code in production gradually (canary release with 1% → 10% → 100% of traffic). Monitor business metrics (transaction error rate, processing latency) in addition to technical metrics.
- 5
5. Enable reasoning traces and integrate with your SIEM
Configure Transform to emit complete reasoning traces to CloudWatch Logs. Create dedicated log groups with 90-day retention (minimum for audit in regulated environments). Integrate with your SIEM (Splunk, Datadog, Security Hub) to detect anomalous generation patterns — for example, the agent repeatedly trying to circumvent a custom rule.
- 6
6. Establish a mandatory human-in-the-loop gate
Never configure Transform to automatically merge generated code into production branches. The diff report generated by Transform must pass review by a senior architect before merging — especially for modules that touch financial calculation logic, authentication, or integration with regulated external systems.
Observability of the agentic process: what you need to monitor
One of the least-discussed aspects of AWS Transform is the observability of the modernization process itself. In regulated financial environments, you cannot simply run a transformation and trust the result — you need to be able to demonstrate, to internal and external auditors, exactly what decisions the agent made, why, and how they were validated.
Transform emits reasoning traces to CloudWatch Logs when properly configured. These traces include: the dependency graph built by the analysis agent, the candidate transformations considered by the generation agent, the results of each iteration of the validation loop, and the custom rules applied (or that failed to be applied). This is valuable audit material — but only if you configure adequate retention and structure the logs for querying.
My recommendation is to create a dedicated CloudWatch Log Group for Transform with 90-day retention, export to S3 with S3 Object Lock (WORM) for compliance, and create CloudWatch Insights queries to detect: iterations that exhausted the budget without converging (signal of unmanageable complexity), custom rules violated by the agent (signal of poorly defined recipe), and modules that had a test failure rate above 20% after transformation (signal of insufficient coverage).
For OpenTelemetry integration — which I use in all my platform projects — Transform does not yet emit OTLP traces natively. The current solution is to parse CloudWatch Logs and create synthetic spans via a processing Lambda. It is not elegant, but it works for creating end-to-end visibility in Datadog or Grafana alongside the rest of the CI/CD pipeline.
AWS Transform vs. alternative modernization approaches
| Criterion | AWS Transform | LLM-assisted manual migration (Copilot/Cursor) | Specialized tools (OpenRewrite, Moderne) | |
|---|---|---|---|---|
| Supported scope | Java 8→17/21; expansion in progress | Any language/platform | Java, Kotlin, Groovy, XML configs | — |
| Pattern consistency | High with well-defined custom rules | Low — depends on the engineer | Very high — based on deterministic recipes | — |
| Auditability | Medium — traces available but not SIEM-structured | Low — decisions implicit in developer context | High — declarative and versionable transformations | — |
| Cost for 500k LOC | ~$15k–$30k estimated (per-LOC pricing + Bedrock) | $80k–$200k in senior engineer hours | $5k–$20k (Moderne license) + recipe effort | — |
| Suitability for financial environments | Medium — requires additional guardrails | High — full control, but limited scale | High — deterministic and auditable by design | — |
OpenRewrite as a complement, not a competitor
The combination I have found most effective in real projects is to use OpenRewrite (via Moderne or directly) for deterministic, well-documented transformations — Spring Boot upgrades, JUnit 4→5 migrations, import substitutions — and AWS Transform for transformations that require contextual reasoning about the code: complex logic refactoring, consolidation of inconsistent patterns, and exception handling modernization. The two tools complement each other better than they compete.
Well-Architected lens applied to AWS Transform
Security
Source code is not used to train models (confirmed by AWS), but you still need to ensure the Transform IAM role has minimal permissions over the code repository. Use an IAM policy with aws:ResourceTag condition to restrict access only to repositories qualified for migration. Configure KMS CMK for encryption of intermediate artifacts generated by the agent.
Reliability
The agent's iteration limit is a reliability risk: complex projects may not converge. Mitigate by pre-decomposing the monolith into smaller modules before submitting to Transform. Define clear exit criteria: if after N iterations the test failure rate has not dropped below X%, escalate to human review rather than continuing to iterate.
Performance efficiency
Transform processing time is dominated by the size of the dependency graph and the number of validation loop iterations. For large codebases (>200k LOC), expect hours of execution time. Plan transformation windows outside peak CI/CD hours to avoid build resource contention.
Cost optimization
Transform pricing is composite: there is a per-LOC-transformed cost plus Bedrock inference costs (which vary by model and token count). For large projects, Bedrock costs can exceed Transform costs themselves. Monitor via Cost Explorer with project tags and set budgets with alerts at 80% of planned budget.
After evaluating Transform in the context of real financial projects, my position is this: use it as a modernization accelerator for the subset of the portfolio where the preconditions are met — adequate test coverage, mappable dependencies, deterministic toolchain. Do not use it as a substitute for the human architectural analysis that must precede any serious migration. The hardest lesson I have learned in modernizations is that automation amplifies both competence and incompetence: if you don't understand what you are migrating, Transform will modernize your problems faster than you can notice. The investment in custom transformation rules is where the real ROI lies — not in automatic execution, but in codifying your architectural decisions as generation constraints, which creates a reusable asset for the entire portfolio.
Verdict: promising, but still maturing for critical environments
AWS Transform after one year is a genuinely useful tool for the specific problem it sets out to solve: Java modernization in projects with good test coverage and a well-defined toolchain. Custom transformations support is the most important addition and transforms the service from a migration tool into a modernization governance framework — which is a much more interesting value proposition for organizations with large portfolios. The limitations are real and should not be minimized: the dependency on existing test coverage, the difficulty with proprietary dependencies, and observability still immature for regulated environments. For mission-critical financial environments, my recommendation is selective and defensive adoption: rigorously qualify the portfolio, invest in custom rules before running, and never give up the human-in-the-loop gate. Transform does not replace architects — it frees them to work on the problems that genuinely require human judgment. That alone justifies the evaluation.
References and further reading
Architecture intelligence, in your inbox
Curated signals and original analysis on AWS, AI, distributed systems and the market — the way a solutions architect reads them.
- Curated AWS · AI · architecture · market signals
- New architecture studies & deep-dives when they ship
- Sharp summaries — depth without the noise
- No spam · double opt-in · unsubscribe anytime