kestra-io / kestra-io/plugin-oci
[Plugin] OCI — Block Storage (Volumes & Backups)
- Dominant language
- Java
- Stars
- 0
- Forks
- 0
- Avg merge
- 18h 3m
- Merged PRs (30d)
- 1
Description
## Summary
The OCI Block Storage sub-plugin for `plugin-oci` enables Kestra flows to create, attach, detach, and back up block volumes — making persistent disk management part of reproducible, auditable orchestration pipelines. Teams can automate snapshot schedules, pre-provision volumes before launching compute instances, and clean up disks as part of teardown flows.
## Motivation
Infrastructure automation teams provisioning ephemeral OCI environments need to manage block volumes alongside compute resources. Today this requires OCI CLI scripts or Terraform runs that are hard to coordinate with downstream tasks. A native Block Storage sub-plugin lets flows create a volume, attach it to a freshly launched instance (Compute sub-plugin), and back it up — all in a single typed, expression-aware flow.
## Context
Part of the OCI Plugin Suite EPIC: https://github.com/kestra-io/plugin-oci/issues/2
Block Storage shares the `oci-java-sdk-core` module with the Compute sub-plugin (see #7943).
Reference: `plugin-aws` EBS tasks.
## API Reference
- **Official docs**: https://docs.oracle.com/en-us/iaas/api/#/en/iaas/latest/Volume
- **Authentication**: Config-file (`~/.oci/config`), instance principal, or `SimpleAuthenticationDetailsProvider`
- **Base URL pattern**: `https://iaas.{region}.oraclecloud.com/20160918/`
- **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")
// Block Storage shares the core module with Compute
implementation "com.oracle.oci.sdk:oci-java-sdk-core"
implementation "com.oracle.oci.sdk:oci-java-sdk-common"
```
## Plugin Structure
- **Repository**: `plugin-oci`
- **Namespace**: `io.kestra.plugin.oci.blockstorage`
- **Sub-plugins**: `blockstorage` (volumes, backups)
## Suggested Tasks
1. `CreateVolume` — provision a new block volume (size, compartment, AD)
2. `DeleteVolume` — delete a volume by OCID
3. `GetVolume` — fetch volume details and emit lifecycle state as output
4. `ListVolumes` — list volumes in a compartment
5. `AttachVolume` — attach a volume to a compute instance (iSCSI or paravirtualized)
6. `DetachVolume` — detach a volume from an instance
7. `CreateVolumeBackup` — create an on-demand backup of a volume
8. `DeleteVolumeBackup` — delete a volume backup
9. Add `VolumeLifecycleTrigger` — poll until volume reaches target lifecycle state
10. Write unit + integration tests
## YAML Examples
### Example 1 — Create a volume, attach it to an instance, and trigger a backup
```yaml
id: provision_and_backup_volume
namespace: company.platform
inputs:
- id: instance_ocid
type: STRING
- id: compartment_ocid
type: STRING
tasks:
- id: create_volume
type: io.kestra.plugin.oci.blockstorage.CreateVolume
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
sizeInGBs: 100
displayName: kestra-data-vol-{{ execution.id }}
- id: attach_volume
type: io.kestra.plugin.oci.blockstorage.AttachVolume
region: eu-frankfurt-1
tenancyOcid: "{{ secret('OCI_TENANCY_OCID') }}"
userId: "{{ secret('OCI_USER_OCID') }}"
fingerprint: "{{ secret('OCI_FINGERPRINT') }}"
privateKey: "{{ secret('OCI_PRIVATE_KEY') }}"
instanceId: "{{ inputs.instance_ocid }}"
volumeId: "{{ outputs.create_volume.volumeId }}"
type: PARAVIRTUALIZED
- id: backup_volume
type: io.kestra.plugin.oci.blockstorage.CreateVolumeBackup
region: eu-frankfurt-1
tenancyOcid: "{{ secret('OCI_TENANCY_OCID') }}"
userId: "{{ secret('OCI_USER_OCID') }}"
fingerprint: "{{ secret('OCI_FINGERPRINT') }}"
privateKey: "{{ secret('OCI_PRIVATE_KEY') }}"
volumeId: "{{ outputs.create_volume.volumeId }}"
displayName: backup-{{ execution.startDate | dateFormat('yyyy-MM-dd') }}
```
### Example 2 — List volumes and log their sizes
```yaml
id: audit_block_volumes
namespace: company.platform
tasks:
- id: list_volumes
type: io.kestra.plugin.oci.blockstorage.ListVolumes
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') }}"
- id: log_volumes
type: io.kestra.plugin.core.log.Log
message: "Found {{ outputs.list_volumes.count }} volumes"
```
### Example 3 — Trigger cleanup when a volume backup completes
```yaml
id: on_volume_backup_available
namespace: company.platform
triggers:
- id: backup_watcher
type: io.kestra.plugin.oci.blockstorage.VolumeLifecycleTrigger
region: eu-frankfurt-1
tenancyOcid: "{{ secret('OCI_TENANCY_OCID') }}"
userId: "{{ secret('OCI_USER_OCID') }}"
fingerprint: "{{ secret('OCI_FINGERPRINT') }}"
privateKey: "{{ secret('OCI_PRIVATE_KEY') }}"
volumeId: "{{ secret('OCI_VOLUME_OCID') }}"
targetLifecycleState: AVAILABLE
interval: PT3M
tasks:
- id: notify
type: io.kestra.plugin.core.log.Log
message: "Volume {{ trigger.volumeId }} is now AVAILABLE"
```
## Acceptance Criteria
- [ ] `CreateVolume`, `DeleteVolume`, `GetVolume`, `ListVolumes`, `AttachVolume`, `DetachVolume`, `CreateVolumeBackup`, `DeleteVolumeBackup` tasks implemented
- [ ] `VolumeLifecycleTrigger` 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 in the plugin-oci repository by reviewing the existing Compute sub-plugin and the plugin-aws EBS tasks, then inspect build.gradle and package-info.java. Implement the eight block-storage tasks and VolumeLifecycleTrigger described in the issue, with expression-capable Property fields. Run ./gradlew test and ./gradlew build; done means the acceptance checklist passes, including unit and integration tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- cloud, infrastructure
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100