Install
openclaw skills install volcengine-iacUse Terraform/IaC for Volcengine resources only when the user explicitly chooses Terraform/IaC, already has a Terraform workflow/state, or confirms they need plan/diff/drift/destroy safety for VKE, managed databases/cache/storage, load balancers, domains/certificates, logging/monitoring, or team-managed infrastructure.
openclaw skills install volcengine-iacGenerate, plan, and apply Volcengine infrastructure with Terraform when the user chooses IaC. volcengine-deploy still owns application packaging, runtime rollout, health checks, and CLI resource-ledger deployment.
When writing new examples, prefer the Cloud Control provider volcengine/volcenginecc. Clean no-op verified volcenginecc examples now cover network, VPC extras, VPC traffic mirror filters and CLB targets, private NAT, ECS, ECS placement/template extras, EBS snapshots, VKE, CR, TOS including bucket notification to veFaaS, TLS including scheduled SQL and TOS import tasks, CloudMonitor disabled alert rules, Redis, IAM, IAM users/groups, CLB instance/certificate/ACL, ALB full private entry traffic plus health check template/certificate/ACL/customized config, APIG private gateway/service, VPN IPsec gateway/connection/route plus SSL server, CEN with VPC attachment, DirectConnect gateway, TransitRouter, PrivateLink CLB endpoint service and endpoint, veFaaS, RDS MySQL, RDS PostgreSQL, Kafka allowlist, FileNAS, EFS, DNS, and PrivateZone under assets/examples/; volcenginecc-ebs-snapshot-group, volcenginecc-autoscaling, and volcenginecc-rdsmssql are lifecycle-verified only and have documented provider drift/destroy caveats. See the matching references/volcenginecc-*.md file for validation results and pitfalls. Blocked resources are tracked in references/volcenginecc-blocked.md. Existing reusable modules under assets/modules/ still use the legacy volcengine/volcengine provider until each component is re-verified with volcenginecc.
Use this skill when one of these is true:
Do not use this skill just because a deployment is long-lived, VKE-based, or has managed dependencies. Recommend IaC where appropriate, but let the user choose. Do not use this skill when the user asks for CLI, a temporary demo/quick validation, a pure ECS single-VM service with no plan/diff/destroy requirement, or when Terraform/provider installation is blocked and the target can safely use the CLI fallback.
The skill ships forty-six clean no-op verified volcenginecc examples (volcenginecc-network, volcenginecc-vpc-extras, volcenginecc-vpc-traffic-mirror-filter, volcenginecc-vpc-traffic-mirror-target, volcenginecc-private-nat, volcenginecc-ecs, volcenginecc-ecs-extras, volcenginecc-ecs-launch-template-version, volcenginecc-ebs-snapshot, volcenginecc-vke, volcenginecc-cr, volcenginecc-tos, volcenginecc-tos-notification, volcenginecc-tls, volcenginecc-tls-schedule-sql, volcenginecc-tls-import-task, volcenginecc-cloudmonitor, volcenginecc-redis, volcenginecc-redis-public-address, volcenginecc-iam, volcenginecc-iam-users, volcenginecc-iam-oidc-provider, volcenginecc-iam-saml-provider, volcenginecc-clb, volcenginecc-clb-certificate, volcenginecc-clb-acl, volcenginecc-alb, volcenginecc-alb-health-check, volcenginecc-alb-certificate, volcenginecc-alb-acl, volcenginecc-alb-customized-cfg, volcenginecc-apig, volcenginecc-vpn, volcenginecc-vpn-ssl, volcenginecc-cen, volcenginecc-directconnect, volcenginecc-transitrouter, volcenginecc-privatelink, volcenginecc-vefaas, volcenginecc-rdsmysql, volcenginecc-rdspostgresql, volcenginecc-kafka-allow-list, volcenginecc-filenas, volcenginecc-efs, volcenginecc-dns, volcenginecc-privatezone), three lifecycle-verified examples (volcenginecc-ebs-snapshot-group, volcenginecc-autoscaling, volcenginecc-rdsmssql), six legacy reusable modules (network, vke, cr, rds-mysql, redis, tos), and four wrapper scripts (gen_tfvars.py, plan_summary.sh, export_outputs.sh, check_drift.sh).
Resources outside the six legacy modules (CLB/ALB, VKE, CR, databases, caches, object storage) should be added as verified volcenginecc examples first, then wrapped only after repeated use proves the interface is stable.
Required env vars: VOLCENGINE_ACCESS_KEY, VOLCENGINE_SECRET_KEY, VOLCENGINE_REGION.
Required tools: terraform >= 1.5, jq, git, python3 (for gen_tfvars.py).
Optional: .volcengine/deploy-choice.json from volcengine-prepare/volcengine-deploy. If absent, ask a short batch of Terraform-specific questions.
The skill writes Terraform working files into .volcengine/terraform/ by default. State can use a TOS S3-compatible backend when the user wants remote state; see references/backend-tos.md. Local state is acceptable for small one-off experiments when the user accepts the tradeoff.
If invoked by volcengine-deploy, return outputs in .volcengine/iac-outputs.json and let deploy continue with image build/push, Cloud Assistant commands, Kubernetes manifests, veFaaS release, migrations, and health checks.
.volcengine/deploy-choice.jsonskill_dir="$(dirname "$0")"
work_dir="${work_dir:-.volcengine/terraform}"
workload="${workload:-standard}"
mkdir -p "$work_dir"
python3 "$skill_dir/scripts/gen_tfvars.py" \
--input ".volcengine/deploy-choice.json" \
--output "$work_dir/terraform.tfvars" \
--workload "$workload"
gen_tfvars.py derives:
project, region, AZ pair from the choice file and environmentenable_vke / enable_cr / enable_rds / enable_redis / enable_tos flags from the chosen mode and known dependencies--workload tierThe user can override any value before applying.
When no prepare report exists, ask the user one batch of questions, then create a Terraform working directory from verified examples or legacy modules and generate matching variable values. Required answers:
cn-beijing)gen_tfvars.py writes only terraform.tfvars. The Terraform configuration files come from copied verified examples under assets/examples/ or from a small root module assembled from assets/modules/; edit those files to match the selected stack instead of expecting the script to generate them.
| File | Purpose |
|---|---|
main.tf / variables.tf | Copied or assembled Terraform configuration |
terraform.tfvars | Concrete values generated by gen_tfvars.py or edited by hand |
backend.tf | Generated only when TOS remote state is selected; otherwise omit it |
The full per-module variable schema lives in references/modules.md. For new volcenginecc work, start from a verified example under assets/examples/ instead of these legacy modules unless the user explicitly needs the old provider.
volcenginecc verified examplesCopy the relevant verified example, then run the same init/validate/plan sequence:
cp -R "$skill_dir/assets/examples/<example-name>" "$work_dir/<component>"
cd "$work_dir/<component>"
terraform init -backend=false -input=false
terraform validate
terraform plan -out=tfplan.binary -input=false
Before apply, show the plan summary and require explicit user confirmation. Read the matching reference before changing inputs or destroying resources; the references contain field choices, validation notes, import IDs, and provider pitfalls.
Use these opinionated stacks to choose verified examples. Start with examples; wrap into reusable modules only after repeated use proves the interface stable.
| Deployment shape | Examples to compose |
|---|---|
ecs-docker-public / ecs-systemd-public | volcenginecc-network, volcenginecc-ecs, optional volcenginecc-tls, volcenginecc-cloudmonitor |
vke-webapp-cr-clb | volcenginecc-network, volcenginecc-vke, volcenginecc-cr, volcenginecc-clb |
vke-webapp-cr-alb | volcenginecc-network, volcenginecc-vke, volcenginecc-cr, volcenginecc-alb, optional ALB health/cert/ACL examples |
vefaas-http | volcenginecc-vefaas, optional volcenginecc-apig, volcenginecc-tls |
webapp-rds-redis-tos | runtime stack plus volcenginecc-rdsmysql or volcenginecc-rdspostgresql, volcenginecc-redis, volcenginecc-tos |
private-service-with-nat | volcenginecc-network, volcenginecc-private-nat, runtime stack |
domain-and-edge-entry | runtime stack plus volcenginecc-dns, ALB/CLB certificate examples, optional CDN/WAF only after verified examples exist |
The stack mapping is a selection guide, not a promise that a prebuilt module exists. Copy the relevant verified examples into .volcengine/terraform/<component> and keep component boundaries clear so plan/destroy output remains readable.
For the end-to-end VKE private CR nginx path, use assets/examples/volcengine-vke-cr-nginx/ and read references/volcengine-vke-cr-nginx.md first. That example exists for the CR credential addon, core-dns, CR token expiry, and image architecture pitfalls found in a real run.
volcenginecc examples| Example | Purpose | Resources |
|---|---|---|
assets/examples/volcenginecc-network | Network foundation for ECS/VKE/RDS/Redis/LB deployments | vpc_vpc, vpc_subnet, vpc_route_table, vpc_security_group, vpc_eip, natgateway_ngw, natgateway_snatentry, natgateway_dnatentry |
assets/examples/volcenginecc-vpc-extras | Additional VPC controls for subnet ACLs, CIDR reuse, ENIs, HAVIP, and shared bandwidth | vpc_prefix_list, vpc_network_acl, vpc_eni, vpc_ha_vip, vpc_bandwidth_package |
assets/examples/volcenginecc-vpc-traffic-mirror-filter | Traffic mirror filter conditions before ECS/CLB target/session wiring | vpc_traffic_mirror_filter, vpc_traffic_mirror_filter_rule |
assets/examples/volcenginecc-vpc-traffic-mirror-target | Traffic mirror destination backed by a private CLB | vpc_traffic_mirror_target, clb_clb |
assets/examples/volcenginecc-private-nat | Private NAT gateway and additional transit IP for private address translation | natgateway_ngw, natgateway_nat_ip |
assets/examples/volcenginecc-ecs | Direct ECS deployments, utility hosts, launch templates, Cloud Assistant commands | ecs_keypair, storageebs_volume, ecs_command, ecs_launch_template, ecs_instance, second-stage ecs_invocation |
assets/examples/volcenginecc-ecs-extras | ECS placement primitives without creating instances | ecs_deployment_set, ecs_hpc_cluster |
assets/examples/volcenginecc-ecs-launch-template-version | Additional ECS launch template versions for controlled rollout changes | ecs_launch_template, ecs_launch_template_version |
assets/examples/volcenginecc-ebs-snapshot | Manual snapshot backup for standalone EBS data disks | storageebs_volume, storageebs_snapshot |
assets/examples/volcenginecc-ebs-snapshot-group | Snapshot consistency group for an attached ECS system volume | storageebs_snapshot_group, plus ECS/network prerequisites |
assets/examples/volcenginecc-autoscaling | Lifecycle-verified Auto Scaling group/configuration/hook for ECS capacity control | autoscaling_scaling_group, autoscaling_scaling_configuration, autoscaling_scaling_lifecycle_hook, plus launch template/network prerequisites |
assets/examples/volcenginecc-vke | Managed Kubernetes control plane, private kubeconfig, node pools, and managed addon | vke_cluster, vke_node_pool, vke_default_node_pool, vke_addon, vke_kubeconfig |
assets/examples/volcenginecc-cr | Container Registry image repositories for build/deploy pipelines | cr_registry, cr_name_space, cr_repository, cr_endpoint_acl_policy |
assets/examples/volcenginecc-tos | Object storage buckets for artifacts, static assets, logs, backups, or state prerequisites | tos_bucket, tos_bucket_cors, tos_bucket_encryption |
assets/examples/volcenginecc-tos-notification | TOS object-created event notifications delivered to a released veFaaS function | tos_bucket_notification, tos_bucket, vefaas_function, vefaas_release |
assets/examples/volcenginecc-tls | Log Service project/topic/index/rule/consumer group for application logs | tls_project, tls_topic, tls_index, tls_rule, tls_consumer_group |
assets/examples/volcenginecc-tls-schedule-sql | Scheduled SQL analysis from one TLS topic to another | tls_project, tls_topic, tls_index, tls_schedule_sql_task |
assets/examples/volcenginecc-tls-import-task | TOS-to-TLS import task with its target topic and source bucket | tls_project, tls_topic, tls_index, tos_bucket, tls_import_task |
assets/examples/volcenginecc-cloudmonitor | Disabled CloudMonitor ECS CPU alert rule for lifecycle-verified monitoring policy management | cloudmonitor_rule |
assets/examples/volcenginecc-redis | Redis cache instance with allowlist, parameter group, and app account | redis_instance, redis_account, redis_allow_list, redis_parameter_group |
assets/examples/volcenginecc-redis-public-address | Redis public endpoint bound to a dedicated EIP; use only when public exposure is deliberate | redis_endpoint_public_address, vpc_eip |
assets/examples/volcenginecc-iam | IAM project, assumable role, and custom policy primitives | iam_project, iam_role, iam_policy |
assets/examples/volcenginecc-iam-users | IAM user and group identity primitives without access keys or login password | iam_user, iam_group |
assets/examples/volcenginecc-iam-oidc-provider | External OIDC identity provider metadata for IAM federation | iam_oidc_provider |
assets/examples/volcenginecc-iam-saml-provider | SAML identity provider metadata for IAM SSO | iam_saml_provider |
assets/examples/volcenginecc-clb | Private Classic Load Balancer instance for entry traffic | clb_clb |
assets/examples/volcenginecc-clb-certificate | CLB uploaded server certificate for HTTPS listeners | clb_certificate |
assets/examples/volcenginecc-clb-acl | Classic Load Balancer access-control policy group | clb_acl |
assets/examples/volcenginecc-alb | Private Basic Application Load Balancer, server group, listener, and rule | alb_load_balancer, alb_server_group, alb_listener, alb_rule |
assets/examples/volcenginecc-alb-health-check | Reusable ALB health check template | alb_health_check_template |
assets/examples/volcenginecc-alb-certificate | ALB uploaded server certificate for HTTPS listeners | alb_certificate |
assets/examples/volcenginecc-alb-acl | ALB access-control policy group | alb_acl |
assets/examples/volcenginecc-alb-customized-cfg | ALB reusable NGINX customized config | alb_customized_cfg |
assets/examples/volcenginecc-apig | Private API Gateway entry point and service default domain | apig_gateway, apig_gateway_service |
assets/examples/volcenginecc-vpn | Site-to-site IPsec VPN gateway, connection, and static route for VPC connectivity | vpn_vpn_gateway, vpn_customer_gateway, vpn_vpn_connection, vpn_vpn_gateway_route |
assets/examples/volcenginecc-vpn-ssl | SSL VPN remote-access entry point for a VPC | vpn_vpn_gateway, vpn_ssl_vpn_server |
assets/examples/volcenginecc-cen | Cloud Enterprise Network with a VPC attachment for cross-network connectivity | cen_cen, vpc_vpc |
assets/examples/volcenginecc-directconnect | Direct Connect gateway foundation for dedicated-line connectivity | directconnect_direct_connect_gateway |
assets/examples/volcenginecc-transitrouter | TransitRouter foundation before VPC/VPN/DirectConnect/peer attachments | transitrouter_transit_router |
assets/examples/volcenginecc-privatelink | Interface PrivateLink service backed by private CLB plus consumer endpoint | privatelink_endpoint_service, privatelink_vpc_endpoint, clb_clb |
assets/examples/volcenginecc-vefaas | Serverless function, release, and disabled timer trigger | vefaas_function, vefaas_release, vefaas_timer |
assets/examples/volcenginecc-rdsmysql | MySQL instance, database, app account, allowlist, and parameter template | rdsmysql_instance, rdsmysql_database, rdsmysql_db_account, rdsmysql_allow_list, rdsmysql_parameter_template |
assets/examples/volcenginecc-rdspostgresql | PostgreSQL instance, database, app account, schema, allowlist, endpoint, and backup | rdspostgresql_instance, rdspostgresql_db_account, rdspostgresql_database, rdspostgresql_schema, rdspostgresql_allow_list, rdspostgresql_db_endpoint, rdspostgresql_backup |
assets/examples/volcenginecc-rdsmssql | Lifecycle-verified SQL Server Basic instance and allowlist with destroy retry caveat | rdsmssql_instance, rdsmssql_allow_list |
assets/examples/volcenginecc-kafka-allow-list | Standalone Kafka access allowlist for future Kafka instances | kafka_allow_list |
assets/examples/volcenginecc-filenas | NFS shared file system for ECS/VKE/application storage | filenas_instance |
assets/examples/volcenginecc-efs | EFS shared file system for multi-node application or dataset storage | efs_file_system |
assets/examples/volcenginecc-dns | Public DNS zone for application domains and edge CNAME targets | dns_zone |
assets/examples/volcenginecc-privatezone | VPC-scoped private DNS zone and record for internal service discovery | privatezone_private_zone, privatezone_record |
volcengine modules| Module | Purpose | Key inputs | Key outputs |
|---|---|---|---|
network | VPC + 2× AZ subnets + default SG | project, az_*, CIDRs | vpc_id, subnet_ids, security_group_id |
vke | Cluster + node pool + addons | vpc_id, subnet_ids, node_instance_type | cluster_id, kubeconfig_private (base64) |
cr | Registry + namespace + repository | registry_name, namespace, repository_name | registry_endpoint, repository_uri, registry_username |
rds-mysql | HA MySQL instance | subnet_id, primary_zone_id, secondary_zone_id, instance_type | instance_id, endpoints[] |
redis | Redis instance (single or HA) | subnet_id, engine_version, shard_capacity | instance_id (endpoint via ve redis DescribeDBInstanceDetail) |
tos | Object storage bucket | bucket_name, public_acl, storage_class | bucket_name, intranet_endpoint, extranet_endpoint |
Why ECS / CLB are not modules yet: ECS workloads vary too widely (build host vs runtime vs jumphost) for a single helpful interface, so ECS is a verified example rather than a module. EIP and NAT are covered in the verified
volcenginecc-networkexample. CLB/ALB should be added as verified examples before they become reusable modules.
cd "$work_dir"
# Map Volcengine creds to the Terraform s3 backend's required env variable names.
export AWS_ACCESS_KEY_ID="$VOLCENGINE_ACCESS_KEY"
export AWS_SECRET_ACCESS_KEY="$VOLCENGINE_SECRET_KEY"
export AWS_EC2_METADATA_DISABLED=true
terraform init -input=false
tf_workspace="${tf_workspace:-default}"
terraform workspace select "$tf_workspace" || \
terraform workspace new "$tf_workspace"
When remote state is requested, generate backend.tf from references/backend-tos.md. The verified TOS backend shape requires skip_requesting_account_id = true and must not set force_path_style or use_path_style.
Provider download (~30–60 seconds first time) goes through registry.terraform.io. In China networks this may be blocked or slow. If public registry access fails and the user still wants IaC, configure Terraform provider_installation with a filesystem or internal mirror. Otherwise return to volcengine-deploy and ask whether to use the CLI resource-ledger path.
For the TOS bucket prerequisite (must exist before init), see references/backend-tos.md. Without a TOS bucket, omit backend.tf and Terraform falls back to local state.
terraform plan -out=tfplan.binary -input=false
terraform show -json tfplan.binary > tfplan.json
bash "$skill_dir/scripts/plan_summary.sh" tfplan.json
plan_summary.sh groups changes by action (CREATE / UPDATE / DELETE / REPLACE) and prints a one-line summary at the end. Show this to the user before any apply.
Watch for:
terraform show tfplan.binaryAlways require explicit user confirmation. Do not pass -auto-approve. The pattern:
The plan above will create N resources, change M, destroy K. Approve apply? [yes/no]
After yes:
terraform apply tfplan.binary
VKE cluster creation takes ~10–15 minutes. RDS HA instances take ~20 minutes. Surface the long-running message to the user once at apply start so they don't think it hung.
After apply succeeds, run export_outputs.sh automatically:
bash "$skill_dir/scripts/export_outputs.sh"
echo "Resources ready. .volcengine/iac-outputs.json now contains downstream consumption keys."
export_outputs.sh writes terraform output -json to .volcengine/iac-outputs.json (mode 0600). The schema downstream skills (volcengine-deploy) consume:
{
"vpc_id": { "value": "vpc-xxxx" },
"subnet_ids": { "value": ["subnet-aaa", "subnet-bbb"] },
"security_group_id": { "value": "sg-xxxx" },
"cluster_id": { "value": "cluster-xxxx" },
"kubeconfig_private":{ "value": "<base64>", "sensitive": true },
"registry_endpoint": { "value": "cr-xxx.cr.volces.com" },
"repository_uri": { "value": "cr-xxx.cr.volces.com/myapp/myapp" },
"cr_username": { "value": "..." },
"mysql_endpoint": { "value": "<addr>:<port>" },
"redis_instance_id": { "value": "redis-xxxx" },
"tos_bucket": { "value": "myapp-bucket" }
}
Some keys are conditional on which modules were enabled. Consumers must jq defensively (use // empty defaults).
# Show what will be destroyed first
terraform plan -destroy -out=destroy.binary
terraform show -json destroy.binary | bash "$skill_dir/scripts/plan_summary.sh"
Then:
This will permanently delete N resources including RDS / Redis / TOS bucket data. Confirm? [yes/no]
On yes:
terraform destroy
# Note: provider does not accept -auto-approve=false; we rely on the agent-level prompt above.
Hard rule: never destroy in prod workspace without a second confirmation. The agent should explicitly re-prompt:
Workspace = prod. Re-confirm destroy by typing 'destroy prod':
bash "$skill_dir/scripts/check_drift.sh"
Returns:
0 and {"drift": false, ...} — no drift2 and {"drift": true, "changed_resources": N, ...} — N resources changed outside Terraform1 and {"drift": "error", ...} — refresh-only plan erroredUse this:
apply to confirm baseline matches stateIf the user has resources created via volcengine-cli (or console) and wants to adopt them under Terraform, use terraform import. The import ID format differs per resource. Common cases:
# VPC
terraform import 'module.network.volcengine_vpc.main' vpc-xxxxxxxx
# Subnet
terraform import 'module.network.volcengine_subnet.primary' subnet-xxxxxxxx
# VKE cluster
terraform import 'module.vke.volcengine_vke_cluster.main' cluster-xxxxxxxx
# CR registry — replace cr-basic with the actual registry name
terraform import 'module.cr.volcengine_cr_registry.main' cr-basic
# CR namespace (compound ID: registry:namespace)
terraform import 'module.cr.volcengine_cr_namespace.main' cr-basic:my-namespace
# CR repository (compound ID: registry:namespace:repo)
terraform import 'module.cr.volcengine_cr_repository.main' cr-basic:my-namespace:my-repo
# RDS MySQL
terraform import 'module.rds_mysql.volcengine_rds_mysql_instance.main' mysql-xxxxxxxx
# Redis
terraform import 'module.redis.volcengine_redis_instance.main' redis-xxxxxxxx
# TOS bucket — replace my-bucket with the actual globally-unique name
terraform import 'module.tos.volcengine_tos_bucket.main' my-bucket
After import, run terraform plan to surface any divergence between your .tf config and the imported reality, and reconcile by editing the config (not the state).
| Rule | Reason |
|---|---|
Never read ~/.volcengine/config.json | File contains plaintext AK/SK |
Never commit terraform.tfstate* | Contains sensitive state |
Always .gitignore .volcengine/iac-outputs.json | Contains kubeconfig + DB creds |
Never pass -auto-approve to terraform apply/destroy | Bypasses human gate |
Run check_drift.sh before every apply on shared envs | Prevents trampling out-of-band changes |
Set chmod 0600 on any file holding kubeconfig or secrets | Defense-in-depth |
| Pin provider versions in every module/example | Provider on 0.0.x line — patch bumps may still change behavior |
The skill's scripts enforce most of these mechanically (export_outputs.sh chmods 0600). Apply and destroy gates are the agent's responsibility.
| Symptom | Cause | Fix |
|---|---|---|
terraform init: "Failed to query available provider packages" | Outbound to registry.terraform.io blocked | If the user still wants IaC, set up a provider_installation filesystem mirror and rerun init; otherwise return to volcengine-deploy and ask whether to use CLI resource-ledger provisioning. |
terraform init: "InvalidAccessKeyId" against TOS backend | Terraform s3 backend env vars are not exported | Export AWS_ACCESS_KEY_ID="$VOLCENGINE_ACCESS_KEY", AWS_SECRET_ACCESS_KEY="$VOLCENGINE_SECRET_KEY", and AWS_EC2_METADATA_DISABLED=true. |
terraform init: TOS backend returns InvalidPathAccess | Backend uses path-style access or an unsupported workspace prefix shape | Use the verified template in references/backend-tos.md: keep skip_requesting_account_id = true and remove force_path_style / use_path_style. |
apply succeeds for VPC but fails for subnet with InvalidVpc.InvalidStatus | VPC not yet Available | Add depends_on = [volcengine_vpc.main] (already in network module) |
VKE cluster stuck in Creating for >20 minutes | Quota or AZ capacity | `ve vke DescribeClusters --body '{"Filter":{"Ids":["..."]}}' |
redis module output missing endpoint | Provider does not export it | Resolve via ve redis DescribeDBInstanceDetail --InstanceId $(jq -r '.redis_instance_id.value' .volcengine/iac-outputs.json) |
terraform plan shows unexpected changes after no edits | Drift, or provider patch bump silently changing default value | Run check_drift.sh, inspect tfplan.json, decide whether to accept or revert |
Two engineers' apply collide | TOS backend has no DynamoDB-style locking | Coordinate manually; see references/backend-tos.md |