AZURE APP SERVICE UND FUNCTIONS → STACKIT · ARCHITEKTUR

Azure App Service und Functions auf STACKIT

STACKIT kennt keinen App-Service-Plan und, wie der Lauf festhält, kein allgemein verfügbares Function-as-a-Service. Eine Code-Web-App wechselt zu Cloud Foundry, eine Container-Web-App zu SKE, und eine Function App wird zur Cloud-Foundry-App oder zum Container. Diese Seite zeigt an einer Demo-Umgebung, wie StackToIT jeden Fall einstuft und wie Sie das Ziel für Ihre eigenen Apps wählen.

Eine Code-Web-App und eine Function App, bewertet

Eine für diese Seite geschriebene Demo-Umgebung, am 4. November 2026 von StackToIT bewertet: ein Linux-App-Service-Plan mit einer Node.js-Web-App, eine Container-Web-App und eine Python-Function-App mit ihrem Host-Storage-Account. Links zwei der Eingabeblöcke, rechts der einzige Ressourcenblock, den die Engine für beide schreibt; die Prüfkommentare darüber in der Datei sind hier ausgelassen. Die Eingabeblöcke stehen in main.tf nicht direkt hintereinander; jeder steht deshalb wörtlich in einem eigenen Ausschnitt.

Eingabe: azurerm_linux_web_app.portalmain.tf
resource "azurerm_linux_web_app" "portal" {
  name                = "app-portal-gwc"
  resource_group_name = azurerm_resource_group.apps.name
  location            = azurerm_resource_group.apps.location
  service_plan_id     = azurerm_service_plan.apps.id
  https_only          = true

  site_config {
    always_on = true

    application_stack {
      node_version = "20-lts"
    }
  }

  app_settings = {
    "WEBSITE_RUN_FROM_PACKAGE" = "1"
    "ORDERS_API_URL"           = "https://orders.example.internal"
  }
}
Eingabe: azurerm_linux_function_app.jobsmain.tf
resource "azurerm_linux_function_app" "jobs" {
  name                       = "func-jobs-gwc"
  resource_group_name        = azurerm_resource_group.apps.name
  location                   = azurerm_resource_group.apps.location
  service_plan_id            = azurerm_service_plan.apps.id
  storage_account_name       = azurerm_storage_account.func.name
  storage_account_access_key = azurerm_storage_account.func.primary_access_key

  site_config {
    application_stack {
      python_version = "3.11"
    }
  }

  app_settings = {
    "QUEUE_CONNECTION" = "stfuncappsgwc01"
  }
}
STACKIT-Terraform von StackToITterraform/apps.tf
resource "stackit_scf_organization" "migrated_apps" {
  project_id = var.project_id
  name       = "migrated-apps"
}
  • Eine Organisation, keine App

    stackit_scf_organization ist eine Cloud-Foundry-Organisation. Die Apps werden mit cf push in einen Space dieser Organisation ausgerollt, mit Manifest, Buildpack und Umgebungsvariablen; nichts davon erzeugt der Entwurf. Der „NOT CARRIED“-Kommentar nennt die Einstellungen der Demo (App-Einstellungen, HTTPS only, Always On, Plan-Verweis und Runtime-Version) und hält fest, dass keine App-Service-Einstellung erzeugt wird: Plan, Runtime-Stack, App-Einstellungen, Site-Konfiguration, Authentifizierung, Identität, Backup, Logs, Slots.

  • Zwei Quellen, eine Organisation

    Die Portal-Web-App und die Function App teilen sich den Block, weil beide in derselben Cloud-Foundry-Organisation landen. Der Kommentar darüber nennt beide unter „replaces“.

  • Prüfpunkte des Laufs

    Für die Web-App bittet der Lauf Sie zu prüfen, ob ein Cloud-Foundry-Buildpack Runtime-Stack und Version abdeckt. Laut FAQ von STACKIT Cloud Foundry listet cf buildpacks die aktuell eingebauten Buildpacks auf, und voller Support gilt nur für diese; ein Community-Buildpack lässt sich über GitHub-URL und Versions-Tag angeben, aber nur vorübergehend. Für die Function App bittet er Sie, die Trigger und Bindings aus host.json oder function.json aufzulisten, weil das Terraform sie nicht zeigt.

Eine Container-Web-App, bewertet

Aus demselben Lauf. Die Legacy-Web-App läuft bereits als Container-Image; der Lauf stuft sie daher als CONTAINERIZE ein und entwirft einen Cluster dafür, nicht den Workload.

Beispieleingabemain.tf
resource "azurerm_linux_web_app" "legacy" {
  name                = "app-legacy-gwc"
  resource_group_name = azurerm_resource_group.apps.name
  location            = azurerm_resource_group.apps.location
  service_plan_id     = azurerm_service_plan.apps.id
  https_only          = true

  site_config {
    always_on = true

    application_stack {
      docker_image_name   = "shop/legacy-api:2.4"
      docker_registry_url = "https://registry.example.com"
    }
  }
}
STACKIT-Terraform von StackToITterraform/kubernetes.tf
resource "stackit_ske_cluster" "containers" {
  project_id = var.project_id
  name       = "containers"
  node_pools = [{
    name               = "workloads"
    machine_type       = var.containers_machine_type
    minimum            = var.containers_nodes_min
    maximum            = var.containers_nodes_max
    availability_zones = var.availability_zones
  }]
}
  • Der Cluster ohne seine Manifeste

    Der Entwurf erzeugt einen SKE-Cluster mit einem Node Pool. Deployments, Services, Ingress und Secrets der Workload werden nicht erzeugt; der Kommentar sagt, dass Image, CPU, Speicher, Umgebung, Probes, Skalierungsregeln und Registry-Zugang nirgends im Entwurf gesetzt sind.

  • Werte, die nur Sie liefern

    Maschinentyp und Knotengrenzen haben keinen Standardwert. Die maximale Knotenzahl muss mindestens der Zahl der Zonen entsprechen, weil die SKE-API einen Pool mit niedrigerem Maximum ablehnt; der Entwurf erzwingt das in einer Validierung.

  • Ein Cluster für alle Container-Apps

    Hat Ihr Entwurf schon einen SKE-Cluster, dürfen Ihre Architekten laut Kommentar die Workloads dort betreiben und diesen Cluster streichen.

Die Validierung, die den Node Pool schützt

Kopiert aus terraform/variables.tf des Laufs. Sie zeigt, wie der Entwurf eine Plattformgrenze in eine Prüfung verwandelt, bevor irgendetwas angewendet wird.

STACKIT-Terraform von StackToITterraform/variables.tf
variable "containers_nodes_max" {
  type        = number
  description = "Maximum nodes of the node pool hosting the migrated container workloads."
  validation {
    condition     = var.containers_nodes_max >= length(var.availability_zones)
    error_message = "At least the number of zones in var.availability_zones: the SKE API refuses a node pool whose maximum node count is below the number of its zones (\"maximum node count should be greater than or equal to the number of zones specified for this pool\"). Set the maximum to at least that number, or list fewer zones."
  }
}

Wie die vier Einheiten eingestuft wurden

Azure-RessourceSTACKIT-Ziel und KlasseAussage des Laufs
Linux-Web-App, Node.js-Code (portal)Cloud Foundry, REPLATFORMcf push baut die App mit einem Buildpack. App-Einstellungen werden zu Umgebungsvariablen, Connection Strings zu Service Bindings. Alternativ wird sie für SKE containerisiert.
Linux-Web-App, Container-Image (legacy)SKE-Workload oder Cloud-Foundry-Docker-App, CONTAINERIZEDas Image existiert schon; es zieht daher als Deployment um oder als Cloud-Foundry-App aus dem Image. App-Einstellungen werden zu Umgebungsvariablen und Secrets.
Linux-Function-App, Python (jobs)Cloud Foundry, CONTAINERIZESTACKIT hat kein allgemein verfügbares Function-as-a-Service. Trigger und Bindings zu Azure-Diensten werden gegen die migrierten Dienste neu geschrieben. Laut Lauf entfallen Scale-to-zero und Abrechnung je Ausführung des Consumption-Plans; die Demo-Funktion läuft ohnehin auf dem gemeinsamen P1v3-Plan und hatte beides nie.
Storage Account hinter der Function AppImplizit, RECONFIGUREEr trägt nur den Functions-Host (Trigger, Sperren, Deployment-Pakete) und verschwindet mit ihm. Prüfen Sie, dass keine Anwendungsdaten darin liegen.
App-Service-Plan, RessourcengruppeKeine Ressource, als unterstützende Einstellungen geprüftDer Lauf prüft Standort, Betriebssystem und Ressourcengruppe des Plans als unterstützende Einstellungen, und der Standort der Ressourcengruppe bleibt für eine Person offen; der Plan selbst hat kein STACKIT-Gegenstück.

Klassen so, wie der Lauf sie entschieden hat, aus assessment.json. Die Konfidenz ist für alle vier Einheiten MEDIUM, weil keine Lock-Datei die Provider-Version festlegt.

Das Ziel wählen: Cloud Foundry oder SKE

Die Engine schlägt je App ein Ziel vor. Die Wahl zwischen den beiden Plattformen treffen Sie, und sie hängt von der App ab, nicht vom Azure-Dienst, aus dem sie kommt.

ZielPasst, wennPreis dafür
Cloud FoundryDie App ist Quellcode in einer von einem Buildpack unterstützten Sprache, hat wenige bewegliche Teile und nutzt verwaltete Dienste.Sie übernehmen cf push, Manifeste und Service Bindings. Die STACKIT-Seite nennt Java, Node.js, Python und Ruby nur als Beispiele; prüfen Sie daher Ihre genaue Runtime und Version.
SKE mit ContainernDie App wird schon als Image ausgeliefert, braucht Sidecars oder eigene Runtimes oder läuft neben anderen Kubernetes-Workloads.Sie schreiben und pflegen Kubernetes-Manifeste, Ingress und Secrets. Die Control Plane ist verwaltet, das Workload-Design liegt bei Ihnen.
Function App als Cloud-Foundry-App oder ContainerTimer und Queue-Trigger, deren Logik gewöhnlicher Code ist; der Trigger lässt sich durch einen Scheduler oder einen Consumer ersetzen.Das Azure-Functions-Programmiermodell, Bindings und die Scale-to-zero-Abrechnung haben kein Gegenstück; jeder Trigger wird neu geschrieben.

So entscheiden Sie je App

  1. Beim Hosting-Plan beginnen

    Auf Azure verrät der Hosting-Plan der Function App, wie sie sich verhält: Flex Consumption, Premium, Dedicated, Container Apps oder der ältere Consumption-Plan. Eine App im Dedicated-Plan läuft schon auf App-Service-Infrastruktur zu festen Kosten; eine App, die auf Scale-to-zero angewiesen war, verliert diese Eigenschaft.

  2. Nach einem Container-Image suchen

    App Service kann eigene Container ausrollen. Ist die App schon ein Image, spart SKE oder eine Cloud-Foundry-Docker-App den Neubau; ist sie Code, ist Cloud Foundry der kürzere Weg.

  3. Trigger und Bindings auflisten

    Der Lauf sagt, dass das Terraform sie nicht zeigt. Lesen Sie host.json und function.json und schreiben Sie eine Tabelle: Trigger, Quelldienst, Ersatz auf STACKIT, zum Beispiel RabbitMQ für eine Queue.

  4. Identität und Secrets ausdrücklich umziehen

    Managed Identity und Key-Vault-Referenzen werden nicht übernommen. Jede Verwendung wird zu expliziten Zugangsdaten, also zu einer Code- und Konfigurationsänderung.

  5. Die Reihenfolge festlegen

    Der Lauf legt beide Web-Apps in Welle 1 und die Function App in Welle 2, nach ihrem Storage Account. Beginnen Sie mit der App mit den wenigsten Bindings.

Was keine Einstellung übernimmt

  • Deployment-Slots

    Slots gehören zum App-Service-Modell. Cloud Foundry und SKE nutzen eigene Rollout-Strategien; planen Sie den Release-Prozess daher neu.

  • Always On, Plangröße, Skalierungsregeln

    Für Plangröße und Regeln gibt es keine Zuordnung. Bemessen Sie die Cloud-Foundry-Quota oder den SKE-Node-Pool aus gemessener Last.

  • Registry-Zugangsdaten

    Für die Container-App führt der Lauf die Registry-Zugangsdaten als Prüfpunkt: Benutzer und Passwort oder die Managed Identity werden zu cf push --docker-username für Cloud Foundry oder zu einem Image Pull Secret auf SKE, das auf die migrierte Registry zeigt.

  • Authentifizierung und Logs

    Eingebaute Authentifizierung, Log-Einstellungen und Backups der Web-App werden nicht erzeugt; sie werden in der Anwendung oder der Plattform neu aufgebaut.

Fragen aus Anwendungsteams

Hat STACKIT ein Function-as-a-Service?

Der Lauf hält fest, dass STACKIT kein allgemein verfügbares Function-as-a-Service hat. Eine Function App läuft als Cloud-Foundry-App oder als Container auf SKE, und ihre Trigger und Bindings werden neu geschrieben.

Gehört eine Web-App zu Cloud Foundry oder zu SKE?

Ein Code-Deployment wird Cloud Foundry zugeordnet, ein Container-Image SKE oder einer Cloud-Foundry-Docker-App. Die Tabelle oben nennt, wann was passt. Der Entwurf legt nur die Organisation oder den Cluster an; die Apps werden danach ausgerollt.

Warum ist die Function App CONTAINERIZE und nicht REPLATFORM?

Der Lauf begründet es damit, dass die Function App als Cloud-Foundry-App oder als Container auf SKE läuft, weil schon der Azure-Functions-Host in einem Container läuft. Ihr Ziel nennt die Cloud-Foundry-Organisation, dieselbe, die die Code-Web-App als REPLATFORM erhält. Lesen Sie die Klasse also als Verpackungsaufwand, nicht als andere Plattform. Wählen Sie stattdessen SKE, wird die Funktion in ein Image gebaut.

Was geschieht mit dem App-Service-Plan?

Dafür wird nichts angelegt. Nutzen Sie Plangröße und Instanzzahl als Eingabe, wenn Sie Cloud-Foundry-Quota oder SKE-Node-Pool bemessen, und behandeln Sie Standort und Ressourcengruppe als zu entscheidende Einstellungen.

Quellen

Ihr nächster Schritt: STACKIT.

Erzählen Sie uns von Ihrer Umgebung. Wir zeigen Ihnen, was StackToIT dafür liefert: Zielarchitektur, Terraform-Artefakte und einen strukturierten Migrationsplan.