HUAWEI CLOUD ELB → STACKIT · TUTORIAL

Huawei Cloud ELB to STACKIT load balancing, hands on

This walk-through runs a small Huawei Cloud estate with one shared and one dedicated load balancer through StackToIT and reads what comes out. The shared load balancer is mapped to the STACKIT Network Load Balancer as RECONFIGURE. The dedicated one is left to you as MANUAL_REVIEW, with the Application Load Balancer as the candidate. Listeners, pools, members and monitors are not assessed at all in this build, and that is where the real decision sits: layer 4 or layer 7, and who ends TLS. The sections below show the input, the command, the output and what to change before you build anything.

Step 1: the command and the variable file

The demo estate has twelve resources in one main.tf: a VPC, a subnet, a security group, two servers, a shared load balancer with listener, pool, members and monitor, and a dedicated load balancer with listener and pool. The dedicated load balancer reads two flavor IDs from variables that have no default. Placeholder values go into a variable file; the two listener certificate IDs in main.tf are placeholders too. Use your own IDs.

Commandterminal
stacktoit assess ./edge-terraform --var-file ./demo.tfvars
Variable filedemo.tfvars
l4_flavor_id = "l4-flavor-placeholder"
l7_flavor_id = "l7-flavor-placeholder"
  • Nothing connects to Huawei Cloud

    StackToIT reads the Terraform and the variable file. It opens no Huawei Cloud account.

  • The output folder

    assessment.json, engineering/architect-report.md, migration/technical-sequencing.md, execution/manual/actions.md and index.html are the files you read next.

Step 2: what a missing variable does

The same estate, run once without the variable file and once with it. Left: three summary lines of the first run's console output. Right: the same three lines of the second run. Each line is copied as printed.

Without the fileconsole output
Source        12 resources · 12 units · visibility: Required input missing
Migration     0 drafted · 9 manual · 3 have no draft because an input the source needs is not in the package (of 12 units: 9 the draft considered, 3 have no draft)
Attention     2 variables without a value (var.l4_flavor_id, var.l7_flavor_id) · 7 open requests (3 block the draft, marked in inputs-template.yaml)
With the fileconsole output
Source        12 resources · 12 units · visibility: Complete
Migration     0 drafted · 12 manual (of 12 units the draft considered)
Attention     5 open requests (1 block the draft, marked in inputs-template.yaml)
  • Three units without a draft

    Without values for l4_flavor_id and l7_flavor_id, the dedicated load balancer and the two units that depend on it have no draft because an input the source needs is not in the package, and they carry no wave.

  • Twelve units either way

    The unit count and the classes do not change. The variables change how complete the picture is, and which units can be ordered into waves.

Step 3: the shared load balancer

Left: the three blocks of the input that make up the public web entry (the members and the monitor are in the same file). Right: the result the run recorded for them, an excerpt of assessment.json.

Example inputmain.tf
resource "huaweicloud_lb_loadbalancer" "web" {
  name          = "edge-web"
  vip_subnet_id = huaweicloud_vpc_subnet.app.ipv4_subnet_id
}

resource "huaweicloud_lb_listener" "https" {
  name                      = "edge-web-https"
  protocol                  = "TERMINATED_HTTPS"
  protocol_port             = 443
  default_tls_container_ref = "web-certificate-id-placeholder"
  loadbalancer_id           = huaweicloud_lb_loadbalancer.web.id
}

resource "huaweicloud_lb_pool" "web" {
  name        = "edge-web-pool"
  protocol    = "HTTP"
  lb_method   = "ROUND_ROBIN"
  listener_id = huaweicloud_lb_listener.https.id
}
StackToIT assessmentassessment.json
[
  {
    "id": "huaweicloud_lb_loadbalancer.web",
    "result": {
      "class": "RECONFIGURE",
      "confidence": "MEDIUM",
      "target": {
        "service": "STACKIT Network Load Balancer"
      },
      "reason": "A shared load balancer becomes a STACKIT Network Load Balancer. Listeners and backends are rewritten, and the public address changes."
    }
  },
  {
    "id": "huaweicloud_lb_listener.https",
    "result": {
      "class": "MANUAL_REVIEW",
      "confidence": "LOW",
      "reason": "huaweicloud_lb_listener is not in the knowledge base catalogue; an architect has to decide the target. Nothing of this resource is assessed or drafted (unknown source type)."
    }
  },
  {
    "id": "huaweicloud_lb_pool.web",
    "result": {
      "class": "MANUAL_REVIEW",
      "confidence": "LOW",
      "reason": "huaweicloud_lb_pool is not in the knowledge base catalogue; an architect has to decide the target. Nothing of this resource is assessed or drafted (unknown source type)."
    }
  }
]
  • The balancer is mapped

    A shared load balancer becomes a STACKIT Network Load Balancer, RECONFIGURE with MEDIUM confidence. Listeners and backends are rewritten and the public address changes.

  • Its listener and pool are not

    huaweicloud_lb_listener, lb_pool, lb_member and lb_monitor are not in the knowledge base catalogue of this build. Each is MANUAL_REVIEW with LOW confidence and nothing of it is assessed or drafted.

  • The HTTPS listener is the signal

    Port 443 with HTTPS means TLS ends on the balancer. The Network Load Balancer works at layer 4 only, so this listener points to an Application Load Balancer. The run cannot see that, because it does not read the listener.

Step 4: the dedicated load balancer

The dedicated balancer in the same layout. Its flavor IDs come from the variable file of step 1.

Example inputmain.tf
resource "huaweicloud_elb_loadbalancer" "api" {
  name              = "edge-api"
  vpc_id            = huaweicloud_vpc.main.id
  ipv4_subnet_id    = huaweicloud_vpc_subnet.app.ipv4_subnet_id
  l4_flavor_id      = var.l4_flavor_id
  l7_flavor_id      = var.l7_flavor_id
  availability_zone = ["eu-west-101a", "eu-west-101b"]
}

resource "huaweicloud_elb_listener" "api" {
  name               = "edge-api-https"
  protocol           = "HTTPS"
  protocol_port      = 8443
  server_certificate = "api-certificate-id-placeholder"
  loadbalancer_id    = huaweicloud_elb_loadbalancer.api.id
}

resource "huaweicloud_elb_pool" "api" {
  name        = "edge-api-pool"
  protocol    = "HTTP"
  lb_method   = "LEAST_CONNECTIONS"
  listener_id = huaweicloud_elb_listener.api.id
}
StackToIT assessmentassessment.json
[
  {
    "id": "huaweicloud_elb_loadbalancer.api",
    "result": {
      "class": "MANUAL_REVIEW",
      "confidence": "LOW",
      "target": {
        "service": "STACKIT Application Load Balancer"
      },
      "reason": "A dedicated ELB can serve layer 4 and layer 7. Choose a STACKIT Application or Network Load Balancer from its listeners, and rewrite them."
    }
  },
  {
    "id": "huaweicloud_elb_listener.api",
    "result": {
      "class": "MANUAL_REVIEW",
      "confidence": "LOW",
      "reason": "huaweicloud_elb_listener is not in the knowledge base catalogue; an architect has to decide the target. Nothing of this resource is assessed or drafted (unknown source type)."
    }
  },
  {
    "id": "huaweicloud_elb_pool.api",
    "result": {
      "class": "MANUAL_REVIEW",
      "confidence": "LOW",
      "reason": "huaweicloud_elb_pool is not in the knowledge base catalogue; an architect has to decide the target. Nothing of this resource is assessed or drafted (unknown source type)."
    }
  }
]
  • Candidate, not decision

    The run names the STACKIT Application Load Balancer as the candidate and classes the unit MANUAL_REVIEW: a dedicated ELB can serve layer 4 and layer 7, so the choice depends on its listeners.

  • Six settings to you

    Availability zones, subnet, both flavors, name and one more setting are listed as critical settings left to the architect.

Step 5: the order the run proposes

Waves 3 to 6 of migration/technical-sequencing.md, as written. Wave 1 holds the VPC and the security group, wave 2 the subnet.

Wave ordermigration/technical-sequencing.md
## Wave 3 — 3 unit(s)

| Unit | Class | Target |
|---|---|---|
| `huaweicloud_compute_instance.app` | RECONFIGURE / MEDIUM | STACKIT Compute Engine |
| `huaweicloud_elb_loadbalancer.api` | MANUAL_REVIEW / LOW | STACKIT Application Load Balancer |
| `huaweicloud_lb_loadbalancer.web` | RECONFIGURE / MEDIUM | STACKIT Network Load Balancer |

## Wave 4 — 2 unit(s)

| Unit | Class | Target |
|---|---|---|
| `huaweicloud_elb_listener.api` | MANUAL_REVIEW / LOW | — |
| `huaweicloud_lb_listener.https` | MANUAL_REVIEW / LOW | — |

## Wave 5 — 2 unit(s)

| Unit | Class | Target |
|---|---|---|
| `huaweicloud_elb_pool.api` | MANUAL_REVIEW / LOW | — |
| `huaweicloud_lb_pool.web` | MANUAL_REVIEW / LOW | — |

## Wave 6 — 2 unit(s)

| Unit | Class | Target |
|---|---|---|
| `huaweicloud_lb_member.web` | MANUAL_REVIEW / LOW | — |
| `huaweicloud_lb_monitor.web` | MANUAL_REVIEW / LOW | — |

## Cutover (decision support — performed by the customer)

No cutover facts: the scan and the draft established no DNS record set whose value the draft re-binds to a generated address, no public address re-binding, no DNS record unit, no certificate unit and no open cutover decision. That is not a statement that nothing has to be cut over: a name, an address or a certificate outside the scanned source is not seen, and a unit that exists only if OpenTofu decides so at plan time is not read here. StackToIT performs no cutover and gives no time estimate.
  • Balancers before listeners

    Listeners follow the balancers, pools follow the listeners, members and monitors come last. Servers and both balancers are in wave 3.

  • An order of dependency

    It is a starting point for your wave plan, not a schedule and not a cutover sequence.

Shared, dedicated, Network and Application Load Balancer

ConcernHuawei Cloud ELBSTACKIT
Layers and protocolsShared: frontend TCP, UDP, HTTP, HTTPS; backend TCP, UDP, HTTP. Dedicated adds QUIC and TLS at the frontend and HTTPS, QUIC, TLS and GRPC at the backend.Network Load Balancer: layer 4, TCP (the page also names UDP). Application Load Balancer: layer 7, HTTP and HTTPS, WebSocket.
TLSBoth terminate TLS at the listener: the shared type with protocol TERMINATED_HTTPS and default_tls_container_ref, the dedicated type with HTTPS and server_certificate.Network Load Balancer: no TLS handling, encryption is yours. Application Load Balancer: TLS offloading and TLS bridging.
RoutingShared: forwarding rules by domain name and path. Dedicated adds HTTP method, header, query string and CIDR block, plus redirects, rewrites and fixed responses.Application Load Balancer: by host, path, header and query parameter. Network Load Balancer: one target pool per listener.
Health checksBoth types check backend server groups.Network Load Balancer: active, on by default, interval and thresholds adjustable. Application Load Balancer: TCP checks everywhere, advanced HTTP checks through API and SDK.
Algorithm and persistenceWeighted round robin, weighted least connections, source IP hash; dedicated adds connection ID.Network Load Balancer: round robin by default, source-IP persistence switches to Maglev. Application Load Balancer: cookie persistence.
Public addressAn EIP: associated with a shared load balancer as a separate resource; a dedicated one references an existing EIP or creates one with its bandwidth settings.Network Load Balancer: a static external IP you supply or an ephemeral one. Application Load Balancer: an ephemeral IP, or a deployment in the private network only.

Huawei Cloud column from the ELB load balancer types page, STACKIT column from the Network and Application Load Balancer pages, all read on 4 November 2026. As of November 2026 the Application Load Balancer feature table lists advanced HTTP health checks for API and SDK only, with Terraform and Portal support in progress, so check the current state.

What to change before you build

  1. 1. List every listener with protocol and certificate

    Do this from main.tf, because the run does not assess listeners. Note frontend protocol, port, backend protocol and the certificate reference (default_tls_container_ref or server_certificate).

  2. 2. Choose the balancer type per listener

    Plain TCP pass-through fits the Network Load Balancer; for UDP, confirm support first, because the Network Load Balancer page names layer 4 TCP in its overview and TCP and UDP in its listener section. HTTP routing or TLS termination fits the Application Load Balancer. In the example, the shared listener is TERMINATED_HTTPS on port 443 in front of an HTTP pool on port 8080 with an HTTP health check: the balancer ends TLS, so despite the run's Network Load Balancer mapping it belongs on the Application Load Balancer. The dedicated listener (HTTPS on 8443, HTTP pool) points the same way, which matches the run's candidate.

  3. 3. Prepare the network and the rules

    Create the STACKIT networks of waves 1 and 2. Targets in the same STACKIT network get a target security group automatically; targets in another network need one by hand, and targets in another project must be in the same Network Area.

  4. 4. Create pool and targets

    The Network Load Balancer documentation asks for at least two targets for load balancing. The example has two servers, matching its two members.

  5. 5. Rebuild health checks and certificates

    The /healthz monitor of the example is a layer 7 check. Decide whether a TCP check is enough or the Application Load Balancer is needed, and move the certificate to where the target balancer expects it.

  6. 6. Change the public address and DNS

    The address is new. Lower the DNS TTL before the switch, point the name at the new balancer and keep the Huawei Cloud balancer until traffic is clean. Pointing the name back is the way back; write it down.

Questions about the load balancer move

Which STACKIT load balancer replaces a Huawei Cloud shared ELB?

The run maps it to the Network Load Balancer. That fits layer 4 traffic. If a listener terminates TLS or routes by host or path, use the Application Load Balancer instead and treat the run result as a starting point.

Why are listeners, pools, members and monitors MANUAL_REVIEW?

Their resource types are not in the knowledge base catalogue of this build, so nothing of them is assessed or drafted. You rewrite them on the STACKIT side from the Terraform you already have.

What do the l4 and l7 flavor variables do in the run?

They are inputs of the dedicated load balancer. Without values the run reports them as missing and leaves the dependent units without a draft and a wave; with a variable file all twelve units are ordered.

Does the public IP stay the same?

No. The run states that the public address changes, so DNS records and allow lists that name it change as well.

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.