
Alibabacloud Dms Skill
- 298 installs
- 208 repo stars
- Updated August 4, 2026
- aliyun/alibabacloud-aiops-skills
Manage databases in Alibaba Cloud DMS: schema design, SQL execution, access control, migration tasks, and safe change workflows for RDS and compatible engines.
About
Database skill for Alibaba Cloud Data Management Service: connect instances, author and review SQL, manage schemas and permissions, run migrations and sync jobs, and follow safe change workflows for production and staging databases.
- Runs governed SQL in DMS
- Manages schemas and instances
- Supports migration and sync tasks
- Enforces approval and access rules
- Works across RDS-compatible engines
Alibabacloud Dms Skill by the numbers
- 298 all-time installs (skills.sh)
- Ranked #176 of 911 Databases 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-dms-skillAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 298 |
|---|---|
| repo stars | ★ 208 |
| Last updated | August 4, 2026 |
| Repository | aliyun/alibabacloud-aiops-skills ↗ |
What it does
Manage databases in Alibaba Cloud DMS: schema design, SQL execution, access control, migration tasks, and safe change workflows for RDS and compatible engines.
Files
Alibaba Cloud DMS Database Read/Write
Search for target databases and execute SQL queries and data modifications via Alibaba Cloud DMS OpenAPI.
Scenario Description
This skill implements the following workflow:
1. Search Target Database — Search databases by keyword to get Database ID 2. Execute SQL Query — Execute SQL statements on the target database
Architecture
User Request → Search Database → Get Database ID → Execute SQL → Return ResultsPrerequisites
AI-Mode Lifecycle (MUST follow in order)
This skill MUST run inside an AI-Mode session. Treat the following five steps as a strict lifecycle — do not skip, reorder, or interleave the setup steps with command execution:
1. aliyun configure ai-mode enable # Enable AI-Mode
2. aliyun configure ai-mode set-user-agent AlibabaCloud-Agent-Skills/alibabacloud-dms-skill # Register skill User-Agent
3. aliyun configure set --auto-plugin-install true && aliyun plugin update # Plugin update
4. <execute DMS commands via ./scripts/*.sh> # Execute commands
5. aliyun configure ai-mode disable # Disable AI-Mode (Cleanup)Steps 1–3 belong to setup (this section). Step 4 is covered by Core Workflow. Step 5 is covered by Cleanup.
Pre-checks
Pre-check 0: Aliyun CLI >= 3.3.3 required
Run aliyun version to verify >= 3.3.3. If not installed or version too low,run curl -fsSL https://aliyuncli.alicdn.com/setup.sh | bash to install/update,or see references/cli-installation-guide.md for installation instructions.Pre-check 1: Enable AI-Mode
[MUST] run aliyun configure ai-mode enable to enable AI-Mode before any other configuration or command.This activates the AI-Mode session that downstream OpenAPI services use to recognize agent-issued traffic.
Pre-check 2: Register skill User-Agent under AI-Mode
[MUST] run aliyun configure ai-mode set-user-agent AlibabaCloud-Agent-Skills/alibabacloud-dms-skillto register this skill's identifier as the AI-Mode User-Agent for the current session.
Run this immediately after ai-mode enable and before any plugin update or DMS command.Pre-check 3: Aliyun CLI plugin update required
[MUST] run aliyun configure set --auto-plugin-install true to enable automatic plugin installation.[MUST] run aliyun plugin update to ensure that any existing plugins are always up-to-date.Plugin update MUST happen AFTER AI-Mode is enabled and the User-Agent is registered, so the plugin manager itself reports the correct identifier.
- Aliyun CLI >= 3.3.3
- jq (for JSON parsing):
brew install jq - Credentials configured via
aliyun configure
Pre-check 4: Alibaba Cloud Credentials Required
>
Security Rules:
- NEVER read, echo, or print AK/SK values (e.g., echo $ALIBABA_CLOUD_ACCESS_KEY_ID is FORBIDDEN)- NEVER ask the user to input AK/SK directly in the conversation or command line
- NEVER use aliyun configure set with literal credential values- ONLY use aliyun configure list to check credential status>
```bash
aliyun configure list
```
Check the output for a valid profile (AK, STS, or OAuth identity).
>
If no valid profile exists, STOP here.
1. Obtain credentials from Alibaba Cloud Console
2. Configure credentials outside of this session (via aliyun configure in terminal or environment variables in shell profile)3. Return and re-run after aliyun configure list shows a valid profile[MUST] Per-command CLI User-Agent — In addition to the AI-Mode User-Agent registered in Pre-check 2, every aliyun CLI command invocation in step 4 MUST also include: --user-agent AlibabaCloud-Agent-Skills/alibabacloud-dms-skill The per-command flag and the AI-Mode session-level setting are complementary — both MUST be present so the identifier is sent on every request even if the AI-Mode session expires.
RAM Permissions
[MUST] RAM Permission Pre-check: Verify that the current user has the following RAM permissions before execution.
See references/ram-policies.md for the complete permission list.Parameter Confirmation
IMPORTANT: Parameter Confirmation — Before executing any command or API call,
ALL user-customizable parameters (e.g., database keyword, SQL statement, db-id, etc.)
MUST be confirmed with the user. Do NOT assume or use default values without explicit user approval.
| Parameter | Required/Optional | Description | Default |
|---|---|---|---|
| keyword | Required | Database search keyword (1-128 chars, alphanumeric) | - |
| db-id | Required | Database ID (positive integer, obtained from search) | - |
| sql | Required | SQL statement to execute (1-10000 chars) | - |
| logic | Optional | Whether to use logic database mode | false |
| force | Optional | Confirm write operations (INSERT/UPDATE/DELETE) | false |
| dry-run | Optional | Preview write operations without executing | false |
Core Workflow
Task 1: Search Target Database
Search for databases by keyword to get the Database ID:
./scripts/search_database.sh <keyword> --jsonExample:
# Search for databases containing "mydb"
./scripts/search_database.sh mydb --jsonThe output includes database_id, schema_name, db_type, host, port, etc.
Task 2: Execute SQL Query
Execute SQL using the Database ID obtained in the previous step:
./scripts/execute_query.sh --db-id <database_id> --sql "<SQL_statement>"Write Operation Protection
For write operations (INSERT/UPDATE/DELETE), the script implements protective pre-check:
| Parameter | Description |
|---|---|
--force | Required to confirm and execute write operations |
--dry-run | Preview write operations without executing |
DDL Operations (DROP/TRUNCATE/ALTER/RENAME) are completely blocked — these must be executed via DMS Console.
Examples:
# Read operations (no confirmation needed)
./scripts/execute_query.sh --db-id 78059000 --sql "SHOW TABLES"
./scripts/execute_query.sh --db-id 78059000 --sql "SELECT * FROM users LIMIT 10" --json
# Write operations - preview first (recommended)
./scripts/execute_query.sh --db-id 78059000 --sql "INSERT INTO users (name) VALUES ('test')" --dry-run
# Write operations - execute with confirmation
./scripts/execute_query.sh --db-id 78059000 --sql "INSERT INTO users (name) VALUES ('test')" --force
./scripts/execute_query.sh --db-id 78059000 --sql "UPDATE users SET name='test' WHERE id=1" --force
./scripts/execute_query.sh --db-id 78059000 --sql "DELETE FROM users WHERE id=1" --force
# Logic database mode
./scripts/execute_query.sh --db-id 78059000 --sql "SELECT 1" --logicComplete Example
# 1. Search database (assuming searching for "order")
./scripts/search_database.sh order --json
# Example output:
# [{"DatabaseId": "78059000", "SchemaName": "order_db", ...}]
# 2. Execute query
./scripts/execute_query.sh --db-id 78059000 --sql "SELECT COUNT(*) FROM orders"Success Verification
After executing SQL, check the returned results:
1. Script return code is 0 2. Output contains query results (column names and row data) 3. No error messages
# Verify query success
./scripts/execute_query.sh --db-id <db-id> --sql "SELECT 1" --json
# Expected output: [{"Success": true, "RowCount": 1, ...}]Cleanup
This skill performs read and write operations but does not create persistent resources, so no database resources need to be released.
However, the AI-Mode lifecycle requires an explicit teardown step:
[MUST] Disable AI-Mode after all tasks complete
Run aliyun configure ai-mode disable once all DMS commands in this skill session have finished(success or failure). This terminates the AI-Mode session and prevents the registered
AlibabaCloud-Agent-Skills/alibabacloud-dms-skill User-Agent from leaking into subsequent unrelated CLI usage.aliyun configure ai-mode disableWrite Operation Safety
| Operation Type | Behavior |
|---|---|
| SELECT / SHOW / DESC | Execute directly |
| INSERT / UPDATE / DELETE | Require --force or --dry-run |
| DROP / TRUNCATE / ALTER / RENAME | Blocked — use DMS Console |
Available Scripts
| Script | Description |
|---|---|
scripts/search_database.sh | Search databases by keyword |
scripts/execute_query.sh | Execute SQL queries |
Note: Scripts use aliyun-cli credentials configured via aliyun configure.Best Practices
1. Confirm database — Verify the target database before executing SQL 2. Use --json parameter — Facilitates programmatic processing of output 3. Preview write operations — Always use --dry-run first for INSERT/UPDATE/DELETE 4. Explicit confirmation — Use --force only after reviewing the preview 5. Avoid DDL operations — DROP/TRUNCATE/ALTER/RENAME are blocked; use DMS Console instead
Reference Links
| Document | Description |
|---|---|
| references/cli-installation-guide.md | CLI Installation Guide |
| references/ram-policies.md | RAM Permission Policies |
| references/related-apis.md | Related API List |
| references/acceptance-criteria.md | Acceptance Criteria |
Acceptance Criteria: DMS Database Query
Scenario: DMS Database Query Workflow Purpose: Skill testing acceptance criteria
---
Correct SDK Code Patterns
1. Import Patterns
✅ CORRECT
from alibabacloud_dms_enterprise20181101.client import Client as DmsClient
from alibabacloud_dms_enterprise20181101 import models as dms_models
from alibabacloud_tea_openapi import models as open_api_models❌ INCORRECT
# Wrong: Using old SDK import paths
from aliyunsdkdms_enterprise.request.v20181101 import GetUserActiveTenantRequest
# Wrong: Missing required imports
from alibabacloud_dms_enterprise20181101 import Client # Missing models---
2. Client Initialization
✅ CORRECT
def create_client() -> DmsClient:
ak = os.getenv("ALICLOUD_ACCESS_KEY_ID") or os.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
sk = os.getenv("ALICLOUD_ACCESS_KEY_SECRET") or os.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
if not ak or not sk:
raise RuntimeError("Missing credentials")
config = open_api_models.Config(
access_key_id=ak,
access_key_secret=sk,
endpoint="dms-enterprise.cn-hangzhou.aliyuncs.com",
)
return DmsClient(config)❌ INCORRECT
# Wrong: Hardcoded credentials
config = open_api_models.Config(
access_key_id="LTAI5tXXXXXXXX", # NEVER hardcode
access_key_secret="8dXXXXXXXXXX", # NEVER hardcode
)
# Wrong: Missing endpoint
config = open_api_models.Config(
access_key_id=ak,
access_key_secret=sk,
# endpoint missing
)---
3. Get Tenant ID (Tid)
✅ CORRECT
def get_tid(client: DmsClient) -> int:
resp = client.get_user_active_tenant(dms_models.GetUserActiveTenantRequest())
if not resp.body.success:
raise RuntimeError(f"Failed to get Tid: {resp.body.error_message}")
return resp.body.tenant.tid❌ INCORRECT
# Wrong: Not checking success status
def get_tid(client):
resp = client.get_user_active_tenant(dms_models.GetUserActiveTenantRequest())
return resp.body.tenant.tid # May fail silently
# Wrong: Hardcoded Tid
tid = 12345 # NEVER hardcode Tid---
4. Search Database
✅ CORRECT
def search_databases(keyword: str) -> list[dict]:
client = create_client()
tid = get_tid(client)
req = dms_models.SearchDatabaseRequest(search_key=keyword, tid=tid)
resp = client.search_database(req)
records = []
if resp.body.search_database_list and resp.body.search_database_list.search_database:
for db in resp.body.search_database_list.search_database:
records.append({
"database_id": db.database_id,
"schema_name": db.schema_name,
})
return records❌ INCORRECT
# Wrong: Not passing Tid
req = dms_models.SearchDatabaseRequest(search_key=keyword) # Missing tid
# Wrong: Not handling empty results
for db in resp.body.search_database_list.search_database: # May raise AttributeError
pass---
5. Execute SQL Query
✅ CORRECT
def execute_query(db_id: int, sql: str, logic: bool = False) -> list[dict]:
client = create_client()
tid = get_tid(client)
req = dms_models.ExecuteScriptRequest(
tid=tid,
db_id=db_id,
script=sql,
logic=logic,
)
resp = client.execute_script(req)
if not resp.body.success:
raise RuntimeError(f"SQL execution failed: {resp.body.error_message}")
# Process results...❌ INCORRECT
# Wrong: Using wrong parameter names
req = dms_models.ExecuteScriptRequest(
tid=tid,
database_id=db_id, # Wrong: should be db_id
sql=sql, # Wrong: should be script
)
# Wrong: Not checking success status
resp = client.execute_script(req)
return resp.body.results # May contain error---
Test Scenarios
Scenario 1: Get Tenant ID
Input: Valid credentials in environment variables Expected Output: Integer Tid value Verification:
python scripts/get_tid.py
# Output: 12345 (numeric Tid)Scenario 2: Search Database
Input: Keyword "test" Expected Output: List of matching databases Verification:
python scripts/search_database.py test --json
# Output: [{"database_id": "xxx", "schema_name": "test_db", ...}]Scenario 3: Execute SQL Query
Input: Valid db_id and SQL "SELECT 1" Expected Output: Query results Verification:
python scripts/execute_query.py --db-id 12345 --sql "SELECT 1" --json
# Output: [{"success": true, "row_count": 1, ...}]---
Error Handling Patterns
✅ CORRECT Error Handling
try:
results = execute_query(db_id, sql)
except RuntimeError as e:
print(f"Error: {e}", file=sys.stderr)
return 1❌ INCORRECT Error Handling
# Wrong: Catching all exceptions silently
try:
results = execute_query(db_id, sql)
except:
pass # Silently ignoring errors
# Wrong: No error handling
results = execute_query(db_id, sql) # May crash---
Environment Requirements
- Python >= 3.10
- Required packages:
alibabacloud-dms-enterprise20181101,alibabacloud-tea-openapi,alibabacloud-credentials - Environment variables:
ALICLOUD_ACCESS_KEY_ID,ALICLOUD_ACCESS_KEY_SECRET
Aliyun CLI Installation & Configuration Guide
Complete guide for installing and configuring Aliyun CLI.
Aliyun CLI 3.3.3+: Supports installing and using all published Alibaba Cloud product plugins. Make sure to upgrade to 3.3.3 or later for full plugin ecosystem coverage.
Installation
macOS
Using Homebrew (Recommended)
brew install aliyun-cli
# Upgrade to latest
brew upgrade aliyun-cli
# Verify version (>= 3.3.3)
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 update 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=http://proxy.example.com:8080
export HTTPS_PROXY=http://proxy.example.com:8080
# 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.3+ 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
RAM Policies for DMS Database Query
This document lists the RAM (Resource Access Management) permissions required for the DMS database query workflow.
Summary Table
| Product | RAM Action | Resource Scope | Description |
|---|---|---|---|
| DMS | dms:GetUserActiveTenant | * | Get tenant ID |
| DMS | dms:SearchDatabase | * | Search databases by keyword |
| DMS | dms:ExecuteScript | * | Execute SQL scripts |
RAM Policy Document
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dms:GetUserActiveTenant",
"dms:SearchDatabase",
"dms:ExecuteScript"
],
"Resource": "*"
}
]
}Minimal Permission Policy
For production environments, consider restricting permissions to specific resources:
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dms:GetUserActiveTenant"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"dms:SearchDatabase"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"dms:TenantId": "${your-tenant-id}"
}
}
},
{
"Effect": "Allow",
"Action": [
"dms:ExecuteScript"
],
"Resource": "acs:dms:*:*:database/${database-id}",
"Condition": {
"StringEquals": {
"dms:SqlType": ["SELECT"]
}
}
}
]
}Permission Descriptions
dms:GetUserActiveTenant
- Purpose: Retrieve the tenant ID (Tid) for the current user
- Required: Yes (prerequisite for all other DMS API calls)
- Resource:
*(tenant-level operation)
dms:SearchDatabase
- Purpose: Search for databases by keyword
- Required: Yes (to find the target database)
- Resource:
*(searches across all accessible databases)
dms:ExecuteScript
- Purpose: Execute SQL scripts on a database
- Required: Yes (core functionality)
- Resource: Can be restricted to specific database IDs
- Note: This permission allows execution of SELECT, DML, and DDL statements. Consider restricting to read-only queries in production.
Best Practices
1. Least Privilege: Only grant dms:ExecuteScript on specific databases that users need to access 2. Read-Only Access: For reporting/analytics users, consider creating a separate policy that only allows SELECT queries 3. Audit Logging: Enable DMS audit logging to track all SQL executions 4. Regular Review: Periodically review and revoke unnecessary permissions
Related Documentation
Related APIs for DMS Database Query
This document lists all APIs used in the DMS database query workflow.
API Summary Table
| Product | API Name | SDK Method | Description |
|---|---|---|---|
| DMS | GetUserActiveTenant | get_user_active_tenant() | Get current user's tenant ID |
| DMS | SearchDatabase | search_database() | Search databases by keyword |
| DMS | ExecuteScript | execute_script() | Execute SQL scripts |
API Details
GetUserActiveTenant
Description: Get the active tenant information for the current user. All DMS API calls require the Tid (tenant ID) parameter.
Endpoint: dms-enterprise.cn-hangzhou.aliyuncs.com
Request Parameters: None required
Response:
{
"RequestId": "xxx",
"Success": true,
"Tenant": {
"Tid": 12345,
"TenantName": "xxx",
"Status": "ACTIVE"
}
}SDK Usage:
from alibabacloud_dms_enterprise20181101 import models as dms_models
resp = client.get_user_active_tenant(dms_models.GetUserActiveTenantRequest())
tid = resp.body.tenant.tid---
SearchDatabase
Description: Search for databases by keyword. Returns matching databases with their IDs, types, and connection information.
Endpoint: dms-enterprise.cn-hangzhou.aliyuncs.com
Request Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Tid | Long | Yes | Tenant ID |
| SearchKey | String | Yes | Search keyword |
Response:
{
"RequestId": "xxx",
"Success": true,
"SearchDatabaseList": {
"SearchDatabase": [
{
"DatabaseId": "12345",
"SchemaName": "mydb",
"DbType": "MySQL",
"Host": "rm-xxx.mysql.rds.aliyuncs.com",
"Port": 3306,
"Encoding": "utf8mb4",
"EnvType": "product"
}
]
}
}SDK Usage:
from alibabacloud_dms_enterprise20181101 import models as dms_models
req = dms_models.SearchDatabaseRequest(
search_key="mydb",
tid=tid
)
resp = client.search_database(req)
for db in resp.body.search_database_list.search_database:
print(db.database_id, db.schema_name)---
ExecuteScript
Description: Execute SQL scripts on a specified database. Supports SELECT, DML (INSERT/UPDATE/DELETE), and DDL statements.
Endpoint: dms-enterprise.cn-hangzhou.aliyuncs.com
Request Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Tid | Long | Yes | Tenant ID |
| DbId | Long | Yes | Database ID |
| Script | String | Yes | SQL statement to execute |
| Logic | Boolean | No | Whether to use logic database mode (default: false) |
Response:
{
"RequestId": "xxx",
"Success": true,
"Results": {
"Results": [
{
"Success": true,
"Message": "",
"RowCount": 10,
"ColumnNames": ["id", "name", "created_at"],
"Rows": {
"Row": [
{"RowValue": ["1", "Alice", "2024-01-01"]}
]
}
}
]
}
}SDK Usage:
from alibabacloud_dms_enterprise20181101 import models as dms_models
req = dms_models.ExecuteScriptRequest(
tid=tid,
db_id=12345,
script="SELECT * FROM users LIMIT 10",
logic=False
)
resp = client.execute_script(req)
for result in resp.body.results.results:
print(result.column_names)
for row in result.rows.row:
print(row.row_value)Additional Useful APIs
These APIs are not used in the core workflow but may be useful for extended scenarios:
| API Name | Description |
|---|---|
| ListDatabases | List all databases for an instance |
| GetDatabase | Get database details by ID |
| ListTables | List tables in a database |
| ListColumns | List columns in a table |
| GetMetaTableDetailInfo | Get table metadata |
API Documentation Links
#!/bin/bash
# Execute SQL query against a DMS database using aliyun-cli.
#
# Prerequisites:
# - aliyun-cli installed (brew install aliyun-cli)
# - aliyun configure set --mode AK --access-key-id <AK> --access-key-secret <SK> --region cn-hangzhou
# - jq installed for JSON parsing (brew install jq)
#
# Usage:
# ./execute_query.sh --db-id 12345 --sql "SELECT 1"
# ./execute_query.sh --db-id 12345 --sql "SHOW TABLES" --json
# ./execute_query.sh --db-id 12345 --sql "SELECT * FROM users LIMIT 5" --logic
set -e
# Default region
REGION="${REGION:-cn-hangzhou}"
# Parse arguments
DB_ID=""
SQL=""
LOGIC=false
OUTPUT_JSON=false
FORCE=false
DRY_RUN=false
print_help() {
echo "Usage: $0 --db-id <database_id> --sql <sql_statement> [options]"
echo ""
echo "Required arguments:"
echo " --db-id <id> Database ID"
echo " --sql <statement> SQL statement to execute"
echo ""
echo "Optional arguments:"
echo " --logic Use logic database mode"
echo " --json Output results in JSON format"
echo " --region <region> Aliyun region (default: cn-hangzhou)"
echo " --force Skip confirmation for write operations (INSERT/UPDATE/DELETE)"
echo " --dry-run Preview write operations without executing"
echo " -h, --help Show this help message"
echo ""
echo "Examples:"
echo " $0 --db-id 12345 --sql \"SELECT 1\""
echo " $0 --db-id 12345 --sql \"SHOW TABLES\" --json"
echo " $0 --db-id 12345 --sql \"SELECT * FROM users LIMIT 5\" --logic"
echo " $0 --db-id 12345 --sql \"INSERT INTO users (name) VALUES ('test')\" --force"
echo " $0 --db-id 12345 --sql \"UPDATE users SET name='test' WHERE id=1\" --dry-run"
}
while [[ $# -gt 0 ]]; do
case "$1" in
--db-id)
DB_ID="$2"
shift 2
;;
--sql)
SQL="$2"
shift 2
;;
--logic)
LOGIC=true
shift
;;
--json)
OUTPUT_JSON=true
shift
;;
--region)
REGION="$2"
shift 2
;;
--force)
FORCE=true
shift
;;
--dry-run)
DRY_RUN=true
shift
;;
-h|--help)
print_help
exit 0
;;
-*)
echo "Unknown option: $1" >&2
print_help >&2
exit 1
;;
*)
echo "Unexpected argument: $1" >&2
print_help >&2
exit 1
;;
esac
done
# Validate required arguments
if [[ -z "$DB_ID" ]]; then
echo "Error: --db-id is required" >&2
print_help >&2
exit 1
fi
# Validate DB_ID: must be a positive integer (Long type)
if ! echo "$DB_ID" | grep -qE '^[0-9]+$'; then
echo "Error: --db-id 必须是正整数" >&2
exit 1
fi
if [[ ${#DB_ID} -gt 19 ]]; then
echo "Error: --db-id 超出有效范围 (最大 19 位数字)" >&2
exit 1
fi
if [[ -z "$SQL" ]]; then
echo "Error: --sql is required" >&2
print_help >&2
exit 1
fi
# Validate SQL: length 1-10000 characters
if [[ ${#SQL} -gt 10000 ]]; then
echo "Error: SQL 语句长度不能超过 10000 个字符" >&2
exit 1
fi
if [[ ${#SQL} -lt 1 ]]; then
echo "Error: SQL 语句不能为空" >&2
exit 1
fi
# Validate REGION: must match Alibaba Cloud region format
if ! echo "$REGION" | grep -qE '^[a-z]{2,3}-[a-z]+-?[0-9]*$'; then
echo "Error: region 格式不正确,应为阿里云 Region ID 格式 (如 cn-hangzhou, cn-shanghai, us-west-1)" >&2
exit 1
fi
# Check if jq is installed
if ! command -v jq &> /dev/null; then
echo "Error: jq is required for JSON parsing. Install with: brew install jq" >&2
exit 1
fi
# Check if aliyun cli is installed
if ! command -v aliyun &> /dev/null; then
echo "Error: aliyun-cli is not installed. Install with: brew install aliyun-cli" >&2
exit 1
fi
# User-Agent for tracking
USER_AGENT="AlibabaCloud-Agent-Skills/alibabacloud-dms-skill"
# Timeout settings (in seconds)
READ_TIMEOUT=10
CONNECT_TIMEOUT=10
# Detect write operation type
SQL_UPPER=$(echo "$SQL" | tr '[:lower:]' '[:upper:]')
IS_WRITE_OP=false
WRITE_OP_TYPE=""
if echo "$SQL_UPPER" | grep -qE '^\s*INSERT\s'; then
IS_WRITE_OP=true
WRITE_OP_TYPE="INSERT"
elif echo "$SQL_UPPER" | grep -qE '^\s*UPDATE\s'; then
IS_WRITE_OP=true
WRITE_OP_TYPE="UPDATE"
elif echo "$SQL_UPPER" | grep -qE '^\s*DELETE\s'; then
IS_WRITE_OP=true
WRITE_OP_TYPE="DELETE"
elif echo "$SQL_UPPER" | grep -qE '^\s*(DROP|TRUNCATE|ALTER|RENAME)\s'; then
# Block destructive DDL operations completely
echo "Error: 安全检查失败 - 不允许执行 DDL 破坏性操作 (DROP/TRUNCATE/ALTER/RENAME)" >&2
echo " 这些操作可能导致数据不可恢复丢失,请通过 DMS 控制台执行" >&2
exit 1
fi
# Handle write operations with protective pre-check
if [[ "$IS_WRITE_OP" == "true" ]]; then
echo "" >&2
echo "========================================" >&2
echo " [警告] 检测到写操作: $WRITE_OP_TYPE" >&2
echo "========================================" >&2
echo " 目标数据库 ID: $DB_ID" >&2
echo " SQL 语句:" >&2
echo " $SQL" >&2
echo "========================================" >&2
if [[ "$DRY_RUN" == "true" ]]; then
echo "" >&2
echo "[DRY-RUN 模式] 仅预览,不会执行实际操作" >&2
echo "如需执行,请移除 --dry-run 参数并添加 --force 参数" >&2
exit 0
fi
if [[ "$FORCE" != "true" ]]; then
echo "" >&2
echo "此操作将修改数据库数据。" >&2
echo "如需执行,请添加 --force 参数确认操作。" >&2
echo "如需预览,请添加 --dry-run 参数。" >&2
echo "" >&2
echo "示例:" >&2
echo " $0 --db-id $DB_ID --sql \"$SQL\" --force" >&2
echo " $0 --db-id $DB_ID --sql \"$SQL\" --dry-run" >&2
exit 1
fi
echo "" >&2
echo "[--force 已确认] 将执行写操作..." >&2
echo "" >&2
fi
# Step 1: Get Tenant ID (Tid)
echo "Fetching Tenant ID..." >&2
TID_RESPONSE=$(aliyun dms-enterprise get-user-active-tenant \
--region "$REGION" \
--user-agent "$USER_AGENT" \
--read-timeout "$READ_TIMEOUT" \
--connect-timeout "$CONNECT_TIMEOUT" 2>&1)
# Check if the request was successful
if ! echo "$TID_RESPONSE" | jq -e '.Success' > /dev/null 2>&1; then
echo "Error: Failed to get Tenant ID" >&2
echo "$TID_RESPONSE" >&2
exit 1
fi
SUCCESS=$(echo "$TID_RESPONSE" | jq -r '.Success')
if [[ "$SUCCESS" != "true" ]]; then
ERROR_MSG=$(echo "$TID_RESPONSE" | jq -r '.ErrorMessage // "Unknown error"')
echo "Error: $ERROR_MSG" >&2
exit 1
fi
TID=$(echo "$TID_RESPONSE" | jq -r '.Tenant.Tid')
if [[ -z "$TID" || "$TID" == "null" ]]; then
echo "Error: Failed to extract Tid from response" >&2
exit 1
fi
echo "Tenant ID: $TID" >&2
# Step 2: Execute SQL Script
echo "Executing SQL on database $DB_ID..." >&2
# Build command arguments
CMD_ARGS=(
"dms-enterprise" "execute-script"
"--tid" "$TID"
"--db-id" "$DB_ID"
"--script" "$SQL"
"--logic" "$LOGIC"
"--region" "$REGION"
"--user-agent" "$USER_AGENT"
"--read-timeout" "$READ_TIMEOUT"
"--connect-timeout" "$CONNECT_TIMEOUT"
)
EXEC_RESPONSE=$(aliyun "${CMD_ARGS[@]}" 2>&1)
# Check if the request was successful
SUCCESS=$(echo "$EXEC_RESPONSE" | jq -r '.Success')
if [[ "$SUCCESS" != "true" ]]; then
ERROR_MSG=$(echo "$EXEC_RESPONSE" | jq -r '.ErrorMessage // "Unknown error"')
echo "Error: 执行SQL失败 - $ERROR_MSG" >&2
exit 1
fi
# Extract results
RESULTS=$(echo "$EXEC_RESPONSE" | jq '.Results.Results // []')
if [[ "$OUTPUT_JSON" == "true" ]]; then
# Output JSON format
echo "$RESULTS" | jq '.'
else
# Output table format
RESULT_COUNT=$(echo "$RESULTS" | jq 'length')
if [[ "$RESULT_COUNT" -eq 0 ]]; then
echo "查询完成,无返回结果"
else
for ((i=0; i<RESULT_COUNT; i++)); do
RESULT=$(echo "$RESULTS" | jq ".[$i]")
if [[ "$RESULT_COUNT" -gt 1 ]]; then
echo "--- 结果集 $((i+1)) ---"
fi
RESULT_SUCCESS=$(echo "$RESULT" | jq -r '.Success')
if [[ "$RESULT_SUCCESS" != "true" ]]; then
MSG=$(echo "$RESULT" | jq -r '.Message // "Unknown error"')
echo "错误: $MSG"
continue
fi
# Get column names
COLUMNS=$(echo "$RESULT" | jq -r '.ColumnNames // [] | @tsv')
if [[ -n "$COLUMNS" ]]; then
echo "$COLUMNS"
echo "--------------------------------------------------"
fi
# Get rows
ROWS=$(echo "$RESULT" | jq -r '.Rows.Row // []')
ROW_COUNT=$(echo "$ROWS" | jq 'length')
for ((j=0; j<ROW_COUNT; j++)); do
ROW_VALUES=$(echo "$ROWS" | jq -r ".[$j].RowValue // [] | @tsv")
echo "$ROW_VALUES"
done
TOTAL_ROWS=$(echo "$RESULT" | jq -r '.RowCount // 0')
echo ""
echo "($TOTAL_ROWS rows)"
done
fi
fi
#!/bin/bash
# Search DMS databases by keyword using aliyun-cli.
#
# Prerequisites:
# - aliyun-cli installed (brew install aliyun-cli)
# - aliyun configure set --mode AK --access-key-id <AK> --access-key-secret <SK> --region cn-hangzhou
# - jq installed for JSON parsing (brew install jq)
#
# Usage:
# ./search_database.sh <keyword>
# ./search_database.sh testdb
# ./search_database.sh testdb --json
set -e
# Default region
REGION="${REGION:-cn-hangzhou}"
# Parse arguments
KEYWORD=""
OUTPUT_JSON=false
while [[ $# -gt 0 ]]; do
case "$1" in
--json)
OUTPUT_JSON=true
shift
;;
--region)
REGION="$2"
shift 2
;;
-h|--help)
echo "Usage: $0 <keyword> [--json] [--region <region>]"
echo ""
echo "Arguments:"
echo " keyword Search keyword for database name"
echo " --json Output results in JSON format"
echo " --region Aliyun region (default: cn-hangzhou)"
echo ""
echo "Examples:"
echo " $0 mydb"
echo " $0 mydb --json"
echo " $0 mydb --region cn-shanghai"
exit 0
;;
-*)
echo "Unknown option: $1" >&2
exit 1
;;
*)
KEYWORD="$1"
shift
;;
esac
done
if [[ -z "$KEYWORD" ]]; then
echo "Error: keyword is required" >&2
echo "Usage: $0 <keyword> [--json] [--region <region>]" >&2
exit 1
fi
# Validate KEYWORD: length 1-128 characters, alphanumeric and common symbols only
if [[ ${#KEYWORD} -gt 128 ]]; then
echo "Error: keyword 长度不能超过 128 个字符" >&2
exit 1
fi
if ! echo "$KEYWORD" | grep -qE '^[a-zA-Z0-9_\-\.]+$'; then
echo "Error: keyword 只能包含字母、数字、下划线、连字符和点号" >&2
exit 1
fi
# Validate REGION: must match Alibaba Cloud region format
if ! echo "$REGION" | grep -qE '^[a-z]{2,3}-[a-z]+-?[0-9]*$'; then
echo "Error: region 格式不正确,应为阿里云 Region ID 格式 (如 cn-hangzhou, cn-shanghai, us-west-1)" >&2
exit 1
fi
# Check if jq is installed
if ! command -v jq &> /dev/null; then
echo "Error: jq is required for JSON parsing. Install with: brew install jq" >&2
exit 1
fi
# Check if aliyun cli is installed
if ! command -v aliyun &> /dev/null; then
echo "Error: aliyun-cli is not installed. Install with: brew install aliyun-cli" >&2
exit 1
fi
# User-Agent for tracking
USER_AGENT="AlibabaCloud-Agent-Skills/alibabacloud-dms-skill"
# Timeout settings (in seconds)
READ_TIMEOUT=10
CONNECT_TIMEOUT=10
# Step 1: Get Tenant ID (Tid)
echo "Fetching Tenant ID..." >&2
TID_RESPONSE=$(aliyun dms-enterprise get-user-active-tenant \
--region "$REGION" \
--user-agent "$USER_AGENT" \
--read-timeout "$READ_TIMEOUT" \
--connect-timeout "$CONNECT_TIMEOUT" 2>&1)
# Check if the request was successful
if ! echo "$TID_RESPONSE" | jq -e '.Success' > /dev/null 2>&1; then
echo "Error: Failed to get Tenant ID" >&2
echo "$TID_RESPONSE" >&2
exit 1
fi
SUCCESS=$(echo "$TID_RESPONSE" | jq -r '.Success')
if [[ "$SUCCESS" != "true" ]]; then
ERROR_MSG=$(echo "$TID_RESPONSE" | jq -r '.ErrorMessage // "Unknown error"')
echo "Error: $ERROR_MSG" >&2
exit 1
fi
TID=$(echo "$TID_RESPONSE" | jq -r '.Tenant.Tid')
if [[ -z "$TID" || "$TID" == "null" ]]; then
echo "Error: Failed to extract Tid from response" >&2
exit 1
fi
echo "Tenant ID: $TID" >&2
# Step 2: Search Database
echo "Searching databases with keyword: $KEYWORD" >&2
SEARCH_RESPONSE=$(aliyun dms-enterprise search-database \
--tid "$TID" \
--search-key "$KEYWORD" \
--region "$REGION" \
--user-agent "$USER_AGENT" \
--read-timeout "$READ_TIMEOUT" \
--connect-timeout "$CONNECT_TIMEOUT" 2>&1)
# Check if the request was successful
SUCCESS=$(echo "$SEARCH_RESPONSE" | jq -r '.Success')
if [[ "$SUCCESS" != "true" ]]; then
ERROR_MSG=$(echo "$SEARCH_RESPONSE" | jq -r '.ErrorMessage // "Unknown error"')
echo "Error: $ERROR_MSG" >&2
exit 1
fi
# Extract database list
DATABASES=$(echo "$SEARCH_RESPONSE" | jq '.SearchDatabaseList.SearchDatabase // []')
if [[ "$OUTPUT_JSON" == "true" ]]; then
# Output JSON format
echo "$DATABASES" | jq '.'
else
# Output table format
DB_COUNT=$(echo "$DATABASES" | jq 'length')
if [[ "$DB_COUNT" -eq 0 ]]; then
echo "未找到匹配的数据库"
else
echo ""
echo "共找到 $DB_COUNT 个匹配:"
echo ""
printf "%-15s %-25s %-12s %-30s\n" "DATABASE_ID" "SCHEMA_NAME" "DB_TYPE" "HOST:PORT"
printf "%s\n" "-------------------------------------------------------------------------------------"
echo "$DATABASES" | jq -r '.[] | "\(.DatabaseId // "N/A")|\(.SchemaName // "N/A")|\(.DbType // "N/A")|\(.Host // "N/A"):\(.Port // "N/A")"' | \
while IFS='|' read -r db_id schema_name db_type host_port; do
printf "%-15s %-25s %-12s %-30s\n" "$db_id" "$schema_name" "$db_type" "$host_port"
done
fi
fi