Skill v1.0.0
currentAutomated scan100/100version: "1.0.0" name: redc-template-management description: Create, maintain, and validate redc Terraform templates for multi-cloud deployment scenarios. Use this skill whenever someone wants to add a new cloud template (ECS, EC2, VM, etc.), create a userdata script, write a compose template, update an existing template's version or configuration, fix CI validation failures, or add support for a new cloud provider. Also use when reviewing template PRs, checking case.json compliance, or standardizing output naming conventions across templates.
redc Template Management
This skill guides you through creating and maintaining templates for the redc multi-cloud deployment engine. redc templates are Terraform-based infrastructure-as-code definitions organized by cloud provider, with a metadata layer (case.json) that the redc engine and GUI consume.
Template Types
redc has four template types, each in its own directory:
| Type | template value | Directory | When to use | |
|---|---|---|---|---|
| Preset | preset or omit | aliyun/, aws/, tencent/, etc. | Full cloud scenarios (ECS+VPC+SG) shown in Scene Management | |
| Base | base | base-templates/ | Minimal cloud primitives for Custom Deployment | |
| Userdata | userdata | userdata-templates/ | Init scripts (bash/powershell) composable with any base | |
| Compose | compose | compose-templates/ | Docker Compose definitions for Compose Management |
Pick preset for self-contained "one-click deploy" scenarios. Pick base when providing a minimal building block that users combine with userdata scripts. Pick userdata for software installation scripts. Pick compose for Docker service stacks.
Creating a New Template
Step 1: Determine the template type and location
Preset template → <provider>/<scene-name>/ (e.g., aliyun/nat-probe/, aws/proxy/) Base template → base-templates/<provider>-<resource>/ (e.g., base-templates/aws-ec2/) Userdata template → userdata-templates/<name>/ (e.g., userdata-templates/redis-bash/) Compose template → compose-templates/<name>/ (e.g., compose-templates/elk-stack/)
Directory and file names: lowercase, hyphens for word separation, no spaces.
Step 2: Create the required files
Every template directory needs at minimum:
scene-name/├── case.json ← Metadata (REQUIRED)├── README.md ← Documentation in Chinese (REQUIRED)├── README_EN.md ← Documentation in English (REQUIRED)├── versions.tf ← Provider version locks (preset/base only)├── main.tf ← Core resources (preset/base only)├── variables.tf ← Input variables (preset/base only)└── outputs.tf ← Output values (preset/base only)
For userdata templates, the structure is simpler:
script-name/├── case.json├── README.md├── README_EN.md└── userdata ← The script file (no extension)
For compose templates:
stack-name/├── case.json├── README.md├── README_EN.md└── redc-compose.yaml
Step 3: Write case.json
This is the most important file — the redc engine and CI both validate it strictly.
Common required fields (all template types, CI will fail without these):
| Field | Type | Description | |
|---|---|---|---|
name | string | 模板名称,非空 | |
user | string | 作者名,非空 | |
version | string | 语义化版本号,如 "1.0.0" | |
description | string | 中文描述,非空 | |
description_en | string | 英文描述,非空 | |
tags | list | 标签列表,非空 |
Type-specific required fields (CI also enforces these):
| Template Type | Extra Required Fields | Description | |
|---|---|---|---|
preset | arch | 架构,如 "x86_64" 或 "arm64" | |
base | arch, provider | 架构 + 云厂商标识(如 "alicloud", "aws") | |
userdata | nameZh, type, category | 中文名 + 脚本类型 (bash/powershell) + 分类 (basic/tool/service/security) | |
compose | (无额外字段) | — |
Preset template example:
{"name": "ecs","user": "redc","version": "1.0.0","description": "阿里云 ECS 实例","description_en": "Alibaba Cloud ECS instance","tags": ["ecs", "basic"],"arch": "x86_64","template": "preset"}
Base template example:
{"name": "alicloud-ecs","user": "redc","version": "1.0.5","description": "阿里云 ECS 基础模板","description_en": "Alibaba Cloud ECS base template","tags": ["ecs"],"arch": "x86_64","provider": "alicloud","template": "base"}
Userdata template example:
{"name": "f8x-bash","nameZh": "f8x 渗透测试工具集","user": "r0fus0d","version": "1.0.1","description": "f8x 渗透测试工具集","description_en": "f8x penetration testing toolkit","tags": ["tool"],"type": "bash","category": "tool","template": "userdata"}
Optional fields (not enforced by CI, but useful):
| Field | Used by | Description | |
|---|---|---|---|
redc_plugins | preset | 逗号分隔的插件列表 | |
provider | preset | 云厂商标识(preset 可选,base 必填) | |
vulType | userdata | 漏洞类型(安全类 userdata) | |
cveId | userdata | CVE 编号 |
Version numbering: Use semantic versioning (major.minor.patch). Bump patch for fixes, minor for new features, major for breaking changes. Every template change must bump the version — redc uses this field to detect updates; unchanged versions will not trigger redc pull updates on user machines.
Step 4: Write Terraform files (preset/base templates)
versions.tf
Lock the provider version to avoid compatibility surprises:
terraform {required_providers {alicloud = {source = "aliyun/alicloud"version = "1.241.0"}}}provider "alicloud" {profile = "cloud-tool"region = var.region}
Current provider versions in use across the repo:
aliyun/alicloud:1.241.0hashicorp/aws:5.25.0tencentcloudstack/tencentcloud:1.81.8hashicorp/azurerm:4.61.0volcengine/volcengine:0.0.184
When adding a template for an existing provider, match the version already used unless there's a specific reason to differ.
variables.tf
Declare all configurable inputs. Common patterns:
variable "region" {type = stringdescription = "Cloud region"default = "cn-beijing"}variable "instance_name" {type = stringdescription = "Instance name"default = "my-scene"}variable "instance_password" {type = stringdescription = "Login password (leave empty to auto-generate)"sensitive = truedefault = ""}
Hardcoded AMIs/image IDs and regions are a common template smell — extract them to variables with sensible defaults so users can override them.
main.tf
The core resource definitions. Follow these patterns:
Password auto-generation (standard pattern used across all templates):
locals {password_seed = replace(uuid(), "-", "")generated_password = format("%s_+%s", substr(local.password_seed, 0, 12), substr(local.password_seed, 12, 10))instance_password = var.instance_password != "" ? var.instance_password : local.generated_password}
User data script: Inline with <<-EOF heredoc. Always include:
- Basic packages:
curl,wget,tmux,unzip - BBR network optimization
- Cloud agent removal (for Chinese clouds)
- trzsz for terminal file transfer
Security groups: Open all TCP/UDP for lab/pentest use. Add a comment noting this is intentional.
Naming: Use var.instance_name prefix for all resource names to avoid collisions.
outputs.tf
The redc engine and GUI read these outputs. Use these standardized names:
| Output | Description | Use when | |
|---|---|---|---|
public_ip | Instance public IP | Always (if instance has public IP) | |
ssh_user | SSH username | Always | |
ssh_command | Full SSH command | Always | |
ssh_password | Instance password (nonsensitive) | Password-based auth | |
ssh_private_key_path | Path to SSH key file | Key-based auth (AWS, GCP) |
Legacy names (ecs_ip, ecs_password) still work but prefer the standardized names for new templates.
output "public_ip" {description = "Public IP address"value = alicloud_instance.ecs.public_ip}output "ssh_user" {description = "SSH login username"value = "root"}output "ssh_command" {description = "SSH connection command"value = "ssh root@${alicloud_instance.ecs.public_ip}"}output "ssh_password" {description = "SSH password"value = nonsensitive(local.instance_password)}
Step 5: Write README.md and README_EN.md
Every template must have both a Chinese README (README.md) and an English README (README_EN.md). The redc website uses README_EN.md when users browse in English mode, so both files are required by CI.
Both READMEs should include:
- Title and description — What this template deploys
- Architecture diagram (for complex setups) — ASCII art showing resource relationships
- Usage section — Both
redccommands and standaloneterraformcommands - Variables table — All configurable parameters with defaults
- Outputs table — What information is returned after deployment
- Notes/caveats — Cost warnings, region restrictions, security implications
Template:
# Scene NameBrief description of what gets deployed.## Usage### Via redc\```bashredc pull <provider>/<scene>redc run <provider>/<scene>redc statusredc stop\```### Standalone\```bashterraform initterraform apply -auto-approveterraform destroy -auto-approve\```## Variables| Variable | Default | Description ||----------|---------|-------------|| `region` | `cn-beijing` | Cloud region |## Outputs| Output | Description ||--------|-------------|| `public_ip` | Instance public IP |
Step 6: Validate
Before committing, run these checks:
# Format checkterraform fmt -check .# Syntax validationterraform init -backend=falseterraform validate# Auto-fix formattingterraform fmt .
Also verify case.json has all required fields — both the 6 common fields (name, user, version, description, description_en, tags) and the type-specific fields:
- preset:
arch - base:
arch,provider - userdata:
nameZh,type,category
Clean up before committing: remove .terraform/, .terraform.lock.hcl, and any *.tfstate* files.
Maintaining Existing Templates
Updating a template
⚠️ 重要: 任何场景模板的更新(包括 .tf 文件、README、case.json 字段修改等),都必须同时更新case.json中的version字段。redc 工具通过版本号判断模板是否有更新,如果版本号不变,用户端的redc pull不会拉取到最新模板。
- Bump the version in
case.json— patch for fixes (1.0.1→1.0.2), minor for features (1.0.x→1.1.0) - Make the changes to
.tffiles - Update
README.mdif the interface changed - Run
terraform fmt .andterraform validate
Common maintenance tasks
Updating provider version: Change version in versions.tf, run terraform init -upgrade to verify compatibility, update the lock file.
Adding a variable: Add to variables.tf with a default value (backward-compatible), reference in main.tf, document in README.md.
Fixing output names: When standardizing from ecs_ip → public_ip, keep both outputs during transition (old one with a deprecation comment).
CI Validation Rules
The GitHub Actions CI (validate.yml) checks:
- Every template directory must have
README.md,README_EN.mdandcase.json - Common required fields:
name,user,version,description,description_en,tags - Type-specific required fields:
preset:archbase:arch,provideruserdata:nameZh,type,categorycompose: (no extra fields)
- Field constraints:
name/user/description/description_enmust be non-empty strings,versionmust be a string,tagsmust be a non-empty list - Terraform syntax:
terraform fmtmust pass (syntax only, not formatting style) - Directories in
plugins/,.git/,.github/are excluded from checks
Adding a new cloud provider
- Create the provider directory at repo root (e.g.,
oracle/) - Add at least one template (e.g.,
oracle/compute/) - Follow existing patterns — look at
aliyun/ecs/oraws/ec2/as reference - Update
README.mdat repo root to list the new provider - Optionally add a base template in
base-templates/<provider>-<resource>/
Reference: Cloud Provider Patterns
Alibaba Cloud (aliyun/)
- Provider:
aliyun/alicloud - Auth:
profile = "cloud-tool"(redc manages credentials) - Network: VPC + VSwitch + Security Group
- Instance:
alicloud_instancewithinternet_max_bandwidth_outfor public IP - Agent removal: wget aegis uninstall scripts
- Spot instances:
spot_strategy = "SpotWithPriceLimit"for cost savings
AWS (aws/)
- Provider:
hashicorp/aws - Auth: environment variables (redc injects)
- SSH: auto-generate via
tls_private_key+aws_key_pair+local_file - Instance:
aws_instancewith auto-assigned public IP via subnet - Random suffix:
random_id.suffix.hexfor unique resource names - Spot:
aws_spot_instance_requestfor cost savings
Tencent Cloud (tencent/)
- Provider:
tencentcloudstack/tencentcloud - Auth: environment variables
- Network: VPC + Subnet + Security Group
- Instance:
tencentcloud_instance - Output file:
output.tf(note: singular, notoutputs.tf)
Azure (azure/)
- Provider:
hashicorp/azurerm - Auth:
features {}block required - Resource group required for all resources
- Network: VNet + Subnet + NSG + Public IP + NIC
Reference: Userdata Script Patterns
Userdata scripts go in userdata-templates/<name>/userdata (no file extension).
Bash template:
#!/bin/bash# Install <tool><installation commands>echo "<tool> installed successfully!"
PowerShell template:
# Install <tool><installation commands>Write-Host "<tool> installed successfully!"
Keep scripts minimal and idempotent. The redc engine injects these into the user_data field of cloud instances.