---
title: Configuring Namazu Conductor Providers
description: "Each Namazu Conductor provider [Element](https://namazustudios.com/glossary/element/) is configured independently via attributes, and each honors a different subset of the common [core concepts](namazu-conductor) — profiles come from a different provider-native resource, and placement/scope hints are only applied where the provider has an…"
url: "https://namazustudios.com/docs/add-ons/container-on-demand/configuring-namazu-conductor-providers/"
updated: "2026-08-14"
category: "Add-Ons / Container on Demand"
---

# Configuring Namazu Conductor Providers

Each Namazu Conductor provider [Element](https://namazustudios.com/glossary/element/) is configured independently via attributes, and each honors a different subset of the common [core concepts](namazu-conductor) — profiles come from a different provider-native resource, and placement/scope hints are only applied where the provider has an equivalent concept. This page covers EdgeGap, AWS ECS, Kubernetes, and Unity Multiplay.

---

## Placement and Scope Support

You can send the same `JobRequest` — including any combination of `JobPlacement` and `JobScope` entries — to every provider you have deployed. Each one only acts on what it understands:

| Provider | `RegionPlacement` | `IpPlacement` | `LatitudeLongitudePlacement` | `NamespaceScope` | `ClusterScope` | `command` / `args` override |
| --- | --- | --- | --- | --- | --- | --- |
| EdgeGap | Ignored | Honored (`ip_list`) | Honored (`geo_ip_list`) | Ignored | Ignored | Not supported by the EdgeGap deploy API |
| ECS | Ignored — placement is governed by the configured subnets/security groups (`awsvpc`) or the target container instance (EC2) | Ignored | Ignored | Ignored | Honored — overrides the cluster a task is launched into | Honored (container override on the [Profile](https://namazustudios.com/glossary/profile/)'s primary container) |
| Kubernetes | Honored — sets a `topology.kubernetes.io/zone` node selector | Ignored | Ignored | Honored — overrides where the workload (and any [Service](https://namazustudios.com/glossary/service/)) is created | Ignored | Honored (container override) |
| Multiplay | Honored — the first entry's `id` is sent as the allocation's `regionId` | Ignored | Ignored | Ignored | Ignored | Not supported by the Multiplay allocation API |

---

## EdgeGap

The EdgeGap provider talks to the EdgeGap [REST](https://namazustudios.com/glossary/rest/) API v1. A `JobProfile` corresponds to one active app version (`<appName>:<versionName>`); `getAvailableProfiles()` lists every active version across every app visible to your API key.

| Attribute | Default | Description |
| --- | --- | --- |
| `dev.getelements.conductor.edgegap.api.key` | *none — required* | EdgeGap API key, sent as the bare `Authorization` header value. Marked sensitive. |
| `dev.getelements.conductor.edgegap.base.url` | `https://api.edgegap.com` | EdgeGap API base URL. Override for a regional mirror or a test environment. |
| `dev.getelements.conductor.edgegap.stdio.bridge.port` | `10080` | Port the `namazu-stdio-bridge` sidecar listens on, if your app version's image includes one. See [Streaming Job Stdio in Namazu Conductor](streaming-job-stdio-in-namazu-conductor). |
| `dev.getelements.conductor.edgegap.stdio.bridge.base.path` | *(empty)* | Base path prefix for the bridge's WebSocket endpoints. Must match the bridge's own `NAMAZU_CONDUCTOR_STDIO_URI`. |

Status polling runs against `GET /v1/status/{request_id}` every 5 seconds (fixed, not currently configurable). EdgeGap's own status strings are mapped onto `JobStatus` as: anything ending in `INITIALIZING` or `WAITING` → `PENDING`; `RUNNING` → `RUNNING`; `TERMINATED`/`TERMINATING` → `COMPLETED`; anything else → `FAILED`.

---

## AWS ECS

The ECS provider talks to AWS ECS via the AWS SDK v2. A `JobProfile` corresponds to one active task definition family; `getAvailableProfiles()` only surfaces families tagged `namazu.conductor:jobSet=<value>` matching your configured job set.

| Attribute | Default | Description |
| --- | --- | --- |
| `dev.getelements.conductor.ecs.region` | *none — required* | AWS region the cluster lives in (e.g. `us-east-1`). |
| `dev.getelements.conductor.ecs.cluster` | *none — required* | Default cluster [name](https://namazustudios.com/glossary/name/) or ARN tasks launch into. Overridable per request via `ClusterScope`. |
| `dev.getelements.conductor.ecs.subnets` | *none* | Comma-separated subnet IDs. Required for task definitions using `awsvpc` network mode. |
| `dev.getelements.conductor.ecs.security.groups` | *none* | Comma-separated security group IDs. Required for `awsvpc` task definitions. |
| `dev.getelements.conductor.ecs.job.set` | `default` | Only task definition families tagged `namazu.conductor:jobSet=<value>` matching this are surfaced as profiles. |
| `dev.getelements.conductor.ecs.stdio.bridge.port` | `10080` | Port the `namazu-stdio-bridge` sidecar listens on, if your task definition's image includes one. |
| `dev.getelements.conductor.ecs.stdio.bridge.base.path` | *(empty)* | Base path prefix for the bridge's WebSocket endpoints. |

### Fargate vs. EC2 launch type

There's no separate attribute to pick Fargate vs. EC2 — the launch type is read per task definition family from an ECS resource tag, `namazu.conductor:launchType`. If the tag is absent, the family defaults to Fargate. Similarly, whether a launched task gets a public IP is controlled by the `namazu.conductor:assignPublicIp` tag (default: disabled).

Subnet/security group/public-IP configuration is only applied when the task definition's network mode is `awsvpc`. For EC2 tasks running in bridge network mode, that configuration is skipped entirely and Conductor instead resolves the job's reachable host/endpoints from the underlying container instance's EC2 IP.

### ClusterScope and task tracking

When a request's `ClusterScope` overrides the configured default cluster, ECS task ARNs (`arn:aws:ecs:<region>:<account>:task/<cluster>/<task-id>`) carry the cluster [name](https://namazustudios.com/glossary/name/), so `stop()` and status polling can recover it without Conductor persisting any extra state. The one exception is `listExecutions()`, which always queries the *configured default* cluster — tasks launched into a cluster-scoped override won't appear there.

---

## Kubernetes

The Kubernetes provider maps `PodTemplate` resources to `JobProfile`s using Fabric8. Client configuration comes from Fabric8's auto-detection (in-cluster [Service](https://namazustudios.com/glossary/service/) account, then `~/.kube/config`) unless `KUBECONFIG_PATH` / `MASTER_URL` are set.

| Attribute | Default | Description |
| --- | --- | --- |
| `dev.getelements.conductor.kubernetes.namespace` | `default` | Namespace `PodTemplate`s are discovered in and workloads are created in by default. Overridable per request via `NamespaceScope`. |
| `dev.getelements.conductor.kubernetes.job.set` | `default` | Only `PodTemplate`s labeled `namazu.conductor/job-set=<value>` matching this are surfaced as profiles. |
| `dev.getelements.conductor.kubernetes.kubeconfig.path` | *(empty)* | Optional path to a kubeconfig file, overriding Fabric8 auto-detection. |
| `dev.getelements.conductor.kubernetes.master.url` | *(empty)* | Optional Kubernetes API server URL override. |
| `dev.getelements.conductor.kubernetes.poll.interval.ms` | `5000` | Polling interval, in milliseconds, while waiting for a target status — used unless watches are enabled below. |
| `dev.getelements.conductor.kubernetes.watch.enabled` | `false` | When `true`, status transitions are observed via a Kubernetes watch on the Pod/Job instead of polling. Falls back to polling if the watch closes with an error before reaching a terminal status. |

Behavior is otherwise driven entirely by labels and annotations on the `PodTemplate` itself:

| Label / Annotation | Values | Effect |
| --- | --- | --- |
| `namazu.conductor/job-set` (label) | string | Must match the configured job set for the template to be surfaced as a [Profile](https://namazustudios.com/glossary/profile/). |
| `namazu.conductor/workload-kind` | `pod` (default) or `job` | `pod` launches a long-standing, bare `Pod`; `job` launches a one-off `batch/v1 Job`. Pod phases / Job status map onto `JobStatus` accordingly. |
| `namazu.conductor/expose-ports` | e.g. `"7777/udp,8080/tcp"` | If present, a `Service` selecting the workload is created. If absent, no `Service` is created and endpoints fall back to the pod IP. |
| `namazu.conductor/Service-type` | `NodePort` (default), `LoadBalancer`, or `ClusterIP` | Type of the created `Service`, when one is created. |

The following annotations apply only when `namazu.conductor/workload-kind: job`. Each is an optional integer string; if absent, the field is omitted and the Kubernetes default applies; if invalid (non-numeric or negative), a warning is logged and the field is likewise omitted.

| Annotation | Job field | Kubernetes default |
| --- | --- | --- |
| `namazu.conductor/ttl-seconds-after-finished` | `spec.ttlSecondsAfterFinished` | none |
| `namazu.conductor/backoff-limit` | `spec.backoffLimit` | 6 |
| `namazu.conductor/active-deadline-seconds` | `spec.activeDeadlineSeconds` | none |
| `namazu.conductor/completions` | `spec.completions` | 1 |
| `namazu.conductor/parallelism` | `spec.parallelism` | 1 |

Created `Service`s carry a `namazu.conductor/owned-by=<workload-name>` label, which is how `stop()` finds and deletes them without Conductor persisting any extra state of its own.

`streamStdio()` is native here — it attaches to the pod's first container the same way `kubectl attach` does. The pod must be in the `Running` phase; otherwise the call throws.

---

## Unity Multiplay

The Multiplay provider authenticates against Unity's Services API using a [Service](https://namazustudios.com/glossary/service/) account (key [id](https://namazustudios.com/glossary/id/) + secret), exchanging it for an access token that's cached for 55 minutes (tokens themselves expire after an hour). A `JobProfile` corresponds to one fleet + build configuration pair; `getAvailableProfiles()` lists every pair referenced across your project's fleets and environments.

| Attribute | Default | Description |
| --- | --- | --- |
| `dev.getelements.conductor.multiplay.key.id` | *(empty) — required* | Unity [Service](https://namazustudios.com/glossary/service/) account key [id](https://namazustudios.com/glossary/id/). |
| `dev.getelements.conductor.multiplay.key.secret` | *(empty) — required* | Unity [Service](https://namazustudios.com/glossary/service/) account key secret. |
| `dev.getelements.conductor.multiplay.project.id` | *(empty) — required* | Unity project [id](https://namazustudios.com/glossary/id/) (GUID) that owns the Multiplay resources. |
| `dev.getelements.conductor.multiplay.environment.id` | *(empty) — required* | Unity environment [id](https://namazustudios.com/glossary/id/) (GUID) within the project, e.g. production or staging. |

Executing a job creates a Multiplay allocation. Job status is derived from the allocation's own status: `ALLOCATED` → `RUNNING`, `FAILED` → `FAILED`, `CANCELLED` → `COMPLETED`, anything else → `PENDING`. Multiplay's allocation API has no container-exec equivalent, so `streamStdio()` isn't supported on this provider.
