a7-plugin-fault-injection

star 1

Skill for configuring the API7 Enterprise Edition fault-injection plugin via the a7 CLI. Covers injecting delays and HTTP aborts for chaos engineering, percentage-based sampling, conditional injection via vars expressions, custom response headers and body with Nginx variable interpolation.

api7 By api7 schedule Updated 5/12/2026

name: a7-plugin-fault-injection description: >- Skill for configuring the API7 Enterprise Edition fault-injection plugin via the a7 CLI. Covers injecting delays and HTTP aborts for chaos engineering, percentage-based sampling, conditional injection via vars expressions, custom response headers and body with Nginx variable interpolation. version: "1.0.0" author: API7.ai Contributors license: Apache-2.0 metadata: category: plugin apisix_version: ">=3.0.0" plugin_name: fault-injection a7_commands: - a7 route create - a7 route update - a7 config sync


a7-plugin-fault-injection

Overview

The fault-injection plugin in API7 Enterprise Edition (API7 EE) injects faults — delays and HTTP aborts — into requests for chaos engineering and resiliency testing. It runs in the rewrite phase with priority 11000 (very early), meaning it executes before most other plugins including authentication and rate limiting.

Execution order: delay first → abort second. If abort fires, subsequent plugins do NOT execute.

When to Use

  • Chaos engineering: simulate upstream failures and slowdowns.
  • Resiliency testing: verify timeout handling and circuit breakers.
  • Load testing: add artificial latency to measure degradation.
  • Canary fault testing: inject faults for specific users or conditions.

Plugin Configuration Reference

At least one of abort or delay must be specified.

abort Object

Field Type Required Default Description
http_status integer Yes HTTP status code (≥ 200)
body string No Response body; supports Nginx variables ($remote_addr)
headers object No Response headers; values support Nginx variables
percentage integer No 100 (always) Percentage of requests to abort (0–100)
vars array No Conditional rules using expression syntax (max 20 items)

delay Object

Field Type Required Default Description
duration number Yes Delay in seconds (supports decimals: 0.5, 1.5)
percentage integer No 100 (always) Percentage of requests to delay (0–100)
vars array No Conditional rules using expression syntax (max 20 items)

Vars Expression Syntax

The vars field uses logical expressions for conditional fault injection.

Structure

[
  [["condition1a"], ["condition1b"]],  // AND group 1
  [["condition2a"]]                     // AND group 2
]
// Groups joined by OR — first matching group triggers the fault

Variable Access

Prefix Source Example
arg_* Query parameters arg_name?name=value
http_* Request headers http_apikeyX-Api-Key header
(none) Nginx built-ins remote_addr, uri, request_method

Operators

Operator Example
== ["arg_name", "==", "jack"]
~= ["arg_env", "~=", "prod"]
>, >=, <, <= ["arg_age", ">", 18]
~~ ["arg_env", "~~", "[Dd]ev"] (regex)
~* ["arg_env", "~*", "dev"] (case-insensitive regex)
in ["arg_ver", "in", ["v1","v2"]]
! ["arg_age", "!", "<", 18] (negation → >=)
ipmatch ["remote_addr", "ipmatch", ["10.0.0.0/8"]]

Step-by-Step Examples

1. Fixed Delay (3 Seconds)

a7 route create --gateway-group default -f - <<'EOF'
{
  "id": "delay-test",
  "uri": "/api/*",
  "plugins": {
    "fault-injection": {
      "delay": {
        "duration": 3
      }
    }
  },
  "upstream": {
    "type": "roundrobin",
    "nodes": [{"host": "backend", "port": 8080, "weight": 1}]
  }
}
EOF

2. Percentage-Based Abort (50% Return 503)

a7 route create --gateway-group default -f - <<'EOF'
{
  "id": "abort-test",
  "uri": "/api/*",
  "plugins": {
    "fault-injection": {
      "abort": {
        "http_status": 503,
        "body": "Service temporarily unavailable",
        "percentage": 50
      }
    }
  },
  "upstream": {
    "type": "roundrobin",
    "nodes": [{"host": "backend", "port": 8080, "weight": 1}]
  }
}
EOF

3. Conditional Abort Based on Query Parameter

Only abort when ?name=jack:

a7 route create --gateway-group default -f - <<'EOF'
{
  "id": "conditional-abort",
  "uri": "/api/*",
  "plugins": {
    "fault-injection": {
      "abort": {
        "http_status": 403,
        "body": "Fault Injection!\n",
        "vars": [
          [["arg_name", "==", "jack"]]
        ]
      }
    }
  },
  "upstream": {
    "type": "roundrobin",
    "nodes": [{"host": "backend", "port": 8080, "weight": 1}]
  }
}
EOF

4. Complex Conditional Logic (AND/OR)

Abort when (name=jack AND age≥18) OR (has api-key header):

a7 route create --gateway-group default -f - <<'EOF'
{
  "id": "complex-fault",
  "uri": "/api/*",
  "plugins": {
    "fault-injection": {
      "abort": {
        "http_status": 403,
        "body": "Fault Injection!\n",
        "vars": [
          [
            ["arg_name", "==", "jack"],
            ["arg_age", "!", "<", 18]
          ],
          [
            ["http_apikey", "==", "api-key"]
          ]
        ]
      }
    }
  },
  "upstream": {
    "type": "roundrobin",
    "nodes": [{"host": "backend", "port": 8080, "weight": 1}]
  }
}
EOF

5. Custom Headers with Nginx Variables

a7 route create --gateway-group default -f - <<'EOF'
{
  "id": "headers-fault",
  "uri": "/api/*",
  "plugins": {
    "fault-injection": {
      "abort": {
        "http_status": 200,
        "body": "{\"uri\": \"$uri\"}",
        "headers": {
          "X-Fault-Injected": "true",
          "X-Request-URI": "$uri"
        }
      }
    }
  },
  "upstream": {
    "type": "roundrobin",
    "nodes": [{"host": "backend", "port": 8080, "weight": 1}]
  }
}
EOF

6. Canary Fault Testing

Only users with X-Canary: true header experience 10% fault rate:

a7 route create --gateway-group default -f - <<'EOF'
{
  "id": "canary-fault",
  "uri": "/api/*",
  "plugins": {
    "fault-injection": {
      "abort": {
        "http_status": 500,
        "percentage": 10,
        "vars": [
          [["http_x_canary", "==", "true"]]
        ]
      }
    }
  },
  "upstream": {
    "type": "roundrobin",
    "nodes": [{"host": "backend", "port": 8080, "weight": 1}]
  }
}
EOF

7. Combined Delay + Abort with Different Conditions

a7 route create --gateway-group default -f - <<'EOF'
{
  "id": "combined-fault",
  "uri": "/api/*",
  "plugins": {
    "fault-injection": {
      "delay": {
        "duration": 2,
        "vars": [
          [["http_x_slow", "==", "true"]]
        ]
      },
      "abort": {
        "http_status": 503,
        "vars": [
          [["http_x_fail", "==", "true"]]
        ]
      }
    }
  },
  "upstream": {
    "type": "roundrobin",
    "nodes": [{"host": "backend", "port": 8080, "weight": 1}]
  }
}
EOF

Config Sync Example

version: "1"
gateway_group: default
routes:
  - id: fault-injection-demo
    uri: /api/*
    plugins:
      fault-injection:
        delay:
          duration: 1
          percentage: 25
        abort:
          http_status: 503
          body: "Service unavailable"
          percentage: 5
    upstream:
      type: roundrobin
      nodes:
        - host: backend
          port: 8080
          weight: 1

Execution Behavior

  1. Delay evaluated first: if vars match and percentage sampled → sleep(duration).
  2. Abort evaluated second: if vars match and percentage sampled → return immediately.
  3. Percentage sampling: math.random(1, 100) <= percentage.
  4. When abort fires: subsequent plugins (auth, rate limiting) are skipped.

Plugin Priority Context

Priority 11000 means fault-injection runs very early:

  • ✅ Tracing plugins (zipkin, skywalking) capture faults.
  • ❌ Rate limiting won't prevent faults.
  • ❌ Authentication won't block faults.

To apply faults only to authenticated users, use vars to check auth-related variables or headers.

Troubleshooting

Symptom Cause Fix
Fault never triggers percentage: 0 or vars never match Check vars expressions; set percentage > 0
Fault always triggers No percentage set (defaults to 100%) Set percentage to desired value
Auth bypass via fault Plugin runs before auth (priority 11000) Use vars to restrict fault scope
Body not interpolated Missing $ prefix on variable Use $uri not uri in body/headers
Abort + delay both fire Delay runs first, then abort This is expected behavior; delay always executes before abort check
Install via CLI
npx skills add https://github.com/api7/a7 --skill a7-plugin-fault-injection
Repository Details
star Stars 1
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator