Huawei Cloud Cci

Huawei Cloud Cci

Certified
Enterprise Edition

Task runner that executes a task inside a Pod on Huawei Cloud CCI (Cloud Container Instance).

This plugin is only available in the Enterprise Edition (EE).

CCI is Huawei Cloud's serverless container service — the closest equivalent to AWS Batch/ECS on Huawei Cloud. This runner targets CCI 2.0, which exposes a Kubernetes-shaped API (/apis/cci/v2/namespaces/{namespace}/pods) but has no Job controller: Kestra creates a bare Pod with restartPolicy: Never and owns its entire lifecycle.

Make sure to set the containerImage property because this runner runs the task in a container.

Prerequisites: a CCI namespace must already exist and be bound to a VPC Network — this runner does not create or manage namespaces, VPCs, or networking. If the namespace is missing or not yet bound to a Network, Pod creation fails with an actionable error.

Authentication: set accessKeyId and secretAccessKey — the same credentials every other Huawei Cloud plugin takes. Requests to CCI are signed with AK/SK (SDK-HMAC-SHA256), which is computed locally and adds no IAM round-trip, and the same pair covers OBS file staging (inputFiles, outputFiles, namespaceFiles). temporaryCredentials works too, exchanging credentials via IAM STS once per execution.

A pre-obtained project-scoped IAM token can be supplied via securityToken instead, sent as X-Auth-Token. That path is only worth it where AK/SK are unavailable: IAM tokens expire after 24h and cannot be renewed, so a scheduled flow configured with one stops working the next day.

To access the task's working directory, use the {{ workingDir }} Pebble expression or the WORKING_DIR environment variable. This directory will contain all input files and namespace files (if enabled).

To generate output files you can either use the outputFiles task property and create a file with the same name in the task's working directory, or create any file in the output directory which can be accessed using the {{ outputDir }} Pebble expression or the OUTPUT_DIR environment variable.

To use inputFiles, outputFiles or namespaceFiles properties, make sure to set the bucket property. Input files are uploaded to OBS before the Pod starts and pulled into the Pod by an input-files init container; output files are pushed back to OBS by an output-files sidecar container once the main container finishes, then downloaded to internal storage. The sidecar containers use amazon/aws-cli against OBS's S3-compatible API endpoint (configurable via obsSyncImage) — override it if your environment restricts pulling that public image. The OBS accessKeyId/secretAccessKey are passed to these containers via a Kubernetes Secret (created alongside the Pod and referenced with secretKeyRef), not as plaintext Pod env values, and are removed together with the Pod when delete is true.

The task runner will generate a folder in the configured bucket for each task run. You can access that folder using the {{bucketPath}} Pebble expression or the BUCKET_PATH environment variable.

Note that when the Kestra Worker running this task is terminated, the Pod will still run until completion; after restarting, the Worker will resume polling the existing Pod unless resume is set to false.

This task runner will return with an exit code according to the following mapping:

  • Succeeded: 0
  • Failed: 1
  • Running: 2
  • Pending: 4
  • Unknown / other: -1

To avoid zombie Pods, set the timeout property on the task, and Kestra will delete the Pod if the task is not completed within the specified duration.

Resource sizing: CCI schedules Pods against a fixed set of flavor tiers. resources.request must use one of the supported vCPU values (0.25, 0.5, 1, 2, 4, 8, 16, 32, 48, 64) with memory between 1x and 8x that value in GiB; CCI may still round the effective flavor up and enforce additional constraints server-side.

Log streaming cap: streamed pod logs are capped at 10 MiB per pod; beyond that, this runner stops streaming further log lines (a one-time warning is logged) but the task keeps running to completion — the full log remains retrievable directly from CCI.

yaml
type: io.kestra.plugin.ee.huawei.runner.Cci

Execute a Shell command in a container on Huawei Cloud CCI.

yaml
id: run_container
namespace: company.team

variables:
  region: eu-west-101
  cci_namespace: kestra

tasks:
  - id: shell
    type: io.kestra.plugin.scripts.shell.Commands
    containerImage: alpine
    taskRunner:
      type: io.kestra.plugin.ee.huawei.runner.Cci
      region: "{{ vars.region }}"
      endpointSuffix: myhuaweicloud.eu # EU sovereign cloud; omit for myhuaweicloud.com
      namespace: "{{ vars.cci_namespace }}"
      accessKeyId: "{{ secret('HUAWEI_ACCESS_KEY_ID') }}"
      secretAccessKey: "{{ secret('HUAWEI_SECRET_ACCESS_KEY') }}"
    commands:
      - echo "Hello World"

Pass input files to the task, execute a Shell command, then retrieve the output files.

yaml
id: container_with_input_files
namespace: company.team

inputs:
  - id: file
    type: FILE

variables:
  region: eu-west-101
  cci_namespace: kestra

tasks:
  - id: shell
    type: io.kestra.plugin.scripts.shell.Commands
    inputFiles:
      data.txt: "{{ inputs.file }}"
    outputFiles:
      - out.txt
    # CCI pulls every image through the in-region SWR mirror, whose anonymous Docker Hub
    # passthrough is rejected (401), so mirror both images into your own SWR organization.
    containerImage: swr.eu-west-101.myhuaweicloud.eu/my-org/alpine:3.20
    taskRunner:
      type: io.kestra.plugin.ee.huawei.runner.Cci
      region: "{{ vars.region }}"
      endpointSuffix: myhuaweicloud.eu # EU sovereign cloud; omit for myhuaweicloud.com
      namespace: "{{ vars.cci_namespace }}"
      accessKeyId: "{{ secret('HUAWEI_ACCESS_KEY_ID') }}"
      secretAccessKey: "{{ secret('HUAWEI_SECRET_ACCESS_KEY') }}"
      bucket: kestra-cci-staging
      imagePullSecret: imagepull-secret # applies to the file-sync containers too
      obsSyncImage: swr.eu-west-101.myhuaweicloud.eu/my-org/aws-cli:latest
    commands:
      - cp {{ workingDir }}/data.txt {{ workingDir }}/out.txt
Properties

CCI namespace in which to run the Pod.

Must already exist and be bound to a VPC Network; this runner does not create or manage namespaces.

Huawei Cloud region.

Region identifier such as eu-west-101, ap-southeast-1, or cn-north-4. Used to derive both the CCI and OBS endpoints.

Access Key (AK) used to authenticate with Huawei Cloud.

Paired with secretAccessKey, this is the recommended way to authenticate: requests to both CCI and OBS are signed with AK/SK (SDK-HMAC-SHA256), exactly as in every other Huawei Cloud plugin. Unlike securityToken, AK/SK do not expire, so scheduled flows keep working. Sensitive — always provide via {{ secret('NAME') }}.

OBS bucket used to upload (inputFiles and namespaceFiles) and download (outputFiles) files.

Mandatory if you want to use such properties. Requires accessKeyId/secretAccessKey (OBS uses AK/SK signing, not the CCI IAM token).

DefaultPT5S

Determines how often Kestra should poll the Pod for completion.

Must be a positive duration. Defaults to every 5 seconds. Lower it for quick jobs, raise it for long-running ones to reduce API calls.

Defaulttrue

Whether the Pod should be deleted upon completion.

Warning: if the Pod is not deleted, a retry of the task could resume the old attempt's Pod.

Huawei Cloud Account Domain ID.

Required only when using temporaryCredentials with domain-scoped token scope.

Override the CCI service endpoint URL.

Replaces the region-derived endpoint (e.g. https://cci.eu-west-101.myhuaweicloud.com). Intended for testing against a local WireMock server, or for sovereign-cloud hosts not covered by endpointSuffix.

Defaultmyhuaweicloud.com

Huawei Cloud domain suffix used to derive the CCI (and OBS) endpoint.

Defaults to myhuaweicloud.com. Set to myhuaweicloud.eu for the EU sovereign cloud. Ignored when endpointOverride is set.

Image pull secret for private container registries (e.g. SWR).

Name of an existing kubernetes.io/dockerconfigjson secret in namespace.

Defaultamazon/aws-cli

Container image used by the inputFiles/outputFiles OBS sync containers.

Defaults to amazon/aws-cli, pointed at OBS's S3-compatible API endpoint. Override if your environment cannot pull that public image or you prefer a different OBS-capable CLI image.

Reference (ref) of the pluginDefaults to apply to this task runner.

Huawei Cloud Project ID.

Identifies the region-scoped project. Required for OBS file staging; optional for the CCI API itself, whose paths are namespace-scoped rather than project-scoped.

Default{ "request": { "cpu": "0.5", "memory": "1Gi" } }

Requested (and limit) resources for the main container.

vCPU must be one of CCI's supported flavor tiers (0.25, 0.5, 1, 2, 4, 8, 16, 32, 48, 64); memory must be a Kubernetes quantity (e.g. 1Gi, 512Mi) between 1x and 8x the vCPU value in GiB. Requests and limits are always set equal (a safe default; CCI 2.0 also permits requests ≤ limits).

Definitions
request*Required

Requested (and limit) CPU/memory for the container.

cpu*Requiredstring

CPU quantity.

For resources.request, must be one of CCI's supported vCPU tiers (e.g. 0.5, 1, 2). Not constrained for sidecarResources.

memory*Requiredstring

Memory quantity.

A Kubernetes quantity such as 1Gi or 512Mi.

Defaulttrue

Whether to reconnect to the current Pod if it already exists.

Secret Key (SK) used to authenticate with Huawei Cloud.

Huawei Cloud secret key paired with accessKeyId. Required whenever accessKeyId is set, and for OBS file staging (inputFiles/outputFiles/namespaceFiles). Sensitive — always provide via {{ secret('NAME') }}.

Session token, or a pre-obtained IAM project-scoped token.

Interpreted according to what else is configured:

  • with accessKeyId/secretAccessKey — treated as an STS session token and folded into the AK/SK signature, the same meaning it has in the other Huawei Cloud plugins. Leave it unset when using permanent AK/SK.
  • on its own — treated as an IAM project-scoped token and sent as X-Auth-Token. Obtain one via POST /v3/auth/tokens. Note that IAM tokens expire after 24h and cannot be renewed, so this suits ad-hoc runs rather than scheduled flows; prefer AK/SK for those.

Sensitive.

Resources for the input-files/output-files sync containers.

If not set, defaults to 0.25 vCPU / 0.5Gi memory. Unlike resources.request, these are not required to match a CCI flavor tier — they are summed with the main container's request when CCI resolves the Pod's overall flavor.

Definitions
request*Required

Requested (and limit) CPU/memory for the container.

cpu*Requiredstring

CPU quantity.

For resources.request, must be one of CCI's supported vCPU tiers (e.g. 0.5, 1, 2). Not constrained for sidecarResources.

memory*Requiredstring

Memory quantity.

A Kubernetes quantity such as 1Gi or 512Mi.

Defaultfalse

Whether to download the whole task working directory back to Kestra's internal storage once the Pod completes.

Defaults to false. Enable this when the task writes files anywhere under the working directory rather than only to outputFiles or {{ outputDir }}. Requires an OBS bucket.

Inline IAM credential exchange.

When set, the connection layer calls the Huawei IAM STS API once per task execution and uses the returned session token/credentials instead of the static accessKeyId/secretAccessKey/ securityToken properties. The exchange runs once at invocation start; for long-running Pods that outlive durationSeconds, the token may expire mid-run — set a long-lived securityToken for those cases instead.

Definitions
authMethodstring
DefaultPASSWORD
Possible Values
PASSWORDTOKEN

Authentication method

Controls which credentials are used to obtain the session token before exchanging for temporary STS credentials.

  • PASSWORD (default): provide username, password, and domainName.
  • TOKEN: provide an existing iamToken (X-Auth-Token).
domainNamestring

Account domain name (PASSWORD method only)

The Huawei Cloud account name (domain name) that owns the IAM user. Required when authMethod is PASSWORD. Visible in the Huawei Cloud console under My Credentials → Domain Name.

durationSecondsintegerstring
Default900

Lifetime of the temporary credentials in seconds

How long the returned temporary AK/SK/security-token should remain valid. Huawei Cloud accepts values between 900 (15 minutes) and 86400 (24 hours). Defaults to 900 seconds.

endpointSuffixstring
Defaultmyhuaweicloud.com

Huawei Cloud IAM endpoint suffix

Domain suffix used to build the IAM endpoint URL when no explicit endpoint override is set. Defaults to myhuaweicloud.com. Set to myhuaweicloud.eu for the European sovereign cloud (region eu-west-101 / EU-Dublin).

iamTokenstring

IAM token to exchange (TOKEN method only)

An existing Huawei Cloud X-Auth-Token to exchange for temporary STS credentials. Required when authMethod is TOKEN. Sensitive — always provide via {{ secret('NAME') }}.

passwordstring

IAM password (PASSWORD method only)

Password for the IAM user identified by username. Required when authMethod is PASSWORD. Sensitive — always provide via {{ secret('NAME') }}.

projectNamestring

Project name for project-scoped tokens (PASSWORD method only)

Overrides the project name used for scope=PROJECT token requests. Defaults to the task's region value when omitted, which is correct for most regions.

scopestring
DefaultPROJECT
Possible Values
PROJECTDOMAIN

Token scope (PASSWORD method only)

Scope of the session token obtained during password authentication.

  • PROJECT (default): token is scoped to the project matching projectName (or the task's region when projectName is omitted). Use for most downstream tasks.
  • DOMAIN: token is scoped to the domain.
usernamestring

IAM username (PASSWORD method only)

Huawei Cloud IAM username. Required when authMethod is PASSWORD.

Plugin Version

Defines the version of the plugin to use.

The version must follow the Semantic Versioning (SemVer) specification:

  • A single-digit MAJOR version (e.g., 1).
  • A MAJOR.MINOR version (e.g., 1.1).
  • A MAJOR.MINOR.PATCH version, optionally with any qualifier (e.g., 1.1.2, 1.1.0-SNAPSHOT).
DefaultPT1H

The maximum duration to wait for Pod completion unless the task timeout property is set, which takes precedence over this property.

Must be a positive duration. The Pod is deleted upon reaching this duration and the task is marked as failed. Defaults to 1 hour.

Default10240

Maximum storage in MiB for the task's working directory emptyDir volume.

Raise it for tasks that sync large input or output files. Must be at least 1 MiB. Defaults to 10240 MiB (10 GiB).