This Terraform error occurs when you try to create an AWS Step Functions state machine with a name that already exists in your AWS account/region, but the resource isn't managed by your current Terraform state. Fix it by importing the existing resource or choosing a unique name.
The "StateMachineAlreadyExists" error happens when Terraform attempts to create a new AWS Step Functions state machine, but AWS rejects the operation because a state machine with that name already exists in the same region of your AWS account. This occurs when there's a mismatch between what Terraform thinks should exist and what actually exists in AWS. The state machine may have been created manually through the AWS Console, CloudFormation, AWS CLI, or by a previous Terraform run whose state file was lost or is not being used. Terraform doesn't know about the existing state machine because it's not tracked in your current Terraform state file (.tfstate). When Terraform tries to create what it believes is a new resource, AWS responds with an error because a resource with that name already exists.
First, verify that the state machine actually exists in your AWS account and region:
aws stepfunctions list-state-machines --region us-east-1Look for your state machine name in the output. If it's there, you need to either import it or delete it and recreate it through Terraform.
If you want Terraform to manage the existing state machine, use the terraform import command. First, get the full ARN of your state machine:
aws stepfunctions list-state-machines --region us-east-1 \
--query "stateMachines[?name=='your-state-machine-name'].stateMachineArn" \
--output textThen import it into your Terraform state:
terraform import aws_sfn_state_machine.example arn:aws:states:us-east-1:123456789012:stateMachine:your-state-machine-nameAfter importing, Terraform will track the state machine in your state file. You can then update the resource definition in your Terraform configuration to match the actual state machine.
If you want Terraform to create a fresh state machine, delete the existing one from AWS:
aws stepfunctions delete-state-machine \
--state-machine-arn arn:aws:states:us-east-1:123456789012:stateMachine:your-state-machine-nameThen run Terraform apply to create it fresh:
terraform applyThis approach is safe if the state machine is not in use and has no active executions. Check for active executions first:
aws stepfunctions list-executions \
--state-machine-arn arn:aws:states:us-east-1:123456789012:stateMachine:your-state-machine-name \
--status-filter RUNNINGModify your Terraform configuration to use unique state machine names across environments:
resource "aws_sfn_state_machine" "example" {
name = "my-state-machine-${var.environment}"
role_arn = aws_iam_role.sfn_role.arn
definition = file("state_machine.json")
}Or use Terraform workspace to isolate resources:
resource "aws_sfn_state_machine" "example" {
name = "my-state-machine-${terraform.workspace}"
role_arn = aws_iam_role.sfn_role.arn
definition = file("state_machine.json")
}This ensures each environment or deployment has a distinct state machine name.
Instead of specifying a fixed name, use name_prefix to let AWS auto-generate unique names:
resource "aws_sfn_state_machine" "example" {
name_prefix = "my-state-machine-"
role_arn = aws_iam_role.sfn_role.arn
definition = file("state_machine.json")
}AWS will create state machines like my-state-machine-abc123xyz. This eliminates naming conflicts entirely, though you'll need to update any references that depend on a specific name.
If working in a team, ensure everyone is using the same Terraform state file. Configure remote state using S3, Terraform Cloud, or other backends:
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "stepfunctions/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks"
}
}This prevents state file conflicts and ensures everyone sees the same infrastructure:
terraform init
terraform applyAll team members will now work with the shared state, avoiding duplicate resource creation.
State Machine ARN Format:
The full ARN format is arn:aws:states:REGION:ACCOUNT_ID:stateMachine:NAME. You need all these components to import correctly.
Preventing State Drift:
Regularly check for state drift by running terraform plan without making changes. This shows differences between your configuration and actual AWS resources. Use terraform refresh to update your state file with current AWS reality.
CloudFormation Stacks:
If the state machine was created by CloudFormation, you cannot import it into Terraform while it's still managed by CloudFormation. You'll need to delete it from the CloudFormation stack first, then import it to Terraform.
State Machine Executability:
When importing an existing state machine, ensure your Terraform configuration exactly matches the actual state machine definition. If they differ, Terraform will try to update it on the next apply, which might disrupt running or scheduled executions.
Development Workflow Best Practice:
Use Terraform workspaces or separate AWS accounts for different environments (dev/staging/prod) to completely eliminate naming conflicts. This also provides better isolation and prevents accidental changes to production resources.
Error: Error installing helm release: cannot re-use a name that is still in use
How to fix "release name in use" error in Terraform with Helm
Error: Error creating GKE Cluster: BadRequest
BadRequest error creating GKE cluster in Terraform
Error: External program failed to produce valid JSON
External program failed to produce valid JSON
Error: Unsupported argument in child module call
How to fix "Unsupported argument in child module call" in Terraform
Error: network is unreachable
How to fix "network is unreachable" in Terraform