Skip to content

feat: add Azure Container Apps support - #228

Merged
hectorvent merged 11 commits into
floci-io:mainfrom
thomhurst:issue-62-container-apps
Sep 8, 2026
Merged

feat: add Azure Container Apps support#228
hectorvent merged 11 commits into
floci-io:mainfrom
thomhurst:issue-62-container-apps

Conversation

@thomhurst

@thomhurst thomhurst commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add Azure-compatible Microsoft.App/managedEnvironments and Microsoft.App/containerApps ARM resources
  • run revision replicas in Docker with shared sidecar networking, readiness checks, scaling, and lifecycle cleanup
  • support external/internal ingress, stable FQDNs, Single/Multiple revision modes, and weighted traffic routing
  • default to Docker-free mocked ARM state; real runtimes remain opt-in
  • add Java SDK compatibility coverage, integration/unit tests, configuration, banner output, and service documentation

Type of change

  • Bug fix (fix:)
  • New feature (feat:)
  • Breaking change (feat!: or fix!:)
  • Docs / chore

Azure Compatibility

Implements the Microsoft.App 2025-07-01 ARM shapes used by Microsoft's generated Java management client. Name availability uses the managed-environment-scoped endpoint; GET responses redact write-only environment and app secrets; both resource types participate in ARM resource-group indexing.

Checklist

  • ./mvnw test passes locally
  • New or updated integration test added
  • Commit messages follow Conventional Commits

Validation

  • ./mvnw.cmd test — 827 passed
  • focused Container Apps regression suite after review fixes — 17 passed
  • git diff --check — clean

Closes #62

@greptile-apps

greptile-apps Bot commented Aug 27, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adds Azure Container Apps ARM resources and optional Docker-backed revision runtimes.

  • Adds managed-environment, container-app, revision, scaling, traffic-routing, and ingress behavior.
  • Preserves encoded ingress paths and authorizes internal ingress using exact same-environment replica addresses.
  • Adds Java SDK compatibility coverage, focused tests, configuration, and service documentation.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
src/main/java/io/floci/az/services/containerapps/ContainerAppsHandler.java Implements ARM and ingress orchestration; the latest authorization ordering addresses the previously reported cold-start and unauthorized-start failures.
src/main/java/io/floci/az/services/containerapps/ContainerAppRuntimeManager.java Manages Docker revision replicas and scopes internal caller recognition to exact same-environment container addresses.
src/main/java/io/floci/az/services/containerapps/ContainerAppIngressProxy.java Proxies ingress while preserving the transport-level encoded path, resolving the prior decoding defect.
src/main/java/io/floci/az/core/AzureRoutingFilter.java Captures the encoded path and transport peer before blocking dispatch so ingress can preserve routing semantics and enforce peer-based authorization.
src/main/java/io/floci/az/core/docker/ContainerLifecycleManager.java Adds exact container-address discovery and label-filtered lookup used by internal ingress authorization.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Router as AzureRoutingFilter
    participant Handler as ContainerAppsHandler
    participant Runtime as ContainerAppRuntimeManager
    participant Docker
    participant App as Revision Replica
    Client->>Router: Request to app FQDN
    Router->>Handler: AzureRequest with rawPath and peer IP
    Handler->>Runtime: Validate internal caller when required
    Runtime->>Docker: Resolve exact labeled-container addresses
    Docker-->>Runtime: Same-environment replica addresses
    Runtime-->>Handler: Allowed or denied
    alt Allowed and revision is cold
        Handler->>Runtime: Start active revision
        Runtime->>Docker: Create replica containers
    end
    Handler->>App: Proxy encoded path to selected endpoint
    App-->>Client: HTTP response
Loading

Reviews (11): Last reviewed commit: "fix(containerapps): align regression tes..." | Re-trigger Greptile

Comment thread src/main/java/io/floci/az/services/containerapps/ContainerAppsHandler.java Outdated
Comment thread src/main/java/io/floci/az/services/containerapps/ContainerAppIngressProxy.java Outdated
@thomhurst
thomhurst force-pushed the issue-62-container-apps branch from 5ca3b5b to 3cad5c1 Compare August 27, 2026 22:47
@thomhurst

Copy link
Copy Markdown
Contributor Author

Addressed the encoded Container Apps resource-path feedback in f1e07ef and pushed the update.

Comment thread src/main/java/io/floci/az/services/containerapps/ContainerAppsHandler.java Outdated
@hectorvent hectorvent added feature container-apps Azure Container Apps labels Aug 28, 2026
@hectorvent

Copy link
Copy Markdown
Contributor

Thank you, this is a lot of service in one PR and the wire behaviour holds up well. I checked the status codes, the read-only synthesis, the enum vocabularies and azurerm's read-back requirements against the 2025-07-01 spec and the provider source, and they line up; the compat test genuinely runs against Microsoft's generated client in CI, which is the evidence that matters most. The four Greptile findings are all properly fixed at head, and the encoded-path test standing up a real server is a nice touch.

(blocking) mocked defaults to false, so out of the box a create pulls and runs the user's image, and when Docker is unavailable the revision is marked failed, which surfaces as provisioningState: Failed and a hard error for the SDK and Terraform rather than clean mocked ARM state. Every other Docker-capable service here defaults to true for exactly that reason.

(blocking) Neither resource type implements ResourceIndexContributor, so they are invisible to the resource-group /resources listing that azurerm checks before deleting a group. That is the failure that interface was added for, and ACI shows the pattern.

(blocking) POST locations/{loc}/checkNameAvailability is not an operation in Microsoft.App; the only ones are scoped under managedEnvironments/{env}/checkNameAvailability. Real Azure 404s that path, so it is worth dropping or replacing with the real one.

Two smaller things worth folding in: environment sharedKey and the daprAI* values are echoed on GET where the app-level secrets are correctly stripped, and the body is missing the template's Type of change and Azure Compatibility sections.

Comment thread src/main/java/io/floci/az/services/containerapps/ContainerAppRuntimeManager.java Outdated
@thomhurst

Copy link
Copy Markdown
Contributor Author

Addressed in e6c9741: mocked mode now defaults on, managed environments and apps contribute to the ARM resource index, name availability uses the managed-environment-scoped endpoint, response secrets are redacted, and the PR description now follows the template. Focused tests: 17 passed.

@thomhurst
thomhurst force-pushed the issue-62-container-apps branch from e6c9741 to ca25bc2 Compare August 29, 2026 19:02
Comment thread src/main/java/io/floci/az/services/containerapps/ContainerAppsHandler.java Outdated
Comment thread src/main/java/io/floci/az/services/containerapps/ContainerAppRuntimeManager.java Outdated

@hectorvent hectorvent left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, all three points are cleared and I checked each one in source rather than taking the summary for it. mocked defaults to true, both resource types now contribute to the resource group index with subscription and group filtering, and name availability is scoped under managedEnvironments/{env} which is the only place that operation actually exists. The environment sharedKey and daprAI values are stripped too, and the description now carries the full template.

(follow-up, separate PR) The default flip has one cost worth closing: ContainerAppsCompatibilityTest only asserts ARM state, so it passes under mocked mode and the Docker backed runtime path now has no CI coverage. The Service Bus precedent handles it, set FLOCI_AZ_SERVICES_CONTAINER_APPS_MOCKED=false in the java suite env and the matching workflow entry, and leave the shipped default alone.

No blockers from my side.

@hectorvent

Copy link
Copy Markdown
Contributor

Since the approval, two of my merges landed under this branch: #268 (host-style routing in AzureRoutingFilter and the golden routing table) and #272 (the host field on AzureRequest), so it now conflicts on those three files. That is on my merge order, not on you. Would you rebase onto main? The approval stands, and once #270 lands its shared ArmResources.indexEntry, the private copy in the container apps handler could become a call to it, but that is not needed for the rebase.

Implement Azure-compatible managed environments, Container Apps, revisions, scaling, and Docker-backed ingress.

Closes floci-io#62
Authorize internal ingress only when transport peer exactly matches a running managed replica address. Network-wide CIDRs let unrelated containers trigger cold starts and reach internal apps.
Bind caller addresses to managed-environment Docker labels. This preserves cold-start authorization across manager restarts while preventing containers outside the target environment from reaching internal apps.
@thomhurst
thomhurst force-pushed the issue-62-container-apps branch from 085e83d to aa3493d Compare September 7, 2026 08:18
@hectorvent

Copy link
Copy Markdown
Contributor

Thank you, cleared. The rebase is content faithful: mocked still defaults to true, both resource types still contribute to the resource index, name availability is still scoped under managedEnvironments/{env}, and the golden routing table carries the new entries.

(follow-up, separate PR) Two things I am tracking rather than asking you to change here. The handler still carries its own private indexEntry, which should become a call to the shared ArmResources.indexEntry once #270 lands, and the mocked default of true means the Docker backed runtime path has no CI coverage. The Service Bus precedent closes the second one: set the mocked flag to false in the java suite env and the matching workflow entry, and leave the shipped default alone.

No blockers from my side.

@hectorvent
hectorvent merged commit 41d61f1 into floci-io:main Sep 8, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

container-apps Azure Container Apps feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Azure Container Apps support

2 participants