
Alibabacloud Flink Instance Manage
- 189 installs
- 208 repo stars
- Updated August 4, 2026
- aliyun/alibabacloud-aiops-skills
Provision, scale, restart, and lifecycle-manage Alibaba Cloud Realtime Compute for Apache Flink instances for streaming ETL and event pipelines.
About
Covers operational management of Alibaba Cloud Flink streaming compute instances via aiops-skills: provisioning workspaces, scaling capacity units, lifecycle controls, and keeping streaming jobs running reliably on managed cloud infrastructure.
- Create and configure Flink workspace instances
- Adjust CU quotas, versions, and runtime settings
- Start, stop, restart, and decommission clusters
- Align networking, IAM, and billing with project needs
Alibabacloud Flink Instance Manage by the numbers
- 189 all-time installs (skills.sh)
- Ranked #464 of 1,039 Cloud & Infrastructure skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/aliyun/alibabacloud-aiops-skills --skill alibabacloud-flink-instance-manageAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 189 |
|---|---|
| repo stars | ★ 208 |
| Last updated | August 4, 2026 |
| Repository | aliyun/alibabacloud-aiops-skills ↗ |
What it does
Provision, scale, restart, and lifecycle-manage Alibaba Cloud Realtime Compute for Apache Flink instances for streaming ETL and event pipelines.
Files
Alibaba Cloud Flink Instance Manage
Operate Alibaba Cloud Flink VVP resources with a strict create/query scope through one wrapper script.
Scope and Entrypoint
- Always run operations through:
python scripts/instance_ops.py <command> [options]- Allowed commands:
create,create_namespace,describe,describe_regions,describe_zones,describe_namespaces,list_tags - Out of scope: update/delete, Flink SQL/job runtime operations, and non-Flink services
Trigger Rules
Use this skill when prompts are about Flink instance/namespace lifecycle operations.
- Positive intent examples:
- "Create a Flink instance in cn-beijing"
- "List Flink instances and status"
- "Describe namespaces for instance f-cn-xxx"
- "查询 Flink 实例标签"
- "Flink 可用区有哪些"
- Negative intent examples:
- ECS/Kafka/OSS/DataWorks operations
- Generic questions (weather, translation, etc.)
- Flink SQL / Flink job authoring or runtime tuning
- Ambiguous prompts:
- Ask one clarification question: instance/namespace management vs SQL/job operations.
Intent to Command Mapping
| User intent | Command |
|---|---|
| Query all instances in a region | describe --region_id <REGION> |
| Create instance | create ... --confirm |
| Query namespaces under an instance | describe_namespaces --region_id <REGION> --instance_id <ID> |
| Create namespace | create_namespace ... --confirm |
| Query supported regions/zones | describe_regions / describe_zones --region_id <REGION> |
| Query tags | list_tags --region_id <REGION> --resource_type <TYPE> [--resource_ids ...] |
Operating Rules
1. Confirmation is mandatory for create commands
createandcreate_namespacemust include--confirm.
2. Verify create results with read-back
- Do not conclude success from create response alone.
3. Retry policy is strict
- Maximum 2 attempts for the same command (initial + one corrected retry).
4. No automatic operation switching
- If an operation fails, do not switch to a different operation without user approval.
5. Lifecycle target lock
- In
create -> create_namespaceflow, namespace must target the same newly createdInstanceIdunless user approves fallback.
6. Namespace pre-check is required
- Before
create_namespace, check instance status/resources and existing namespace allocation.
7. No secret exposure
- Do not output or request plaintext AK/SK. Use default credential chain guidance.
8. Do not invent parameters
- Never fabricate VPC/VSwitch/instance IDs.
9. Keep auditable confirmation evidence
- Lifecycle outputs must contain
SafetyCheckRequiredor explicit--confirmevidence.
10. No partial-completion claims for lifecycle flows
- For flows requiring both
createandcreate_namespace, overall status can becompletedonly when both create operations succeed.
11. No automatic capacity scaling
- If
create_namespacefails due to insufficient resources, report it clearly and ask user to manually scale resources outside this skill scope.
Execution Protocol
Step 1: Classify request
- In-scope create/query for Flink instance/namespace/tag/region/zone -> continue.
- Out-of-scope or non-Flink -> reject or route with explanation.
Step 2: Validate parameters
- Apply
references/parameter-validation.md. - If required parameters are missing, ask user or return clear remediation.
Step 3: Execute command
- Query commands: run once unless transient query error.
- Create commands: construct final command string and verify
--confirmis present before execution.
Step 4: Verify create outcomes
- For
create: verify withdescribe --region_id <REGION>. - For
create_namespace: verify withdescribe_namespaces --region_id <REGION> --instance_id <ID>. - Use up to 3 read checks with short backoff before concluding the create is not reflected yet.
- For chained
create -> create_namespace: - poll
describe --region_id <REGION>on the sameInstanceIdevery 30 seconds - max wait: 10 minutes
- if still not
RUNNING, stop and provide next action (wait/retry later) - do not switch to another instance without explicit user approval
- if namespace create fails, mark lifecycle chain as
failed/not_ready, notcompleted - for
InsufficientResources, ask user to manually scale the instance and retry later
Key References
- Start here:
references/README.mdreferences/quick-start.mdreferences/trigger-recognition-guide.mdreferences/core-execution-flow.mdreferences/command-templates.md
| Document | Purpose |
|---|---|
references/parameter-validation.md | Pre-execution validation checklist |
references/e2e-playbooks.md | Complete execution sequences |
references/common-failures.md | Typical mistakes and fixes |
references/required-confirmation-model.md | Confirmation gate rules |
references/instance-state-management.md | Instance state and readiness checks |
references/output-handling.md | Output parsing and retry policy |
references/verification-method.md | Verification patterns after create/query |
references/acceptance-criteria.md | Completion checklist for normal operations |
references/python-environment-setup.md | Python dependency and auth setup |
references/cli-installation-guide.md | Aliyun CLI diagnostics setup |
references/ram-policies.md | Required RAM permissions |
references/related-apis.md | API and command mapping |
Output Format
All commands return JSON:
{
"success": true,
"operation": "<command>",
"confirmation_check": {
"required_flag": "--confirm",
"provided": true,
"status": "passed"
},
"data": {},
"request_id": "..."
}confirmation_check appears on create operations and is used for auditable safety evidence.
Exit codes: 0 = success, 1 = error.
alibabacloud-foasconsole20211028==2.2.1
alibabacloud-tea-openapi==0.4.3
alibabacloud-tea-util==0.3.14
alibabacloud-credentials==1.0.8
Operation Completion Checklist
Use this checklist to decide whether an instance/namespace operation is actually complete.
1) Entrypoint
Run resource operations only through:
python scripts/instance_ops.py <command> ...Do not replace with raw aliyun foasconsole commands.
2) Confirmation flags
createrequires--confirmcreate_namespacerequires--confirm
If --confirm is missing, fix the command before execution.
3) Read-back verification
A create operation is complete only when:
1. create response is successful (or idempotent equivalent), and 2. follow-up read-back confirms target state.
Create response without read-back is not complete.
4) Retry and fallback
- Max attempts for one command: 2 (initial + one corrected retry)
- No blind retries
- No automatic operation switching without explicit user approval
5) Lifecycle chain consistency
For create + create_namespace in one flow:
- namespace must target the same
InstanceIdreturned bycreate - if instance is not
RUNNING, wait/poll the same instance first - do not switch to a different instance without explicit user approval
- final
completedstatus requires both create commands to returnsuccess: true
6) Security baseline
- No AK/SK hardcoding in commands or scripts
- Use default credential chain (CLI profile or RAM role)
- No secret values in normal response content
7) Response completeness
Final response should include:
operationcreate_resultverify_resultstatus(completed/failed/not_ready)next_actionwhen not completed
8) No partial-success closure for lifecycle flow
For lifecycle tasks that require instance + namespace create:
- if
create_namespacefails, do not mark overall status ascompleted - use
failedornot_readywith explicit next action
Aliyun CLI Installation & Configuration Guide
Complete guide for installing and configuring Aliyun CLI.
Aliyun CLI 3.3.1+: Supports installing and using all published Alibaba Cloud product plugins. Make sure to upgrade to 3.3.1 or later for full plugin ecosystem coverage.
Table of Contents
- Installation
- Configuration
- Verification
- Security Best Practices
- Troubleshooting
- Advanced Configuration
- Next Steps
- References
Installation
macOS
Using Homebrew (Recommended)
brew install aliyun-cli
# Upgrade to latest
brew upgrade aliyun-cli
# Verify version (>= 3.3.1)
aliyun versionUsing Binary
# Download
wget https://aliyuncli.alicdn.com/aliyun-cli-macosx-latest-amd64.tgz
# Extract
tar -xzf aliyun-cli-macosx-latest-amd64.tgz
# Move to PATH
sudo mv aliyun /usr/local/bin/
# Verify
aliyun versionLinux
Debian/Ubuntu
# Download
wget https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgz
# Extract and install
tar -xzf aliyun-cli-linux-latest-amd64.tgz
sudo mv aliyun /usr/local/bin/
# Verify
aliyun versionCentOS/RHEL
# Download
wget https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgz
# Extract and install
tar -xzf aliyun-cli-linux-latest-amd64.tgz
sudo mv aliyun /usr/local/bin/
# Verify
aliyun versionARM64 Architecture
# Download ARM64 version
wget https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-arm64.tgz
# Extract and install
tar -xzf aliyun-cli-linux-latest-arm64.tgz
sudo mv aliyun /usr/local/bin/Windows
Using Binary 1. Download from: https://aliyuncli.alicdn.com/aliyun-cli-windows-latest-amd64.zip 2. Extract the ZIP file 3. Add the directory to your PATH environment variable 4. Open new Command Prompt or PowerShell 5. Verify: aliyun version
Using PowerShell
# Download
Invoke-WebRequest -Uri "https://aliyuncli.alicdn.com/aliyun-cli-windows-latest-amd64.zip" -OutFile "aliyun-cli.zip"
# Extract
Expand-Archive -Path aliyun-cli.zip -DestinationPath C:\aliyun-cli
# Add to PATH (requires admin privileges)
$env:Path += ";C:\aliyun-cli"
[Environment]::SetEnvironmentVariable("Path", $env:Path, [System.EnvironmentVariableTarget]::Machine)
# Verify
aliyun versionConfiguration
Quick Start
aliyun configure set \
--mode AK \
--access-key-id <your-access-key-id> \
--access-key-secret <your-access-key-secret> \
--region cn-hangzhouAll aliyun configure commands support non-interactive flags, which is the recommended approach — it works in scripts, CI/CD pipelines, and agent-driven automation without hanging on stdin prompts.
Where to Get Access Keys
1. Log in to Aliyun Console: https://ram.console.aliyun.com/ 2. Navigate to: AccessKey Management 3. Create a new AccessKey pair 4. Save the secret immediately — it's only shown once
Configuration Modes
Aliyun CLI supports 6 authentication modes. All examples below use non-interactive flags.
1. AK Mode (Access Key)
Most common mode for personal accounts and scripts.
aliyun configure set \
--mode AK \
--access-key-id LTAI5tXXXXXXXX \
--access-key-secret 8dXXXXXXXXXXXXXXXXXXXXXXXX \
--region cn-hangzhouConfiguration is stored in ~/.aliyun/config.json:
{
"current": "default",
"profiles": [
{
"name": "default",
"mode": "AK",
"access_key_id": "LTAI5tXXXXXXXX",
"access_key_secret": "8dXXXXXXXXXXXXXXXXXXXXXXXX",
"region_id": "cn-hangzhou",
"output_format": "json",
"language": "en"
}
]
}2. StsToken Mode (Temporary Credentials)
For short-lived access (tokens expire in 1-12 hours).
aliyun configure set \
--mode StsToken \
--access-key-id LTAI5tXXXXXXXX \
--access-key-secret 8dXXXXXXXXXXXXXXXXXXXXXXXX \
--sts-token v1.0:XXXXXXXXXXXXXXXX \
--region cn-hangzhouUse cases: CI/CD pipelines, temporary access for external contractors, cross-account access.
3. RamRoleArn Mode (Assume RAM Role)
Assume a RAM role for elevated or cross-account access.
aliyun configure set \
--mode RamRoleArn \
--access-key-id LTAI5tXXXXXXXX \
--access-key-secret 8dXXXXXXXXXXXXXXXXXXXXXXXX \
--ram-role-arn acs:ram::123456789012:role/AdminRole \
--role-session-name my-session \
--region cn-hangzhouUse cases: cross-account resource access, temporary elevated privileges, role-based access control.
4. EcsRamRole Mode (ECS Instance RAM Role)
Use the RAM role attached to an ECS instance — no credentials needed.
aliyun configure set \
--mode EcsRamRole \
--ram-role-name MyEcsRole \
--region cn-hangzhouRequirements: must be running on an ECS instance with a RAM role attached.
Use cases: scripts and automation running on ECS instances.
5. RsaKeyPair Mode (RSA Key Pair)
Use RSA key pair for authentication (generate key pair in Aliyun Console first).
aliyun configure set \
--mode RsaKeyPair \
--private-key /path/to/private-key.pem \
--key-pair-name my-key-pair \
--region cn-hangzhou6. RamRoleArnWithEcs Mode (ECS + RAM Role)
Combine ECS instance role with RAM role assumption for cross-account access from ECS.
aliyun configure set \
--mode RamRoleArnWithEcs \
--ram-role-name MyEcsRole \
--ram-role-arn acs:ram::123456789012:role/TargetRole \
--role-session-name my-session \
--region cn-hangzhouEnvironment Variables
Highest priority - overrides config file
Access Key Mode
export ALIBABA_CLOUD_ACCESS_KEY_ID=your_access_key_id
export ALIBABA_CLOUD_ACCESS_KEY_SECRET=your_access_key_secret
export ALIBABA_CLOUD_REGION_ID=cn-hangzhouSTS Token Mode
export ALIBABA_CLOUD_ACCESS_KEY_ID=your_access_key_id
export ALIBABA_CLOUD_ACCESS_KEY_SECRET=your_access_key_secret
export ALIBABA_CLOUD_SECURITY_TOKEN=your_sts_token
export ALIBABA_CLOUD_REGION_ID=cn-hangzhouECS RAM Role Mode
export ALIBABA_CLOUD_ECS_METADATA=role_nameUse Case:
- CI/CD pipelines
- Docker containers
- Temporary credential override
Managing Multiple Profiles
Create Named Profiles
aliyun configure set --profile projectA \
--mode AK \
--access-key-id LTAI5tAAAAAAAA \
--access-key-secret 8dAAAAAAAAAAAAAAAAAAAAAAAA \
--region cn-hangzhou
aliyun configure set --profile projectB \
--mode AK \
--access-key-id LTAI5tBBBBBBBB \
--access-key-secret 8dBBBBBBBBBBBBBBBBBBBBBBBB \
--region cn-shanghaiUse Specific Profile
aliyun ecs describe-instances --profile projectA
export ALIBABA_CLOUD_PROFILE=projectA
aliyun ecs describe-instances # Uses projectAList and Switch Profiles
aliyun configure list # List all profiles
aliyun configure set --current projectA # Switch default profileCredential Priority
Credentials are loaded in this order (first found wins):
1. Command-line flag: --profile <name> 2. Environment variable: ALIBABA_CLOUD_PROFILE 3. Environment credentials: ALIBABA_CLOUD_ACCESS_KEY_ID, etc. 4. Configuration file: ~/.aliyun/config.json (current profile) 5. ECS Instance RAM Role: If running on ECS with attached role
Verification
Test Authentication
# Basic test - list regions
aliyun ecs describe-regions
# Expected output: JSON array of regionsIf successful, you'll see:
{
"Regions": {
"Region": [
{
"RegionId": "cn-hangzhou",
"RegionEndpoint": "ecs.cn-hangzhou.aliyuncs.com",
"LocalName": "华东 1(杭州)"
},
...
]
},
"RequestId": "..."
}If failed, you'll see error messages:
InvalidAccessKeyId.NotFound- Wrong Access Key IDSignatureDoesNotMatch- Wrong Access Key SecretInvalidSecurityToken.Expired- STS token expired (for StsToken mode)Forbidden.RAM- Insufficient permissions
Debug Configuration
# Show current configuration
aliyun configure get
# Test with debug logging
aliyun ecs describe-regions --log-level=debug
# Check credential provider
aliyun configure get modeSecurity Best Practices
1. Use RAM Users (Not Root Account)
❌ Don't: Use Aliyun root account credentials ✅ Do: Create RAM users with specific permissions
# Create RAM user in console
# Attach only necessary policies
# Use RAM user's access keys2. Principle of Least Privilege
Grant only the minimum permissions needed:
# Example: Read-only ECS access
# Attach policy: AliyunECSReadOnlyAccess3. Rotate Access Keys Regularly
# Create new access key in RAM Console, then refresh configuration
aliyun configure set --access-key-id NEW_KEY --access-key-secret NEW_SECRET
# Delete old access key from console4. Use STS Tokens for Temporary Access
aliyun configure set --mode StsToken \
--access-key-id XXXX --access-key-secret XXXX \
--sts-token XXXX --region cn-hangzhou5. Use ECS RAM Roles When Possible
aliyun configure set --mode EcsRamRole --ram-role-name MyRole --region cn-hangzhou6. Never Commit Credentials
# Add to .gitignore
echo "~/.aliyun/config.json" >> .gitignore
# Use environment variables in CI/CD instead7. Secure Config File
# Restrict permissions
chmod 600 ~/.aliyun/config.jsonTroubleshooting
Issue: Command Not Found
# Check installation
which aliyun
# Check PATH
echo $PATH
# Reinstall or add to PATHIssue: Authentication Failed
# Verify configuration
aliyun configure get
# Test with debug
aliyun ecs describe-regions --log-level=debug
# Check credentials in console
# Verify access key is activeIssue: Permission Denied
# Error: Forbidden.RAM
# Check RAM user permissions
# Attach necessary policies in RAM console
# Example: AliyunECSFullAccess for ECS operationsIssue: STS Token Expired
# Error: InvalidSecurityToken.Expired
# Reconfigure with new token
aliyun configure set --mode StsToken \
--access-key-id XXXX --access-key-secret XXXX \
--sts-token NEW_TOKEN --region cn-hangzhouIssue: Wrong Region
# Some resources may not exist in the specified region
# Check available regions
aliyun ecs describe-regions
# Update default region
aliyun configure set region cn-shanghaiAdvanced Configuration
Custom Endpoint
# Use custom or private endpoint
export ALIBABA_CLOUD_ECS_ENDPOINT=ecs-vpc.cn-hangzhou.aliyuncs.comProxy Settings
# HTTP proxy
export HTTP_PROXY=<proxy-url>
export HTTPS_PROXY=<proxy-url>
# No proxy for specific domains
export NO_PROXY=localhost,127.0.0.1,.aliyuncs.comTimeout Settings
# Connection timeout (default: 10s)
export ALIBABA_CLOUD_CONNECT_TIMEOUT=30
# Read timeout (default: 10s)
export ALIBABA_CLOUD_READ_TIMEOUT=30Next Steps
After installation and configuration:
1. Install plugins for services you need (v3.3.1+ supports all published product plugins):
aliyun plugin install --names ecs vpc rds
# List all available plugins
aliyun plugin list-remote2. Explore commands:
aliyun ecs --help
aliyun fc --help3. Read documentation:
- Command Syntax Guide
- Global Flags Reference
- Common Scenarios
References
- Official Documentation: https://help.aliyun.com/zh/cli/
- RAM Console: https://ram.console.aliyun.com/
- Access Key Management: https://ram.console.aliyun.com/manage/ak
- Plugin Repository: https://github.com/aliyun/aliyun-cli
Command Templates
Copy-paste ready command templates for all operations.
Query Operations
List all regions
python scripts/instance_ops.py describe_regionsList zones in a region
python scripts/instance_ops.py describe_zones --region_id cn-beijingQuery instances in a region
python scripts/instance_ops.py describe --region_id cn-beijingQuery namespaces in an instance
python scripts/instance_ops.py describe_namespaces \
--region_id cn-beijing \
--instance_id f-cn-xxxList tags for resources
python scripts/instance_ops.py list_tags \
--region_id cn-beijing \
--resource_type vvpinstance \
--resource_ids f-cn-xxx,f-cn-yyyCreate Operations
Create instance (PayAsYouGo) - using cu_count
python scripts/instance_ops.py create \
--region_id cn-beijing \
--name my-flink-instance \
--instance_type PayAsYouGo \
--vswitch_id vsw-xxx \
--vpc_id vpc-xxx \
--cu_count 4 \
--confirmNote: --cu_count N = N cores + (N × 4) GB memory
Create instance (PayAsYouGo) - using cpu + memory
python scripts/instance_ops.py create \
--region_id cn-beijing \
--name my-flink-instance \
--instance_type PayAsYouGo \
--vswitch_id vsw-xxx \
--vpc_id vpc-xxx \
--cpu 4 \
--memory_gb 16 \
--confirmCreate instance (Subscription)
python scripts/instance_ops.py create \
--region_id cn-beijing \
--name my-flink-instance \
--instance_type Subscription \
--vswitch_id vsw-xxx \
--vpc_id vpc-xxx \
--cpu 4 \
--memory_gb 16 \
--period 12 \
--confirmCreate namespace (with resources)
python scripts/instance_ops.py create_namespace \
--region_id cn-beijing \
--instance_id f-cn-xxx \
--name prod-namespace \
--cpu 100 \
--memory_gb 400 \
--confirmRequired Parameters Summary
| Command | Required Flags |
|---|---|
describe_regions | none |
describe_zones | --region_id |
describe | --region_id |
create | --region_id, --name, --instance_type, --vswitch_id, --vpc_id, resource spec, --confirm |
describe_namespaces | --region_id, --instance_id |
create_namespace | --region_id, --instance_id, --name, --cpu, --memory_gb, --confirm (for new namespace) |
list_tags | --region_id, --resource_type |
Resource Specification for Create
Option 1: --cu_count N
- Automatically calculates: N cores + (N × 4) GB
- Example:
--cu_count 4= 4 cores + 16 GB
Option 2: --cpu N --memory_gb M
- Both flags required together
- Example:
--cpu 4 --memory_gb 16
❌ Invalid: --cpu alone or --memory_gb alone
Common Failure Patterns
Patterns to avoid. Each pattern shows the wrong approach and the correct fix.
Pattern 1: Missing Confirmation Flag
Scenario: Create command without --confirm
❌ Wrong:
python scripts/instance_ops.py create \
--region_id cn-beijing \
--name my-instance \
--instance_type PayAsYouGo \
--vswitch_id vsw-xxx \
--vpc_id vpc-xxx \
--cu_count 4Error: SafetyCheckRequired
✓ Correct:
python scripts/instance_ops.py create \
--region_id cn-beijing \
--name my-instance \
--instance_type PayAsYouGo \
--vswitch_id vsw-xxx \
--vpc_id vpc-xxx \
--cu_count 4 \
--confirmWhy: --confirm is a safety gate for all create operations.
---
Pattern 2: Incomplete Resource Specification
Scenario: Providing only --cpu or only --memory_gb
❌ Wrong:
--cpu 4→ Error: MissingParameter (memory_gb required)
❌ Wrong:
--memory_gb 16→ Error: MissingParameter (cpu required)
✓ Correct Option A:
--cpu 4 --memory_gb 16✓ Correct Option B:
--cu_count 4(automatically calculates as 4 cores + 16 GB)
Why: Resource specification must be complete. Use either --cu_count OR both --cpu and --memory_gb.
---
Pattern 3: Invalid instance_type
Scenario: Wrong case or format for --instance_type
❌ Wrong:
--instance_type pay-as-you-go
--instance_type PAYASYOUGO
--instance_type payasyougo✓ Correct:
--instance_type PayAsYouGo
--instance_type SubscriptionWhy: Value must match exactly (case-sensitive).
---
Pattern 4: Missing Required Parameters
Scenario: Omitting required flags for create
❌ Wrong:
python scripts/instance_ops.py create \
--region_id cn-beijing \
--name my-instance \
--confirm→ Error: MissingParameter (instance_type, vswitch_id, vpc_id required)
✓ Correct:
python scripts/instance_ops.py create \
--region_id cn-beijing \
--name my-instance \
--instance_type PayAsYouGo \
--vswitch_id vsw-xxx \
--vpc_id vpc-xxx \
--cu_count 4 \
--confirmWhy: All required flags must be present. See parameter-validation.md for complete list.
---
Pattern 5: Blind Retries Without Fixing Root Cause
Scenario: Repeating the same failed command
❌ Wrong:
# First attempt fails with SafetyCheckRequired
python scripts/instance_ops.py create ... --region_id cn-beijing
# Retry with same command (still fails)
python scripts/instance_ops.py create ... --region_id cn-beijing✓ Correct:
# First attempt fails
python scripts/instance_ops.py create ... --region_id cn-beijing
# Fix the root cause (add --confirm)
python scripts/instance_ops.py create ... --region_id cn-beijing --confirmWhy: Maximum 2 attempts total. Second attempt must correct the error.
---
Pattern 6: Claiming Success Without Verification
Scenario: Reporting success after create response only
❌ Wrong:
Create command returned success: true
→ Reporting: "Instance created successfully"✓ Correct:
# Step 1: Create command
python scripts/instance_ops.py create ... --confirm
# Step 2: Verify with query
python scripts/instance_ops.py describe --region_id cn-beijing
# Step 3: Confirm instance exists with correct spec
→ Reporting: "Instance created and verified: found my-instance with 4 cores, 16 GB"Why: Success requires create response + read-back verification.
---
Pattern 7: Auto-switching Operations on Failure
Scenario: Create fails, agent switches to different operation
❌ Wrong:
# Create instance fails
python scripts/instance_ops.py create ... --confirm
# Error: InstanceNameConflict
# Agent tries different operation without user approval
python scripts/instance_ops.py create_namespace ...✓ Correct:
# Create instance fails
python scripts/instance_ops.py create ... --confirm
# Error: InstanceNameConflict
# Report error and ask user
"Instance creation failed: name 'my-instance' already exists with different configuration.
Options:
1. Use a different name
2. Verify existing instance spec
3. Delete existing instance (requires update/delete scope - outside skill)"Why: Never switch operations without explicit user approval.
---
Pattern 8: Creating Duplicate Resources
Scenario: Creating resource that already exists
❌ Wrong:
# Create instance without checking if it exists
python scripts/instance_ops.py create \
--name my-instance \
...✓ Correct:
# Step 1: Query existing instances
python scripts/instance_ops.py describe --region_id cn-beijing
# Step 2: Check if my-instance exists
# If exists with same config: skip creation (idempotent success)
# If exists with different config: report conflict
# If not exists: proceed with creationWhy: Check existing state before create to avoid conflicts and enable idempotent behavior.
---
Pattern 9: Operating on Not-Ready Instance
Scenario: Creating namespace immediately after instance creation
❌ Wrong:
# Create instance
python scripts/instance_ops.py create ... --confirm
# Immediately create namespace (fails)
python scripts/instance_ops.py create_namespace --instance_id f-cn-xxx --name ns --confirmError: "Resource adjustment in progress" or "Instance is not ready"
✓ Correct:
# Create instance
python scripts/instance_ops.py create ... --confirm
# Wait for instance to be RUNNING (not just AVAILABLE)
sleep 60
python scripts/instance_ops.py describe --region_id cn-beijing
# Check status is RUNNING before proceeding
# Then create namespace
python scripts/instance_ops.py create_namespace --instance_id f-cn-xxx --name ns --confirmWhy: Instances need time to fully initialize. AVAILABLE status is not sufficient; wait for RUNNING.
---
Pattern 10: Insufficient Resources for Namespace
Scenario: Creating namespace with resources that exceed instance capacity
❌ Wrong:
# Instance has 1 CPU, 4 GB total
# Existing namespace uses 1 CPU, 4 GB
python scripts/instance_ops.py create_namespace \
--instance_id f-cn-xxx \
--name new-ns \
--cpu 2 \
--memory_gb 8 \
--confirmError: "Insufficient resources" or similar
✓ Correct:
# Step 1: Check instance resources
python scripts/instance_ops.py describe --region_id cn-beijing
# Note: Total = 1 CPU, 4 GB
# Step 2: Check existing namespaces
python scripts/instance_ops.py describe_namespaces --instance_id f-cn-xxx --region_id cn-beijing
# Note: Allocated = 1 CPU, 4 GB
# Step 3: Calculate available
# Available = Total - Allocated = 0 CPU, 0 GB
# Report clearly and request manual capacity action
# (this skill does not support scaling operations)
# "Insufficient resources for new namespace.
# Please manually expand or reallocate the instance resources, then retry."Why: Resources are pre-allocated to namespaces. Check availability before creating.
---
Pattern 11: Using Decimal CPU Values
Scenario: Specifying fractional CPU for namespace
❌ Wrong:
python scripts/instance_ops.py create_namespace \
--instance_id f-cn-xxx \
--name ns \
--cpu 0.5 \
--memory_gb 2 \
--confirmError: "CPU must be an integer"
✓ Correct:
python scripts/instance_ops.py create_namespace \
--instance_id f-cn-xxx \
--name ns \
--cpu 1 \
--memory_gb 2 \
--confirmWhy: CPU allocation must be integer values only.
---
Pattern 12: Parsing Output with Grep
Scenario: Using grep to extract instance details from JSON
❌ Wrong:
python scripts/instance_ops.py describe --region_id cn-beijing | grep "InstanceId"This is fragile and may miss context.
✓ Correct Option A (Parse JSON):
python scripts/instance_ops.py describe --region_id cn-beijing | \
python -c "import json,sys; data=json.load(sys.stdin); print(json.dumps([x for x in data['data']['Instances'] if x['InstanceId']=='f-cn-xxx'], indent=2))"✓ Correct Option B (Save and parse):
python scripts/instance_ops.py describe --region_id cn-beijing > /tmp/instances.json
python -c "import json; data=json.load(open('/tmp/instances.json')); inst=[x for x in data['data']['Instances'] if x['InstanceId']=='f-cn-xxx']; print(f\"Status: {inst[0]['Status']}\") if inst else print('Not found')"Why: JSON parsing is reliable. Grep is fragile for structured data.
---
Pattern 13: Fake Closed Loop by Switching Instance
Scenario: Created instance is still CREATING, then namespace is created on another pre-existing instance
❌ Wrong:
# create returns new instance: f-cn-new
python scripts/instance_ops.py create ... --confirm
# f-cn-new still CREATING
python scripts/instance_ops.py describe --region_id cn-beijing
# agent switches target without user approval
python scripts/instance_ops.py create_namespace --instance_id f-cn-old --name ns --confirm✓ Correct:
# keep target locked to f-cn-new
python scripts/instance_ops.py describe --region_id cn-beijing
# poll until f-cn-new status is RUNNING (up to timeout window)
# then create namespace on f-cn-new
python scripts/instance_ops.py create_namespace --instance_id f-cn-new --name ns --confirmWhy: Minimal lifecycle loop requires same-target chain integrity.
---
Pattern 14: Declaring Completion While Namespace Step Is Pending
Scenario: Instance is created, but namespace step has not been executed or verified yet.
❌ Wrong:
Instance created successfully.
Namespace will be created later when instance becomes RUNNING.
Final: completed✓ Correct:
operation: create + create_namespace
create_result: success
verify_result: instance still CREATING after wait window; namespace not executed
status: not_ready
next_action: wait until RUNNING, then create namespace on the same instanceWhy: Lifecycle completion requires both steps to be executed and verified on the same target instance.
---
Pattern 15: Declaring Completion After Namespace Create Failure
Scenario: create_namespace was attempted but returned success: false, yet final report says workflow completed.
❌ Wrong:
Instance create succeeded.
Namespace create failed due to capacity.
Final: completed✓ Correct:
operation: create + create_namespace
create_result: instance created
verify_result: namespace create failed (InsufficientResources)
status: failed
next_action: manually expand/reallocate instance resources, then retry create_namespaceWhy: For lifecycle create/create_namespace flow, completion requires BOTH create commands to succeed.
---
Quick Reference: Error Code → Fix
| Error Code | Root Cause | Fix Action |
|---|---|---|
| SafetyCheckRequired | Missing --confirm | Add --confirm flag, retry once |
| MissingParameter | Missing required flag | Add missing flag, retry once |
| ValueError | Invalid param combo | Fix resource spec, retry once |
| InstanceNameConflict | Instance exists with different config | Use different name or verify existing |
| NamespaceNotFound | Parent instance not found | Verify instance_id exists |
| AccessDenied | Insufficient permissions | Stop, report required RAM policy |
| Throttling | Rate limit | Wait and retry once (query only) |
| ResourceAdjustmentInProgress | Instance not fully initialized | Wait 2-5 min, check status is RUNNING |
| InsufficientResources | Namespace resources exceed available | Inform user to manually expand/reallocate resources, then retry |
| InvalidCpuValue | CPU is not integer | Use integer value (e.g., 1, 2, 4) |
Maximum retries: 2 total (initial + one corrected retry)
Core execution flow
This document defines the execution flow for Alibaba Cloud Flink VVP instance operations.
When to Use This Skill
Trigger when user request is about Flink instance/namespace lifecycle create/query.
English triggers
- "create a Flink instance" / "create Flink"
- "query Flink instance" / "describe Flink"
- "list Flink namespaces" / "query namespace"
- "what regions support Flink" / "Flink regions"
- "Flink VVP" / "Flink on Cloud"
Chinese triggers (中文触发词)
- "创建Flink实例" / "创建实时计算实例"
- "查询Flink实例" / "查询实例信息"
- "创建命名空间" / "Flink命名空间"
- "Flink VVP实例" / "实时计算Flink版"
- "查询Flink区域" / "Flink可用区"
Explicitly DO NOT trigger for
- Flink SQL queries ("运行Flink SQL", "Flink job")
- Other Alibaba Cloud services (ECS, Kafka, OSS, DataWorks)
- Update/delete operations (拒绝此类请求并说明scope)
Execution Entry Point
Use the Python script as the default execution entrypoint. For initial validation, run a query-only command.
python scripts/instance_ops.py describe_regions1) Lifecycle chain
Use this minimal chain for end-to-end requests:
1. discover target scope 2. create resource 3. query read-back verification
Rules:
- Capture
InstanceIdfromcreateresponse and keep it as the single target. - Do not switch to a different instance in the same chain unless user explicitly approves.
- If resource is not visible immediately after create, use repeated read checks
before deciding retry/failure.
- Do not mark lifecycle flow completed when namespace create fails.
2) Discover and inspect
python scripts/instance_ops.py describe_regions
python scripts/instance_ops.py describe --region_id cn-hangzhou
python scripts/instance_ops.py describe_zones --region_id cn-hangzhou3) Create instance
python scripts/instance_ops.py create \
--region_id cn-hangzhou \
--name my-flink-instance \
--instance_type PayAsYouGo \
--zone_id cn-hangzhou-g \
--vswitch_id vsw-xxx \
--vpc_id vpc-xxx \
--cpu 200 \
--memory_gb 800 \
--confirmIf required network parameters (--vpc_id, --vswitch_id) are missing, stop and ask user to provide explicit values. Do not fabricate values.
python scripts/instance_ops.py describe --region_id cn-hangzhou4) Create namespace
python scripts/instance_ops.py create_namespace \
--region_id cn-hangzhou \
--instance_id f-cn-xxx \
--name prod-ns \
--cpu 100 \
--memory_gb 400 \
--confirmpython scripts/instance_ops.py describe_namespaces \
--region_id cn-hangzhou \
--instance_id f-cn-xxx5) Query tag state
python scripts/instance_ops.py list_tags \
--region_id cn-hangzhou \
--resource_type vvpinstance \
--resource_ids f-cn-xxx6) Completion reminders
- Every create command must have a follow-up read check (
describe*orlist*). - Report completion based on read-back result, not create response alone.
- Max attempts: 2 total for the same operation (initial + one corrected retry).
- Keep auditable confirmation evidence in output (
SafetyCheckRequiredor--confirm). - For lifecycle requests requiring instance+namespace create,
completedmeans both
create operations succeeded.
End-to-end playbooks
Complete execution sequences for common scenarios. Each playbook includes discovery, execution, and verification.
Core principle: Never claim success without read-back verification.
Playbook 1: Create Instance (PayAsYouGo)
Step 1: Discover
python scripts/instance_ops.py describe_regions
python scripts/instance_ops.py describe --region_id <REGION>Decision: Check if target instance name already exists
Step 2: Execute
python scripts/instance_ops.py create \
--region_id <REGION> \
--name <NAME> \
--instance_type PayAsYouGo \
--vswitch_id <VSWITCH_ID> \
--vpc_id <VPC_ID> \
--cu_count <N> \
--confirmStep 3: Verify
python scripts/instance_ops.py describe --region_id <REGION>Verify: InstanceId, InstanceName, CPU/memory all match
CRITICAL: Check instance status is RUNNING (not just AVAILABLE)
- If status is
CREATINGor notRUNNING, wait 60 seconds and re-check - Instance must be
RUNNINGbefore creating namespaces - See
instance-state-management.mdfor detailed state handling
Step 4: Report
{
"operation": "create",
"create_result": "success",
"instance_id": "f-cn-xxx",
"verify_result": "Instance found with matching spec",
"final_status": "completed"
}Done when: Create success + read-back verification confirms presence and spec
2) Create namespace
Target lock for lifecycle chain
If this namespace step is part of a create instance -> create namespace closed loop:
- use the
InstanceIdreturned by that same create operation - do not switch to another existing RUNNING instance without explicit user approval
- if not ready, wait/poll on the same target instead of pivoting
Pre-requisite Checks
1. Verify instance exists and is READY:
python scripts/instance_ops.py describe --region_id <region>- Confirm instance status is
RUNNING(notCREATINGorAVAILABLE) - If not
RUNNING, wait before proceeding (seeinstance-state-management.md)
2. Check available resources:
python scripts/instance_ops.py describe_namespaces --region_id <region> --instance_id <id>- Note total instance CPU/memory
- Calculate used resources from existing namespaces
- Ensure sufficient resources available
Execution Steps
1. Run describe --region_id <region> and verify target instance exists AND status is RUNNING. 2. Run describe_namespaces and check whether target namespace already exists. 3. If namespace does not exist:
- Calculate required resources (must be integer CPU, GB memory)
- Verify resources are available (total - used >= required)
- Run
create_namespace --cpu <N> --memory_gb <M> --confirm - If resources insufficient: do not blind retry; explicitly tell user to manually
expand or reallocate instance resources (this skill does not support scaling) and retry later. 4. If namespace already exists: treat as idempotent success only when existing spec matches expected; otherwise report mismatch and remediation. 5. Run describe_namespaces for the same instance. 6. Verify namespace exists; if CPU/memory was requested, verify spec matches.
If target instance is not ready
- Poll every 30 seconds (same
InstanceId) until status becomesRUNNING - Maximum wait time: 10 minutes
- If still not
RUNNING, stop and provide a clear next action - Do not claim closed-loop completion before namespace is actually created and verified
Common Errors
- Resource adjustment in progress: Instance not fully ready → Wait 2-5 minutes
- Insufficient resources: Namespace resources exceed available → Ask user to
manually expand/reallocate resources, then retry
- CPU must be integer: Decimal CPU value → Use integer (1, 2, 4, etc.)
Done when:
- namespace exists in
describe_namespaces - expected namespace spec is verified (or explicitly confirmed unchanged)
Not done when:
create_namespacereturnssuccess: falsefor all allowed attempts- namespace step was skipped due to capacity issues
- chain switched to another instance without explicit user approval
3) Query-only inspection
When user requests inspection without create:
1. Instance scope:
- run
describe --region_id <region>
2. Namespace scope:
- run
describe_namespaces --region_id <region> --instance_id <id>
3. Region/zone scope:
- run
describe_regions - run
describe_zones --region_id <region>
4. Tag scope:
- run
list_tags --region_id <region> --resource_type vvpinstance --resource_ids <ids>
Done when:
- returned data clearly answers user query
- response includes the exact filters used (region, instance_id, resource_ids)
4) Batch operation checklist
When request includes multiple targets (IDs/names):
1. Parse all items in input order. 2. For each item: execute create/query -> run read-back verification -> record status. 3. Continue remaining items after single-item failure unless all-or-nothing is required. 4. Return per-item final table (item, result, verify, status, reason).
Evaluation Deliverables Contract
Use this document for evaluator-facing tasks. It defines required artifacts and auditable evidence patterns.
1) Required Artifact Matrix
| Eval scenario | Required artifact | Required filename |
|---|---|---|
| should-trigger batch | positive trigger jsonc | outputs/should_trigger.jsonc |
| should-not-trigger batch | negative trigger jsonc | outputs/should_not_trigger.jsonc |
| lifecycle minimal flow | command/output trace + closure summary | ran_scripts/*.log + outputs/lifecycle_flow_summary.md |
Hard rule: do not replace required jsonc artifacts with markdown-only summaries.
2) Generate Trigger Artifacts (Recommended)
Use the standard template copier:
python scripts/prepare_trigger_batch.py --type positive --output outputs/should_trigger.jsonc
python scripts/prepare_trigger_batch.py --type negative --output outputs/should_not_trigger.jsoncIf file exists and should be refreshed:
python scripts/prepare_trigger_batch.py --type positive --output outputs/should_trigger.jsonc --force3) Safety Confirmation Evidence Requirements
For lifecycle checks involving create or create_namespace, evaluator evidence must match SafetyCheckRequired|--confirm.
Use at least one of the following evidence paths:
1. Negative probe: run a create command without --confirm and capture SafetyCheckRequired. 2. Positive execution evidence: keep successful create JSON output that includes confirmation_check.required_flag = "--confirm".
Do not claim confirmation enforcement without one of the above in logs/output.
4) Minimal Closure Checklist
Before finishing any evaluator task, verify:
- required output file names exist exactly (
should_trigger.jsonc/should_not_trigger.jsonc) - trigger files are valid JSONC with
triggering.typeandtriggering.test_cases - create steps include confirmation evidence (
SafetyCheckRequiredor--confirm) - final summary references generated artifact paths
Instance State Management
This document provides guidance on handling instance states and waiting for readiness.
Instance States
Common States
CREATING- Instance is being createdRUNNING- Instance is operational and readyAVAILABLE- Instance is available but may not be fully readyRELEASING- Instance is being deletedEXCEPTION- Instance has errors
State Transitions
CREATING → RUNNING (normal flow)
CREATING → EXCEPTION (creation failed)
RUNNING → RELEASING (deletion initiated)Waiting for Instance Readiness
After creating an instance, you MUST wait for it to become fully ready before creating namespaces.
Step 1: Check Initial State
python scripts/instance_ops.py describe --region_id <REGION>Look for:
ClusterStatusorStatusfield- Instance should be
RUNNING(not justAVAILABLE)
Step 2: Poll for Readiness (if needed)
If instance is in CREATING or AVAILABLE but not RUNNING:
# Wait loop (check every 30 seconds)
for i in {1..10}; do
python scripts/instance_ops.py describe --region_id <REGION> > /tmp/instance_status.json
status=$(python -c "import json; data=json.load(open('/tmp/instance_status.json')); inst=[x for x in data['data']['Instances'] if x['InstanceId']=='<INSTANCE_ID>']; print(inst[0].get('Status', 'UNKNOWN') if inst else 'NOT_FOUND')")
if [ "$status" == "RUNNING" ]; then
echo "Instance is ready"
break
fi
echo "Instance status: $status, waiting..."
sleep 30
doneStep 3: Verify Readiness for Namespace Operations
Before creating namespaces, verify: 1. Instance status is RUNNING 2. No "resource adjustment in progress" errors 3. Instance has available resources (CPU/Memory not fully allocated)
# Check available resources
python scripts/instance_ops.py describe --region_id <REGION> | \
python -c "import json,sys; data=json.load(sys.stdin); inst=[x for x in data['data']['Instances'] if x['InstanceId']=='<INSTANCE_ID>']; print(f\"Total: {inst[0]['Cpu']} CPU, {inst[0]['MemoryGB']} GB\" if inst else 'Not found')"
# Check existing namespaces to see resource usage
python scripts/instance_ops.py describe_namespaces --region_id <REGION> --instance_id <INSTANCE_ID>Common Errors and Solutions
Error: "Resource adjustment in progress"
Cause: Instance is still initializing or undergoing resource changes
Solution: 1. Wait 2-5 minutes for initialization to complete 2. Check instance status until it shows RUNNING 3. Retry namespace creation
Do NOT:
- Blindly retry without waiting
- Switch to a different instance without user approval
- Report failure immediately
Error: "Insufficient resources"
Cause: Instance doesn't have enough free CPU/memory for namespace
Solution: 1. Query existing namespaces to see resource allocation 2. Check total instance resources vs allocated resources 3. Either:
- Create namespace with smaller resources
- Use a different instance with more available resources (with user approval)
- Create namespace without resource specification (shares instance pool)
Error: "Instance not found"
Cause: Instance ID is incorrect or instance was deleted
Solution: 1. Verify instance exists with describe command 2. Check correct region_id was used 3. If instance was deleted, report to user
Resource Calculation for Namespaces
Minimum Resources
- CPU: 1 (minimum integer value)
- Memory: 1 GB (minimum)
Resource Allocation Rules
- CPU must be integer (no decimals)
- Memory must be in GB (integer)
- Both CPU and memory must be specified together
- Resources cannot exceed instance total capacity
Example Calculations
Instance: 4 CPU, 16 GB Existing namespace: 1 CPU, 4 GB (already allocated) Available for new namespace: 3 CPU, 12 GB maximum
Valid namespace creation:
# Within available resources
python scripts/instance_ops.py create_namespace \
--region_id cn-hangzhou \
--instance_id f-cn-xxx \
--name new-ns \
--cpu 2 \
--memory_gb 8 \
--confirmInvalid namespace creation (would fail):
# Exceeds available resources
--cpu 5 --memory_gb 20 # Too much
# Decimal CPU (invalid)
--cpu 0.5 --memory_gb 2 # CPU must be integerTimeout Guidelines
Creation Timeouts
- Instance creation: 5-10 minutes
- Namespace creation: 30-60 seconds
- Status transitions: 2-5 minutes
Polling Intervals
- Check instance status: Every 30 seconds
- Maximum wait time: 10 minutes
- Polling checks are separate from command retry policy in
output-handling.md
Best Practices
1. Always verify state before proceeding to next operation 2. Use JSON parsing instead of grep for reliability 3. Check resource availability before creating namespaces 4. Wait for RUNNING state not just AVAILABLE 5. Report temporary states to user with expected timeline
Output handling
scripts/instance_ops.py writes JSON results. Always inspect:
success: true or falseoperation: operation namedata: successful response payloaderror.codeanderror.message: failure diagnosticsconfirmation_check(create operations): auditable confirmation gate status
Retry policy (strict)
Never use blind retries. Maximum attempts for the same command: 2 total (initial run + one corrected retry).
1. error.code == SafetyCheckRequired
- Cause: missing confirmation flag.
- Action: add the required flag from
required-confirmation-model.mdand retry once.
2. Input/argument issues (MissingParameter, ValueError, invalid format)
- Action: correct parameters according to
error.message, then retry once. - If error indicates missing credentials, fix default credential chain and retry once.
3. Permission issues (AccessDenied, Forbidden, Unauthorized)
- Action: do not retry until permissions are fixed; report required RAM policy.
4. Transient platform issues (Throttling, timeout, internal error)
- Query operations: retry once after short backoff.
- Create operations: first run a read check to verify whether request already took effect;
only retry once if not applied. 5. Create command reports success, but read-back verification fails
- Treat as incomplete, not successful.
- Check region/instance/resource identifiers first.
- Run one corrected create retry only when verification confirms state did not change.
6. Idempotent result handling
AlreadyExists: success only if read-back fully matches expected target state.- Any mismatch after read-back means incomplete task.
7. Create command fails with business mismatch (NamespaceNotFound, missing required options)
- Action: stop and ask user for clarification.
- Do not switch to a different operation automatically.
8. create_namespace fails with InsufficientResources
- Action: mark lifecycle chain as not completed; provide next action.
- State clearly that this skill does not support instance scale-up/update.
- Ask user to manually expand/reallocate resources, then retry.
- Do not label overall flow as completed.
If the corrected retry still fails, stop and return a clear remediation message instead of continuing attempts.
Eventual consistency read-back
After successful create, read-back may lag briefly. Use this sequence:
1. immediate read check 2. short backoff, second read check 3. short backoff, third read check
Do not perform extra create retries before completing these read checks.
Completion rule
Do not conclude task success from create response alone. Success requires:
1. create response success 2. read-back state verification success
Final response template (recommended)
Use a concise closure report:
operation: target operation namecreate_result: success/failure + key error code when failedverify_result: read-back result summarystatus: completed/failed/not_readynext_action: remediation when not completed
For lifecycle flows requiring both instance and namespace create:
status=completedis allowed only when both create operations succeeded and were verified.
Parameter Validation Rules
Pre-execution validation checklist. If any check fails, do not execute.
Create Command Validation
1. Confirmation flag (MANDATORY)
- ✓
--confirmflag MUST be present - ❌ Missing flag → SafetyCheckRequired error
- Action: Add
--confirmand retry ONCE
2. Resource specification (EXACTLY ONE option)
Option A: --cu_count N
- Valid:
--cu_count 4 - Auto-calculates: 4 cores + 16 GB
Option B: --cpu N --memory_gb M
- Valid:
--cpu 4 --memory_gb 16 - Both flags required together
Invalid patterns:
- ❌
--cpu 4alone (missing memory_gb) - ❌
--memory_gb 16alone (missing cpu) - ❌
--cu_count 4 --cpu 2(conflicting specs) - ❌ No resource spec at all
Action: Fix parameter combination and retry ONCE
3. Required flags for create
All of these MUST be present:
--region_id(never assume default)--name(instance name)--instance_type(exact: "PayAsYouGo" or "Subscription", case-sensitive)--vswitch_id--vpc_id
Invalid patterns:
- ❌
--instance_type pay-as-you-go(wrong case) - ❌
--instance_type PAYASYOUGO(wrong format) - ✓
--instance_type PayAsYouGo(correct)
4. Subscription-specific requirements
If --instance_type Subscription:
- Optional:
--period(1, 2, 3, 6, or 12 months) - Optional:
--auto_renew(flag)
Create Namespace Validation
1. Confirmation flag (MANDATORY)
- ✓
--confirmflag MUST be present - ❌ Missing → SafetyCheckRequired error
2. Required flags
--region_id--instance_id(must reference existing instance)--name(namespace name)
3. Resource specification (optional)
For creating a NEW namespace:
- Both
--cpuAND--memory_gbare required together - ❌ Invalid: only
--cpuor only--memory_gb - ❌ Invalid: omit both for a new namespace
Idempotent exception:
- If namespace already exists with the same
--name, create operation can return
idempotent success without requiring new resource values.
Query Command Validation
Query commands have minimal validation:
describe_regions: no parameters requireddescribe_zones: requires--region_iddescribe: requires--region_iddescribe_namespaces: requires--region_idand--instance_idlist_tags: requires--region_idand--resource_type
Error Code to Validation Mapping
| Error Code | Cause | Fix |
|---|---|---|
| SafetyCheckRequired | Missing --confirm | Add --confirm flag |
| MissingParameter | Missing required flag | Add the required flag |
| ValueError | Invalid parameter combination | Check resource spec rules |
| InstanceNameConflict | Instance exists with different config | Use different name or verify existing instance |
| NamespaceNotFound | Parent instance not found | Verify instance_id exists |
| InsufficientResources | Requested namespace resources exceed available capacity | Inform user and request manual instance resource expansion/reallocation, then retry |
Validation Checklist Template
Before executing create:
□ --confirm flag present
□ --region_id present
□ --name present
□ --instance_type valid (PayAsYouGo or Subscription)
□ --vswitch_id present
□ --vpc_id present
□ Resource spec: either --cu_count OR (--cpu AND --memory_gb)
□ No conflicting parametersBefore executing create_namespace:
□ --confirm flag present
□ --region_id present
□ --instance_id present
□ --name present
□ For new namespace: both --cpu AND --memory_gb present
□ Resource request does not exceed available instance capacityPython Environment Setup Guide
Complete guide for setting up the Python environment for Flink instance operations.
Table of Contents
- Prerequisites
- Step 1: Verify Python Installation
- Step 2: Install Dependencies
- Step 3: Configure Authentication
- Step 4: Verify Setup
- Troubleshooting
- Virtual Environment (Optional)
- Prepare RAM Identity
- Security Best Practices
- Next Steps
Prerequisites
- Python 3.6 or higher
- pip (Python package manager)
- Alibaba Cloud credentials available from the default credential chain
---
Step 1: Verify Python Installation
# Check Python version (must be 3.6+)
python3 --versionExpected Output:
Python 3.6.0 or higherIf Python is not installed:
macOS
# Using Homebrew
brew install python@3.9Linux (Ubuntu/Debian)
sudo apt-get install python3 python3-pipLinux (CentOS/RHEL)
sudo yum install python3 python3-pipWindows
Download from https://www.python.org/downloads/
---
Step 2: Install Dependencies
# Navigate to the project directory
cd alibabacloud-flink-instance-manage
# Install required packages
pip install -r assets/requirements.txtThis installs:
alibabacloud-foasconsole20211028>=2.2.1- Flink OpenAPI SDKalibabacloud-tea-openapi>=0.4.3- OpenAPI clientalibabacloud-tea-util>=0.3.14- Utility library
Verify installation:
pip show alibabacloud-foasconsole20211028---
Step 3: Configure Authentication
Method 1: Default Aliyun CLI Profile
Use the default profile once, then let the SDK resolve credentials from the default credential chain automatically:
aliyun configure
aliyun configure listMethod 2: RAM Role (Recommended on Alibaba Cloud runtime)
When running on ECS/ACK/FC/SAE with a RAM role attached, credentials are automatically retrieved from role metadata. No AK/SK export is needed.
---
Step 4: Verify Setup
# Test the script
python scripts/instance_ops.py describe_regionsExpected Output:
{
"success": true,
"operation": "describe_regions",
"data": {
"Regions": {
"Region": [
{
"RegionId": "cn-hangzhou",
...
}
]
}
},
"request_id": "..."
}---
Troubleshooting
Issue: Python version too low
Symptom:
Python 3.5.2
# or lowerSolution: Upgrade Python to 3.6 or higher using your system's package manager.
Issue: Module not found
Symptom:
ModuleNotFoundError: No module named 'alibabacloud_foasconsole20211028'Solution:
pip install -r assets/requirements.txtIssue: Missing credentials
Symptom:
NoCredentialError: unable to resolve credentials from default credential chainSolution:
aliyun configure
aliyun configure listIssue: Permission denied
Symptom:
Forbidden.RAM: Insufficient permissionsSolution: 1. Check RAM user permissions according to the RAM policy document 2. Attach required policies to the RAM user 3. Verify the RAM identity is active and authorized
Issue: pip not found
Symptom:
bash: pip: command not foundSolution:
# Use pip3 instead
pip3 install -r assets/requirements.txt
# Or install pip
sudo apt-get install python3-pip # Ubuntu/Debian
sudo yum install python3-pip # CentOS/RHEL---
Virtual Environment (Optional)
For isolated dependencies, use a virtual environment:
# Create virtual environment
python3 -m venv venv
# Activate virtual environment
source venv/bin/activate # macOS/Linux
venv\Scripts\activate # Windows
# Install dependencies
pip install -r assets/requirements.txt
# Deactivate when done
deactivate---
Prepare RAM Identity
1. Log in to Alibaba Cloud Console: https://ram.console.aliyun.com/ 2. Create or select a RAM identity (user/role) with required policies 3. Prefer temporary credentials via RAM role when possible 4. If using a local profile, configure it once with aliyun configure 5. Verify permissions with the RAM policy document
---
Security Best Practices
1. Never commit credentials - Never hardcode AK/SK in code or scripts 2. Use RAM users - Don't use the root account for daily operations 3. Rotate AccessKeys regularly - Every 90 days recommended 4. Principle of least privilege - Grant only necessary permissions 5. Use RAM roles/default chain - Prefer temporary credentials over explicit AK/SK handling
---
Next Steps
After setup: 1. Read SKILL.md in the project root for usage documentation 2. Try the quick start examples in the quick-start document 3. Review RAM policy requirements before production use
Quick Start
Alibaba Cloud Flink VVP instance operations with create/query command scope.
Trigger Recognition
Use this skill when request is about:
- Flink instance create/query
- Flink namespace create/query
- Flink region/zone/tag queries
Do not use this skill for:
- Flink SQL or Flink jobs
- Other Alibaba Cloud services (ECS, Kafka, OSS, DataWorks)
- Update or delete operations
1) Install Dependencies
pip install -r assets/requirements.txt2) Configure Credentials
aliyun configure
aliyun configure list3) Run Read-only Checks
python scripts/instance_ops.py describe_regions
python scripts/instance_ops.py describe_zones --region_id cn-hangzhou
python scripts/instance_ops.py describe --region_id cn-hangzhou4) Create Instance and Verify
python scripts/instance_ops.py create \
--region_id cn-hangzhou \
--name my-instance \
--instance_type PayAsYouGo \
--zone_id cn-hangzhou-g \
--vswitch_id vsw-xxx \
--vpc_id vpc-xxx \
--cpu 200 \
--memory_gb 800 \
--confirm
python scripts/instance_ops.py describe --region_id cn-hangzhou5) Create Namespace and Verify
python scripts/instance_ops.py create_namespace \
--region_id cn-hangzhou \
--instance_id f-cn-xxx \
--name prod-ns \
--cpu 100 \
--memory_gb 400 \
--confirm
python scripts/instance_ops.py describe_namespaces \
--region_id cn-hangzhou \
--instance_id f-cn-xxxCommand Scope
| Category | Commands |
|---|---|
| Query | describe_regions, describe_zones, describe, describe_namespaces, list_tags |
| Create | create, create_namespace |
Required Confirmation
| Operation | Flag |
|---|---|
create | --confirm |
create_namespace | --confirm |
Reference Map
| Document | Purpose |
|---|---|
../SKILL.md | Main skill instructions and workflow |
trigger-recognition-guide.md | Trigger and rejection examples |
core-execution-flow.md | Standard operation flow |
parameter-validation.md | Parameter checklist |
verification-method.md | Read-back verification methods |
output-handling.md | Retry and error handling |
common-failures.md | Typical mistakes and fixes |
python-environment-setup.md | Python setup guide |
related-apis.md | API command mapping |
Output Shape
{
"success": true,
"operation": "describe",
"data": {},
"request_id": "..."
}Exit codes: 0 = success, 1 = error.
RAM Policies for Flink Instance Operations
Alibaba Cloud RAM permissions required by scripts/instance_ops.py under a create/query-only execution model.
Note: For OpenAPI 2021-10-28, official action names use the stream:*namespace.
Required Permissions
The following actions cover allowed commands in this skill:
stream:CreateVvpInstance-createstream:DescribeVvpInstances-describestream:CreateVvpNamespace-create_namespacestream:DescribeVvpNamespaces-describe_namespacesstream:QueryTagVvpResources-list_tags
DescribeSupportedRegions and DescribeSupportedZones pages currently state "暂无授权信息透出", so they are intentionally not listed as mandatory actions.
Minimum Permission Policy
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": [
"stream:CreateVvpInstance",
"stream:DescribeVvpInstances",
"stream:CreateVvpNamespace",
"stream:DescribeVvpNamespaces",
"stream:QueryTagVvpResources"
],
"Resource": [
"acs:stream:*:*:vvpinstance/*",
"acs:stream:*:*:vvpinstance/*/vvpnamespace/*"
]
}
]
}Permission Breakdown by Operation
| API Action | RAM Action |
|---|---|
CreateInstance | stream:CreateVvpInstance |
DescribeInstances | stream:DescribeVvpInstances |
CreateNamespace | stream:CreateVvpNamespace |
DescribeNamespaces | stream:DescribeVvpNamespaces |
ListTagResources | stream:QueryTagVvpResources |
Resource ARN Examples
Use resource-level constraints when possible:
- Instance:
acs:stream:{regionId}:{accountId}:vvpinstance/{instanceId} - Namespace:
acs:stream:{regionId}:{accountId}:vvpinstance/{instanceId}/vvpnamespace/{namespace}
Example policy for one specific instance:
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": [
"stream:DescribeVvpInstances",
"stream:DescribeVvpNamespaces"
],
"Resource": "acs:stream:cn-hangzhou:123456789012:vvpinstance/f-cn-xxx"
}
]
}Predefined System Policies
Alibaba Cloud currently provides these common system policies:
AliyunStreamFullAccessAliyunStreamReadOnlyAccess
If your organization requires least privilege, prefer custom policy with explicit stream:* actions listed above.
Troubleshooting
Error: Forbidden.RAM
1. Verify attached policies:
aliyun ram ListPoliciesForUser --UserName <your-username>2. Attach a policy that includes required stream:* actions. 3. Retry the operation.
Error: InvalidAccessKeyId.NotFound
1. Verify AccessKey:
aliyun ram ListAccessKeys --UserName <your-username>2. Rotate/recreate AccessKey and refresh local profile.
References
References Index
This folder is organized by operation lifecycle, not by evaluation workflow.
1) Start Here
quick-start.md: install, auth, first commandstrigger-recognition-guide.md: when to use this skillcore-execution-flow.md: standard flow for create/query tasks
2) Execute Commands
command-templates.md: copy-paste command templatesparameter-validation.md: pre-execution parameter checksrequired-confirmation-model.md: mandatory--confirmrules
3) Verify and Close
verification-method.md: read-back verification patternsinstance-state-management.md: readiness and polling rulesoutput-handling.md: output parsing, retry policy, completion statusacceptance-criteria.md: operation completion checklist
4) Troubleshooting
common-failures.md: common error patterns and fixespython-environment-setup.md: Python/runtime troubleshootingcli-installation-guide.md: Aliyun CLI diagnostics and setup
5) Permissions and APIs
ram-policies.md: RAM policy requirementsrelated-apis.md: OpenAPI action mapping
Related APIs and Command Mapping
Alibaba Cloud Flink (Real-Time Compute) API version 2021-10-28.
Mandatory execution rule
Use this document for mapping/reference only. During task execution, always run operations through:
python scripts/instance_ops.py <command> ...Do not execute raw product commands such as aliyun foasconsole ....
Command to API mapping (create/query only)
| Script Command | API Action | Notes |
|---|---|---|
describe_regions | DescribeSupportedRegions | List supported regions |
describe_zones | DescribeSupportedZones | List zones in a region |
create | CreateInstance | Create a Flink instance |
describe | DescribeInstances | List/query instances |
create_namespace | CreateNamespace | Create namespace |
describe_namespaces | DescribeNamespaces | Query namespaces |
list_tags | ListTagResources | Query tags |
Notes
- Product code is still
foasconsole, but this remains an internal implementation detail. - Confirmation checks are required only for create commands.
- For executable examples, follow
SKILL.mdandcore-execution-flow.md.
Required confirmation model
Use a hard confirmation gate for every create operation. Missing confirmation flags is a policy violation.
1) Pre-execution hard gate (mandatory)
Before executing any create command:
1. Build the full command string first. 2. Validate the required confirmation flag is present. 3. If the flag is missing, do not execute. Rebuild the command with the correct flag. 4. Never bypass this check, even if a previous step failed. 5. Keep confirmation evidence in logs/output (SafetyCheckRequired or --confirm).
2) Command-to-flag mapping
create:--confirmcreate_namespace:--confirm
Query commands do not require confirmation flags.
Trigger Recognition Guide
This guide helps identify when to use the alibabacloud-flink-instance-manage skill.
Quick Rule
Use this skill when the prompt is about Flink VVP instance/namespace create or query.
Positive Triggers (Use Skill)
Instance Operations
| User Request | Skill Action |
|---|---|
| "Create a Flink instance" | create command |
| "Query my Flink instances" | describe command |
| "创建Flink实例" | create command |
| "查询Flink实例信息" | describe command |
| "List Flink VVP instances" | describe command |
| "What regions support Flink" | describe_regions command |
| "Flink可用区有哪些" | describe_zones command |
| "查询 Flink 实例标签" | list_tags command |
Namespace Operations
| User Request | Skill Action |
|---|---|
| "Create a Flink namespace" | create_namespace command |
| "List namespaces for Flink instance X" | describe_namespaces command |
| "创建Flink命名空间" | create_namespace command |
| "查询实例下的命名空间" | describe_namespaces command |
Negative Triggers (Do Not Use Skill)
Different Service Domain
| User Request | Reason | Correct Action |
|---|---|---|
| "Create an ECS instance" | Wrong service | Use ECS skill or reject |
| "Create Kafka topic" | Wrong service | Use Kafka skill or reject |
| "Upload to OSS" | Wrong service | Use OSS skill or reject |
| "Create a DataWorks workflow" | Wrong service | Use DataWorks workflow skill or reject |
| "创建ECS实例" | Wrong service | Not Flink related |
| "今天天气怎么样" | Generic question | Do not trigger this skill |
Different Flink Domain
| User Request | Reason | Correct Action |
|---|---|---|
| "Run Flink SQL query" | Flink SQL, not instance | Use Flink SQL skill |
| "Submit Flink job" | Job management | Different skill |
| "运行Flink SQL" | Flink SQL, not instance | Use Flink SQL skill |
In-Domain but Rejected (Trigger + Reject)
| User Request | Reason | Correct Action |
|---|---|---|
| "Update Flink instance config" | Update not supported by command scope | Trigger skill, then reject with scope explanation |
| "Delete Flink instance" | Delete not supported by command scope | Trigger skill, then reject with scope explanation |
| "修改Flink实例配置" | Update not supported by command scope | Trigger skill, then reject with scope explanation |
| "删除Flink实例" | Delete not supported by command scope | Trigger skill, then reject with scope explanation |
Ambiguous Cases
When request intent is unclear, ask one clarifying question:
- "Do you need Flink instance/namespace management, or Flink SQL/job operations?"
Decision Tree
User request about Flink
│
├─ Mentions "instance" or "namespace" or "VVP"?
│ ├─ YES → USE THIS SKILL
│ │ ├─ create/query → Execute
│ │ └─ update/delete → Reject with explanation
│ │
│ └─ NO → Check further
│ ├─ Mentions "SQL" or "job" → Different Flink skill
│ └─ Unclear → Ask user to clarify
│
└─ Request about other service (ECS, Kafka, OSS)?
└─ YES → Do NOT use this skillVerification Methods
Step-by-step verification methods for Flink instance create/query operations.
Mandatory rule
All executable examples in this document use:
python scripts/instance_ops.py <command> ...Do not run raw aliyun foasconsole resource commands as substitutes.
Pre-operation verification
1) Environment diagnostics
aliyun version
aliyun configure list
python scripts/instance_ops.py describe_regionsIf the Python command fails with missing modules, follow python-environment-setup.md.
2) Region/network readiness (when create is needed)
python scripts/instance_ops.py describe_regions
python scripts/instance_ops.py describe_zones --region_id cn-hangzhouIf VPC/VSwitch is missing, provide explicit parameters before create execution.
Operation verification pattern
For every create operation, follow:
1. execute create with required confirmation flag 2. run read-back verification 3. conclude status based on read-back result
Example: create instance
python scripts/instance_ops.py create \
--region_id cn-hangzhou \
--name verify-demo \
--instance_type PayAsYouGo \
--vswitch_id vsw-xxx \
--vpc_id vpc-xxx \
--cpu 200 \
--memory_gb 800 \
--confirmRead-back:
python scripts/instance_ops.py describe --region_id cn-hangzhouExample: create namespace
python scripts/instance_ops.py create_namespace \
--region_id cn-hangzhou \
--instance_id f-cn-xxx \
--name verify-ns \
--cpu 100 \
--memory_gb 400 \
--confirmRead-back:
python scripts/instance_ops.py describe_namespaces \
--region_id cn-hangzhou \
--instance_id f-cn-xxxFailure verification
- Parse
error.codeanderror.messagefrom command output - For create operations, also inspect
confirmation_checkfor auditable--confirmevidence - Apply retry policy in
output-handling.md - Retry only same operation with corrected parameters (max one retry)
- If unresolved, report as incomplete with remediation
- For lifecycle flows requiring both create steps, keep overall status non-completed when
namespace create fails (for example InsufficientResources)
References
core-execution-flow.mdrequired-confirmation-model.mdoutput-handling.mdpython-environment-setup.md
#!/usr/bin/env python3
"""
Flink Instance Manager - CLI for Alibaba Cloud Flink OpenAPI (2021-10-28)
Usage:
python instance_ops.py <command> [options]
Commands:
create Create a new Flink instance
describe Describe instances
describe_regions List supported regions
describe_zones List supported zones
create_namespace Create a namespace
describe_namespaces Describe namespaces
list_tags List tags for resources
Authentication:
Uses Alibaba Cloud default credential chain (RAM role, CLI profile, etc.)
Output:
JSON to stdout, exit code 0 = success
"""
import argparse
import json
import sys
from alibabacloud_credentials.client import Client as CredentialClient
from alibabacloud_foasconsole20211028 import models as foas_models
from alibabacloud_foasconsole20211028.client import Client
from alibabacloud_tea_openapi import models as openapi_models
from alibabacloud_tea_util import models as util_models
DEFAULT_CONNECT_TIMEOUT_MS = 10_000
DEFAULT_READ_TIMEOUT_MS = 60_000
DEFAULT_USER_AGENT = "AlibabaCloud-Agent-Skills"
class FlinkClient:
"""Flink OpenAPI client (2021-10-28) with automatic authentication."""
def __init__(self, region_id):
if not region_id:
raise ValueError(
"region_id is required. Please specify the region for this operation."
)
config = openapi_models.Config(
credential=CredentialClient(),
region_id=region_id,
endpoint=f"foasconsole.{region_id}.aliyuncs.com",
user_agent=DEFAULT_USER_AGENT,
)
self.client = Client(config)
self.runtime_options = util_models.RuntimeOptions(
connect_timeout=DEFAULT_CONNECT_TIMEOUT_MS,
read_timeout=DEFAULT_READ_TIMEOUT_MS,
)
def call_api(self, method_name, request=None):
"""Call API with timeout runtime options when available."""
method_with_options = None
for candidate in (f"{method_name}_with_options", f"{method_name}with_options"):
method_with_options = getattr(self.client, candidate, None)
if method_with_options:
break
if method_with_options:
if request is None:
return method_with_options(self.runtime_options)
return method_with_options(request, self.runtime_options)
method = getattr(self.client, method_name)
if request is None:
return method()
return method(request)
def _get_resource_spec_values(spec):
"""Return normalized (cpu, memory_gb) tuple from a resource spec map."""
if not isinstance(spec, dict):
return None, None
cpu = spec.get("Cpu")
memory_gb = spec.get("MemoryGB")
if cpu is None:
cpu = spec.get("cpu")
if memory_gb is None:
memory_gb = spec.get("memory_gb")
return cpu, memory_gb
def _confirmation_audit(confirm_provided):
"""Return an auditable confirmation gate snapshot for create operations."""
provided = bool(confirm_provided)
return {
"required_flag": "--confirm",
"provided": provided,
"status": "passed" if provided else "missing",
}
def list_namespaces(client, region_id, instance_id):
"""Return namespace list for an instance."""
request = foas_models.DescribeNamespacesRequest(
instance_id=instance_id, region=region_id
)
response = client.call_api("describe_namespaces", request)
return response.body.to_map().get("Namespaces", [])
def find_namespace_by_name(client, region_id, instance_id, namespace_name):
"""Return namespace detail by name from DescribeNamespaces result."""
namespaces = list_namespaces(client, region_id, instance_id)
for namespace in namespaces:
if namespace.get("Namespace") == namespace_name:
return namespace
return None
def find_instance_by_name(client, region_id, instance_name):
"""Return instance detail by name from DescribeInstances result."""
request = foas_models.DescribeInstancesRequest(region=region_id)
response = client.call_api("describe_instances", request)
instances = response.body.to_map().get("Instances", [])
for inst in instances:
if inst.get("InstanceName") == instance_name:
return inst
return None
def find_instance_by_id(client, region_id, instance_id):
"""Return instance detail by id from DescribeInstances result."""
request = foas_models.DescribeInstancesRequest(region=region_id)
response = client.call_api("describe_instances", request)
instances = response.body.to_map().get("Instances", [])
for inst in instances:
if inst.get("InstanceId") == instance_id:
return inst
return None
def _sum_namespace_allocations(namespaces):
"""Return aggregated namespace allocation as (cpu, memory_gb)."""
total_cpu = 0
total_memory = 0
for namespace in namespaces:
cpu, memory_gb = _get_resource_spec_values(namespace.get("ElasticResourceSpec"))
if cpu is None and memory_gb is None:
cpu, memory_gb = _get_resource_spec_values(namespace.get("ResourceSpec"))
total_cpu += int(cpu or 0)
total_memory += int(memory_gb or 0)
return total_cpu, total_memory
def create_instance(args):
"""Create a new Flink instance."""
try:
if not args.confirm:
result = {
"success": False,
"operation": "create",
"confirmation_check": _confirmation_audit(args.confirm),
"error": {
"code": "SafetyCheckRequired",
"message": (
"Creating an instance is a cost-incurring operation. "
"Please confirm by adding --confirm flag."
),
},
}
print(json.dumps(result, indent=2))
return 1
if not args.region_id:
raise ValueError("region_id is required. Please specify the region.")
has_cpu = args.cpu is not None
has_memory = args.memory_gb is not None
has_cu = args.cu_count is not None
if has_cpu != has_memory:
result = {
"success": False,
"operation": "create",
"confirmation_check": _confirmation_audit(args.confirm),
"error": {
"code": "MissingParameter",
"message": "--cpu and --memory_gb must be provided together.",
},
}
print(json.dumps(result, indent=2))
return 1
if not (has_cu or (has_cpu and has_memory)):
result = {
"success": False,
"operation": "create",
"confirmation_check": _confirmation_audit(args.confirm),
"error": {
"code": "MissingParameter",
"message": (
"Must specify --cpu and --memory_gb, or --cu_count parameter"
),
},
}
print(json.dumps(result, indent=2))
return 1
cpu = args.cpu if has_cpu else args.cu_count
memory_gb = args.memory_gb if has_memory else args.cu_count * 4
charge_type = "POST" if args.instance_type == "PayAsYouGo" else "PRE"
client = FlinkClient(region_id=args.region_id)
existing_instance = find_instance_by_name(client, args.region_id, args.name)
if existing_instance:
existing_charge_type = existing_instance.get("ChargeType")
existing_cpu, existing_memory = _get_resource_spec_values(
existing_instance.get("ResourceSpec", {})
)
if (
existing_charge_type == charge_type
and existing_cpu == cpu
and existing_memory == memory_gb
):
result = {
"success": True,
"operation": "create",
"confirmation_check": _confirmation_audit(args.confirm),
"idempotent_noop": True,
"message": (
f"Instance '{args.name}' already exists with the same "
"configuration. Skipped duplicate create."
),
"data": {"ExistingInstance": existing_instance},
"request_id": "",
}
print(json.dumps(result, indent=2))
return 0
result = {
"success": False,
"operation": "create",
"confirmation_check": _confirmation_audit(args.confirm),
"error": {
"code": "InstanceNameConflict",
"message": (
f"Instance name '{args.name}' already exists with a different "
"configuration. Refuse to create to avoid non-idempotent "
"side effects."
),
},
}
print(json.dumps(result, indent=2))
return 1
request = foas_models.CreateInstanceRequest(
region=args.region_id,
instance_name=args.name,
charge_type=charge_type,
v_switch_ids=[args.vswitch_id],
vpc_id=args.vpc_id,
resource_spec=foas_models.CreateInstanceRequestResourceSpec(
cpu=cpu, memory_gb=memory_gb
),
storage=foas_models.CreateInstanceRequestStorage(fully_managed=True),
)
if args.zone_id:
request.zone_id = args.zone_id
if args.auto_renew:
request.auto_renew = True
if args.period:
request.duration = args.period
request.pricing_cycle = "Month"
response = client.call_api("create_instance", request)
result = {
"success": True,
"operation": "create",
"confirmation_check": _confirmation_audit(args.confirm),
"data": response.body.to_map(),
"request_id": getattr(response, "headers", {}).get("x-acs-request-id", ""),
}
print(json.dumps(result, indent=2))
return 0
except Exception as exc:
result = {
"success": False,
"operation": "create",
"confirmation_check": _confirmation_audit(getattr(args, "confirm", False)),
"error": {"code": type(exc).__name__, "message": str(exc)},
}
print(json.dumps(result, indent=2))
return 1
def describe_instances(args):
"""Describe Flink instances."""
try:
if not args.region_id:
raise ValueError("region_id is required. Please specify the region.")
client = FlinkClient(region_id=args.region_id)
request = foas_models.DescribeInstancesRequest(region=args.region_id)
response = client.call_api("describe_instances", request)
result = {
"success": True,
"operation": "describe",
"data": response.body.to_map(),
"request_id": getattr(response, "headers", {}).get("x-acs-request-id", ""),
}
print(json.dumps(result, indent=2))
return 0
except Exception as exc:
result = {
"success": False,
"operation": "describe",
"error": {"code": type(exc).__name__, "message": str(exc)},
}
print(json.dumps(result, indent=2))
return 1
def describe_regions(_args):
"""Describe supported regions."""
try:
client = FlinkClient(region_id="cn-beijing")
response = client.call_api("describe_supported_regions")
result = {
"success": True,
"operation": "describe_regions",
"data": response.body.to_map(),
"request_id": getattr(response, "headers", {}).get("x-acs-request-id", ""),
}
print(json.dumps(result, indent=2))
return 0
except Exception as exc:
result = {
"success": False,
"operation": "describe_regions",
"error": {"code": type(exc).__name__, "message": str(exc)},
}
print(json.dumps(result, indent=2))
return 1
def describe_zones(args):
"""Describe supported zones."""
try:
if not args.region_id:
raise ValueError("region_id is required. Please specify the region.")
client = FlinkClient(region_id=args.region_id)
request = foas_models.DescribeSupportedZonesRequest(region=args.region_id)
response = client.call_api("describe_supported_zones", request)
result = {
"success": True,
"operation": "describe_zones",
"data": response.body.to_map(),
"request_id": getattr(response, "headers", {}).get("x-acs-request-id", ""),
}
print(json.dumps(result, indent=2))
return 0
except Exception as exc:
result = {
"success": False,
"operation": "describe_zones",
"error": {"code": type(exc).__name__, "message": str(exc)},
}
print(json.dumps(result, indent=2))
return 1
def create_namespace(args):
"""Create a namespace."""
try:
if not args.confirm:
result = {
"success": False,
"operation": "create_namespace",
"confirmation_check": _confirmation_audit(args.confirm),
"error": {
"code": "SafetyCheckRequired",
"message": (
"Creating a namespace consumes cluster resources. "
"Please confirm by adding --confirm flag."
),
},
}
print(json.dumps(result, indent=2))
return 1
has_cpu = args.cpu is not None
has_memory = args.memory_gb is not None
if has_cpu != has_memory:
result = {
"success": False,
"operation": "create_namespace",
"confirmation_check": _confirmation_audit(args.confirm),
"error": {
"code": "MissingParameter",
"message": (
"--cpu and --memory_gb must be provided together when "
"specifying namespace resources."
),
},
}
print(json.dumps(result, indent=2))
return 1
client = FlinkClient(region_id=args.region_id)
existing_namespace = find_namespace_by_name(
client, args.region_id, args.instance_id, args.name
)
if existing_namespace:
existing_cpu, existing_memory = _get_resource_spec_values(
existing_namespace.get("ElasticResourceSpec")
)
if existing_cpu is None and existing_memory is None:
existing_cpu, existing_memory = _get_resource_spec_values(
existing_namespace.get("ResourceSpec")
)
if not has_cpu and not has_memory:
result = {
"success": True,
"operation": "create_namespace",
"confirmation_check": _confirmation_audit(args.confirm),
"idempotent_noop": True,
"message": (
f"Namespace '{args.name}' already exists. "
"Skipped duplicate create."
),
"data": {"ExistingNamespace": existing_namespace},
"request_id": "",
}
print(json.dumps(result, indent=2))
return 0
if existing_cpu == args.cpu and existing_memory == args.memory_gb:
result = {
"success": True,
"operation": "create_namespace",
"confirmation_check": _confirmation_audit(args.confirm),
"idempotent_noop": True,
"message": (
f"Namespace '{args.name}' already exists with the same "
"resource specification. Skipped duplicate create."
),
"data": {"ExistingNamespace": existing_namespace},
"request_id": "",
}
print(json.dumps(result, indent=2))
return 0
result = {
"success": False,
"operation": "create_namespace",
"confirmation_check": _confirmation_audit(args.confirm),
"error": {
"code": "NamespaceConflict",
"message": (
f"Namespace '{args.name}' already exists with a different "
"configuration. Refuse to create to avoid non-idempotent "
"side effects."
),
},
}
print(json.dumps(result, indent=2))
return 1
if not has_cpu and not has_memory:
result = {
"success": False,
"operation": "create_namespace",
"confirmation_check": _confirmation_audit(args.confirm),
"error": {
"code": "MissingParameter",
"message": (
"New namespace creation requires explicit --cpu and --memory_gb. "
"If the target namespace already exists, reuse the same --name to "
"perform an idempotent create."
),
},
}
print(json.dumps(result, indent=2))
return 1
instance = find_instance_by_id(client, args.region_id, args.instance_id)
if not instance:
result = {
"success": False,
"operation": "create_namespace",
"confirmation_check": _confirmation_audit(args.confirm),
"error": {
"code": "NamespaceNotFound",
"message": (
f"Instance '{args.instance_id}' was not found in region "
f"'{args.region_id}'."
),
},
}
print(json.dumps(result, indent=2))
return 1
total_cpu, total_memory = _get_resource_spec_values(instance.get("ResourceSpec", {}))
total_cpu = int(total_cpu or 0)
total_memory = int(total_memory or 0)
used_cpu, used_memory = _sum_namespace_allocations(
list_namespaces(client, args.region_id, args.instance_id)
)
available_cpu = max(total_cpu - used_cpu, 0)
available_memory = max(total_memory - used_memory, 0)
if args.cpu > available_cpu or args.memory_gb > available_memory:
result = {
"success": False,
"operation": "create_namespace",
"confirmation_check": _confirmation_audit(args.confirm),
"error": {
"code": "InsufficientResources",
"message": (
"Requested namespace resources exceed available capacity. "
f"requested=({args.cpu} CPU, {args.memory_gb} GB), "
f"available=({available_cpu} CPU, {available_memory} GB), "
f"instance_total=({total_cpu} CPU, {total_memory} GB), "
f"allocated=({used_cpu} CPU, {used_memory} GB). "
"This skill does not support instance scale-up. "
"Please manually expand or reallocate instance resources, "
"then retry create_namespace."
),
},
}
print(json.dumps(result, indent=2))
return 1
request = foas_models.CreateNamespaceRequest(
instance_id=args.instance_id,
region=args.region_id,
namespace=args.name,
)
if has_cpu and has_memory:
request.resource_spec = foas_models.CreateNamespaceRequestResourceSpec(
cpu=args.cpu, memory_gb=args.memory_gb
)
response = client.call_api("create_namespace", request)
result = {
"success": True,
"operation": "create_namespace",
"confirmation_check": _confirmation_audit(args.confirm),
"data": response.body.to_map(),
"request_id": getattr(response, "headers", {}).get("x-acs-request-id", ""),
}
print(json.dumps(result, indent=2))
return 0
except Exception as exc:
result = {
"success": False,
"operation": "create_namespace",
"confirmation_check": _confirmation_audit(getattr(args, "confirm", False)),
"error": {"code": type(exc).__name__, "message": str(exc)},
}
print(json.dumps(result, indent=2))
return 1
def describe_namespaces(args):
"""Describe namespaces."""
try:
client = FlinkClient(region_id=args.region_id)
request = foas_models.DescribeNamespacesRequest(
instance_id=args.instance_id, region=args.region_id
)
response = client.call_api("describe_namespaces", request)
result = {
"success": True,
"operation": "describe_namespaces",
"data": response.body.to_map(),
"request_id": getattr(response, "headers", {}).get("x-acs-request-id", ""),
}
print(json.dumps(result, indent=2))
return 0
except Exception as exc:
result = {
"success": False,
"operation": "describe_namespaces",
"error": {"code": type(exc).__name__, "message": str(exc)},
}
print(json.dumps(result, indent=2))
return 1
def list_tags(args):
"""List tags for resources."""
try:
if not args.region_id:
raise ValueError("region_id is required. Please specify the region.")
client = FlinkClient(region_id=args.region_id)
request = foas_models.ListTagResourcesRequest(
region_id=args.region_id, resource_type=args.resource_type
)
if args.resource_ids:
resource_ids = (
args.resource_ids.split(",")
if "," in args.resource_ids
else [args.resource_ids]
)
request.resource_id = resource_ids
response = client.call_api("list_tag_resources", request)
result = {
"success": True,
"operation": "list_tags",
"data": response.body.to_map(),
"request_id": getattr(response, "headers", {}).get("x-acs-request-id", ""),
}
print(json.dumps(result, indent=2))
return 0
except Exception as exc:
result = {
"success": False,
"operation": "list_tags",
"error": {"code": type(exc).__name__, "message": str(exc)},
}
print(json.dumps(result, indent=2))
return 1
def main():
parser = argparse.ArgumentParser(
description="Flink Instance Manager (API 2021-10-28)"
)
subparsers = parser.add_subparsers(dest="command", help="Commands")
create_parser = subparsers.add_parser("create", help="Create a new Flink instance")
create_parser.add_argument("--region_id", required=True, help="Region ID")
create_parser.add_argument("--name", required=True, help="Instance name")
create_parser.add_argument(
"--instance_type",
required=True,
choices=["Subscription", "PayAsYouGo"],
help="Billing type",
)
create_parser.add_argument(
"--zone_id", help="Zone ID (optional, passed through when provided)"
)
create_parser.add_argument("--vswitch_id", required=True, help="VSwitch ID")
create_parser.add_argument("--vpc_id", required=True, help="VPC ID")
create_parser.add_argument(
"--cu_count", type=int, help="Compute unit count (1 CU = 1 Core + 4 GB)"
)
create_parser.add_argument(
"--cpu", type=int, help="CPU in Core (override cu_count)"
)
create_parser.add_argument(
"--memory_gb", type=int, help="Memory in GB (override cu_count)"
)
create_parser.add_argument("--auto_renew", action="store_true", help="Auto-renew")
create_parser.add_argument(
"--period", type=int, choices=[1, 2, 3, 6, 12], help="Period (months)"
)
create_parser.add_argument(
"--confirm",
action="store_true",
help="Confirm creation (cost-incurring operation)",
)
create_parser.set_defaults(func=create_instance)
describe_parser = subparsers.add_parser("describe", help="Describe instances")
describe_parser.add_argument("--region_id", required=True, help="Region ID")
describe_parser.set_defaults(func=describe_instances)
regions_parser = subparsers.add_parser("describe_regions", help="Describe regions")
regions_parser.set_defaults(func=describe_regions)
zones_parser = subparsers.add_parser("describe_zones", help="Describe zones")
zones_parser.add_argument("--region_id", required=True, help="Region ID")
zones_parser.set_defaults(func=describe_zones)
ns_create_parser = subparsers.add_parser(
"create_namespace", help="Create namespace"
)
ns_create_parser.add_argument("--region_id", required=True, help="Region ID")
ns_create_parser.add_argument("--instance_id", required=True, help="Instance ID")
ns_create_parser.add_argument("--name", required=True, help="Namespace name")
ns_create_parser.add_argument("--cpu", type=int, help="CPU in Core (optional)")
ns_create_parser.add_argument(
"--memory_gb", type=int, help="Memory in GB (optional)"
)
ns_create_parser.add_argument(
"--confirm",
action="store_true",
help="Confirm creation (resource-consuming operation)",
)
ns_create_parser.set_defaults(func=create_namespace)
ns_desc_parser = subparsers.add_parser(
"describe_namespaces", help="Describe namespaces"
)
ns_desc_parser.add_argument("--region_id", required=True, help="Region ID")
ns_desc_parser.add_argument("--instance_id", required=True, help="Instance ID")
ns_desc_parser.set_defaults(func=describe_namespaces)
list_tags_parser = subparsers.add_parser("list_tags", help="List tags")
list_tags_parser.add_argument("--region_id", required=True, help="Region ID")
list_tags_parser.add_argument(
"--resource_type", required=True, help="Resource type"
)
list_tags_parser.add_argument("--resource_ids", help="Resource IDs")
list_tags_parser.set_defaults(func=list_tags)
args = parser.parse_args()
if not args.command:
parser.print_help()
return 1
return args.func(args)
if __name__ == "__main__":
sys.exit(main())
#!/usr/bin/env python3
"""
Prepare standard trigger batch artifacts for evaluator-compatible delivery.
Examples:
python scripts/prepare_trigger_batch.py --type positive --output outputs/should_trigger.jsonc
python scripts/prepare_trigger_batch.py --type negative --output outputs/should_not_trigger.jsonc
"""
import argparse
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
SOURCE_BY_TYPE = {
"positive": ROOT / "evals/triggering/autoGenerated/should_trigger.jsonc",
"negative": ROOT / "evals/triggering/autoGenerated/should_not_trigger.jsonc",
}
EXPECTED_FILENAME = {
"positive": "should_trigger.jsonc",
"negative": "should_not_trigger.jsonc",
}
def parse_args():
parser = argparse.ArgumentParser(
description="Copy standard trigger jsonc template to evaluator output path."
)
parser.add_argument(
"--type",
required=True,
choices=["positive", "negative"],
help="Trigger batch type.",
)
parser.add_argument(
"--output",
required=True,
help="Output jsonc path (for example outputs/should_trigger.jsonc).",
)
parser.add_argument(
"--force",
action="store_true",
help="Overwrite existing output file.",
)
return parser.parse_args()
def main():
args = parse_args()
src = SOURCE_BY_TYPE[args.type]
dst = Path(args.output).expanduser().resolve()
if not src.exists():
raise FileNotFoundError(f"Template not found: {src}")
if dst.exists() and not args.force:
raise FileExistsError(
f"Output already exists: {dst}. Use --force to overwrite."
)
dst.parent.mkdir(parents=True, exist_ok=True)
dst.write_text(src.read_text(encoding="utf-8"), encoding="utf-8")
expected = EXPECTED_FILENAME[args.type]
filename_note = ""
if dst.name != expected:
filename_note = (
f"\n[WARN] Recommended filename for {args.type} batch is '{expected}'."
)
print(
f"[OK] Generated {args.type} trigger artifact: {dst}"
f"\n[INFO] Source template: {src}{filename_note}"
)
if __name__ == "__main__":
main()