Add Kubernetes Job workload support to the Kubernetes publisher
- Dominant language
- C#
- Stars
- 6.3k
- Forks
- 991
- Avg merge
- 2d 15h
- Merged PRs (30d)
- 196
Description
# Feature Request: Add Kubernetes Job workload support to the Kubernetes publisher
## Background and motivation
The Aspire Kubernetes publisher currently generates Kubernetes workloads such as Deployment resources for application resources. There are scenarios where an application resource is better represented by a Kubernetes Job: a workload that should run to completion rather than remain continuously running.
A common example is an initialization or migration task that needs to execute once before another application starts:
```text
Kubernetes Job
│
│ completes successfully
▼
Application Deployment
```
Today, there does not appear to be a way to express this workload type through the Aspire application model and have the Kubernetes publisher generate a Kubernetes Job.
This requires users to either manually augment the generated manifests/Helm chart or maintain separate Kubernetes resources outside of Aspire.
## Proposed feature
Add first-class support for Kubernetes Job workloads to the Aspire Kubernetes publisher.
Ideally, an Aspire resource could be declared as a job and the Kubernetes publisher would generate a `batch/v1` Job rather than a `apps/v1` Deployment.
For example, an API along the lines of:
```csharp
var migration = builder.PublishAsKubernetesJob("migration", "my-migration-image");
```
or an appropriate equivalent that fits Aspire's existing resource model.
The generated Kubernetes resource would be conceptually:
```yaml
apiVersion: batch/v1
kind: Job
metadata:
name: migration
spec:
template:
spec:
restartPolicy: Never
containers:
- name: migration
image: my-migration-image
```
The exact API and generated manifest structure are, of course, open to discussion.
## Use cases
- Database schema migrations
- One-time database/data initialization
- Generating or populating shared configuration/data
- Importing initial data
- Performing one-time setup of shared storage
- Other workloads that have a defined start and completion rather than continuously serving traffic
One particularly useful scenario is allowing a Job to complete before a dependent application is deployed or started.
For example:
```text
migration-job
↓
api
↓
frontend
```
This would allow Aspire's application model to describe the intended lifecycle and dependencies rather than requiring users to manually maintain additional Kubernetes manifests.
## Expected behavior
When publishing to Kubernetes, a resource identified as a Job should produce a Kubernetes `Job` rather than a `Deployment`.
The Job should support the relevant configuration already available for Aspire resources where applicable, including container image, environment variables, secrets, volumes, resource limits/requests, configuration, and service/resource references where meaningful.
## Dependency handling
A particularly valuable aspect of Job support would be the ability to express dependencies on the completion of a Job.
For example, an application might declare that it depends on a migration Job. If Aspire already has a resource dependency model, Job completion could provide additional dependency semantics:
- Resource dependency → resource must be available
- Job dependency → Job must successfully complete
Kubernetes itself does not provide a native `dependsOn` relationship between arbitrary workloads, so the publisher would need to translate this into an appropriate deployment/orchestration mechanism.
The implementation could potentially leverage the deployment tooling used by the generated manifests, such as Helm hooks or another mechanism.
## Alternatives considered
### Manually maintaining Kubernetes manifests
A user can create a Kubernetes Job outside of Aspire and deploy it separately. This works, but means the workload is no longer represented by the Aspire application model and requires maintaining two separate deployment configurations.
### Using an init container
An init container can perform some initialization before the application container starts. However, this is not always an appropriate replacement for a Job. A Job may need to be independently deployed, independently observable, run only once, shared by multiple application instances, or completed before a separate Deployment is started.
### Running the operation in the application container
The application itself could perform initialization on startup. This couples the initialization lifecycle to the application and can result in multiple replicas attempting to perform the same operation.
## Additional considerations
It would be useful if the feature could eventually support common Kubernetes Job settings such as `backoffLimit`, `activeDeadlineSeconds`, `ttlSecondsAfterFinished`, `completions`, `parallelism`, and `restartPolicy`.
These do not necessarily need to be exposed in the initial implementation. A minimal first version supporting a single-run Job would already address many use cases.
## Request
Please consider adding Kubernetes `Job` workload support to the Aspire Kubernetes publisher, preferably as a first-class Aspire resource/workload type that can participate in the Aspire resource dependency model.
This would make Aspire substantially more useful for applications that require one-time initialization, migrations, and other finite Kubernetes workloads while avoiding the need to maintain separate Kubernetes manifests.
Contributor guide
Research direction
Start by tracing the Kubernetes publisher and the Aspire application resource model, then compare how existing Deployment resources are represented and generated. Define the smallest first version that emits a batch/v1 Job with the requested container settings, and determine how resource dependencies and Job completion should be handled. Done means a declared Job publishes correctly without requiring separate manifests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, kubernetes
- Domain
- devops, infrastructure
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100