AWS → STACKIT · MIGRATION GUIDE

The complete AWS to STACKIT migration guide

Migrate in this order: assess the Terraform, decide what has no like-for-like target, build the network, stand up the data services, move the data, switch the clients, retire the source. This guide follows one 12-resource AWS estate through a StackToIT run and shows, at each step, which file of the output holds the answer and which decisions stay with your architects.

The seven steps

The order is the one the run's own waves and work packages follow.

  1. 1. Assess the Terraform

    Point StackToIT at the folder with your AWS Terraform. It reads the configuration and its modules offline, builds a dependency graph and assigns each resource a class and a target. Nothing is called in AWS or STACKIT.

  2. 2. Read the classes and settle the decisions

    DIRECT and RECONFIGURE units are plain work. REPLATFORM, CONTAINERIZE and REDESIGN units change the programming model. Copy decisions-template.yaml, record your answers and run the assessment again with --decisions; the new report shows which answers were applied and which decisions are still open.

  3. 3. Build the foundation

    Create the project layout, the networks and the security groups. This is wave 2 in the run, after the VPC unit.

  4. 4. Stand up the data and messaging services

    Apply the PostgreSQL Flex, Valkey, RabbitMQ, MongoDB Flex and Object Storage drafts. They are empty until you move data.

  5. 5. Move the data

    The run writes a data-move document per stateful unit. StackToIT moves no data; your team runs the commands after a rehearsal.

  6. 6. Switch producers, consumers and clients

    The run's cutover work packages switch the data consumers, the clients, then the workloads with the message producers and consumers. Reading that numbering as a sequence is our summary; the binding order is the steps each step comes after, listed in execution/manual/actions.md.

  7. 7. Verify, keep the way back, retire

    Run the checks, record the rollback limit, keep the source for the retention you decide, then retire it.

The commands behind the steps

These are the documented StackToIT commands, each quoted from the public documentation page named above it. The optional discover step adds a read-only AWS inventory to compare with the Terraform; explain traces a unit to its evidence; verify checks a finished run against its manifest.

Docs · assessdocs/guides/aws-to-stackit
stacktoit assess ./aws-terraform
Docs · optional discoverdocs/guides/aws-to-stackit
stacktoit discover commands
stacktoit discover aws ./aws-terraform-stacktoit --region eu-central-1
stacktoit assess ./aws-terraform ./aws-terraform-stacktoit
Docs · explaindocs/cli/explain
stacktoit explain ./terraform-stacktoit 'UNIT_ADDRESS'
Docs · verifydocs/cli/verify
stacktoit verify ./terraform-stacktoit
  • Offline by default

    assess itself does not connect to an AWS account. discover aws uses your local AWS CLI credentials and read-only collection commands.

  • A draft is not an approval

    The documentation is explicit: the presence of a Terraform draft is not approval to apply it.

The run: 12 resources, 11 units

Estate written for this page and assessed on 4 November 2026: a VPC with two subnets, a security group, an EC2 instance, an RDS PostgreSQL database, an S3 bucket, an ElastiCache group, an SQS queue, a Lambda function and a DynamoDB table. Classes come from assessment.json; the database subnet group folds into the database.

AWS unitSTACKIT targetClass
aws_vpc.mainProject networking, Network Area where networks must talk privatelyReconfigure
aws_subnet.private_a, private_bOne stackit_network each, same IPv4 prefixReconfigure
aws_security_group.appSTACKIT security group with rulesReconfigure
aws_instance.appSTACKIT server, network interface, volumeReconfigure
aws_db_instance.main (PostgreSQL 16)PostgreSQL FlexReplatform
aws_s3_bucket.uploadsObject Storage bucket and credentials groupDirect
aws_elasticache_replication_group.sessionsKey Value Store (Valkey)Reconfigure
aws_sqs_queue.jobsRabbitMQ instanceReplatform
aws_lambda_function.thumbnailerCloud Foundry organization, handler in an always-on processContainerize
aws_dynamodb_table.auditMongoDB Flex instance, as an alternative to a JSONB designRedesign

By class: 6 RECONFIGURE, 2 REPLATFORM, 1 DIRECT, 1 CONTAINERIZE, 1 REDESIGN, all with medium confidence. None of the 11 units has its critical settings closed yet: 5 get there once their open items are answered, and 6 need work that a person does by hand in this build.

Foundation: subnets become networks

Left: the VPC and its two subnets. Right: the two stackit_network blocks of the draft, each with the comment line that names the availability zone it does not carry; the other comment lines of the file are left out. STACKIT has no VPC container object, so the project the draft is created in is the VPC's boundary.

Example inputmain.tf
resource "aws_vpc" "main" {
  cidr_block = "10.30.0.0/16"
}

resource "aws_subnet" "private_a" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.30.1.0/24"
  availability_zone = "eu-central-1a"
}

resource "aws_subnet" "private_b" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.30.2.0/24"
  availability_zone = "eu-central-1b"
}
STACKIT Terraform by StackToITterraform/network.tf
# NOT CARRIED (aws_subnet.private_a): availability_zone = eu-central-1a — stackit_network has no availability zone (pinned provider): the network serves the region; servers and volumes choose their zone.
resource "stackit_network" "private_a" {
  project_id       = var.project_id
  name             = "private-a"
  ipv4_prefix      = "10.30.1.0/24"
  ipv4_nameservers = var.default_ipv4_nameservers
}

# NOT CARRIED (aws_subnet.private_b): availability_zone = eu-central-1b — stackit_network has no availability zone (pinned provider): the network serves the region; servers and volumes choose their zone.
resource "stackit_network" "private_b" {
  project_id       = var.project_id
  name             = "private-b"
  ipv4_prefix      = "10.30.2.0/24"
  ipv4_nameservers = var.default_ipv4_nameservers
}
  • Same prefixes, no zone

    Subnets keep their IPv4 prefixes, which keeps addressing plans stable. The availability zone is dropped: a STACKIT network serves the region, and servers and volumes choose their zone.

  • Public or private is not a subnet property

    On STACKIT, servers get public IPs explicitly. The run records that outbound internet access cannot be disabled for a network the way a private AWS subnet had none, and leaves that as an open decision.

Data: RDS becomes PostgreSQL Flex

Left: the RDS instance. Right: the draft instance with the two NOT CARRIED comment lines that precede it in the file; the other comment lines are left out. Flavor and storage are derived from the source: 2.16 is 2 vCPU and 16 GiB, the smallest single-node flavor covering db.m6g.large, and storage is rounded up from 100 GiB to 108 because STACKIT states gigabytes without defining the unit.

Example inputmain.tf
resource "aws_db_instance" "main" {
  identifier              = "app-db"
  engine                  = "postgres"
  engine_version          = "16.4"
  instance_class          = "db.m6g.large"
  allocated_storage       = 100
  db_subnet_group_name    = aws_db_subnet_group.main.name
  username                = "app"
  manage_master_user_password = true
  storage_encrypted       = true
  backup_retention_period = 7
}
STACKIT Terraform by StackToITterraform/data.tf
# NOT CARRIED (aws_db_instance.main): db_subnet_group_name — stackit_postgresflex_instance has no subnet, availability-zone or IP-family attribute (pinned provider): clients reach the instance at the endpoint STACKIT assigns.
# NOT CARRIED (aws_db_instance.main): manage_master_user_password — the master secret in AWS Secrets Manager (managed master password) is not carried: STACKIT generates the credential (pinned provider) and has no rotation schedule; keep the new one in STACKIT Secrets Manager or the application's own store.
resource "stackit_postgresflex_instance" "main" {
  project_id = var.project_id
  name       = "app-db"
  version    = "16"
  flavor_id  = "2.16"
  storage = {
    class = var.postgresflex_storage_class
    size  = 108
  }
  backup_schedule = "0 2 * * *"
  network = {
    acl          = var.relational_database_allowed_cidrs
    access_scope = var.relational_database_access_scope == "SNA" ? "SNA" : null
  }
  retention_days = 32
}
  • Credentials change

    STACKIT generates the master credential, and the application receives the new one. There is no rotation schedule to carry over.

  • Endpoint, not subnet

    The instance has its own endpoint and an access list; the source's placement in a subnet group is not carried. Exposure is a decision.

  • Turn on instance protection

    STACKIT's PostgreSQL Flex documentation warns that in API v3, deleting an instance without active instance protection loses its data immediately and permanently. Enable protection before the database holds production data.

The order the run proposes

Waves are computed from dependencies. Units in the same wave can move in parallel; the run calls this a starting point for your plan, not a schedule.

WaveUnitsWhy here
1VPC, S3 bucket, ElastiCache group, SQS queue, Lambda function, DynamoDB tableThey depend on no other unit of the estate
2Security group, both subnetsThey depend on the VPC
3RDS instance, EC2 instanceThey depend on the subnets

The execution package adds 24 automated steps (18 resource blocks and 6 API calls) and 102 manual steps in 33 work packages. Of the 24 automated steps, 19 are free of decisions and manual prerequisites but still wait for values such as project_id.

Decisions your architects own

The register of this run lists 26 records. These are the ones with the largest effect.

  • DynamoDB

    No DynamoDB-compatible service exists on STACKIT. The draft offers one MongoDB Flex instance, STACKIT's managed MongoDB service, with each table as a collection; relational JSONB on PostgreSQL Flex is the other option. Either way the access layer is rewritten, and key design, capacity modes and conditional writes do not carry over.

  • Lambda

    The run notes that STACKIT has no generally available function service. The handler runs in an always-on process: a Cloud Foundry app, or a container. The execution model changes from per-invocation to always-on.

  • Boot image

    An AMI is replaced by a STACKIT image you choose. Until that is answered, the connectivity check and the cutover steps wait.

  • Egress and endpoints

    The draft keeps outbound traffic closed and exposes the databases on a public endpoint limited by an access list; both are defaults you confirm or replace. Fill the access lists yourself: STACKIT's RabbitMQ documentation says a new data service starts with a default access list that includes STACKIT IP ranges.

  • Data movement method

    Dump and restore or logical replication for PostgreSQL; sync tools for buckets. The right choice depends on data size and freeze window, which the Terraform does not state.

Questions architects ask first

Where do I start?

With an assessment of your Terraform. It takes the folder of your AWS configuration and writes a report, a draft and a plan. Read index.html first, then the classes in assessment.json.

Does StackToIT change anything in AWS or STACKIT?

No. assess reads files and writes files. The generated scripts and Terraform are applied by a person.

What if my estate is not in Terraform?

The documented optional discover step collects a read-only AWS inventory with your local CLI credentials to compare with the Terraform. It complements Terraform input; it does not replace it.

Which services are the hardest to move?

The ones with no like-for-like target: DynamoDB (REDESIGN) and Lambda (CONTAINERIZE) in this run. Queues and managed databases are replatforming: same purpose, different API or release.

How do I know the migration is complete?

When the checks of the plan pass, the rollback limit is recorded and the source is retired after the retention you decided. The run lists those checks per unit in execution/verify/checks.md.

Sources

Your next move: STACKIT.

Tell us about your estate. We show you what StackToIT delivers for it: target architecture, Terraform artifacts and a structured migration plan.