kestra-io / kestra-io/plugin-oci
[Plugin] OCI — Container Instances
- Dominant language
- Java
- Stars
- 0
- Forks
- 0
- Avg merge
- 18h 3m
- Merged PRs (30d)
- 1
Description
## Summary
The OCI Container Instances sub-plugin for `plugin-oci` enables Kestra flows to launch, monitor, and terminate OCI Container Instances — ephemeral containers that run without managing Kubernetes. This makes OCI Container Instances a lightweight compute backend for Kestra task execution: spin up a container to run a job, collect its exit code and logs, then tear it down — all within a single flow.
## Motivation
Platform teams that want to run containerized workloads on OCI without the overhead of managing an OKE cluster are adopting OCI Container Instances. Integrating this service with Kestra allows flows to treat a container run as a task: pass in environment variables from secrets, wait for the container to exit, and branch on success or failure. Without a native plugin, teams resort to OCI CLI wrappers or REST calls with manual request signing.
## Context
Part of the OCI Plugin Suite EPIC: https://github.com/kestra-io/plugin-oci/issues/2
Reference: `plugin-aws` ECS `RunTask` / `plugin-gcp` Cloud Run Job patterns.
## API Reference
- **Official docs**: https://docs.oracle.com/en-us/iaas/api/#/en/container-instances/latest/
- **Authentication**: Config-file (`~/.oci/config`), instance principal, or `SimpleAuthenticationDetailsProvider`
- **Base URL pattern**: `https://compute-containers.{region}.oci.oraclecloud.com/20210415/`
- **SDK**: OCI Java SDK v3.87.0 via BOM
## Gradle Dependencies
Add to `build.gradle`:
```groovy
// OCI Java SDK BOM
implementation platform("com.oracle.oci.sdk:oci-java-sdk-bom:3.87.0")
// Container Instances
implementation "com.oracle.oci.sdk:oci-java-sdk-containerinstances"
implementation "com.oracle.oci.sdk:oci-java-sdk-common"
```
## Plugin Structure
- **Repository**: `plugin-oci`
- **Namespace**: `io.kestra.plugin.oci.containerinstances`
- **Sub-plugins**: `containerinstances`
## Suggested Tasks
1. `CreateContainerInstance` — launch a container instance with image, env vars, CPU/memory, and optionally wait for completion
2. `StartContainerInstance` — start a stopped container instance
3. `StopContainerInstance` — stop a running container instance
4. `DeleteContainerInstance` — delete a container instance
5. `GetContainerInstance` — fetch details and emit lifecycle state, exit code as outputs
6. `ListContainerInstances` — list instances in a compartment with optional state filter
7. Add `ContainerInstanceStateTrigger` — poll until a container instance reaches a target lifecycle state
8. Write unit + integration tests
## YAML Examples
### Example 1 — Run a container instance and wait for it to exit
```yaml
id: run_container_job
namespace: company.platform
inputs:
- id: image
type: STRING
- id: compartment_ocid
type: STRING
tasks:
- id: run_container
type: io.kestra.plugin.oci.containerinstances.CreateContainerInstance
region: eu-frankfurt-1
tenancyOcid: "{{ secret('OCI_TENANCY_OCID') }}"
userId: "{{ secret('OCI_USER_OCID') }}"
fingerprint: "{{ secret('OCI_FINGERPRINT') }}"
privateKey: "{{ secret('OCI_PRIVATE_KEY') }}"
compartmentId: "{{ inputs.compartment_ocid }}"
availabilityDomain: AD-1
shape: CI.Standard.E4.Flex
shapeConfig:
ocpus: 2
memoryInGBs: 8
containers:
- imageUrl: "{{ inputs.image }}"
displayName: kestra-job
environmentVariables:
EXECUTION_ID: "{{ execution.id }}"
DB_PASSWORD: "{{ secret('DB_PASSWORD') }}"
waitForCompletion: true
- id: log_result
type: io.kestra.plugin.core.log.Log
message: "Container exited — state: {{ outputs.run_container.lifecycleState }}"
```
### Example 2 — List running container instances
```yaml
id: audit_container_instances
namespace: company.platform
tasks:
- id: list
type: io.kestra.plugin.oci.containerinstances.ListContainerInstances
region: eu-frankfurt-1
tenancyOcid: "{{ secret('OCI_TENANCY_OCID') }}"
userId: "{{ secret('OCI_USER_OCID') }}"
fingerprint: "{{ secret('OCI_FINGERPRINT') }}"
privateKey: "{{ secret('OCI_PRIVATE_KEY') }}"
compartmentId: "{{ secret('OCI_COMPARTMENT_OCID') }}"
lifecycleState: ACTIVE
- id: log
type: io.kestra.plugin.core.log.Log
message: "{{ outputs.list.count }} active container instances"
```
### Example 3 — Trigger a flow when a container instance becomes INACTIVE
```yaml
id: on_container_inactive
namespace: company.platform
triggers:
- id: container_watcher
type: io.kestra.plugin.oci.containerinstances.ContainerInstanceStateTrigger
region: eu-frankfurt-1
tenancyOcid: "{{ secret('OCI_TENANCY_OCID') }}"
userId: "{{ secret('OCI_USER_OCID') }}"
fingerprint: "{{ secret('OCI_FINGERPRINT') }}"
privateKey: "{{ secret('OCI_PRIVATE_KEY') }}"
containerInstanceId: "{{ secret('OCI_CONTAINER_INSTANCE_OCID') }}"
targetLifecycleState: INACTIVE
interval: PT1M
tasks:
- id: cleanup
type: io.kestra.plugin.core.log.Log
message: "Container instance {{ trigger.containerInstanceId }} is INACTIVE — cleaning up"
```
## Acceptance Criteria
- [ ] `CreateContainerInstance`, `StartContainerInstance`, `StopContainerInstance`, `DeleteContainerInstance`, `GetContainerInstance`, `ListContainerInstances` tasks implemented
- [ ] `CreateContainerInstance` supports multi-container definitions, environment variables, and `waitForCompletion: true`
- [ ] `ContainerInstanceStateTrigger` polling trigger implemented
- [ ] All `Property` fields support Kestra expression language
- [ ] Unit + integration tests pass (`./gradlew test`)
- [ ] `package-info.java` with `@PluginSubGroup(category = PluginSubGroup.PluginCategory.CLOUD)`
- [ ] Build passes with `./gradlew build`
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with build.gradle and the existing plugin-oci structure, then compare the plugin-aws ECS RunTask and plugin-gcp Cloud Run Job patterns. Review the OCI Container Instances API and SDK references before scoping the listed tasks and trigger. Done means the acceptance checklist is satisfied, including package-info.java and passing ./gradlew test and ./gradlew build.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- cloud
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100