ORACLE CLOUD → STACKIT · CASE STUDY

An OCI shop, assessed end to end

One realistic OCI estate, run through StackToIT from Terraform to migration plan: a web server behind a load balancer, a MySQL database, a media bucket and an order queue, on two subnets with a NAT gateway and an IAM policy. 11 resources became 11 units in 3 waves: 7 RECONFIGURE, 2 REPLATFORM and 2 MANUAL_REVIEW, 9 at medium confidence and 2 at low. This walkthrough reads the run in the order an architect would, and names the decisions that are still yours at the end.

The run in numbers

Assessed on 4 November 2026 offline, without source validation. Every figure is from assessment.json and the console summary of the run.

  • 11 resources, 11 units

    One file, main.tf. Source status COMPLETE, 8 dependencies between the units.

  • 7 · 2 · 2 by class

    RECONFIGURE 7, REPLATFORM 2 (the database and the queue), MANUAL_REVIEW 2 (the NAT gateway and the IAM policy). No unit is DIRECT, CONTAINERIZE, REDESIGN or BLOCKED.

  • 9 medium, 2 low

    The two low-confidence units are the two MANUAL_REVIEW units. The provider is not pinned by a lock file, which caps every unit at medium.

  • 0 drafted, 11 manual

    For an Oracle Cloud source the run writes no STACKIT resource blocks: terraform/ holds only the provider and variable files, and all 11 units are manual steps in 8 work packages.

  • 56 critical settings listed

    None of the 11 units has all of its critical settings closed. The report names the settings per unit, from 3 for a VCN to 11 for the instance.

  • 1 request blocks the draft

    The target region, eu01 or eu02, in review/inputs.yaml.

Network and compute: the instance, its security group and the NAT gateway

Left: three blocks from main.tf. Right: the decisions as they stand in assessment.json. assessment.json is written as a single line, so the pane shows selected fields of each unit, indented and nested as in the file, with the values unchanged.

Example inputmain.tf
resource "oci_core_network_security_group" "web" {
  compartment_id = var.compartment_id
  vcn_id         = oci_core_vcn.shop.id
  display_name   = "web"
}

resource "oci_core_nat_gateway" "egress" {
  compartment_id = var.compartment_id
  vcn_id         = oci_core_vcn.shop.id
  display_name   = "egress"
}

resource "oci_core_instance" "web" {
  compartment_id      = var.compartment_id
  availability_domain = var.availability_domain
  display_name        = "shop-web-01"
  shape               = "VM.Standard.E5.Flex"

  shape_config {
    ocpus         = 2
    memory_in_gbs = 16
  }

  source_details {
    source_type = "image"
    source_id   = var.image_id
  }

  create_vnic_details {
    subnet_id        = oci_core_subnet.web.id
    nsg_ids          = [oci_core_network_security_group.web.id]
    assign_public_ip = false
  }
}
StackToIT assessmentassessment.json
[
  {
    "id": "oci_core_network_security_group.web",
    "result": {
      "class": "RECONFIGURE",
      "confidence": "MEDIUM",
      "target": {
        "service": "STACKIT security groups"
      },
      "reason": "A network security group becomes a STACKIT security group. Its rules are rewritten, and STACKIT rules only allow traffic."
    }
  },
  {
    "id": "oci_core_nat_gateway.egress",
    "result": {
      "class": "MANUAL_REVIEW",
      "confidence": "LOW",
      "reason": "Gateways do not carry over one to one. Whether the egress needs a STACKIT network with a public address or a NAT design is a decision for the network owner."
    }
  },
  {
    "id": "oci_core_instance.web",
    "result": {
      "class": "RECONFIGURE",
      "confidence": "MEDIUM",
      "target": {
        "service": "STACKIT Compute Engine"
      },
      "reason": "A compute instance becomes a STACKIT server. The shape becomes a STACKIT flavor, the image is rebuilt or imported, and the attached volumes and network interfaces move with it."
    }
  }
]
  • The server

    RECONFIGURE at medium confidence: the shape becomes a STACKIT flavor, the image is rebuilt or imported, and the attached volumes and interfaces move with it. The report lists 11 settings of the block for your architect.

  • The security group

    Becomes a STACKIT security group. Its rules are rewritten, and STACKIT rules only allow traffic.

  • The NAT gateway is a decision

    MANUAL_REVIEW at low confidence: gateways do not carry over one to one. Whether egress needs a STACKIT network with a public address or a NAT design is for the network owner.

The data tier: database, bucket and queue

Lines 100 to 124 of main.tf: the database is highly available in the input and sits on the private subnet, the media bucket holds the shop images, and the queue carries orders. assessment.json is written as a single line, so the pane shows selected fields of each unit, indented and nested as in the file, with the values unchanged.

Example inputmain.tf
resource "oci_mysql_mysql_db_system" "shop" {
  compartment_id          = var.compartment_id
  availability_domain     = var.availability_domain
  display_name            = "shop-mysql"
  shape_name              = "MySQL.4"
  subnet_id               = oci_core_subnet.db.id
  admin_username          = "dbadmin"
  admin_password          = var.db_admin_password
  data_storage_size_in_gb = 100
  is_highly_available     = true
  mysql_version           = "8.4.3"
}

resource "oci_objectstorage_bucket" "media" {
  compartment_id = var.compartment_id
  namespace      = "examplenamespace"
  name           = "shop-media"
  access_type    = "NoPublicAccess"
}

resource "oci_queue_queue" "orders" {
  compartment_id       = var.compartment_id
  display_name         = "orders"
  retention_in_seconds = 345600
}
StackToIT assessmentassessment.json
[
  {
    "id": "oci_mysql_mysql_db_system.shop",
    "result": {
      "class": "REPLATFORM",
      "confidence": "MEDIUM",
      "target": {
        "service": "STACKIT MariaDB"
      },
      "reason": "STACKIT offers MariaDB, not MySQL; test MySQL-specific features and any HeatWave analytics before cut-over, and move the data with a logical dump."
    }
  },
  {
    "id": "oci_objectstorage_bucket.media",
    "result": {
      "class": "RECONFIGURE",
      "confidence": "MEDIUM",
      "target": {
        "service": "STACKIT Object Storage"
      },
      "reason": "A bucket becomes a STACKIT Object Storage bucket with an S3 API. Clients change endpoint and credentials; lifecycle, replication and access rules are rewritten."
    }
  },
  {
    "id": "oci_queue_queue.orders",
    "result": {
      "class": "REPLATFORM",
      "confidence": "MEDIUM",
      "target": {
        "service": "STACKIT RabbitMQ"
      },
      "reason": "An OCI queue becomes a queue on STACKIT RabbitMQ. Clients change protocol, and messages in flight are drained before cut-over."
    }
  }
]
  • MySQL becomes MariaDB

    REPLATFORM. STACKIT offers MariaDB, not MySQL: test MySQL-specific features and any HeatWave analytics before cutover, and move the data with a logical dump. The STACKIT page describes MariaDB as keeping compatibility with MySQL applications and offers 3-node Galera clusters with automatic failover.

  • The bucket changes endpoint

    RECONFIGURE to STACKIT Object Storage, an S3-compatible service. Clients change endpoint and credentials, and lifecycle, replication and access rules are rewritten. The data movement file lists the bucket next to the database as a stateful unit with no method chosen.

  • The queue changes protocol

    REPLATFORM to STACKIT RabbitMQ. Clients change protocol, and messages in flight are drained before cutover. Retention is one of the 3 settings the report leaves to you.

The edge: load balancer and IAM policy

The estate declares the load balancer but no listener, backend set or certificate, and the run rates it MEDIUM. In the load balancer tutorial, where those resources are declared and reported as uncatalogued linked resources, the same kind of block is rated LOW. assessment.json is written as a single line, so the pane shows selected fields of each unit, indented and nested as in the file, with the values unchanged.

Example inputmain.tf
resource "oci_load_balancer_load_balancer" "shop" {
  compartment_id = var.compartment_id
  display_name   = "shop"
  shape          = "flexible"
  subnet_ids     = [oci_core_subnet.web.id]

  shape_details {
    minimum_bandwidth_in_mbps = 10
    maximum_bandwidth_in_mbps = 50
  }
}
StackToIT assessmentassessment.json
[
  {
    "id": "oci_load_balancer_load_balancer.shop",
    "result": {
      "class": "RECONFIGURE",
      "confidence": "MEDIUM",
      "target": {
        "service": "STACKIT Application Load Balancer"
      },
      "reason": "A load balancer becomes a STACKIT Application Load Balancer. Listeners, backends and certificates are rewritten, and the public address changes."
    }
  }
]
  • The public address changes

    The load balancer becomes a STACKIT Application Load Balancer; listeners, backends and certificates are rewritten and the public address changes.

  • The policy stays with a person

    oci_identity_policy.web is MANUAL_REVIEW at low confidence: OCI policies have no document-level counterpart on STACKIT. Its statement, "Allow dynamic-group shop-web to read objects in compartment shop", is read by people, who map the web tier to a STACKIT service account and a role.

All eleven units

Targets, classes and confidence as the run decided them.

OCI resourceSTACKIT targetClass · confidence
VCN (shop)STACKIT networkRECONFIGURE · MEDIUM
Subnet (web)STACKIT networkRECONFIGURE · MEDIUM
Subnet (db)STACKIT networkRECONFIGURE · MEDIUM
Network security group (web)STACKIT security groupsRECONFIGURE · MEDIUM
NAT gateway (egress)No target; your decisionMANUAL_REVIEW · LOW
Compute instance (web)STACKIT Compute EngineRECONFIGURE · MEDIUM
Load balancer (shop)STACKIT Application Load BalancerRECONFIGURE · MEDIUM
MySQL DB system (shop)STACKIT MariaDBREPLATFORM · MEDIUM
Object Storage bucket (media)STACKIT Object StorageRECONFIGURE · MEDIUM
Queue (orders)STACKIT RabbitMQREPLATFORM · MEDIUM
IAM policy (web)No target; your decisionMANUAL_REVIEW · LOW

Each subnet is its own unit in the run and has its own row.

The order of the move

Three waves from the dependencies. Units in a wave can move in parallel.

  1. Wave 1

    The VCN, the IAM policy, the media bucket and the queue: nothing else is needed first.

  2. Wave 2

    The NAT gateway, the security group and the two subnets.

  3. Wave 3

    The server, the load balancer and the database, once their network is in place.

What the run writes, and what each file answers

index.html
The whole run, unit by unit, offline
assessment.json
Class, confidence, target and reason for each unit, machine-readable
engineering/architect-report.md
The queue of units that need a person, and the settings left to you for each
migration/technical-sequencing.md
The three waves
migration/data-movement.md
The database and the bucket as stateful units, mechanism undecided
execution/manual/actions.md
The 11 manual steps in 8 work packages, with owner roles
review/inputs.yaml
The region request and the other questions of the run

The decisions still open at the end

  • Egress design

    NAT gateway or a STACKIT network with a public address. The Network Architect role owns the work package.

  • Roles for the web tier

    Which STACKIT service account the web server uses and which role it gets, instead of the dynamic group.

  • MySQL to MariaDB

    Which MySQL features the shop uses, and how the data moves. The data movement file shows mechanism UNKNOWN, with size, recovery point and downtime tolerance not provided.

  • Order queue semantics

    Retention, redelivery and dead-lettering rebuilt on RabbitMQ and tested with real order volume.

  • Region

    eu01 or eu02, answered once in review/inputs.yaml.

Questions about this walkthrough

Is this a real customer estate?

No. It is a demo estate written for this page. The figures are those of the run on it.

Why is nothing drafted in Terraform?

For an Oracle Cloud source this build writes no STACKIT resource blocks. The run states 0 units generated and 11 left for the architect, and gives every one a target or a reason.

What does the run not see?

Anything that exists only in the tenancy and not in Terraform, and the data itself. It also does not check a plan against a STACKIT project.

How long would this migration take?

The run gives no time estimate. It gives an order and the decisions; durations depend on data volume and the downtime you accept.

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.