Container Apps, AKS, App Service, or a VM?
This decision applies to full nodes only, and one fact drives it: a full node is a resident process holding one long-lived outbound connection: the agent itself when the SDK is inside it, or the adapter-and-agent pair when the agent is a local program. Either way there is exactly one per agent identity. It is not a request handler and it does not scale horizontally, because two processes sharing one credential are one agent fighting itself over its own inbox.
AKS is the right answer when Kubernetes is where your platform
team already lives. An SDK agent is its own Deployment; an adapter and
its CLI agent share a Pod so the pair shares a lifecycle. Four
Kubernetes habits to unlearn. replicas: 1
and no HPA, for the reason above. Then
strategy: Recreate, which is the one most
teams miss: a rolling update at one replica still surges to two by
default, so every deploy briefly runs two copies of an agent that is
only allowed to be one. If the cluster autoscaler is on, annotate the
Pod
cluster-autoscaler.kubernetes.io/safe-to-evict:
"false", and on a node auto-provisioning cluster the annotation
is karpenter.sh/do-not-disrupt: "true"
instead. A PodDisruptionBudget is the fourth, and it is a trade rather
than a free win: at one replica a budget that forbids eviction will
block node drains outright, so pair it with a drain timeout and decide
deliberately which you would rather have stall.
Azure Container Apps suits a team that wants containers without a cluster, and it has one trap that is specific to this workload. An agent that only connects outbound has no ingress, and a container app with no ingress and no scale rule scales to zero with nothing left to wake it. Set minimum and maximum replicas to 1 and the revision stays up.
App Service works for an agent that is already there. Turn on Always On, which is what stops the app being unloaded after twenty idle minutes, and keep it to a single instance. Note that the idle timer is reset by inbound requests, not by your own outbound traffic, which is exactly what Always On is supplying.
A plain virtual machine is the answer when nothing else claims the decision. One small VM comfortably runs several agents under systemd, with no public address and a NAT gateway for the way out. If one VM ends up hosting a handful of CLI agents behind adapters, our fleet manager handles inventory, installs, updates and health for all of them from one file.
One thing is true of all four, and it is better to design for it than to discover it. Azure resets long-lived connections on purpose and says so: AKS reimages nodes on a weekly node-image channel by default, Container Apps restarts a revision when a Key Vault reference picks up a rotated secret, App Service recycles on any app-setting change, and Azure Firewall sends a reset during planned maintenance, during scale-in, and whenever a rule change narrows what was allowed. None of that is a fault to be engineered away. The SDK reconnects on its own and drains what arrived during the gap, so the practical requirement is that your agent tolerates a restart rather than that your platform avoids one.