How to Migrate CloudFormation to Terraform with AI
What AI can safely automate when converting CloudFormation templates into Terraform or OpenTofu, and what teams should still review.
- Topic
- CloudFormation Migration
- Category
- Product Deep-Dive
- Read time
- 5 min read
- Published
- April 24, 2026
- Reviewed
- May 9, 2026
- Author
- ops0 Engineering
Key Takeaways
- AI can translate CloudFormation templates into Terraform or OpenTofu faster than manual conversion
- Humans still need to review resource mappings, IAM, dependencies, and state reconciliation
- ops0 archives original templates and surfaces generated HCL for review before future deployments use the new IaC type
- Migration should end with drift monitoring and queryable confirmation, not just converted files
- migrationService handles same-cloud translation; cloudTransformService handles AWS to GCP, Azure, or Oracle Cloud rewrites
- ImportValue, conditional logic, custom resources, and dynamic counts are the common cases that need manual review
- State reconciliation is intentionally manual because mistaken imports are destructive
Quick Answers
Can AI convert CloudFormation to Terraform?
Yes. AI can translate CloudFormation YAML or JSON into Terraform HCL, but teams should still review mappings, validate plans, and reconcile existing stack state before using Terraform for ongoing management.
Does migrating CloudFormation to Terraform destroy the existing stack?
No. Translation alone should not destroy the stack. The existing AWS resources still need a deliberate import or reconciliation plan before Terraform or OpenTofu becomes the system of record.
How does ops0 support CloudFormation migration?
ops0 supports AI-assisted migration from CloudFormation to Terraform or OpenTofu, archives the original templates, generates HCL files, and connects the migrated project to deployment, policy, query, and drift workflows.
What CloudFormation features need manual review during migration?
ImportValue cross-stack references, conditional logic using If or Equals, dynamic resource counts, and custom resources backed by Lambda functions usually need manual review because they do not always translate one to one into Terraform.
How does ops0 handle cross-cloud migration?
cloudTransformService rewrites AWS resources into the closest semantic equivalent on GCP, Azure, or Oracle Cloud. The transform is intent-preserving rather than lossless, so reviewers decide whether the substitution fits the target architecture.
How do I confirm a migration is complete?
Run terraform plan against the imported state and confirm zero changes, verify Resource Graph reflects the expected resources and tags, enable drift detection for the first week, and run policy gates against the new project.
Related Reading
AI can migrate CloudFormation to Terraform by reading YAML or JSON templates, translating AWS resources into HCL, generating variables and outputs, and preserving the original template for review. In ops0, CloudFormation projects can be migrated to Terraform or OpenTofu through an AI-assisted workflow that archives the source template, creates HCL files, and lets teams review the generated code before future deployments use the new IaC type.
CloudFormation is still common in mature AWS environments. The problem is not that it is broken. The problem is that many platform teams standardize on Terraform or OpenTofu for multi-cloud workflows, policy checks, drift workflows, and team onboarding.
What AI Handles Well
AI is useful for the repetitive translation layer:
- Converting common AWS resource types into Terraform resources
- Splitting monolithic templates into `main.tf`, `variables.tf`, `outputs.tf`, and `terraform.tfvars`
- Preserving names, tags, dependencies, parameters, and outputs where possible
- Explaining mappings that need human attention
- Creating a reviewable migration branch or project state
This saves the most time in large templates where manual conversion is tedious and error-prone.
What Still Needs Review
Migration should not be treated as a blind apply. Humans should review resource mappings, generated variables, IAM behavior, replacement risks, and any custom CloudFormation features that do not map directly to Terraform.
The existing CloudFormation stack is not destroyed because code was translated. You still need a state reconciliation plan: import resources, decide whether to re-deploy, and confirm that Terraform or OpenTofu will manage the same real infrastructure.
How ops0 Approaches the Migration
ops0 keeps the migration explicit. A CloudFormation project can be migrated to Terraform or OpenTofu. The original CloudFormation templates are archived instead of erased. The generated HCL is surfaced for review. Future deployments use the selected CLI and backend after the project type changes.
That workflow matters because migration is both a code conversion and an ownership conversion. The question is not only "can we translate this template?" It is "can the team safely operate this infrastructure under the new workflow?"
Migration Checklist
Before migrating, collect the CloudFormation templates, stack outputs, parameters, current stack status, backend strategy, and owner approvals.
During migration, compare generated HCL to the original resources, validate dependencies, run plan or validation in a safe environment, and mark any resources that need manual import.
After migration, monitor drift, check policy gates, and use Resource Graph or Query Console to confirm that declared state and real state match.
How It Works
The migration path inside ops0 is implemented by two services: migrationService for CloudFormation to Terraform translation, and cloudTransformService for the harder case of cross-cloud transformation when the target is GCP, Azure, or Oracle Cloud rather than AWS.
Inputs are CloudFormation templates in YAML or JSON. The AI generator runs against a system prompt that encodes resource mapping rules, the standard ops0 tag set (Environment, Project, Owner, ManagedBy, ManagedIaC, CostCenter, Stack), and provider-specific defaults. Output is sanitized: markdown code fences and prose explanations are stripped before any file is persisted.
The resulting file structure is opinionated. Generated projects produce main.tf or split modules under templates/networking, templates/security, and templates/compute, with variables.tf derived from CloudFormation Parameters, outputs.tf derived from CloudFormation Outputs, provider.tf for the target cloud, and a backend.tf for remote state with bucket, key, and region. Parameter values move into per-environment JSON files under parameters/ rather than being hardcoded in HCL.
Generated files are recorded in iacGeneratedFiles. The original CloudFormation template is preserved in conversation history so reviewers can compare the source and the translation side by side without recovering the original template from a separate system.
What Does Not Translate Cleanly
Honest migration tooling tells you what it cannot do.
Cross-stack references using ImportValue do not auto-translate to Terraform data sources. Reviewers must wire the equivalent data source or remote state lookup themselves. Conditional logic using CloudFormation If, Equals, and Not does not always map to Terraform conditionals one to one. Dynamic resource counts using CountIndex or Fn::Sub on resource creation usually need to be rewritten as for_each. Custom resources backed by Lambda functions need their function logic preserved separately.
Calling these out in the generated project is more useful than producing HCL that compiles but quietly drops behavior.
State Reconciliation Is Still Manual
Translation is a code transformation. It does not by itself move ownership of live AWS resources from the CloudFormation control plane to Terraform.
The reconciliation plan is left to the operator and usually looks like this. First, freeze changes on the existing CloudFormation stack. Second, run the generated Terraform with terraform plan and confirm that every resource in the plan matches a resource that already exists in the stack. Third, terraform import each resource address that should be adopted, or use a state-mover workflow if you prefer not to touch state by hand. Fourth, run plan again and confirm the result is empty, which means Terraform now believes it owns exactly what AWS already has. Fifth, decommission the CloudFormation stack with retain on the imported resources so deletion of the stack does not delete the live infrastructure.
ops0 surfaces the generated HCL, the parameter files, and the resource list, but the import calls are deliberately a human decision because mistakes here are destructive.
Cross-Cloud Migration Is A Different Service
When the target is not AWS, migration becomes transformation. cloudTransformService handles AWS to GCP, AWS to Azure, and AWS to Oracle Cloud rewrites at the resource level: VPCs become VPC networks or virtual networks, security groups become firewall rules or network security groups, ALBs become load balancer equivalents, RDS becomes Cloud SQL or Azure Database for PostgreSQL.
Cross-cloud transforms are not lossless. They are intent-preserving. The transform service emits Terraform for the target cloud with the closest semantic equivalent, and reviewers decide whether the substitution is acceptable or whether the architecture needs to change to fit the new cloud.
Verifying The Migration Worked
The end of a migration is not the moment the new HCL compiles. It is the moment you can prove the translated project owns the same infrastructure as the original.
Confirm by running terraform plan against the imported state and observing zero changes. Confirm by querying Resource Graph for the migrated project and seeing the expected resources, dependencies, and tags. Confirm by enabling drift detection and watching for divergence over the first week. Confirm by running policy gates against the new project and resolving any Checkov failures that the original CloudFormation never had checked.
A migration that ends here is operationally safe. A migration that ends at "the file compiled" is not.
The Bottom Line
AI does not make CloudFormation migration risk-free. It makes it tractable.
The right workflow is translation plus review plus state reconciliation plus ongoing drift control. That is where ops0 turns a one-time conversion into an operationally safe transition.
Example Migration Check
# Generated Terraform should be reviewed before import or apply.
resource "aws_s3_bucket" "logs" {
bucket = "company-prod-logs"
tags = {
Environment = "production"
ManagedBy = "ops0"
}
}
The next step is not another dashboard.
See how ops0 turns discovery, generated IaC, policy gates, runtime checks, and evidence into one governed infrastructure workflow.
Why ops0
