SKILL DETAIL
huawei-cloud-cci-instance-management
huaweicloud/huaweicloud-skills/huawei-cloud-cci-instance-management
This skill provides full lifecycle management of Huawei Cloud CCI (Cloud Container Instance) using the hcloud CLI (KooCLI). CCI is a serverless container service that eliminates cluster management; you simply create a Namespace, define a Network, and deploy workloads directly. The skill covers creation, update, deletion, and status querying of Namespaces, Networks, Deployments, StatefulSets, and Pods, as well as EIPPool for public IP management, logs, and metrics. The skill enforces a two-step confirmation mechanism for all destructive operations (e.g., deleting namespaces, networks, workloads) to ensure safety. It also adheres to CCI resource constraints, such as mandatory namespace flavor annotations, resources limits equal to requests, and network creation before workloads. When using hcloud CLI, note that network creation requires a Python helper script, and all command parameters should be verified via `--help`.
Installation
npx skills add https://github.com/huaweicloud/huaweicloud-skills --skill huawei-cloud-cci-instance-management
스킬 파일
SKILL.md
최근 동기화 · 2026. 8. 29.
references/acceptance-criteria.md›
# Acceptance Criteria: Correct vs Error Patterns for CCI Operations
## Namespace Creation
| Correct Pattern | Error Pattern |
|---|---|
| `--metadata.annotations.namespace-kubernetes-io/flavor=general-computing` included | Missing flavor annotation — creation request rejected |
| `--metadata.name=my-namespace` specified | Missing metadata.name — parameter error |
## Network Creation
| Correct Pattern | Error Pattern |
|---|---|
| Valid subnet ID and VPC ID from `hcloud VPC ListSubnets` | Invalid or non-existent subnet/VPC ID — creation fails |
| `--namespace=<ns-name>` specified | Missing namespace — operation targets wrong context |
| CIDR != `10.247.0.0/16` (e.g., `10.0.0.0/24`) | CIDR overlaps `10.247.0.0/16` — reserved for CCI internal routing |
## Deployment Creation
| Correct Pattern | Error Pattern |
|---|---|
| `spec.selector.matchLabels` matches `spec.template.metadata.labels` | Selector mismatch — pods not managed by Deployment |
| `spec.template.spec.containers.1.resources.limits.cpu` and `memory` specified | Missing resource limits — pod may fail scheduling or exceed quota |
| **limits == requests** (e.g., both `500m/1Gi`) | limits != requests — CCI rejects with "limit and request doesn't equal" error |
| `--namespace=<ns-name>` specified | Missing namespace — Deployment created in wrong/default namespace |
## Pod Creation
| Correct Pattern | Error Pattern |
|---|---|
| `spec.containers.1.resources.limits.cpu` and `memory` specified | Bare pod without resources — may fail scheduling |
| `--namespace=<ns-name>` specified | Missing namespace — Pod created in wrong context |
## EIPPool Creation
| Correct Pattern | Error Pattern |
|---|---|
| `--apiVersion=crd.yangtse.cni/v1` and `--kind=EIPPool` included | Missing apiVersion or kind — 400 error "Object 'Kind' is missing" |
| `--spec.eipAttributes.networkType=5_bgp` specified | Missing networkType — 422 validation error |
| `--spec.eipAttributes.bandwidth.chargeMode=bandwidth` and `name=<bw-name>` specified | Missing chargeMode or name — 403 validation error |
| `--namespace=<ns-name>` specified | Missing namespace — EIPPool created in wrong context |
## Parameter Format Patterns
| Correct Pattern | Error Pattern | Explanation |
|---|---|---|
| `--spec.template.spec.containers.1.image=nginx` | `--spec.template.spec.containers={"image":"nginx"}` | hcloud CLI uses dotted path with `{*}` indexing, not JSON objects |
| `--spec.template.spec.containers.1.image=nginx` (1-based index) | `--spec.template.spec.containers.0.image=nginx` (0-based index) | hcloud CLI uses 1-based indexing for arrays |
| `--metadata.name=my-ns` | `--metadata.name my-ns` (space separation) | hcloud CLI requires `=` between key and value |
| `--cli-region=cn-north-4` | `--region=cn-north-4` | CLI region flag is `--cli-region`, not `--region` |
| `--spec.template.spec.containers.1.resources.limits.cpu=500m` | `--spec.containers.1.resources.limits.cpu=500m` (shallow path) | Must use full deep nested path as shown in `--help` output |
| `--metadata.annotations.namespace-kubernetes-io/flavor=general-computing` | `--metadata.annotations.flavor=general-computing` (abbreviated key) | Annotation keys must be the exact full key name, not abbreviated |references/cci-operation-catalog.md›
# CCI Operation Catalog
Complete quick reference of all `hcloud CCI` operations organized by category.
## Namespace (Core)
| Operation | Description |
|---|---|
| `createCoreV1Namespace` | Create namespace |
| `listCoreV1Namespace` | List namespaces |
| `readCoreV1Namespace` | Read namespace details |
| `deleteCoreV1Namespace` | Delete namespace |
## Network (CCI-specific CRD)
| Operation | Description |
|---|---|
| `createNetworkingCciIoV1beta1NamespacedNetwork` | Create Network |
| `listNetworkingCciIoV1beta1NamespacedNetwork` | List Networks |
| `readNetworkingCciIoV1beta1NamespacedNetwork` | Read Network |
| `readNetworkingCciIoV1beta1NamespacedNetworkStatus` | Read Network status |
| `deleteNetworkingCciIoV1beta1NamespacedNetwork` | Delete Network |
| `deleteNetworkingCciIoV1beta1CollectionNamespacedNetwork` | Delete all Networks in namespace |
## Deployment (Apps)
| Operation | Description |
|---|---|
| `createAppsV1NamespacedDeployment` | Create Deployment |
| `listAppsV1NamespacedDeployment` | List Deployments in namespace |
| `listAppsV1DeploymentForAllNamespaces` | List Deployments across namespaces |
| `readAppsV1NamespacedDeployment` | Read Deployment |
| `readAppsV1NamespacedDeploymentStatus` | Read Deployment status |
| `readAppsV1NamespacedDeploymentScale` | Read Deployment scale |
| `patchAppsV1NamespacedDeployment` | Update Deployment (patch) |
| `patchAppsV1NamespacedDeploymentScale` | Scale Deployment |
| `replaceAppsV1NamespacedDeployment` | Replace Deployment |
| `replaceAppsV1NamespacedDeploymentScale` | Replace Deployment scale |
| `deleteAppsV1NamespacedDeployment` | Delete Deployment |
| `deleteAppsV1CollectionNamespacedDeployment` | Delete all Deployments in namespace |
## StatefulSet (Apps)
| Operation | Description |
|---|---|
| `createAppsV1NamespacedStatefulSet` | Create StatefulSet |
| `listAppsV1NamespacedStatefulSet` | List StatefulSets |
| `listAppsV1StatefulSetForAllNamespaces` | List StatefulSets across namespaces |
| `readAppsV1NamespacedStatefulSet` | Read StatefulSet |
| `readAppsV1NamespacedStatefulSetStatus` | Read StatefulSet status |
| `patchAppsV1NamespacedStatefulSet` | Update StatefulSet |
| `replaceAppsV1NamespacedStatefulSet` | Replace StatefulSet |
| `deleteAppsV1NamespacedStatefulSet` | Delete StatefulSet |
| `deleteAppsV1CollectionNamespacedStatefulSet` | Delete all StatefulSets in namespace |
## Pod (Core)
| Operation | Description |
|---|---|
| `createCoreV1NamespacedPod` | Create Pod |
| `listCoreV1NamespacedPod` | List Pods in namespace |
| `listCoreV1PodForAllNamespaces` | List Pods across namespaces |
| `readCoreV1NamespacedPod` | Read Pod details |
| `readCoreV1NamespacedPodStatus` | Read Pod status |
| `readCoreV1NamespacedPodLog` | Read Pod logs |
| `patchCoreV1NamespacedPod` | Update Pod |
| `replaceCoreV1NamespacedPod` | Replace Pod |
| `deleteCoreV1NamespacedPod` | Delete Pod |
| `deleteCoreV1CollectionNamespacedPod` | Delete all Pods in namespace |
| `connectCoreV1GetNamespacedPodExec` | Exec into Pod (GET) |
| `connectCoreV1PostNamespacedPodExec` | Exec into Pod (POST) |
## EIPPool (CCI-specific CRD)
| Operation | Description |
|---|---|
| `createCrdYangtseCniV1NamespacedEIPPool` | Create EIPPool |
| `listCrdYangtseCniV1NamespacedEIPPool` | List EIPPools |
| `readCrdYangtseCniV1NamespacedEIPPool` | Read EIPPool |
| `readCrdYangtseCniV1NamespacedEIPPoolStatus` | Read EIPPool status |
| `patchCrdYangtseCniV1NamespacedEIPPool` | Update EIPPool |
| `replaceCrdYangtseCniV1NamespacedEIPPool` | Replace EIPPool |
| `deleteCrdYangtseCniV1NamespacedEIPPool` | Delete EIPPool |
## Service (Core)
| Operation | Description |
|---|---|
| `createCoreV1NamespacedService` | Create Service |
| `listCoreV1NamespacedService` | List Services |
| `readCoreV1NamespacedService` | Read Service |
| `readCoreV1NamespacedServiceStatus` | Read Service status |
| `patchCoreV1NamespacedService` | Update Service |
| `replaceCoreV1NamespacedService` | Replace Service |
| `deleteCoreV1NamespacedService` | Delete Service |
## Ingress (Extensions)
| Operation | Description |
|---|---|
| `createExtensionsV1beta1NamespacedIngress` | Create Ingress |
| `listExtensionsV1beta1NamespacedIngress` | List Ingresses |
| `readExtensionsV1beta1NamespacedIngress` | Read Ingress |
| `readExtensionsV1beta1NamespacedIngressStatus` | Read Ingress status |
| `patchExtensionsV1beta1NamespacedIngress` | Update Ingress |
| `replaceExtensionsV1beta1NamespacedIngress` | Replace Ingress |
| `deleteExtensionsV1beta1NamespacedIngress` | Delete Ingress |
| `deleteExtensionsV1beta1CollectionNamespacedIngress` | Delete all Ingresses |
## ConfigMap
| Operation | Description |
|---|---|
| `createCoreV1NamespacedConfigMap` | Create ConfigMap |
| `listCoreV1NamespacedConfigMap` | List ConfigMaps |
| `readCoreV1NamespacedConfigMap` | Read ConfigMap |
| `patchCoreV1NamespacedConfigMap` | Update ConfigMap |
| `replaceCoreV1NamespacedConfigMap` | Replace ConfigMap |
| `deleteCoreV1NamespacedConfigMap` | Delete ConfigMap |
| `deleteCoreV1CollectionNamespacedConfigMap` | Delete all ConfigMaps |
## Secret
| Operation | Description |
|---|---|
| `createCoreV1NamespacedSecret` | Create Secret |
| `listCoreV1NamespacedSecret` | List Secrets |
| `readCoreV1NamespacedSecret` | Read Secret |
| `patchCoreV1NamespacedSecret` | Update Secret |
| `replaceCoreV1NamespacedSecret` | Replace Secret |
| `deleteCoreV1NamespacedSecret` | Delete Secret |
| `deleteCoreV1CollectionNamespacedSecret` | Delete all Secrets |
## PersistentVolumeClaim
| Operation | Description |
|---|---|
| `createCoreV1NamespacedPersistentVolumeClaim` | Create PVC |
| `listCoreV1NamespacedPersistentVolumeClaim` | List PVCs |
| `readCoreV1NamespacedPersistentVolumeClaim` | Read PVC |
| `replaceCoreV1NamespacedPersistentVolumeClaim` | Replace PVC |
| `deleteCoreV1NamespacedPersistentVolumeClaim` | Delete PVC |
## Job (Batch v1)
| Operation | Description |
|---|---|
| `createBatchV1NamespacedJob` | Create Job |
| `listBatchV1NamespacedJob` | List Jobs |
| `readBatchV1NamespacedJob` | Read Job |
| `readBatchV1NamespacedJobStatus` | Read Job status |
| `patchBatchV1NamespacedJob` | Update Job |
| `replaceBatchV1NamespacedJob` | Replace Job |
| `deleteBatchV1NamespacedJob` | Delete Job |
| `deleteBatchV1CollectionNamespacedJob` | Delete all Jobs |
## Job (Volcano)
| Operation | Description |
|---|---|
| `createBatchVolcanoShV1alpha1NamespacedJob` | Create Volcano Job |
| `listBatchVolcanoShV1alpha1NamespacedJob` | List Volcano Jobs |
| `readBatchVolcanoShV1alpha1NamespacedJob` | Read Volcano Job |
| `patchBatchVolcanoShV1alpha1NamespacedJob` | Update Volcano Job |
| `replaceBatchVolcanoShV1alpha1NamespacedJob` | Replace Volcano Job |
| `deleteBatchVolcanoShV1alpha1NamespacedJob` | Delete Volcano Job |
| `deleteBatchVolcanoShV1alpha1CollectionNamespacedJob` | Delete all Volcano Jobs |
## RBAC
| Operation | Description |
|---|---|
| `createRbacAuthorizationV1NamespacedRoleBinding` | Create RoleBinding |
| `listRbacAuthorizationV1NamespacedRoleBinding` | List RoleBindings |
| `listRbacAuthorizationV1RoleBindingForAllNamespaces` | List RoleBindings across namespaces |
| `readRbacAuthorizationV1NamespacedRoleBinding` | Read RoleBinding |
| `listRbacAuthorizationV1ClusterRole` | List ClusterRoles |
| `readRbacAuthorizationV1ClusterRole` | Read ClusterRole |
| `patchRbacAuthorizationV1NamespacedRoleBinding` | Update RoleBinding |
| `replaceRbacAuthorizationV1NamespacedRoleBinding` | Replace RoleBinding |
| `deleteRbacAuthorizationV1NamespacedRoleBinding` | Delete RoleBinding |
## Events / ResourceQuota / Metrics
| Operation | Description |
|---|---|
| `listCoreV1NamespacedEvent` | List Events |
| `readCoreV1NamespacedEvent` | Read Event |
| `listCoreV1NamespacedResourceQuota` | List ResourceQuotas |
| `listMetricsV1beta1NamespacedPodMetrics` | List Pod metrics |
| `readMetricsV1beta1NamespacedPodMetrics` | Read Pod metrics |
## StorageClass
| Operation | Description |
|---|---|
| `listStorageV1StorageClass` | List StorageClasses |
| `readStorageV1StorageClass` | Read StorageClass |
## ReplicaSet
| Operation | Description |
|---|---|
| `listAppsV1NamespacedReplicaSet` | List ReplicaSets |
| `readAppsV1NamespacedReplicaSet` | Read ReplicaSet |
## Endpoints
| Operation | Description |
|---|---|
| `createCoreV1NamespacedEndpoints` | Create Endpoints |
| `listCoreV1NamespacedEndpoints` | List Endpoints |
| `readCoreV1NamespacedEndpoints` | Read Endpoints |
| `patchCoreV1NamespacedEndpoints` | Update Endpoints |
| `replaceCoreV1NamespacedEndpoints` | Replace Endpoints |
| `deleteCoreV1NamespacedEndpoints` | Delete Endpoints |
## API Discovery
| Operation | Description |
|---|---|
| `GetOpenAPIv2` | Get OpenAPI v2 schema |
| `getAPIVersions` | Get API versions |
| `getCoreAPIVersions` | Get core API versions |
| `getCoreV1APIResources` | Get core v1 API resources |
| `getAppsAPIGroup` | Get apps API group |
| `getAppsV1APIResources` | Get apps v1 API resources |
| `getBatchAPIGroup` | Get batch API group |
| `getBatchV1APIResources` | Get batch v1 API resources |
| `getBatchV1beta1APIResources` | Get batch v1beta1 API resources |
| `getBatchVolcanoShAPIGroup` | Get Volcano API group |
| `getBatchVolcanoShV1alpha1APIResources` | Get Volcano v1alpha1 API resources |
| `getCrdYangtseCniAPIGroup` | Get Yangtse CNI CRD API group |
| `getCrdYangtseCniV1APIResources` | Get Yangtse CNI v1 API resources |
| `getExtensionsAPIGroup` | Get extensions API group |
| `getExtensionsV1beta1APIResources` | Get extensions v1beta1 API resources |
| `getMetricsAPIGroup` | Get metrics API group |
| `getMetricsV1beta1APIResources` | Get metrics v1beta1 API resources |
| `getNetworkingCciIoAPIGroup` | Get networking CCI API group |
| `getNetworkingCciIoV1beta1APIResources` | Get networking v1beta1 API resources |
| `getRbacAuthorizationAPIGroup` | Get RBAC API group |
| `getRbacAuthorizationV1APIResources` | Get RBAC v1 API resources |
---
All operations use the format:
```
hcloud CCI <Operation> --param=value --cli-region=<region> --cli-output=json
```
Namespaced operations require `--namespace=<ns-name>`.references/common-workflows.md›
# CCI Common Workflows
Complete end-to-end workflow sequences with actual `hcloud` commands. Default region: `cn-north-4`.
## Critical Notes
- **Network creation requires a Python helper script**: The annotation key `network.alpha.kubernetes.io/default-security-group` contains dots that `hcloud` CLI cannot pass as parameter names. Use `cci_network_helper.py` from the `scripts/` directory for Network creation.
- **Namespace creation**: Use hyphens instead of dots in annotation keys, e.g. `--metadata.annotations.namespace-kubernetes-io/flavor=general-computing` (CCI auto-normalizes hyphenated keys back to canonical dotted form for Namespace resources).
- **Deployment/Pod/StatefulSet**: CCI requires **limits == requests** for container resources. If limits != requests, creation fails with "limit and request doesn't equal" error. Always set requests to the same values as limits.
- **EIPPool creation**: Requires `--apiVersion=crd.yangtse.cni/v1` and `--kind=EIPPool` (mandatory). Also requires `--spec.eipAttributes.networkType` and all bandwidth fields (`shareType`, `size`, `chargeMode`, `name`).
- **Annotation keys containing dots**: Keys like `yangtse.io/eippool` must use hyphen replacement (`yangtse-io/eippool`) when passed via hcloud CLI.
---
## Workflow 1: Create and Run a Deployment
### Step 1: Create Namespace
```bash
hcloud CCI createCoreV1Namespace \
--metadata.name=my-ns \
--metadata.annotations.namespace-kubernetes-io/flavor=general-computing \
--cli-region=cn-north-4
```
### Step 2: Create Network (requires VPC/subnet — use Python helper)
The Network spec requires these fields: `attachedVPC`, `subnetID`, `networkType`, and **`networkID`** (the neutron network ID of the VPC subnet). Because annotation keys with dots cannot be passed via hcloud CLI, use the helper script.
**Step 2a: Get VPC subnet details (including neutron_network_id)**
```bash
hcloud VPC ShowSubnet \
--vpc_id=vpc-def456 \
--subnet_id=subnet-abc123 \
--cli-region=cn-north-4 \
--cli-output=json
```
Extract `neutron_network_id` from the response.
**Step 2b: Create Network via Python helper script**
```bash
python scripts/cci_network_helper.py create \
--namespace=my-ns \
--name=my-network \
--vpc-id=vpc-def456 \
--subnet-id=subnet-abc123 \
--network-id=<neutron-network-id> \
--security-group-id=<sg-id> \
--region=cn-north-4
```
**Step 2c: Check Network status until Active**
```bash
hcloud CCI readNetworkingCciIoV1beta1NamespacedNetworkStatus \
--name=my-network \
--namespace=my-ns \
--cli-region=cn-north-4 \
--cli-output=json
```
Repeat until `status.phase` is `Active`.
### Step 3: Create Deployment
```bash
hcloud CCI createAppsV1NamespacedDeployment \
--namespace=my-ns \
--metadata.name=my-deploy \
--metadata.annotations.network-alpha-kubernetes-io/default-network=my-network \
--spec.replicas=2 \
--spec.selector.matchLabels.app=my-deploy \
--spec.template.metadata.labels.app=my-deploy \
--spec.template.spec.containers.1.name=nginx \
--spec.template.spec.containers.1.image=nginx:latest \
--spec.template.spec.containers.1.resources.limits.cpu=500m \
--spec.template.spec.containers.1.resources.limits.memory=1Gi \
--spec.template.spec.containers.1.resources.requests.cpu=500m \
--spec.template.spec.containers.1.resources.requests.memory=1Gi \
--spec.template.spec.containers.1.ports.1.containerPort=80 \
--cli-region=cn-north-4
```
### Step 4: Verify Deployment Status (poll until readyReplicas > 0)
```bash
hcloud CCI readAppsV1NamespacedDeploymentStatus \
--namespace=my-ns \
--name=my-deploy \
--cli-region=cn-north-4 \
--cli-output=json
```
Repeat until `status.readyReplicas` equals `spec.replicas`.
### Step 5: View Pod Logs
```bash
hcloud CCI listCoreV1NamespacedPod \
--namespace=my-ns \
--cli-region=cn-north-4 \
--cli-output=json
```
```bash
hcloud CCI readCoreV1NamespacedPodLog \
--namespace=my-ns \
--name=<pod-name> \
--cli-region=cn-north-4
```
---
## Workflow 2: Create a Pod with Public IP (EIPPool)
### Step 1: Create Namespace
```bash
hcloud CCI createCoreV1Namespace \
--metadata.name=eip-ns \
--metadata.annotations.namespace-kubernetes-io/flavor=general-computing \
--cli-region=cn-north-4
```
### Step 2: Create Network (use Python helper)
**Step 2a: Get VPC subnet details**
```bash
hcloud VPC ShowSubnet \
--vpc_id=vpc-def456 \
--subnet_id=subnet-abc123 \
--cli-region=cn-north-4 \
--cli-output=json
```
**Step 2b: Create Network via Python helper script**
```bash
python scripts/cci_network_helper.py create \
--namespace=eip-ns \
--name=eip-network \
--vpc-id=vpc-def456 \
--subnet-id=subnet-abc123 \
--network-id=<neutron-network-id> \
--security-group-id=<sg-id> \
--region=cn-north-4
```
**Step 2c: Check Network status until Active**
```bash
hcloud CCI readNetworkingCciIoV1beta1NamespacedNetworkStatus \
--name=eip-network \
--namespace=eip-ns \
--cli-region=cn-north-4 \
--cli-output=json
```
Repeat until `status.phase` is `Active`.
### Step 3: Create EIPPool
```bash
hcloud CCI createCrdYangtseCniV1NamespacedEIPPool \
--namespace=eip-ns \
--apiVersion=crd.yangtse.cni/v1 \
--kind=EIPPool \
--metadata.name=my-eippool \
--spec.amount=1 \
--spec.eipAttributes.networkType=5_bgp \
--spec.eipAttributes.ipVersion=4 \
--spec.eipAttributes.bandwidth.shareType=PER \
--spec.eipAttributes.bandwidth.size=5 \
--spec.eipAttributes.bandwidth.chargeMode=bandwidth \
--spec.eipAttributes.bandwidth.name=eip-bw \
--cli-region=cn-north-4
```
### Step 4: Create Pod with EIPPool Annotation
```bash
hcloud CCI createCoreV1NamespacedPod \
--namespace=eip-ns \
--metadata.name=eip-pod \
--metadata.annotations.network-alpha-kubernetes-io/default-network=eip-network \
--metadata.annotations.yangtse-io/eippool=my-eippool \
--spec.containers.1.name=nginx \
--spec.containers.1.image=nginx:latest \
--spec.containers.1.resources.limits.cpu=500m \
--spec.containers.1.resources.limits.memory=1Gi \
--spec.containers.1.ports.1.containerPort=80 \
--cli-region=cn-north-4
```
### Step 5: Verify Pod Status and EIP Allocation
```bash
hcloud CCI readCoreV1NamespacedPodStatus \
--namespace=eip-ns \
--name=eip-pod \
--cli-region=cn-north-4 \
--cli-output=json
```
```bash
hcloud CCI readCrdYangtseCniV1NamespacedEIPPoolStatus \
--namespace=eip-ns \
--name=my-eippool \
--cli-region=cn-north-4 \
--cli-output=json
```
Check `status.eips` for the allocated public IP address.
---
## Workflow 3: Scale a Deployment
### Step 1: Read Current Deployment Scale
```bash
hcloud CCI readAppsV1NamespacedDeploymentScale \
--namespace=my-ns \
--name=my-deploy \
--cli-region=cn-north-4 \
--cli-output=json
```
### Step 2: Patch Scale to New Replica Count
```bash
hcloud CCI patchAppsV1NamespacedDeploymentScale \
--namespace=my-ns \
--name=my-deploy \
--spec.replicas=5 \
--cli-region=cn-north-4
```
### Step 3: Verify New Replicas Are Ready
```bash
hcloud CCI readAppsV1NamespacedDeploymentStatus \
--namespace=my-ns \
--name=my-deploy \
--cli-region=cn-north-4 \
--cli-output=json
```
Repeat until `status.readyReplicas >= 5`.
---
## Workflow 4: Update Deployment Image (Rolling Update)
### Step 1: Read Current Deployment
```bash
hcloud CCI readAppsV1NamespacedDeployment \
--namespace=my-ns \
--name=my-deploy \
--cli-region=cn-north-4 \
--cli-output=json
```
### Step 2: Patch Container Image
```bash
hcloud CCI patchAppsV1NamespacedDeployment \
--namespace=my-ns \
--name=my-deploy \
--spec.template.spec.containers.1.image=nginx:1.25 \
--cli-region=cn-north-4
```
### Step 3: Monitor Rolling Update Status
```bash
hcloud CCI readAppsV1NamespacedDeploymentStatus \
--namespace=my-ns \
--name=my-deploy \
--cli-region=cn-north-4 \
--cli-output=json
```
Monitor until:
- `status.updatedReplicas == spec.replicas`
- `status.readyReplicas == spec.replicas`
- `status.oldReplicas == 0` (if present)
---
## Workflow 5: Full Cleanup (Delete All Resources)
### Step 1: Delete All Deployments/StatefulSets/Pods
```bash
hcloud CCI deleteAppsV1CollectionNamespacedDeployment \
--namespace=my-ns \
--cli-region=cn-north-4
hcloud CCI deleteAppsV1CollectionNamespacedStatefulSet \
--namespace=my-ns \
--cli-region=cn-north-4
hcloud CCI deleteCoreV1CollectionNamespacedPod \
--namespace=my-ns \
--cli-region=cn-north-4
```
### Step 2: Delete All EIPPools
```bash
hcloud CCI listCrdYangtseCniV1NamespacedEIPPool \
--namespace=my-ns \
--cli-region=cn-north-4 \
--cli-output=json
hcloud CCI deleteCrdYangtseCniV1NamespacedEIPPool \
--namespace=my-ns \
--name=<eippool-name> \
--cli-region=cn-north-4
```
### Step 3: Delete Network
Network deletion works via hcloud CLI with two-step confirmation:
```bash
hcloud CCI deleteNetworkingCciIoV1beta1NamespacedNetwork \
--name=my-network \
--namespace=my-ns \
--cli-region=cn-north-4
```
### Step 4: Delete Namespace
```bash
hcloud CCI deleteCoreV1Namespace \
--name=my-ns \
--cli-region=cn-north-4
```
**Important**: Deleting a namespace cascades deletion of ALL resources within it (Deployments, Pods, Networks, EIPPools, etc.). The simplest cleanup approach is to delete the namespace directly:
```bash
hcloud CCI deleteCoreV1Namespace \
--name=my-ns \
--cli-region=cn-north-4
```
This is equivalent to Steps 1-4 combined, but the namespace and all its contents must be fully deleted before the namespace name can be reused.
---
## Workflow 6: Create StatefulSet with PVC
### Step 1: Create Namespace + Network
```bash
hcloud CCI createCoreV1Namespace \
--metadata.name=ss-ns \
--metadata.annotations.namespace-kubernetes-io/flavor=general-computing \
--cli-region=cn-north-4
```
**Create Network via Python helper script**:
```bash
hcloud VPC ShowSubnet \
--vpc_id=vpc-def456 \
--subnet_id=subnet-abc123 \
--cli-region=cn-north-4 \
--cli-output=json
```
Extract `neutron_network_id` from the response.
```bash
python scripts/cci_network_helper.py create \
--namespace=ss-ns \
--name=ss-network \
--vpc-id=vpc-def456 \
--subnet-id=subnet-abc123 \
--network-id=<neutron-network-id> \
--security-group-id=<sg-id> \
--region=cn-north-4
```
Check Network status until Active:
```bash
hcloud CCI readNetworkingCciIoV1beta1NamespacedNetworkStatus \
--name=ss-network \
--namespace=ss-ns \
--cli-region=cn-north-4 \
--cli-output=json
```
### Step 2: Create StatefulSet with volumeClaimTemplates
```bash
hcloud CCI createAppsV1NamespacedStatefulSet \
--namespace=ss-ns \
--metadata.name=my-statefulset \
--metadata.annotations.network-alpha-kubernetes-io/default-network=ss-network \
--spec.replicas=3 \
--spec.selector.matchLabels.app=my-statefulset \
--spec.serviceName=my-statefulset \
--spec.template.metadata.labels.app=my-statefulset \
--spec.template.spec.containers.1.name=mysql \
--spec.template.spec.containers.1.image=mysql:5.7 \
--spec.template.spec.containers.1.resources.limits.cpu=1 \
--spec.template.spec.containers.1.resources.limits.memory=2Gi \
--spec.template.spec.containers.1.resources.requests.cpu=1 \
--spec.template.spec.containers.1.resources.requests.memory=2Gi \
--spec.template.spec.containers.1.ports.1.containerPort=3306 \
--spec.template.spec.containers.1.volumeMounts.1.name=data \
--spec.template.spec.containers.1.volumeMounts.1.mountPath=/var/lib/mysql \
--spec.volumeClaimTemplates.1.metadata.name=data \
--spec.volumeClaimTemplates.1.spec.accessModes.1=ReadWriteOnce \
--spec.volumeClaimTemplates.1.spec.resources.requests.storage=10Gi \
--cli-region=cn-north-4
```
### Step 3: Verify PVC Creation
```bash
hcloud CCI listCoreV1NamespacedPersistentVolumeClaim \
--namespace=ss-ns \
--cli-region=cn-north-4 \
--cli-output=json
```
Each replica creates a PVC named `data-my-statefulset-0`, `data-my-statefulset-1`, `data-my-statefulset-2`.
### Step 4: Read Pod Status
```bash
hcloud CCI readAppsV1NamespacedStatefulSetStatus \
--namespace=ss-ns \
--name=my-statefulset \
--cli-region=cn-north-4 \
--cli-output=json
```
Repeat until `status.readyReplicas >= 3`.references/credential-configuration.md›
# Credential Configuration for hcloud CLI
hcloud CLI (KooCLI) supports two credential modes via environment variables, automatically detected at runtime.
> **Security Rules**:
> - 🚫 Never expose AK/SK/SecurityToken values in conversation, commands, or output
> - 🚫 Never use `echo $HUAWEI_CLOUD_AK` or `echo $HUAWEI_CLOUD_SK` to check credentials
> - ✅ Prefer environment variables or hcloud CLI profile mode
> - ✅ Use `hcloud configure list` to check credential status (presence only, not values)
## Mode A — Long-term AK/SK
Suitable for permanent access, CI/CD pipelines, and long-running automation.
```bash
export HUAWEI_CLOUD_AK=<your-ak>
export HUAWEI_CLOUD_SK=<your-sk>
export HUAWEI_CLOUD_REGION=cn-north-4
```
**Characteristics**:
- Credentials are valid until manually revoked in IAM console
- Recommended for service accounts, CI/CD pipelines, and automation scripts
- Rotate regularly following security best practices
## Mode B — Temporary AK/SK + SecurityToken
Recommended for temporary, delegated, or fine-grained access scenarios.
```bash
export HUAWEI_CLOUD_AK=<your-temp-ak>
export HUAWEI_CLOUD_SK=<your-temp-sk>
export HUAWEI_CLOUD_SECURITY_TOKEN=<your-security-token>
export HUAWEI_CLOUD_REGION=cn-north-4
```
**Characteristics**:
- Credentials expire after a configured duration (typically 15 minutes to 24 hours)
- Obtained via IAM `CreateTemporaryAccessKeyByToken` or `CreateTemporaryAccessKeyByAgency` APIs
- Supports scoped permissions via agency delegation
- When `HUAWEI_CLOUD_SECURITY_TOKEN` is present, hcloud CLI automatically uses temporary credential authentication
- When only AK/SK are set, it uses long-term credential authentication
## Validation
After configuring credentials, verify they work:
```bash
# Check credential presence (shows profile name, NOT credential values)
hcloud configure list
# Verify connectivity with a simple query
hcloud CCI listCoreV1Namespace --cli-region=cn-north-4 --cli-output=json
```
## Important Notes
- Never commit credentials to version control
- Use IAM users with minimal required permissions (least privilege principle)
- Enable MFA for sensitive operations
- Rotate long-term AK/SK regularly
- For temporary credentials, use appropriate expiration duration — too short causes frequent re-authentication, too long increases risk
## Known Limitation — Python Helper Script Uses Independent Credentials
The CCI Network creation helper script (`scripts/cci_network_helper.py`) authenticates via `HW_ACCESS_KEY` / `HW_SECRET_KEY` (and optionally `HW_SECURITY_TOKEN`) environment variables. This is **independent** from hcloud CLI's credential source:
| Component | Credential Source | Scope |
|-----------|-----------------|-------|
| hcloud CLI commands | `HUAWEI_CLOUD_AK`/`HUAWEI_CLOUD_SK`/`HUAWEI_CLOUD_SECURITY_TOKEN` env vars, or hcloud profile | Used for all `hcloud CCI ...` commands |
| Python helper script | `HW_ACCESS_KEY`/`HW_SECRET_KEY`/`HW_SECURITY_TOKEN` env vars | Used only for Network creation via `cci_network_helper.py` |
If the credentials in `HW_ACCESS_KEY`/`HW_SECRET_KEY` lack the necessary IAM permissions for CCI Network creation (e.g., missing `CCI FullAccess`), the script will fail with a 403 Forbidden error. Running the helper script **does not affect** hcloud CLI's credential state — hcloud CLI commands continue using their own credential source afterward.
references/iam-policies.md›
# IAM Permission Policies for CCI Operations
## Minimum Required Permissions
| Permission | Description |
|---|---|
| `cci:namespace:create` | Create namespace |
| `cci:namespace:get` | Read namespace |
| `cci:namespace:list` | List namespaces |
| `cci:namespace:delete` | Delete namespace |
| `cci:network:create` | Create Network |
| `cci:network:get` | Read Network |
| `cci:network:list` | List Networks |
| `cci:network:delete` | Delete Network |
| `cci:pod:create` | Create Pod |
| `cci:pod:get` | Read Pod |
| `cci:pod:list` | List Pods |
| `cci:pod:delete` | Delete Pod |
| `cci:deployment:create` | Create Deployment |
| `cci:deployment:get` | Read Deployment |
| `cci:deployment:list` | List Deployments |
| `cci:deployment:update` | Update/scale Deployment |
| `cci:deployment:delete` | Delete Deployment |
| `cci:statefulset:create` | Create StatefulSet |
| `cci:statefulset:get` | Read StatefulSet |
| `cci:statefulset:list` | List StatefulSets |
| `cci:statefulset:update` | Update StatefulSet |
| `cci:statefulset:delete` | Delete StatefulSet |
| `vpc:vpcs:list` | List VPCs (for Network creation) |
| `vpc:subnets:get` | Read subnet details (for Network creation) |
## Minimum Required Policy JSON
```json
{
"Version": "5.0",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cci:namespace:create",
"cci:namespace:get",
"cci:namespace:list",
"cci:namespace:delete",
"cci:network:create",
"cci:network:get",
"cci:network:list",
"cci:network:delete",
"cci:pod:create",
"cci:pod:get",
"cci:pod:list",
"cci:pod:delete",
"cci:deployment:create",
"cci:deployment:get",
"cci:deployment:list",
"cci:deployment:update",
"cci:deployment:delete",
"cci:statefulset:create",
"cci:statefulset:get",
"cci:statefulset:list",
"cci:statefulset:update",
"cci:statefulset:delete",
"vpc:vpcs:list",
"vpc:subnets:get"
],
"Resource": [
"CCI:*:*:namespace:*",
"CCI:*:*:network:*",
"CCI:*:*:pod:*",
"CCI:*:*:deployment:*",
"CCI:*:*:statefulset:*"
]
}
]
}
```
## System Policies
| System Policy | Applicable Scenario |
|---|---|
| `CCI Administrator` | Full CCI management permissions |
| `CCI Viewer` | Read-only, view all CCI resources |
| `VPC Viewer` | Read-only VPC access (for Network creation) |
## EIPPool Additional Permissions
If using EIPPool, add these permissions to the policy:
| Permission | Description |
|---|---|
| `cci:eippool:create` | Create EIPPool |
| `cci:eippool:get` | Read EIPPool |
| `cci:eippool:list` | List EIPPools |
| `cci:eippool:delete` | Delete EIPPool |
| `vpc:publicIps:list` | List available EIPs |
## Permission Failure Handling Process
When any command fails due to permission errors:
1. Read this iam-policies.md file
2. Show required permission list and policy JSON to user
3. Guide user to create custom policy in IAM console
4. Pause execution and wait for user confirmationreferences/parameter-format.md›
# CCI Parameter Format Rules
CCI uses deeply nested Kubernetes-style objects via the hcloud CLI. Understanding the parameter format is critical.
## 1. Dot Notation for Nested Objects
Nested fields are accessed via dot-separated paths:
```bash
--metadata.name=my-ns
--metadata.annotations.namespace-kubernetes-io/flavor=general-computing
--metadata.labels.app=my-deploy
--spec.template.spec.containers.1.image=nginx:latest
--spec.networkId=subnet-xxx
--spec.routerId=vpc-xxx
```
## 2. `{*}` Format for Maps (Annotations, Labels, Resources)
Maps are expressed as individual key=value entries using dot notation, NOT as JSON objects:
```bash
# Annotations
--metadata.annotations.namespace-kubernetes-io/flavor=general-computing
--metadata.annotations.key1=value1
# Labels
--metadata.labels.app=my-app
--metadata.labels.environment=production
# Resource limits/requests
--spec.template.spec.containers.1.resources.limits.cpu=500m
--spec.template.spec.containers.1.resources.limits.memory=1Gi
--spec.template.spec.containers.1.resources.requests.cpu=250m
--spec.template.spec.containers.1.resources.requests.memory=512Mi
# Selector matchLabels
--spec.selector.matchLabels.app=my-deploy
```
## 3. 1-Based Array Indexing
Arrays use **1-based** indexing (NOT 0-based):
```bash
# First container is .1, second is .2
--spec.template.spec.containers.1.name=main
--spec.template.spec.containers.2.name=sidecar
--spec.template.spec.containers.1.ports.1.containerPort=80
--spec.template.spec.containers.1.ports.2.containerPort=443
--spec.template.spec.volumes.1.name=data-vol
--spec.template.spec.volumes.2.name=config-vol
```
## 4. Resource Quantity Format
| Type | Format | Examples |
|---|---|---|
| CPU | millicores or cores | `500m` (0.5 core), `1` (1 core), `2` (2 cores) |
| Memory | Mi or Gi suffix | `512Mi`, `1Gi`, `2Gi` |
CPU values: `100m` = 0.1 core, `500m` = 0.5 core, `1` = 1 core, `4` = 4 cores.
Memory values: `256Mi`, `512Mi`, `1Gi`, `2Gi`, `4Gi`.
## 5. CCI Annotation Key Limitations
### 5.1 The Dot Parsing Problem
Annotation keys in Kubernetes often contain dots (e.g., `namespace.kubernetes.io/flavor`, `network.alpha.kubernetes.io/default-security-group`). When passed via hcloud CLI dot notation, hcloud treats dots in the **key name** as nested object delimiters, the same as dots in the **field path**.
This means:
```bash
# INTENDED: annotation key = "network.alpha.kubernetes.io/default-security-group"
# ACTUAL: hcloud parses as nested object path:
# metadata.annotations.network.alpha.kubernetes.io.default-security-group
# → {network: {alpha: {kubernetes: {io: {default-security-group: value}}}}}
# This is NOT a valid annotation key-value pair.
--metadata.annotations.network.alpha.kubernetes.io/default-security-group=sg-xxx
```
There is **no escaping mechanism** (quotes, backslashes, etc.) that prevents hcloud from parsing dots as nested delimiters.
### 5.2 Namespace Annotation Workaround (Hyphen Replacement)
For Namespace, the annotation key `namespace.kubernetes.io/flavor` can be passed via hcloud CLI by **replacing dots with hyphens** in the key portion:
```bash
# hcloud CLI parameter (dots replaced with hyphens in the key):
--metadata.annotations.namespace-kubernetes-io/flavor=general-computing
# CCI service auto-adds the canonical dotted version:
# namespace.kubernetes.io/flavor=general-computing
```
This workaround works because the key only contains dots (no additional slashes beyond the single `/` separating domain from name), and CCI recognizes the hyphenated form.
### 5.3 Network Annotation Cannot Use hcloud CLI
The Network resource requires the annotation key `network.alpha.kubernetes.io/default-security-group` (confirmed by official CCI API docs: https://support.huaweicloud.com/api-cci/createNetworkingCciIoV1beta1NamespacedNetwork.html).
This key contains **dots AND a slash**, making it impossible to pass via hcloud CLI:
- Dots are parsed as nested delimiters (no workaround)
- The hyphen replacement trick does not work for Network annotations
- **Use the Python helper script** to create Network resources with this annotation
### 5.4 `--cli-jsonInput` Does Not Solve This
The `--cli-jsonInput` feature allows passing the entire request body as a JSON file. However, it has a critical limitation for CCI:
- Even though `--dryrun` shows annotations correctly in the JSON input, the **actual API request does not include annotations in the request body** when using `--cli-jsonInput`. This is a hcloud bug/limitation.
- `--cli-jsonInput` file encoding must be **ASCII** (UTF-8 with BOM causes parsing failure).
**Do not rely on `--cli-jsonInput` for setting annotations on CCI resources.**
### 5.5 When to Use hcloud CLI vs Python Helper Script
| Resource | Annotation Key | hcloud CLI | Python Script |
|---|---|---|---|
| Namespace | `namespace.kubernetes.io/flavor` | Use hyphen workaround | Optional |
| Network | `network.alpha.kubernetes.io/default-security-group` | **Cannot use** | **Required** |
| Pod / Deployment | Simple keys (no dots) | Works normally | Optional |
| Pod / Deployment | Keys with dots | Cannot pass directly | Required |
### 5.6 Network Required Spec Fields
Network resources require ALL of the following spec fields:
```yaml
spec:
attachedVPC: <vpc-id> # VPC ID
subnetID: <subnet-id> # Subnet ID
networkType: <type> # Network type (e.g., "underlay-neutron")
networkID: <neutron-network-id> # Neutron network ID of the VPC subnet (REQUIRED)
```
The `networkID` field is **REQUIRED** — it is the neutron network ID associated with the VPC subnet, not the same as `subnetID`.
## 6. Common Format Errors
| Wrong | Correct | Issue |
|---|---|---|
| `--metadata.annotations={"namespace.kubernetes.io/flavor":"general-computing"}` | `--metadata.annotations.namespace-kubernetes-io/flavor=general-computing` | Map uses `{*}` dot format, not JSON; use hyphens for Namespace annotation key |
| `--metadata.annotations.network.alpha.kubernetes.io/default-security-group=sg-xxx` | Use Python helper script for Network | Dots in annotation key are parsed as nested delimiters; no hcloud CLI workaround exists |
| `--spec.containers.0.name=main` | `--spec.template.spec.containers.1.name=main` | Array index starts from 1, not 0; also need full path through template.spec |
| `--spec.selector.matchLabels={"app":"my-app"}` | `--spec.selector.matchLabels.app=my-app` | Map uses `{*}` format |
| `--spec.resources.limits={"cpu":"500m"}` | `--spec.template.spec.containers.1.resources.limits.cpu=500m` | Full nested path + `{*}` format |
| `--region=cn-north-4` | `--cli-region=cn-north-4` | Region uses cli prefix |
| `--name my-pod` | `--name=my-pod` | Equals sign required |
## 7. Parameter Path Depth Reference
### Namespace (Shallow)
```
metadata.name
metadata.annotations.*
metadata.labels.*
```
Example:
```bash
hcloud CCI createCoreV1Namespace \
--metadata.name=my-ns \
--metadata.annotations.namespace-kubernetes-io/flavor=general-computing \
--cli-region=cn-north-4
```
### Network (Shallow but Requires Python Script)
```
metadata.name
metadata.annotations.network.alpha.kubernetes.io/default-security-group
spec.attachedVPC
spec.subnetID
spec.networkType
spec.networkID
```
Example (Python helper script — hcloud CLI cannot set this annotation):
```python
# Use the Python helper script for Network creation
# hcloud CLI cannot pass the required annotation key
```
### Pod (Deep)
```
metadata.name
metadata.annotations.*
metadata.labels.*
spec.containers.1.name
spec.containers.1.image
spec.containers.1.resources.limits.*
spec.containers.1.resources.requests.*
spec.containers.1.ports.1.containerPort
spec.volumes.1.*
```
### Deployment (Very Deep)
```
metadata.name
metadata.annotations.*
metadata.labels.*
spec.replicas
spec.selector.matchLabels.*
spec.template.metadata.labels.*
spec.template.spec.containers.1.name
spec.template.spec.containers.1.image
spec.template.spec.containers.1.resources.limits.*
spec.template.spec.containers.1.resources.requests.*
spec.template.spec.containers.1.ports.1.containerPort
spec.template.spec.volumes.1.*
```
Nesting hierarchy (Deployment):
```
spec # Deployment spec
replicas # Number of replicas
selector # Pod selector
matchLabels.* # Label match rules
template # Pod template
metadata # Pod metadata
labels.* # Pod labels
spec # Pod spec
containers.1 # First container (1-based)
name
image
ports.1 # First port (1-based)
containerPort
resources
limits.* # Resource limits map
requests.* # Resource requests map
env.1 # First env var (1-based)
name
value
volumes.1 # First volume (1-based)
name
configMap # Volume source
name
```
## 8. DryRun for Validation
Validate parameters without creating resources:
```bash
hcloud CCI createCoreV1Namespace \
--dryRun=All \
--metadata.name=test-ns \
--metadata.annotations.namespace-kubernetes-io/flavor=general-computing \
--cli-region=cn-north-4
```
```bash
hcloud CCI createAppsV1NamespacedDeployment \
--dryRun=All \
--namespace=test-ns \
--metadata.name=my-deploy \
--spec.replicas=2 \
--spec.selector.matchLabels.app=my-deploy \
--spec.template.metadata.labels.app=my-deploy \
--spec.template.spec.containers.1.name=main \
--spec.template.spec.containers.1.image=nginx:latest \
--spec.template.spec.containers.1.resources.limits.cpu=500m \
--spec.template.spec.containers.1.resources.limits.memory=1Gi \
--cli-region=cn-north-4
```references/task-deployment-management.md›
# Deployment Lifecycle Management
Deployments in CCI are serverless — no node management is needed. CCI automatically provisions compute resources based on container specifications.
## Prerequisites
Before creating a Deployment, the following must already exist:
1. **Namespace** — created via `createCoreV1Namespace`
2. **Network** — created via `createNetworkingCciIoV1beta1NamespacedNetwork` and in `Active` state
## Create Deployment
### Single Container
```bash
hcloud CCI createAppsV1NamespacedDeployment \
--namespace=<ns-name> \
--metadata.name=<deploy-name> \
--spec.replicas=1 \
--spec.selector.matchLabels.app=<deploy-name> \
--spec.template.metadata.labels.app=<deploy-name> \
--spec.template.spec.containers.1.name=<container-name> \
--spec.template.spec.containers.1.image=<image> \
--spec.template.spec.containers.1.resources.limits.cpu=500m \
--spec.template.spec.containers.1.resources.limits.memory=1Gi \
--spec.template.spec.containers.1.resources.requests.cpu=250m \
--spec.template.spec.containers.1.resources.requests.memory=512Mi \
--cli-region=<region> \
--cli-output=json
```
Key constraints:
- `--spec.selector.matchLabels` **MUST match** `--spec.template.metadata.labels` — mismatched labels prevent the Deployment from managing its Pods
- Resource limits and requests are **MANDATORY** for CCI — omitting them causes creation failure
- Array indices are 1-based: `containers.1` is the first container, `containers.2` is the second
### Multi-Container Example
```bash
hcloud CCI createAppsV1NamespacedDeployment \
--namespace=<ns-name> \
--metadata.name=<deploy-name> \
--spec.replicas=1 \
--spec.selector.matchLabels.app=<deploy-name> \
--spec.template.metadata.labels.app=<deploy-name> \
--spec.template.spec.containers.1.name=main \
--spec.template.spec.containers.1.image=nginx \
--spec.template.spec.containers.1.resources.limits.cpu=500m \
--spec.template.spec.containers.1.resources.limits.memory=1Gi \
--spec.template.spec.containers.1.resources.requests.cpu=250m \
--spec.template.spec.containers.1.resources.requests.memory=512Mi \
--spec.template.spec.containers.2.name=sidecar \
--spec.template.spec.containers.2.image=busybox \
--spec.template.spec.containers.2.resources.limits.cpu=100m \
--spec.template.spec.containers.2.resources.limits.memory=256Mi \
--spec.template.spec.containers.2.resources.requests.cpu=50m \
--spec.template.spec.containers.2.resources.requests.memory=128Mi \
--cli-region=<region> \
--cli-output=json
```
### Port Specification Example
```bash
hcloud CCI createAppsV1NamespacedDeployment \
--namespace=<ns-name> \
--metadata.name=<deploy-name> \
--spec.replicas=1 \
--spec.selector.matchLabels.app=<deploy-name> \
--spec.template.metadata.labels.app=<deploy-name> \
--spec.template.spec.containers.1.name=<container-name> \
--spec.template.spec.containers.1.image=<image> \
--spec.template.spec.containers.1.ports.1.containerPort=80 \
--spec.template.spec.containers.1.resources.limits.cpu=500m \
--spec.template.spec.containers.1.resources.limits.memory=1Gi \
--spec.template.spec.containers.1.resources.requests.cpu=250m \
--spec.template.spec.containers.1.resources.requests.memory=512Mi \
--cli-region=<region> \
--cli-output=json
```
## List Deployments
### Within a namespace
```bash
hcloud CCI listAppsV1NamespacedDeployment \
--namespace=<ns-name> \
--cli-region=<region> --cli-output=json
```
### Across all namespaces
```bash
hcloud CCI listAppsV1DeploymentForAllNamespaces \
--cli-region=<region> --cli-output=json
```
## Read Deployment
```bash
hcloud CCI readAppsV1NamespacedDeployment \
--name=<deploy-name> --namespace=<ns-name> \
--cli-region=<region> --cli-output=json
```
## Read Deployment Status
```bash
hcloud CCI readAppsV1NamespacedDeploymentStatus \
--name=<deploy-name> --namespace=<ns-name> \
--cli-region=<region> --cli-output=json
```
Check `readyReplicas` vs `replicas` to determine rollout progress.
## Scale Deployment
```bash
hcloud CCI patchAppsV1NamespacedDeploymentScale \
--name=<deploy-name> --namespace=<ns-name> \
--spec.replicas=<new-count> \
--cli-region=<region>
```
## Update Deployment (Patch)
### Update container image
```bash
hcloud CCI patchAppsV1NamespacedDeployment \
--name=<deploy-name> --namespace=<ns-name> \
--spec.template.spec.containers.1.image=<new-image> \
--cli-region=<region>
```
This triggers a rolling update — Pods are replaced incrementally.
## Delete Deployment
**TWO-STEP CONFIRMATION REQUIRED.**
### Step 1: Warn the user
> **WARNING**: Deleting a Deployment terminates all Pod replicas managed by it. This is irreversible.
### Step 2: Execute (only after explicit user confirmation)
```bash
hcloud CCI deleteAppsV1NamespacedDeployment \
--name=<deploy-name> --namespace=<ns-name> \
--cli-region=<region>
```references/task-eippool-management.md›
# EIPPool Management
EIPPool is a CCI-specific CRD (`crd.yangtse.cni/v1`) for allocating public IPs (EIPs) to Pods automatically.
---
## 1. Create EIPPool
**Option A — Auto-create EIPs (amount-based):**
```bash
hcloud CCI createCrdYangtseCniV1NamespacedEIPPool \
--namespace=<ns-name> \
--apiVersion=crd.yangtse.cni/v1 \
--kind=EIPPool \
--metadata.name=<eippool-name> \
--spec.amount=<number-of-eips> \
--spec.eipAttributes.networkType=5_bgp \
--spec.eipAttributes.ipVersion=4 \
--spec.eipAttributes.bandwidth.shareType=PER \
--spec.eipAttributes.bandwidth.size=5 \
--spec.eipAttributes.bandwidth.chargeMode=bandwidth \
--spec.eipAttributes.bandwidth.name=<bandwidth-name> \
--cli-region=<region> \
--cli-output=json
```
**Option B — Use pre-created EIP IDs:**
```bash
hcloud CCI createCrdYangtseCniV1NamespacedEIPPool \
--namespace=<ns-name> \
--apiVersion=crd.yangtse.cni/v1 \
--kind=EIPPool \
--metadata.name=<eippool-name> \
--spec.eips.1=<eip-id-1> \
--spec.eips.2=<eip-id-2> \
--cli-region=<region> \
--cli-output=json
```
**Required fields for Option A (auto-create):**
| Field | Value | Description |
|-------|-------|-------------|
| `--apiVersion` | `crd.yangtse.cni/v1` | API version (required) |
| `--kind` | `EIPPool` | Resource kind (required) |
| `--spec.amount` | integer | Number of EIPs to create |
| `--spec.eipAttributes.networkType` | `5_bgp` or `5_gray` | EIP network type (required) |
| `--spec.eipAttributes.bandwidth.shareType` | `PER` or `WHOLE` | Bandwidth share type |
| `--spec.eipAttributes.bandwidth.size` | integer | Bandwidth size in Mbit/s |
| `--spec.eipAttributes.bandwidth.chargeMode` | `bandwidth` or `traffic` | Bandwidth billing mode |
| `--spec.eipAttributes.bandwidth.name` | string | Bandwidth name (required for PER share type) |
**Constraints:**
- `--apiVersion=crd.yangtse.cni/v1` and `--kind=EIPPool` are required (missing these causes 400 error)
- `spec.eipAttributes.networkType` is required (missing causes 422 validation error)
- `spec.eipAttributes.bandwidth.chargeMode` and `name` are required when auto-creating EIPs (missing causes 403 validation error)
- EIPPool must be in the same namespace as the Pod that uses it
- Array items are 1-based: `--spec.eips.1=<eip-id>` (not `0`)
- `5_bgp` = Dynamic BGP EIP; `5_gray` = Dedicated load balancing (internal use)
---
## 2. List / Read / Status
```bash
# List EIPPools in namespace
hcloud CCI listCrdYangtseCniV1NamespacedEIPPool --namespace=<ns-name> --cli-region=<region> --cli-output=json
# Read a specific EIPPool
hcloud CCI readCrdYangtseCniV1NamespacedEIPPool --name=<eippool-name> --namespace=<ns-name> --cli-region=<region>
# Read EIPPool status (allocated IPs, available count)
hcloud CCI readCrdYangtseCniV1NamespacedEIPPoolStatus --name=<eippool-name> --namespace=<ns-name> --cli-region=<region> --cli-output=json
```
Status response includes:
- `status.eips` — array of allocated EIP objects (each with `ipv4`, `id`, `status`, `bandwidthSize`)
- `status.usage` — usage string (e.g., `0/1` means 0 of 1 EIPs bound to Pods)
---
## 3. Delete EIPPool — TWO-STEP CONFIRMATION
```bash
hcloud CCI deleteCrdYangtseCniV1NamespacedEIPPool --name=<eippool-name> --namespace=<ns-name> --cli-region=<region>
```
**WARNING:** Pods currently using this EIPPool will lose their public IP access immediately. Always confirm with the user and check for active Pods referencing this EIPPool before deletion.
After deletion, the EIPPool enters Terminating state with finalizer `yangtse.io/eip-pool`. The EIPs created by the pool are released automatically.
---
## 4. Pod Usage — Assign EIP via Annotation
To associate a Pod with an EIPPool, add the annotation at Pod creation:
**Note:** The annotation key `yangtse.io/eippool` contains dots and a slash. This may encounter the same hcloud CLI dot-parsing limitation as other annotation keys. If hcloud CLI cannot pass this annotation, consider:
- Using the hyphen replacement: `--metadata.annotations.yangtse-io/eippool=<eippool-name>` (may or may not work for Pod annotations — needs testing)
- Using `--cli-jsonInput` (but note this has known issues transmitting annotations for CCI resources)
```bash
hcloud CCI createCoreV1NamespacedPod \
--namespace=<ns-name> \
--metadata.name=<pod-name> \
--metadata.annotations.yangtse-io/eippool=<eippool-name> \
--spec.containers.1.name=<container-name> \
--spec.containers.1.image=<image> \
--spec.containers.1.resources.limits.cpu=500m \
--spec.containers.1.resources.limits.memory=1Gi \
--cli-region=<region> \
--cli-output=json
```
For Deployment or StatefulSet, add the annotation in the Pod template:
```bash
# Deployment with EIP (hyphen workaround for annotation key)
--spec.template.metadata.annotations.yangtse-io/eippool=<eippool-name>
# StatefulSet with EIP (hyphen workaround for annotation key)
--spec.template.metadata.annotations.yangtse-io/eippool=<eippool-name>
```
---
## 5. EIPPool vs Manual EIP
| Criteria | EIPPool (CCI-native) | Manual EIP binding |
|---|---|---|
| Allocation | Automatic — Pod gets EIP on creation | Manual — create EIP then bind to resource |
| Scope | Namespace-level, pod-specific | VPC-level, resource-specific |
| Lifecycle | EIP follows Pod lifecycle (released when Pod deleted) | EIP is independent, persists until manually deleted |
| Use case | Container workloads needing public IP | VMs, load balancers, NAT gateways |
| Management | CCI CRD, managed via k8s-style API | ECS/VPC API, managed via Huawei Cloud console/CLI |
| Dynamic scaling | Yes — pool auto-assigns as pods scale | No — each EIP must be manually bound |
Use **EIPPool** for CCI workloads that need direct public IP on Pods.
Use **manual EIP** for non-container resources or when you need persistent IPs independent of Pod lifecycle.references/task-logs-and-status.md›
# Logs and Status Queries
Status reading and log viewing across all CCI resources.
---
## 1. Pod Status
```bash
hcloud CCI readCoreV1NamespacedPodStatus \
--name=<pod-name> --namespace=<ns-name> \
--cli-region=<region> --cli-output=json
```
**Phase values:** `Pending`, `Running`, `Succeeded`, `Failed`, `Unknown`
**JMESPath quick query:**
```bash
--cli-query="status.phase"
```
---
## 2. Pod Logs
```bash
hcloud CCI readCoreV1NamespacedPodLog \
--name=<pod-name> --namespace=<ns-name> \
--container=<container-name> \
--cli-region=<region>
```
**Optional parameters:**
- `--sinceSeconds=3600` — show logs from last hour (3600 seconds)
- `--limitBytes=10000` — limit output to 10000 bytes
- `--previous=true` — show logs from previous (crashed) container instance
- `--tailLines=100` — show last 100 lines
**Multi-container pods:** `--container=<container-name>` is REQUIRED when the Pod has more than one container.
---
## 3. Deployment Status
```bash
hcloud CCI readAppsV1NamespacedDeploymentStatus \
--name=<deploy-name> --namespace=<ns-name> \
--cli-region=<region> --cli-output=json
```
**Key status fields:**
- `replicas` — desired replica count
- `readyReplicas` — pods passing readiness checks
- `availableReplicas` — pods available for service
- `updatedReplicas` — pods on the current template version
---
## 4. StatefulSet Status
```bash
hcloud CCI readAppsV1NamespacedStatefulSetStatus \
--name=<sts-name> --namespace=<ns-name> \
--cli-region=<region> --cli-output=json
```
**Key status fields:** same as Deployment plus `currentReplicas` and `currentRevision`.
---
## 5. Network Status
```bash
hcloud CCI readNetworkingCciIoV1beta1NamespacedNetworkStatus \
--name=<network-name> --namespace=<ns-name> \
--cli-region=<region> --cli-output=json
```
---
## 6. EIPPool Status
```bash
hcloud CCI readCrdYangtseCniV1NamespacedEIPPoolStatus \
--name=<eippool-name> --namespace=<ns-name> \
--cli-region=<region> --cli-output=json
```
Shows allocated EIP count, available EIP count, and specific IP assignments.
---
## 7. Events (Diagnose Issues)
```bash
# List all events in namespace
hcloud CCI listCoreV1NamespacedEvent --namespace=<ns-name> --cli-region=<region> --cli-output=json
# Read a specific event
hcloud CCI readCoreV1NamespacedEvent --name=<event-name> --namespace=<ns-name> --cli-region=<region>
```
Events record pod scheduling failures, image pull errors, crash loops, etc.
---
## 8. ResourceQuota
```bash
hcloud CCI listCoreV1NamespacedResourceQuota --namespace=<ns-name> --cli-region=<region> --cli-output=json
```
Shows CPU, memory, and pod count limits for the namespace.
---
## 9. Pod Metrics
```bash
hcloud CCI listMetricsV1beta1NamespacedPodMetrics --namespace=<ns-name> --cli-region=<region> --cli-output=json
```
Returns current CPU and memory usage per Pod.
---
## 10. Service Status
```bash
hcloud CCI readCoreV1NamespacedServiceStatus \
--name=<svc-name> --namespace=<ns-name> \
--cli-region=<region> --cli-output=json
```
---
## 11. Wait for Pod Running Pattern
Poll Pod status until `phase=Running`:
```bash
# Check status repeatedly until Running
$phase = ""
while ($phase -ne "Running") {
$result = hcloud CCI readCoreV1NamespacedPodStatus `
--name=<pod-name> --namespace=<ns-name> `
--cli-region=<region> --cli-output=json `
--cli-query="status.phase"
$phase = $result.Trim()
if ($phase -ne "Running") {
Start-Sleep -Seconds 5
}
}
Write-Output "Pod is Running"
```
**Alternative phases to wait for:**
- `Succeeded` — for batch/job pods
- `Failed` — indicates error; stop waiting and inspect events
**Timeout pattern:** add a max iteration count to prevent infinite loops (e.g., 60 iterations × 5s = 5 minutes max).references/task-namespace-management.md›
# Namespace Lifecycle Management
Namespaces are the foundational isolation boundary in CCI. All workload operations (Deployments, Pods, Networks) require a namespace.
## Create Namespace
```bash
hcloud CCI createCoreV1Namespace \
--metadata.name=<ns-name> \
--metadata.annotations.namespace-kubernetes-io/flavor=general-computing \
--cli-region=<region> \
--cli-output=json
```
The flavor annotation is **MANDATORY**. Accepted values:
| Flavor | Description |
|--------|-------------|
| `general-computing` | Standard compute instances |
| `gpu-accelerated` | GPU instances — requires additional GPU quota approval |
> GPU-accelerated namespaces require GPU quota to be approved before workloads can be created.
## List Namespaces
```bash
hcloud CCI listCoreV1Namespace --cli-region=<region> --cli-output=json
```
Filter output with JMESPath:
```bash
hcloud CCI listCoreV1Namespace --cli-region=<region> --cli-output=json \
--cli-query="items[].{Name:metadata.name,Status:status.phase,Flavor:metadata.annotations.namespace\.kubernetes\.io/flavor}"
```
## Read Namespace
```bash
hcloud CCI readCoreV1Namespace --name=<ns-name> --cli-region=<region> --cli-output=json
```
## Delete Namespace
**TWO-STEP CONFIRMATION REQUIRED — this operation is irreversible and cascading.**
### Step 1: Preview
Show namespace details and warn the user:
```bash
hcloud CCI readCoreV1Namespace --name=<ns-name> --cli-region=<region> --cli-output=json
```
> **WARNING**: Deleting a namespace cascades to ALL resources under it — Networks, Deployments, Pods, ConfigMaps, Secrets, etc. This cannot be undone.
### Step 2: Execute (only after explicit user confirmation)
```bash
hcloud CCI deleteCoreV1Namespace --name=<ns-name> --cli-region=<region>
```
- This is **irreversible** — no undo, no recovery
- This is **cascading** — all child resources are destroyed
- Always run `readCoreV1Namespace` first so the user can review what will be lost
## Namespace Naming Rules
- Must follow DNS_LABEL format: lowercase alphanumeric and hyphens only
- Must start with a lowercase letter or digit
- Maximum 63 characters
- Examples: `my-app`, `test-ns-01`, `production`
## Namespace Status Phases
| Phase | Meaning |
|-------|---------|
| `Active` | Namespace is ready for use |
| `Terminating` | Namespace is being deleted — all resources are being cleaned up |references/task-network-management.md›
# Network Lifecycle Management
A Network maps a VPC subnet into a CCI namespace. A Network **must exist before any workload** (Deployment, Pod) can be created in the namespace.
## VPC/Subnet Query Prerequisite
Before creating a Network, you must identify the VPC, subnet, and neutron network ID.
### List VPCs
```bash
hcloud VPC ListVpcs --cli-region=<region> --cli-output=json
```
### List Subnets for a VPC
```bash
hcloud VPC ListSubnets --vpc_id=<vpc-id> --cli-region=<region> --cli-output=json
```
Record the following from the output:
- `vpc_id` → used as `--spec.attachedVPC` (or `--attached-vpc` in the helper script)
- `subnet_id` → used as `--spec.subnetID` (or `--subnet-id` in the helper script)
- The subnet's neutron network ID → used as `--spec.networkID` (or `--network-id` in the helper script)
> **IMPORTANT**: The subnet CIDR MUST NOT be `10.247.0.0/16` — this range is reserved for the CCI Service network and will cause conflicts.
## Create Network
### Required Spec Fields
The Network spec requires **three mandatory fields**:
| Spec Field | hcloud CLI Parameter | Helper Script Parameter | Source |
|-----------|---------------------|------------------------|--------|
| `networkID` | `--spec.networkID` | `--network-id` | Neutron network ID from subnet query |
| `attachedVPC` | `--spec.attachedVPC` | `--attached-vpc` | VPC ID from `hcloud VPC ListVpcs` |
| `subnetID` | `--spec.subnetID` | `--subnet-id` | Subnet ID from `hcloud VPC ListSubnets` |
> Omitting `networkID` causes the error: `spec[networkID]: Required value`
### Security Group Annotation
CCI Network creation requires the annotation `network.alpha.kubernetes.io/default-security-group` to specify the default security group:
```
metadata.annotations:
network.alpha.kubernetes.io/default-security-group: <security-group-id>
```
- CCI auto-normalizes this annotation key (the canonical dotted version is preserved alongside any hyphenated variants when applicable)
### hcloud CLI Limitation
**hcloud CLI cannot pass annotation keys containing dots (`.`) as CLI parameters** — hcloud treats dots as nested object delimiters rather than literal annotation key names. The `--cli-jsonInput` approach also fails because hcloud does not properly transmit annotations from JSON input files as part of the request body.
Additionally, `--cli-jsonInput` files must use **ASCII encoding** (not UTF-8 with BOM). UTF-8 with BOM causes the error: `Failed to parse cli-jsonInput parameter file`.
### Primary Method: Python Helper Script
Use the `cci_network_helper.py` script from the skill's `scripts/` directory. It calls the CCI API directly using `huaweicloudsdkcore.signer.signer.Signer` and `requests`, bypassing hcloud's annotation limitation:
```bash
python scripts/cci_network_helper.py create \
--namespace=<ns-name> \
--name=<network-name> \
--network-id=<neutron-network-id> \
--attached-vpc=<vpc-id> \
--subnet-id=<subnet-id> \
--security-group=<security-group-id> \
--region=<region>
```
- `--namespace` = CCI namespace (must already exist)
- `--name` = Network resource name
- `--network-id` = neutron network ID (required)
- `--attached-vpc` = VPC ID
- `--subnet-id` = subnet ID
- `--security-group` = default security group ID (set via the `network.alpha.kubernetes.io/default-security-group` annotation)
- `--region` = Huawei Cloud region
### Fallback: hcloud CLI (Without Security Group Annotation)
If the security group annotation is not needed, hcloud CLI can create a Network without it:
```bash
hcloud CCI createNetworkingCciIoV1beta1NamespacedNetwork \
--namespace=<ns-name> \
--metadata.name=<network-name> \
--spec.networkID=<neutron-network-id> \
--spec.attachedVPC=<vpc-id> \
--spec.subnetID=<subnet-id> \
--cli-region=<region> \
--cli-output=json
```
> **Note**: This omits the `network.alpha.kubernetes.io/default-security-group` annotation. Use the Python helper script for complete Network creation with the security group annotation.
### Network Creation Status Lifecycle
Network creation returns `status.state=Initializing`. The Network transitions to `Active` once ready.
| State | Meaning | Action |
|-------|---------|--------|
| `Initializing` | Network is being created | Wait — do not create workloads yet |
| `Active` | Network is ready | You can now create workloads in the namespace |
**You must verify the Network reaches `Active` before creating workloads.** See "Read Network Status" below.
- One Network per namespace is the typical and recommended pattern
- The namespace must already exist before creating a Network in it
## List Networks
```bash
hcloud CCI listNetworkingCciIoV1beta1NamespacedNetwork \
--namespace=<ns-name> \
--cli-region=<region> \
--cli-output=json
```
## Read Network
```bash
hcloud CCI readNetworkingCciIoV1beta1NamespacedNetwork \
--name=<network-name> --namespace=<ns-name> \
--cli-region=<region> --cli-output=json
```
## Read Network Status
Check whether the Network has become Active (required before creating workloads):
```bash
hcloud CCI readNetworkingCciIoV1beta1NamespacedNetworkStatus \
--name=<network-name> --namespace=<ns-name> \
--cli-region=<region> --cli-output=json
```
- Network must reach `Active` state before workloads can be created in the namespace
- If status is `Initializing`, wait and re-check
## Delete Network
**TWO-STEP CONFIRMATION REQUIRED.**
### Step 1: Warn the user
> **WARNING**: Deleting the Network will cause all pods in this namespace to lose network connectivity. This is irreversible.
### Step 2: Execute (only after explicit user confirmation)
```bash
hcloud CCI deleteNetworkingCciIoV1beta1NamespacedNetwork \
--name=<network-name> --namespace=<ns-name> \
--cli-region=<region>
```
## Annotation Key Reference
| Annotation Key | Value | Purpose | hcloud CLI Support |
|---------------|-------|---------|-------------------|
| `network.alpha.kubernetes.io/default-security-group` | Security group ID (e.g., `sg-xxxx`) | Default security group for Network | **Cannot pass via hcloud CLI** — dots treated as nested delimiters; use Python helper script |
| `namespace.kubernetes.io/flavor` | `general-computing` or `gpu-accelerated` | Namespace flavor type | Works via `--metadata.annotations.namespace-kubernetes-io/flavor` (hyphen workaround) |references/task-pod-management.md›
# Pod Management
Pod lifecycle operations — bare pods (single container instance, no replica management).
---
## 1. Create Pod (Bare Pod)
```bash
hcloud CCI createCoreV1NamespacedPod \
--namespace=<ns-name> \
--metadata.name=<pod-name> \
--spec.containers.1.name=<container-name> \
--spec.containers.1.image=<image> \
--spec.containers.1.resources.limits.cpu=500m \
--spec.containers.1.resources.limits.memory=1Gi \
--spec.containers.1.resources.requests.cpu=250m \
--spec.containers.1.resources.requests.memory=512Mi \
--cli-region=<region> \
--cli-output=json
```
**Prerequisites:**
- Namespace must exist before creating a Pod
- Network resource must exist in the namespace
**CCI-specific requirements:**
- `resources.limits` and `resources.requests` are MANDATORY — CCI rejects pods without resource specifications
- Array items are 1-based: `--spec.containers.1.name` (not `0`)
**NOT recommended for production** — bare pods are not self-healing. Use Deployment or StatefulSet for replica management and restart policies.
---
## 2. List Pods
```bash
# List pods in a specific namespace
hcloud CCI listCoreV1NamespacedPod --namespace=<ns-name> --cli-region=<region> --cli-output=json
# List pods across all namespaces
hcloud CCI listCoreV1PodForAllNamespaces --cli-region=<region> --cli-output=json
```
**JMESPath filter example:**
```bash
hcloud CCI listCoreV1NamespacedPod \
--namespace=<ns-name> \
--cli-region=<region> \
--cli-output=json \
--cli-query="items[].{Name:metadata.name,Phase:status.phase,IP:status.podIP}"
```
---
## 3. Read Pod / Pod Status
```bash
# Read full Pod definition
hcloud CCI readCoreV1NamespacedPod --name=<pod-name> --namespace=<ns-name> --cli-region=<region>
# Read Pod status only
hcloud CCI readCoreV1NamespacedPodStatus --name=<pod-name> --namespace=<ns-name> --cli-region=<region> --cli-output=json
```
---
## 4. Delete Pod — TWO-STEP CONFIRMATION
```bash
hcloud CCI deleteCoreV1NamespacedPod --name=<pod-name> --namespace=<ns-name> --cli-region=<region>
```
Always confirm with the user before deleting a Pod. Check if the pod is managed by a Deployment/StatefulSet first — deleting a replica pod will cause the controller to recreate it.
---
## 5. Pod Phases
| Phase | Meaning |
|---|---|
| `Pending` | Pod accepted but containers not yet running (waiting for scheduling, image pull, etc.) |
| `Running` | Pod bound to a node and at least one container is running |
| `Succeeded` | All containers terminated successfully (won't restart) |
| `Failed` | At least one container terminated with non-zero exit code |
| `Unknown` | Pod state could not be determined (typically node communication failure) |
---
## 6. Pod with EIP Annotation (Public IP)
To assign a public IP to a Pod via EIPPool:
```bash
hcloud CCI createCoreV1NamespacedPod \
--namespace=<ns-name> \
--metadata.name=<pod-name> \
--metadata.annotations.yangtse.io/eippool=<eippool-name> \
--spec.containers.1.name=<container-name> \
--spec.containers.1.image=<image> \
--spec.containers.1.resources.limits.cpu=500m \
--spec.containers.1.resources.limits.memory=1Gi \
--spec.containers.1.resources.requests.cpu=250m \
--spec.containers.1.resources.requests.memory=512Mi \
--cli-region=<region> \
--cli-output=json
```
The annotation `yangtse.io/eippool=<eippool-name>` tells CCI to allocate an EIP from the specified EIPPool to this Pod.references/task-statefulset-management.md›
# StatefulSet Management
StatefulSet lifecycle operations for stateful workloads (databases, message queues, etc.).
---
## 1. Create StatefulSet
```bash
hcloud CCI createAppsV1NamespacedStatefulSet \
--namespace=<ns-name> \
--metadata.name=<sts-name> \
--spec.replicas=1 \
--spec.selector.matchLabels.app=<sts-name> \
--spec.template.metadata.labels.app=<sts-name> \
--spec.template.spec.containers.1.name=<container-name> \
--spec.template.spec.containers.1.image=<image> \
--spec.template.spec.containers.1.resources.limits.cpu=500m \
--spec.template.spec.containers.1.resources.limits.memory=1Gi \
--spec.serviceName=<sts-name> \
--cli-region=<region> \
--cli-output=json
```
**Required fields:**
- `spec.serviceName` — headless Service name for network identity (REQUIRED for StatefulSet)
- `spec.selector.matchLabels` — must match `spec.template.metadata.labels`
- Resources (`limits`) are MANDATORY on CCI
**PVC volumeClaimTemplates example (persistent storage):**
```bash
hcloud CCI createAppsV1NamespacedStatefulSet \
--namespace=<ns-name> \
--metadata.name=<sts-name> \
--spec.replicas=1 \
--spec.selector.matchLabels.app=<sts-name> \
--spec.template.metadata.labels.app=<sts-name> \
--spec.template.spec.containers.1.name=<container-name> \
--spec.template.spec.containers.1.image=<image> \
--spec.template.spec.containers.1.resources.limits.cpu=500m \
--spec.template.spec.containers.1.resources.limits.memory=1Gi \
--spec.template.spec.containers.1.volumeMounts.1.name=data \
--spec.template.spec.containers.1.volumeMounts.1.mountPath=/data \
--spec.volumeClaimTemplates.1.metadata.name=data \
--spec.volumeClaimTemplates.1.spec.accessModes.1=ReadWriteOnce \
--spec.volumeClaimTemplates.1.spec.resources.requests.storage=10Gi \
--spec.volumeClaimTemplates.1.spec.storageClassName=<sc-name> \
--spec.serviceName=<sts-name> \
--cli-region=<region> \
--cli-output=json
```
---
## 2. List / Read / Status
```bash
# List all StatefulSets in namespace
hcloud CCI listAppsV1NamespacedStatefulSet --namespace=<ns-name> --cli-region=<region> --cli-output=json
# Read a specific StatefulSet
hcloud CCI readAppsV1NamespacedStatefulSet --name=<sts-name> --namespace=<ns-name> --cli-region=<region>
# Read StatefulSet status only
hcloud CCI readAppsV1NamespacedStatefulSetStatus --name=<sts-name> --namespace=<ns-name> --cli-region=<region> --cli-output=json
```
---
## 3. Update StatefulSet (Patch)
```bash
hcloud CCI patchAppsV1NamespacedStatefulSet \
--name=<sts-name> --namespace=<ns-name> \
--spec.template.spec.containers.1.image=<new-image> \
--cli-region=<region>
```
Common patch operations:
- Image update: `--spec.template.spec.containers.1.image=<new-image>`
- Replica scaling: `--spec.replicas=<new-count>`
---
## 4. Delete StatefulSet — TWO-STEP CONFIRMATION
```bash
hcloud CCI deleteAppsV1NamespacedStatefulSet --name=<sts-name> --namespace=<ns-name> --cli-region=<region>
```
**WARNING:** PVCs created by volumeClaimTemplates are NOT automatically deleted when the StatefulSet is deleted. Manual cleanup is required:
```bash
hcloud CCI deleteCoreV1NamespacedPersistentVolumeClaim --name=<pvc-name> --namespace=<ns-name> --cli-region=<region>
```
Always confirm with the user before deleting a StatefulSet. List PVCs first to show what will remain.
---
## 5. StatefulSet vs Deployment — When to Use Each
| Criteria | StatefulSet | Deployment |
|---|---|---|
| Workload type | Databases, message queues, distributed storage | Web servers, APIs, microservices |
| Pod identity | Stable hostname (`<sts-name>-0`, `-1`, ...) | Random generated names |
| Pod ordering | Ordered create/delete (0→1→2) | Parallel, no ordering |
| Storage | volumeClaimTemplates per pod | Shared or no persistent storage |
| Network | Stable DNS per pod via headless Service | Single Service endpoint |
| Updates | RollingUpdate with partition support or OnDelete | RollingUpdate by default |
Use **StatefulSet** when you need: stable network identity, ordered deployment, or per-pod persistent storage.
Use **Deployment** for all other stateless workloads.
---
## 6. PVC Handling Notes
- **volumeClaimTemplates** auto-creates one PVC per replica: `<pvc-name>-<sts-name>-<ordinal>`
- PVC naming: `<volumeClaimTemplateName>-<sts-name>-0`, `-1`, etc.
- **StorageClass**: specify `--spec.volumeClaimTemplates.1.spec.storageClassName=<sc-name>`; CCI provides default if omitted
- **PVC lifecycle is independent** — deleting the StatefulSet does NOT delete PVCs
- To clean up: manually delete each PVC after the StatefulSet is removed
- **Reclaim policy**: follows StorageClass settings (Retain or Delete)references/troubleshooting.md›
# Troubleshooting Guide for CCI hcloud CLI Issues
## 1. Namespace Creation Fails
**Cause:** Missing `namespace.kubernetes.io/flavor` annotation.
**Fix:** Add the flavor annotation:
```
--metadata.annotations.namespace-kubernetes-io/flavor=general-computing
```
Without this annotation, CCI rejects namespace creation requests.
## 2. Network Creation Fails
**Cause:** Invalid subnet ID, VPC ID, or CIDR conflict.
**Fix:**
- Verify subnet ID with `hcloud VPC ListSubnets --vpc-id=<vpc-id>`
- Verify VPC ID with `hcloud VPC ShowVpc`
- Ensure Network CIDR does not overlap with `10.247.0.0/16` (reserved for CCI internal routing)
- Use a different CIDR range such as `10.0.0.0/24` or `172.16.0.0/24`
## 3. Pod Stays in Pending State
**Cause:** No Network in namespace, insufficient resources, or image pull failure.
**Fix:**
- Check events: `hcloud CCI listCoreV1NamespacedEvent --namespace=<ns-name>`
- Verify Network exists in the namespace
- Verify image name and credentials
- Check resource availability in the namespace
## 4. Deployment Pods Not Becoming Ready
**Cause:** Container crash, image pull error, or resource limits exceeded.
**Fix:**
- Read Pod status: `hcloud CCI readCoreV1NamespacedPodStatus --name=<pod> --namespace=<ns>`
- Check events: `hcloud CCI listCoreV1NamespacedEvent --namespace=<ns-name>`
- Read Pod logs: `hcloud CCI readCoreV1NamespacedPodLog --name=<pod> --namespace=<ns> --container=<container>`
- Check resource limits vs available namespace resources
## 5. Permission Denied (403)
**Cause:** IAM permissions insufficient for the requested operation.
**Fix:** Refer to iam-policies.md, identify the missing permission, and add it to the IAM policy.
## 6. Parameter Format Errors
**Common mistakes:**
- Using JSON objects instead of `{*}` format for nested parameters
- Using 0-based indexing instead of 1-based indexing
- Missing equals sign in `--key=value` format
- Using wrong parameter names
**Fix:** Refer to parameter-format.md for correct hcloud CLI parameter syntax.
## 7. EIPPool Creation Fails
**Cause:** No available EIPs in the project, or CIDR format error.
**Fix:**
- Verify EIP availability: `hcloud VPC ListPublicIps`
- Check CIDR format (must be valid IPv4 CIDR, e.g., `10.0.0.0/24`)
- Ensure sufficient EIPs exist for the pool size
## 8. Deep Nested Parameter Construction Is Complex
**Fix:**
- Always use `hcloud CCI <Operation> --help` first to see parameter structure
- Build parameters incrementally, adding one nested level at a time
- Use `--dryRun=All` to validate parameters before execution
- Refer to parameter-format.md for nested parameter syntax rules
## 9. hcloud CLI General Errors
| Error Type | Description | Resolution |
|---|---|---|
| `[NETWORK_ERROR]` | Network connectivity issue | Check network connection and proxy settings |
| `[USE_ERROR]` | Parameter format error | Check parameter format, refer to parameter-format.md |
| `[OPENAPI_ERROR]` | API version compatibility issue | Check API version, update hcloud CLI |
| Debug flag | `--cli-debug=true` | Add this flag to any command for detailed debug output |
## 10. Pod Exec Operations
The `connectCoreV1GetNamespacedPodExec` and `connectCoreV1PostNamespacedPodExec` operations are interactive WebSocket operations. They may not work well in hcloud CLI batch mode.
**Alternative:** Use Pod logs for diagnostics instead of exec:
```
hcloud CCI readCoreV1NamespacedPodLog --name=<pod> --namespace=<ns> --container=<container>
```
## 11. CCI Network "securitygroup can not be empty" Error
**Cause:** The annotation key `network.alpha.kubernetes.io/default-security-group` is not correctly passed.
**Common root causes:**
- Wrong annotation key used (e.g., `security-group-id` instead of `default-security-group`)
- hcloud CLI cannot pass annotation keys containing dots - it treats dots as nested levels
- hcloud `--cli-jsonInput` doesn't properly transmit annotations (see Section 13)
**Fix:** Use the Python helper script for Network creation instead of hcloud CLI. The Python SDK correctly handles annotation keys with dots.
## 12. hcloud CLI "Incorrect parameter" Error for Annotation Keys with Dots
**Cause:** When using `--metadata.annotations.network.alpha.kubernetes.io/key=value`, hcloud treats each dot as a nested object level delimiter. No escaping mechanism (backslash, quotes, etc.) works.
**Fix:** This is an hcloud CLI limitation. Use the Python helper script for any CCI resource creation that requires annotation keys with dots (especially Network). hcloud CLI is usable only for annotation keys without dots (e.g., hyphenated keys on Namespace).
## 13. hcloud `--cli-jsonInput` "Failed to parse cli-jsonInput parameter file" Error
**Cause:** Multiple possible causes for this JSON input parsing failure.
**Root causes and fixes:**
- **UTF-8 with BOM encoding:** hcloud cannot parse files with BOM. Use ASCII encoding (or UTF-8 without BOM) for the JSON input file.
- **Annotations with dots not transmitted:** This is a confirmed hcloud bug. Annotations with dots appear in `--dryrun` output but are not included in the actual API request body. Use the Python helper script instead.
- **Incorrect JSON structure:** The JSON structure must exactly match the skeleton format shown by `hcloud CCI <Operation> --help`. Verify field names, nesting, and required fields.
## 14. Network Creation "spec[networkID]: Required value" Error
**Cause:** The `networkID` field (neutron network ID) is missing from the Network spec. This field is required alongside `attachedVPC`, `subnetID`, and `networkType`.
**Fix:** Obtain the neutron network ID from `hcloud VPC ShowSubnet` output and include it in the Network spec as the `networkID` field.
## 15. CCI Annotation Key Auto-Normalization
**Behavior:** For Namespace resources, CCI automatically adds the canonical dotted annotation key (`namespace.kubernetes.io/flavor`) alongside the hyphenated version (`namespace-kubernetes-io/flavor`) when you provide only the hyphenated form. This auto-normalization only works for Namespace.
**Important:** This normalization does NOT apply to Network resources. For Network, you must provide the exact dotted annotation keys (`network.alpha.kubernetes.io/default-security-group`, etc.) yourself. Since hcloud CLI cannot handle dotted keys, use the Python helper script for Network creation.
## 16. Deployment "limit and request doesn't equal" Error
**Cause:** CCI requires container resource limits to equal requests. If limits != requests, CCI rejects the Deployment/Pod creation.
**Fix:** Set requests to the same values as limits:
```bash
--spec.template.spec.containers.1.resources.limits.cpu=500m
--spec.template.spec.containers.1.resources.limits.memory=1Gi
--spec.template.spec.containers.1.resources.requests.cpu=500m
--spec.template.spec.containers.1.resources.requests.memory=1Gi
```
## 17. EIPPool Creation Fails with "Object 'Kind' is missing"
**Cause:** Missing `--apiVersion=crd.yangtse.cni/v1` and `--kind=EIPPool` parameters.
**Fix:** Include both required fields:
```bash
--apiVersion=crd.yangtse.cni/v1 --kind=EIPPool
```
## 18. EIPPool Creation Fails with 422 "spec.eipAttributes.networkType: Required value"
**Cause:** Missing the required `--spec.eipAttributes.networkType` parameter.
**Fix:** Add `--spec.eipAttributes.networkType=5_bgp` (dynamic BGP) or `5_gray` (dedicated load balancing).
## 19. EIPPool Creation Fails with 403 "name, size, shareType and chargeMode are required"
**Cause:** Missing required bandwidth fields when auto-creating EIPs.
**Fix:** Include all bandwidth fields:
```bash
--spec.eipAttributes.bandwidth.shareType=PER
--spec.eipAttributes.bandwidth.size=5
--spec.eipAttributes.bandwidth.chargeMode=bandwidth
--spec.eipAttributes.bandwidth.name=<bandwidth-name>
```references/verification-method.md›
# Step-by-Step Verification Process for CCI Skill Functionality
## 1. Environment Verification
```bash
hcloud version # >= 7.2.2
hcloud configure list # valid profile exists
```
## 2. Namespace Verification
```bash
hcloud CCI listCoreV1Namespace --cli-region=cn-north-4 --cli-output=json
```
Expected: list of namespaces with `metadata.name` and `status.phase`.
## 3. Network Verification
```bash
hcloud CCI readNetworkingCciIoV1beta1NamespacedNetworkStatus \
--name=<network-name> --namespace=<ns-name> \
--cli-region=cn-north-4 --cli-output=json
```
Expected: `status.state=Active`.
## 4. Deployment Verification
```bash
hcloud CCI readAppsV1NamespacedDeploymentStatus \
--name=<deploy-name> --namespace=<ns-name> \
--cli-region=cn-north-4 --cli-output=json
```
Expected: `status.readyReplicas > 0`, `status.availableReplicas > 0`.
## 5. Pod Verification
```bash
hcloud CCI readCoreV1NamespacedPodStatus \
--name=<pod-name> --namespace=<ns-name> \
--cli-region=cn-north-4 --cli-output=json
```
Expected: `status.phase=Running`.
## 6. Log Verification
```bash
hcloud CCI readCoreV1NamespacedPodLog \
--name=<pod-name> --namespace=<ns-name> \
--container=<container-name> \
--cli-region=cn-north-4
```
Expected: application log output.
## 7. Delete Operation Verification
Two-step confirmation process:
1. **Test without confirmation:** show preview and warning only, do not execute deletion.
2. **Test with confirmation:** verify the resource is actually deleted by attempting to read it (should return 404 or empty result).
## 8. Complete Verification Checklist
| Step | Verification Item | Expected Result | Verification Command |
|---|---|---|---|
| 1 | hcloud CLI installed | version >= 7.2.2 | `hcloud version` |
| 2 | CLI profile configured | valid profile listed | `hcloud configure list` |
| 3 | Namespace created | status.phase=Active | `listCoreV1Namespace` |
| 4 | Network created | status.state=Active | `readNetworkingCciIoV1beta1NamespacedNetworkStatus` |
| 5 | Deployment created | readyReplicas > 0 | `readAppsV1NamespacedDeploymentStatus` |
| 6 | Pod running | status.phase=Running | `readCoreV1NamespacedPodStatus` |
| 7 | Logs accessible | application log output | `readCoreV1NamespacedPodLog` |
| 8 | Delete requires confirmation | preview shown, no deletion | test delete without confirm |
| 9 | Delete with confirmation | resource removed | test delete with confirm, then read returns 404 |
| 10 | Permission errors handled | policy shown, execution paused | test with insufficient permissions |scripts/cci_network_helper.py›
#!/usr/bin/env python3
"""
CCI Network Creation Helper Script
This script creates a CCI Network by directly calling the CCI OpenAPI,
bypassing hcloud CLI's limitation with annotation keys containing dots.
hcloud CLI treats dots in annotation keys as nested object delimiters,
making it impossible to pass 'network.alpha.kubernetes.io/default-security-group'
via CLI parameters or --cli-jsonInput (which also doesn't properly transmit
annotations in actual API requests, despite showing them in --dryrun).
Usage:
python cci_network_helper.py create \
--namespace <ns-name> \
--name <network-name> \
--vpc-id <vpc-id> \
--subnet-id <neutron-subnet-id> \
--network-id <neutron-network-id> \
--security-group-id <sg-id> \
--region <region>
python cci_network_helper.py delete \
--namespace <ns-name> \
--name <network-name> \
--region <region>
python cci_network_helper.py status \
--namespace <ns-name> \
--name <network-name> \
--region <region>
Required Python packages:
pip install requests huaweicloudsdkcore
Environment variables (required):
HW_ACCESS_KEY - Huawei Cloud AK
HW_SECRET_KEY - Huawei Cloud SK
Environment variables (optional for temporary credential mode):
HW_SECURITY_TOKEN - Huawei Cloud SecurityToken (temporary credential mode)
Falls back to HUAWEI_CLOUD_SECURITY_TOKEN if HW_SECURITY_TOKEN not set.
When set, the script uses temporary STS credential authentication.
Note: subnet-id must be the neutron_subnet_id (not the VPC subnet ID).
network-id must be the neutron_network_id (not the VPC subnet ID).
Both can be obtained from: hcloud VPC ShowSubnet --subnet_id=<id> --cli-region=<region>
"""
import argparse
import json
import os
import sys
import requests
try:
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkcore.signer.signer import Signer
from huaweicloudsdkcore.sdk_request import SdkRequest
except ImportError:
print("ERROR: huaweicloudsdkcore not installed. Run: pip install huaweicloudsdkcore")
sys.exit(1)
def get_credentials():
ak = os.environ.get("HW_ACCESS_KEY")
sk = os.environ.get("HW_SECRET_KEY")
if not ak or not sk:
print("ERROR: HW_ACCESS_KEY and HW_SECRET_KEY environment variables must be set")
sys.exit(1)
# Support SecurityToken for temporary credential mode
# Check HW_SECURITY_TOKEN first, then fall back to HUAWEI_CLOUD_SECURITY_TOKEN
security_token = os.environ.get("HW_SECURITY_TOKEN") or os.environ.get("HUAWEI_CLOUD_SECURITY_TOKEN")
return ak, sk, security_token
def get_project_id(region):
import subprocess
try:
cmd = f"hcloud IAM KeystoneListProjects --cli-region={region} --cli-output=json"
result = subprocess.run(
cmd, capture_output=True, timeout=15,
encoding="utf-8", errors="replace", shell=True,
)
if result.returncode == 0 and result.stdout.strip().startswith("{"):
data = json.loads(result.stdout)
for p in data.get("projects", []):
if p.get("name") == region:
return p["id"]
except Exception:
pass
print(f"ERROR: Cannot auto-detect project ID for region {region}")
print(f" Please provide --project-id explicitly")
print(f" Or run: hcloud IAM KeystoneListProjects --cli-region={region} --cli-output=json")
sys.exit(1)
def sign_request(method, host, resource_path, body, ak, sk, security_token, project_id):
creds = BasicCredentials(ak=ak, sk=sk, project_id=project_id)
if security_token:
creds = creds.with_security_token(security_token)
signer = Signer(creds)
req = SdkRequest(
method=method,
schema="https",
host=host,
resource_path=resource_path,
uri=resource_path,
body=body,
header_params={"Content-Type": "application/json", "Host": host},
query_params=[],
)
signed_req = signer.sign(req)
headers = signed_req.header_params
headers["X-Project-Id"] = project_id
return headers
def create_network(namespace, name, vpc_id, subnet_id, network_id, security_group_id, region, project_id=None):
ak, sk, security_token = get_credentials()
if not project_id:
project_id = get_project_id(region)
body_dict = {
"apiVersion": "networking.cci.io/v1beta1",
"kind": "Network",
"metadata": {
"name": name,
"annotations": {
"network.alpha.kubernetes.io/default-security-group": security_group_id
},
},
"spec": {
"attachedVPC": vpc_id,
"networkID": network_id,
"subnetID": subnet_id,
"networkType": "underlay_neutron",
},
}
body = json.dumps(body_dict)
host = f"cci.{region}.myhuaweicloud.com"
resource_path = (
f"/apis/networking.cci.io/v1beta1/namespaces/{namespace}/networks"
)
url = f"https://{host}{resource_path}"
headers = sign_request("POST", host, resource_path, body, ak, sk, security_token, project_id)
resp = requests.post(url, data=body.encode("utf-8"), headers=headers)
result = json.loads(resp.text)
if resp.status_code == 201:
state = result.get("status", {}).get("state", "Unknown")
print(f"SUCCESS: Network '{name}' created in namespace '{namespace}'")
print(f" State: {state}")
print(f" UID: {result.get('metadata', {}).get('uid', 'N/A')}")
else:
print(f"ERROR: Network creation failed. Status: {resp.status_code}")
msg = result.get("message", resp.text)
print(f" Message: {msg}")
return resp.status_code
def delete_network(namespace, name, region, project_id=None):
ak, sk, security_token = get_credentials()
if not project_id:
project_id = get_project_id(region)
host = f"cci.{region}.myhuaweicloud.com"
resource_path = (
f"/apis/networking.cci.io/v1beta1/namespaces/{namespace}/networks/{name}"
)
url = f"https://{host}{resource_path}"
headers = sign_request("DELETE", host, resource_path, "", ak, sk, security_token, project_id)
resp = requests.delete(url, headers=headers)
if resp.status_code in (200, 204):
print(f"SUCCESS: Network '{name}' deleted from namespace '{namespace}'")
else:
try:
result = json.loads(resp.text)
print(f"ERROR: Network deletion failed. Status: {resp.status_code}")
print(f" Message: {result.get('message', resp.text)}")
except json.JSONDecodeError:
print(f"ERROR: Network deletion failed. Status: {resp.status_code}")
return resp.status_code
def check_status(namespace, name, region, project_id=None):
ak, sk, security_token = get_credentials()
if not project_id:
project_id = get_project_id(region)
host = f"cci.{region}.myhuaweicloud.com"
resource_path = (
f"/apis/networking.cci.io/v1beta1/namespaces/{namespace}/networks/{name}"
)
url = f"https://{host}{resource_path}"
headers = sign_request("GET", host, resource_path, "", ak, sk, security_token, project_id)
resp = requests.get(url, headers=headers)
result = json.loads(resp.text)
if resp.status_code == 200:
state = result.get("status", {}).get("state", "Unknown")
cidr = result.get("spec", {}).get("cidr", "N/A")
print(f"Network '{name}' in namespace '{namespace}'")
print(f" State: {state}")
print(f" CIDR: {cidr}")
else:
print(f"ERROR: Failed to get network status. Status: {resp.status_code}")
print(f" Message: {result.get('message', resp.text)}")
return resp.status_code
def main():
parser = argparse.ArgumentParser(
description="CCI Network helper (bypasses hcloud CLI annotation key limitation)"
)
subparsers = parser.add_subparsers(dest="action", required=True)
create_parser = subparsers.add_parser("create", help="Create a CCI Network")
create_parser.add_argument("--namespace", required=True, help="CCI namespace name")
create_parser.add_argument("--name", required=True, help="Network name")
create_parser.add_argument("--vpc-id", required=True, help="VPC ID (attachedVPC)")
create_parser.add_argument(
"--subnet-id",
required=True,
help="Neutron subnet ID (not VPC subnet ID). Get from: hcloud VPC ShowSubnet",
)
create_parser.add_argument(
"--network-id",
required=True,
help="Neutron network ID. Get from: hcloud VPC ShowSubnet",
)
create_parser.add_argument(
"--security-group-id",
required=True,
help="Security group ID for the network",
)
create_parser.add_argument("--region", required=True, help="Region (e.g., cn-north-4)")
create_parser.add_argument("--project-id", default=None, help="Project ID (auto-detected if omitted)")
delete_parser = subparsers.add_parser("delete", help="Delete a CCI Network")
delete_parser.add_argument("--namespace", required=True, help="CCI namespace name")
delete_parser.add_argument("--name", required=True, help="Network name")
delete_parser.add_argument("--region", required=True, help="Region")
delete_parser.add_argument("--project-id", default=None, help="Project ID (auto-detected if omitted)")
status_parser = subparsers.add_parser("status", help="Check CCI Network status")
status_parser.add_argument("--namespace", required=True, help="CCI namespace name")
status_parser.add_argument("--name", required=True, help="Network name")
status_parser.add_argument("--region", required=True, help="Region")
status_parser.add_argument("--project-id", default=None, help="Project ID (auto-detected if omitted)")
args = parser.parse_args()
if args.action == "create":
create_network(
args.namespace,
args.name,
args.vpc_id,
args.subnet_id,
args.network_id,
args.security_group_id,
args.region,
args.project_id,
)
elif args.action == "delete":
delete_network(args.namespace, args.name, args.region, args.project_id)
elif args.action == "status":
check_status(args.namespace, args.name, args.region, args.project_id)
if __name__ == "__main__":
main()SKILL.md›
---
name: huawei-cloud-cci-instance-management
description: >-
Huawei Cloud CCI (Cloud Container Instance) full lifecycle management using hcloud CLI.
Covers Namespace, Network, Deployment, StatefulSet, Pod creation/update/delete/status, EIPPool for public IP, logs and metrics.
Two-step confirmation for all destructive operations (delete namespace cascades all resources under it).
Use this skill when the user wants to operate CCI serverless containers via command line.
Triggers: CCI, 云容器实例, serverless container, 容器实例, namespace, deployment, statefulset, pod, EIPPool, CCI负载, 无服务器容器, 创建容器实例, 删除容器实例, 容器状态, 容器日志
tags: [cci, container-instance, serverless, namespace, deployment]
---
# Huawei Cloud CCI Container Instance Lifecycle Management
## Overview
Manage Huawei Cloud CCI (Cloud Container Instance) full lifecycle using hcloud CLI (KooCLI). CCI is a serverless container service — no cluster management needed, just create a Namespace, define a Network, then deploy workloads directly.
**Architecture**: hcloud CLI → CCI OpenAPI → Namespace / Network / Deployment / StatefulSet / Pod / EIPPool / Service / Ingress
## Constraints and Rules
### Security Rules
- **Two-step confirmation**: All destructive operations (delete Namespace/Network/Deployment/StatefulSet/Pod/EIPPool) require explicit user confirmation — preview command, resource details, and risk warning first; execute only after user confirms.
- **Credential security**: Never expose AK/SK values in conversation, commands, or output. Only use `hcloud configure list` to check credential status (presence only). Prefer profile mode or environment variables over explicit AK/SK parameters.
### Resource Constraints
- **Namespace flavor annotation is mandatory**: Every namespace must carry `namespace-kubernetes-io/flavor` annotation (value: `general-computing` or `gpu-accelerated`). Without it, creation fails.
- **limits must equal requests**: CCI enforces `resources.limits == resources.requests`. Mismatch causes "limit and request doesn't equal" error. Set both to the same values (e.g., `500m/1Gi`).
- **Network must precede workloads**: Pod/Deployment/StatefulSet creation fails or stays Pending if no Network exists in the namespace. Always create Network before deploying workloads.
- **VPC CIDR restriction**: VPC subnet CIDR must NOT be `10.247.0.0/16` — CCI reserves this range for Service networking. Using it causes IP conflicts and workload creation failures.
- **Deletion order**: Pod → Deployment/StatefulSet → EIPPool → Network → Namespace. Deleting a Namespace cascades all resources under it.
### hcloud CLI Constraints
- **Network creation must use Python helper script**: hcloud CLI cannot pass annotation keys containing dots (`network.alpha.kubernetes.io/default-security-group`). Neither dot notation nor `--cli-jsonInput` works. Use `scripts/cci_network_helper.py`.
- **Namespace annotation uses hyphen replacement**: Keys like `namespace.kubernetes.io/flavor` can use hyphens (`namespace-kubernetes-io/flavor`) and CCI auto-normalizes. This workaround only works for Namespace, NOT for Network.
- **Always verify parameters with `--help`**: CCI has hundreds of parameters. Run `hcloud CCI <Operation> --help` before constructing any command. The help output is the authoritative source.
> Detailed breakdowns of these rules are in [Security Constraints](#security-constraints), [hcloud CLI Limitations](#hcloud-cli-limitations), and [Precautions](#precautions).
## Standard Workflow
```
1. Create Namespace (with flavor annotation)
2. Create Network (requires Python helper script for annotation — see hcloud CLI Limitations)
3. Create Deployment / StatefulSet / Pod (run workloads)
4. Query status, view logs
5. (Optional) Create EIPPool for Pod public IP access
6. Cleanup: delete workload → delete Network → delete Namespace
```
## Prerequisites
### 1. hcloud CLI Requirements (MANDATORY)
- hcloud CLI installed (version >= 7.2.2)
- Run `hcloud version` to verify installation
- First-time usage: `printf "y\n" | hcloud version` to accept privacy statement
### 2. Credential Configuration
hcloud CLI supports two credential modes. See [references/credential-configuration.md](references/credential-configuration.md) for full details.
**Quick setup** (choose one):
```bash
# Mode A — Long-term AK/SK
export HUAWEI_CLOUD_AK=<your-ak>
export HUAWEI_CLOUD_SK=<your-sk>
export HUAWEI_CLOUD_REGION=cn-north-4
# Mode B — Temporary AK/SK + SecurityToken
export HUAWEI_CLOUD_AK=<your-temp-ak>
export HUAWEI_CLOUD_SK=<your-temp-sk>
export HUAWEI_CLOUD_SECURITY_TOKEN=<your-security-token>
export HUAWEI_CLOUD_REGION=cn-north-4
```
- **Security rules**: Never expose AK/SK/SecurityToken values. Use `hcloud configure list` to check presence only.
> ⚠️ **Known limitation — Python helper script credentials are independent of hcloud CLI**: The Python helper script (`scripts/cci_network_helper.py`) uses `HW_ACCESS_KEY` / `HW_SECRET_KEY` (and optionally `HW_SECURITY_TOKEN`) environment variables for authentication, which are **separate from** hcloud CLI's credential source (profile or `HUAWEI_CLOUD_AK`/`HUAWEI_CLOUD_SK`). If the credentials in `HW_ACCESS_KEY`/`HW_SECRET_KEY` lack the necessary IAM permissions for CCI Network creation, the script will fail with a 403 error. Ensure these variables contain credentials with sufficient CCI permissions (e.g., `CCI FullAccess`). The hcloud CLI continues using its own credential source independently — running the helper script does not affect subsequent hcloud CLI commands.
### 3. Validation Check
```bash
hcloud version
hcloud configure list
```
## Security Constraints
### Dangerous Operation Confirmation Mechanism
> **This skill strictly enforces a two-step confirmation mechanism for all destructive operations.**
All destructive operations require explicit user confirmation before execution. The process:
**Step 1: Preview** — Show the command, resource details, and risk warning
**Step 2: Confirm & Execute** — Only after user explicitly confirms
#### Operations Requiring Confirmation
| Operation | Risk Level | Description |
|-----------|------------|-------------|
| Delete Namespace | 🔴 Critical | Cascades — deletes ALL resources under this namespace (Network, Pods, Deployments, etc.) |
| Delete Network | 🟠 High | Disconnects namespace from VPC; running pods lose network |
| Delete Deployment | 🟠 High | Terminates all replicas of the workload |
| Delete StatefulSet | 🟠 High | Terminates all replicas; PVC data may be lost |
| Delete Pod | 🟠 High | Terminates the container instance |
| Delete EIPPool | 🟡 Medium | Releases public IPs allocated to pods |
### Credential Security
- **Never expose AK/SK/SecurityToken values** in conversation, commands, or output
- **Never ask user to input AK/SK/SecurityToken directly** in conversation
- **Only use** `hcloud configure list` to check credential status (presence only, not values)
- **Prefer** profile mode or environment variables over explicit AK/SK parameters
## Command Format Standard
CCI follows the standard hcloud format with Kubernetes-style nested parameters:
```bash
hcloud CCI <Operation> --param=value --cli-region=<region> --cli-output=json
```
### CCI-Specific Parameter Rules
CCI parameters follow Kubernetes API conventions — deeply nested objects with dot notation:
1. **Annotations use `{*}` format**: `--metadata.annotations.namespace-kubernetes-io/flavor=general-computing`
2. **Labels use `{*}` format**: `--metadata.labels.app=my-app`
3. **Containers array (1-based)**: `--spec.template.spec.containers.1.name=main --spec.template.spec.containers.1.image=nginx`
4. **Resources use `{*}` format**: `--spec.template.spec.containers.1.resources.limits.cpu=500m`
5. **Selector matchLabels use `{*}` format**: `--spec.selector.matchLabels.app=my-app`
6. **Namespaced operations require `--namespace`**: all workload operations must specify namespace
> **⚠️ Critical**: Before constructing any CCI command, always run `hcloud CCI <Operation> --help` to verify exact parameter names. CCI has hundreds of parameters; the help output is the authoritative source.
### Parameter Format Details
See [references/parameter-format.md](references/parameter-format.md) for complete CCI parameter format rules and examples.
## Scenario Routing
| User Intent | Reference Document |
|---|---|
| Create/query/delete Namespace | [references/task-namespace-management.md](references/task-namespace-management.md) |
| Create/query/delete Network | [references/task-network-management.md](references/task-network-management.md) |
| Create/query/update/delete/scale Deployment | [references/task-deployment-management.md](references/task-deployment-management.md) |
| Create/query/update/delete StatefulSet | [references/task-statefulset-management.md](references/task-statefulset-management.md) |
| Create/query/delete Pod | [references/task-pod-management.md](references/task-pod-management.md) |
| Create/query/delete EIPPool | [references/task-eippool-management.md](references/task-eippool-management.md) |
| Query status, view logs, events | [references/task-logs-and-status.md](references/task-logs-and-status.md) |
| Full workflow (create→run→cleanup) | [references/common-workflows.md](references/common-workflows.md) |
| All CCI operations quick reference | [references/cci-operation-catalog.md](references/cci-operation-catalog.md) |
| Troubleshooting | [references/troubleshooting.md](references/troubleshooting.md) |
| IAM permissions | [references/iam-policies.md](references/iam-policies.md) |
| Verification steps | [references/verification-method.md](references/verification-method.md) |
| Correct/error pattern comparison | [references/acceptance-criteria.md](references/acceptance-criteria.md) |
## Core Commands
### Namespace
```bash
# Create namespace (general-computing flavor)
hcloud CCI createCoreV1Namespace \
--metadata.name=<ns-name> \
--metadata.annotations.namespace-kubernetes-io/flavor=general-computing \
--cli-region=<region \
--cli-output=json
# List namespaces
hcloud CCI listCoreV1Namespace --cli-region=<region> --cli-output=json
# Read namespace details
hcloud CCI readCoreV1Namespace --name=<ns-name> --cli-region=<region> --cli-output=json
# Delete namespace (TWO-STEP CONFIRMATION REQUIRED)
hcloud CCI deleteCoreV1Namespace --name=<ns-name> --cli-region=<region>
```
### Network
> **⚠️ hcloud CLI limitation**: Network creation requires a Python helper script because hcloud CLI cannot pass the annotation key `network.alpha.kubernetes.io/default-security-group` (contains dots that hcloud treats as nested levels). The `--cli-jsonInput` approach also doesn't work due to an hcloud bug where annotations show in `--dryrun` but aren't transmitted in actual requests. See [hcloud CLI Limitations](#hcloud-cli-limitations) below.
>
> **⚠️ Credential requirement**: The Python helper script uses `HW_ACCESS_KEY`/`HW_SECRET_KEY` (and optionally `HW_SECURITY_TOKEN`) environment variables for authentication. This is **independent** from hcloud CLI's credential source (which reads from `HUAWEI_CLOUD_AK`/`HUAWEI_CLOUD_SK` or its profile). If the credentials in `HW_ACCESS_KEY`/`HW_SECRET_KEY` lack CCI Network creation permissions, the script will fail with 403. Ensure they have sufficient IAM permissions (e.g., `CCI FullAccess`). After the script runs, hcloud CLI commands continue using their own credential source unaffected.
```bash
# Step 1: Get VPC subnet details (including neutron_network_id)
hcloud VPC ShowSubnet --vpc_id=<vpc-id> --subnet_id=<subnet-id> --cli-region=<region> --cli-output=json
# Step 2: Create network via Python helper script
python scripts/cci_network_helper.py create \
--namespace=<ns-name> \
--name=<network-name> \
--vpc-id=<vpc-id> \
--subnet-id=<subnet-id> \
--network-id=<neutron-network-id> \
--security-group-id=<sg-id> \
--region=<region>
# Step 3: Check network status until Active
hcloud CCI readNetworkingCciIoV1beta1NamespacedNetworkStatus \
--name=<network-name> \
--namespace=<ns-name> \
--cli-region=<region> \
--cli-output=json
# List networks
hcloud CCI listNetworkingCciIoV1beta1NamespacedNetwork \
--namespace=<ns-name> \
--cli-region=<region> \
--cli-output=json
```
**Required Network spec fields**: Network creation requires `attachedVPC`, `subnetID`, `networkType`, AND `networkID` (neutron network ID). The `networkID` field is REQUIRED — it is the neutron network ID obtained from `hcloud VPC ShowSubnet`.
**Required Network annotation**: `network.alpha.kubernetes.io/default-security-group` (the correct annotation key for CCI Network security group, NOT `security-group-id`). This annotation must be set to the security group ID.
### Deployment
```bash
# Create deployment
hcloud CCI createAppsV1NamespacedDeployment \
--namespace=<ns-name> \
--metadata.name=<deploy-name> \
--spec.replicas=1 \
--spec.selector.matchLabels.app=<deploy-name> \
--spec.template.metadata.labels.app=<deploy-name> \
--spec.template.spec.containers.1.name=<container-name> \
--spec.template.spec.containers.1.image=<image> \
--spec.template.spec.containers.1.resources.limits.cpu=500m \
--spec.template.spec.containers.1.resources.limits.memory=1Gi \
--spec.template.spec.containers.1.resources.requests.cpu=500m \
--spec.template.spec.containers.1.resources.requests.memory=1Gi \
--cli-region=<region> \
--cli-output=json
# Scale deployment
hcloud CCI patchAppsV1NamespacedDeploymentScale \
--name=<deploy-name> \
--namespace=<ns-name> \
--spec.replicas=<new-replicas> \
--cli-region=<region>
# Read deployment status
hcloud CCI readAppsV1NamespacedDeploymentStatus \
--name=<deploy-name> \
--namespace=<ns-name> \
--cli-region=<region> \
--cli-output=json
```
### StatefulSet
```bash
# Create statefulset
hcloud CCI createAppsV1NamespacedStatefulSet \
--namespace=<ns-name> \
--metadata.name=<sts-name> \
--spec.replicas=1 \
--spec.selector.matchLabels.app=<sts-name> \
--spec.template.metadata.labels.app=<sts-name> \
--spec.template.spec.containers.1.name=<container-name> \
--spec.template.spec.containers.1.image=<image> \
--spec.template.spec.containers.1.resources.limits.cpu=500m \
--spec.template.spec.containers.1.resources.limits.memory=1Gi \
--cli-region=<region> \
--cli-output=json
# Read statefulset status
hcloud CCI readAppsV1NamespacedStatefulSetStatus \
--name=<sts-name> \
--namespace=<ns-name> \
--cli-region=<region> \
--cli-output=json
```
### Pod
```bash
# Create pod (single container instance)
hcloud CCI createCoreV1NamespacedPod \
--namespace=<ns-name> \
--metadata.name=<pod-name> \
--spec.containers.1.name=<container-name> \
--spec.containers.1.image=<image> \
--spec.containers.1.resources.limits.cpu=500m \
--spec.containers.1.resources.limits.memory=1Gi \
--cli-region=<region> \
--cli-output=json
# Read pod status
hcloud CCI readCoreV1NamespacedPodStatus \
--name=<pod-name> \
--namespace=<ns-name> \
--cli-region=<region> \
--cli-output=json
# Read pod logs
hcloud CCI readCoreV1NamespacedPodLog \
--name=<pod-name> \
--namespace=<ns-name> \
--container=<container-name> \
--cli-region=<region>
```
### EIPPool
```bash
# Create EIPPool (for pod public IP access — auto-create EIPs)
hcloud CCI createCrdYangtseCniV1NamespacedEIPPool \
--namespace=<ns-name> \
--apiVersion=crd.yangtse.cni/v1 \
--kind=EIPPool \
--metadata.name=<eippool-name> \
--spec.amount=1 \
--spec.eipAttributes.networkType=5_bgp \
--spec.eipAttributes.ipVersion=4 \
--spec.eipAttributes.bandwidth.shareType=PER \
--spec.eipAttributes.bandwidth.size=5 \
--spec.eipAttributes.bandwidth.chargeMode=bandwidth \
--spec.eipAttributes.bandwidth.name=<bw-name> \
--cli-region=<region> \
--cli-output=json
# Read EIPPool status
hcloud CCI readCrdYangtseCniV1NamespacedEIPPoolStatus \
--name=<eippool-name> \
--namespace=<ns-name> \
--cli-region=<region> \
--cli-output=json
```
**EIPPool required fields**: `--apiVersion=crd.yangtse.cni/v1` and `--kind=EIPPool` are mandatory. `spec.eipAttributes.networkType` is required (values: `5_bgp` for dynamic BGP, `5_gray` for dedicated load balancing). `spec.eipAttributes.bandwidth.chargeMode` and `name` are required when auto-creating EIPs.
**Pod EIP binding**: To assign an EIPPool to a Pod, add annotation `yangtse.io/eippool=<eippool-name>` (use hyphen workaround: `--metadata.annotations.yangtse-io/eippool=<eippool-name>`).
## VPC/Subnet Prerequisites
CCI workloads run inside a Network that maps to an existing VPC subnet. Before creating a Network, query available VPCs and subnets, and obtain the neutron network ID (required for Network creation):
```bash
# List VPCs
hcloud VPC ListVpcs --cli-region=<region> --cli-output=json
# List subnets
hcloud VPC ListSubnets --cli-region=<region> --cli-output=json
# Get subnet details (including neutron_network_id — REQUIRED for Network creation)
hcloud VPC ShowSubnet --vpc_id=<vpc-id> --subnet_id=<subnet-id> --cli-region=<region> --cli-output=json
```
> **⚠️ VPC subnet CIDR restriction**: The VPC and subnet CIDR must NOT be `10.247.0.0/16` — this range is reserved by CCI for Service networking. Using it causes IP conflicts and workload creation failures.
> **⚠️ neutron_network_id is required**: The `neutron_network_id` from `VPC ShowSubnet` output is the value for the `networkID` field in Network spec. This field is REQUIRED for Network creation.
## Namespace Flavor Types
| Flavor Value | Description | Use Case |
|---|---|---|
| `general-computing` | General computing type | Standard workloads, web services, microservices |
| `gpu-accelerated` | GPU accelerated type | AI, ML, high-performance computing |
## Resource Quota and Limits
CCI enforces resource quotas per namespace. Common defaults:
| Resource | Default Limit |
|---|---|
| Pods | varies by region |
| CPU per Pod | 0.25 - 8 cores |
| Memory per Pod | 0.5Gi - 32Gi |
| PVCs | varies |
Query current quotas:
```bash
hcloud CCI listCoreV1NamespacedResourceQuota --namespace=<ns-name> --cli-region=<region> --cli-output=json
```
## Output Format
### JSON (recommended)
```bash
hcloud CCI <Operation> --cli-region=<region> --cli-output=json
```
### Table (for manual viewing)
```bash
hcloud CCI <Operation> --cli-region=<region> --cli-output=table
```
### JMESPath Filtering
```bash
# Filter deployment status
hcloud CCI readAppsV1NamespacedDeploymentStatus --name=<deploy> --namespace=<ns> --cli-region=<region> --cli-output=json --cli-query="{replicas:status.replicas,ready:status.readyReplicas,available:status.availableReplicas}"
# Filter pod phase
hcloud CCI readCoreV1NamespacedPodStatus --name=<pod> --namespace=<ns> --cli-region=<region> --cli-output=json --cli-query="status.phase"
```
--cli-region=<region> --cli-output=json \
--cli-query="status.phase"
```
## Debugging
Add `--cli-debug=true` to any command for detailed request/response information:
```bash
hcloud CCI <Operation> --cli-debug=true --cli-region=<region>
```
## Parameter Confirmation
Before executing any CCI operation, confirm these parameters:
| Parameter | Required | Description | Source |
|---|---|---|---|
| `--namespace` | Yes | CCI namespace name | Existing or newly created |
| `--cli-region` | Yes | Huawei Cloud region ID | `HUAWEI_CLOUD_REGION` or config |
| `--metadata.name` | Yes | Resource name | User specified |
| Flavor annotation | Yes (Namespace) | `general-computing` or `gpu-accelerated` | User choice |
| VPC/Subnet ID | Yes (Network) | From `VPC ListVpcs` / `VPC ShowSubnet` | Query existing resources |
| neutron_network_id | Yes (Network) | From `VPC ShowSubnet` response | Query result |
> Run `hcloud CCI <Operation> --help` before any CCI command to verify parameter names, then cross-reference the table above.
## Precautions
See [references/troubleshooting.md](references/troubleshooting.md) for detailed troubleshooting.
**Quick reference**:
| Issue | Cause | Quick Fix |
|---|---|---|
| Namespace creation fails | Missing flavor annotation | Add `--metadata.annotations.namespace-kubernetes-io/flavor=general-computing` |
| Network creation fails (400/403) | Missing VPC/subnet/annotation/networkID, or credential scope insufficient | Verify subnet/neutron IDs, security group; use Python helper; use **long-term AK/SK** (Mode A) |
| Pod stays Pending | No Network in namespace | Create Network first |
| 403 permission error | Insufficient IAM | Check [references/iam-policies.md](references/iam-policies.md) |
| Deep nested param errors | Wrong dot notation | Use `--help` to verify exact parameter path |
| Annotation with dots not passed | hcloud CLI limitation | Use Python helper script for Network creation |
| EIPPool creation fails (400/422) | Missing apiVersion/kind/networkType | Add all required fields (see EIPPool section) |
| limit/request mismatch | CCI requires limits == requests | Set requests same as limits (e.g., both `500m/1Gi`) |
## Verification Method
See [references/verification-method.md](references/verification-method.md) for complete verification steps.
**Quick checklist**:
| Step | Command | Expected Result |
|---|---|---|
| Namespace | `hcloud CCI readCoreV1Namespace --name=<ns> --cli-region=<region>` | status.phase=Active |
| Network | `hcloud CCI readNetworkingCciIoV1beta1NamespacedNetworkStatus --name=<net> --namespace=<ns>` | status.phase=Active |
| Deployment | `hcloud CCI readAppsV1NamespacedDeploymentStatus --name=<deploy> --namespace=<ns>` | readyReplicas >= 1 |
| Pod | `hcloud CCI readCoreV1NamespacedPodStatus --name=<pod> --namespace=<ns>` | status.phase=Running |
## Best Practices
1. **Namespace isolation**: Use different namespaces for different teams/projects to avoid resource conflicts
2. **EIPPool on-demand**: Only create EIPPool when Pod public IP access is needed
## hcloud CLI Limitations
> **⚠️ Critical**: hcloud CLI has known limitations that affect CCI operations. Understanding these is essential for successful Network creation.
| Limitation | Impact | Workaround |
|---|---|---|
| **Cannot pass annotation keys containing dots (.) via CLI parameters** | hcloud treats dots in parameter names as nested object levels, so `--metadata.annotations.network.alpha.kubernetes.io/default-security-group` creates a deeply nested structure instead of a single annotation key | Use Python helper script (`scripts/cci_network_helper.py`) for Network creation |
| **`--cli-jsonInput` doesn't properly transmit annotations** | hcloud bug: annotations appear in `--dryrun` output but are not transmitted in actual API requests | Use Python helper script instead |
| **`--cli-jsonInput` requires ASCII encoding** | UTF-8 BOM causes JSON parsing failure | Ensure JSON input files are saved as plain ASCII (no BOM) |
| **Namespace annotation works with hyphen replacement** | Keys like `namespace.kubernetes.io/flavor` can use hyphens (`namespace-kubernetes-io/flavor`) and CCI auto-normalizes them back | This workaround only works for Namespace, NOT for Network |
**Why Network needs a Python helper**: The Network annotation key `network.alpha.kubernetes.io/default-security-group` cannot be passed via hcloud CLI (neither dot notation nor `--cli-jsonInput`). Unlike Namespace annotations, CCI does NOT normalize hyphen-replaced keys for Network resources. The Python helper script (`scripts/cci_network_helper.py`) constructs the correct API request body directly.
## References
| Document | Description |
|---|---|
| [task-namespace-management.md](references/task-namespace-management.md) | Namespace lifecycle operations |
| [task-network-management.md](references/task-network-management.md) | Network lifecycle operations |
| [task-deployment-management.md](references/task-deployment-management.md) | Deployment lifecycle operations |
| [task-statefulset-management.md](references/task-statefulset-management.md) | StatefulSet lifecycle operations |
| [task-pod-management.md](references/task-pod-management.md) | Pod lifecycle operations |
| [task-eippool-management.md](references/task-eippool-management.md) | EIPPool operations |
| [task-logs-and-status.md](references/task-logs-and-status.md) | Status queries and log viewing |
| [cci-operation-catalog.md](references/cci-operation-catalog.md) | Full CCI operation quick reference |
| [parameter-format.md](references/parameter-format.md) | CCI parameter format rules and examples |
| [common-workflows.md](references/common-workflows.md) | Complete workflow sequences |
| [credential-configuration.md](references/credential-configuration.md) | Credential setup (long-term AK/SK & temporary AK/SK+SecurityToken) |
| [iam-policies.md](references/iam-policies.md) | IAM permission policies |
| [troubleshooting.md](references/troubleshooting.md) | Error troubleshooting |
| [verification-method.md](references/verification-method.md) | Verification steps |
| [acceptance-criteria.md](references/acceptance-criteria.md) | Correct/error pattern comparison |
| [scripts/cci_network_helper.py](scripts/cci_network_helper.py) | Python helper script for Network creation (bypasses hcloud CLI annotation limitations) |