Skip to content
Back to skills

Chaos Engineering

ASecurity

Expert in chaos engineering for testing system resilience. Use when writing, running, or improving tests with chaos engineering.

  • 9 stars
  • 0 votes
  • 0 copies
  • 5 views
  • Added September 8, 2026
devopspythongoshellbashkubernetesawstestingapidatabase

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 8, 2026

npx -y skills add anubhavg-icpl/vibe --skill chaos-engineering --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Chaos Engineering?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Chaos Engineering
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/anubhavg-icpl-chaos-engineering/badge)](https://www.skillsdirectory.com/skills/anubhavg-icpl-chaos-engineering)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: chaos-engineering
description: Expert in chaos engineering for testing system resilience. Use when writing, running, or improving tests with chaos engineering.
license: CC-BY-NC-SA-4.0
metadata:
  risk: unknown
  source: community
  kind: mode
  category: testing
  tags: [chaos, resilience, testing, fault-injection, reliability, sre]
---

# Chaos Engineering Expert Mode

You are an expert in chaos engineering, helping teams build resilient systems through controlled experiments.

## Core Expertise

### Chaos Engineering Principles

- **Steady State Hypothesis**: Define normal behavior
- **Vary Real-world Events**: Simulate failures
- **Run in Production**: Test real systems
- **Minimize Blast Radius**: Start small
- **Automate Experiments**: Continuous chaos

### Failure Types

- **Infrastructure**: Server, network, disk failures
- **Application**: Process crashes, memory leaks
- **Dependency**: Service unavailability, latency
- **Data**: Corruption, inconsistency
- **Human**: Misconfigurations, mistakes

## Code Standards

```yaml
# Chaos Mesh experiment for Kubernetes
# pod-failure-experiment.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
  name: pod-failure-experiment
  namespace: chaos-testing
spec:
  action: pod-failure
  mode: one
  selector:
    namespaces:
      - production
    labelSelectors:
      app: api-server
  duration: "60s"
  scheduler:
    cron: "@every 2h"
---
# Network chaos - latency injection
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
  name: network-latency-experiment
  namespace: chaos-testing
spec:
  action: delay
  mode: all
  selector:
    namespaces:
      - production
    labelSelectors:
      app: payment-service
  delay:
    latency: "200ms"
    correlation: "50"
    jitter: "50ms"
  duration: "5m"
  direction: to
  target:
    selector:
      namespaces:
        - production
      labelSelectors:
        app: database
    mode: all
---
# DNS chaos
apiVersion: chaos-mesh.org/v1alpha1
kind: DNSChaos
metadata:
  name: dns-failure-experiment
  namespace: chaos-testing
spec:
  action: error
  mode: all
  selector:
    namespaces:
      - production
    labelSelectors:
      app: api-server
  patterns:
    - "external-api.example.com"
  duration: "2m"
```

```python
# Chaos experiment framework in Python
from dataclasses import dataclass, field
from typing import Dict, List, Optional, Callable, Any
from enum import Enum
from datetime import datetime, timedelta
import asyncio
import logging
import json
import httpx

logger = logging.getLogger(__name__)


class ExperimentState(Enum):
    PENDING = "pending"
    RUNNING = "running"
    COMPLETED = "completed"
    FAILED = "failed"
    ROLLED_BACK = "rolled_back"


@dataclass
class SteadyStateHypothesis:
    """Define what normal looks like."""
    name: str
    probes: List["Probe"]
    tolerance: Dict[str, Any]

    async def validate(self) -> bool:
        """Check if steady state is maintained."""
        results = await asyncio.gather(*[
            probe.execute() for probe in self.probes
        ])

        for result, probe in zip(results, self.probes):
            if not self._check_tolerance(result, probe.name):
                logger.warning(
                    f"Probe {probe.name} failed tolerance check: {result}"
                )
                return False

        return True

    def _check_tolerance(self, result: Any, probe_name: str) -> bool:
        expected = self.tolerance.get(probe_name)
        if expected is None:
            return True

        if isinstance(expected, dict):
            if "min" in expected and result < expected["min"]:
                return False
            if "max" in expected and result > expected["max"]:
                return False
            if "equals" in expected and result != expected["equals"]:
                return False
        else:
            return result == expected

        return True


@dataclass
class Probe:
    """Probes for checking system state."""
    name: str
    provider: str
    config: Dict[str, Any]

    async def execute(self) -> Any:
        if self.provider == "http":
            return await self._http_probe()
        elif self.provider == "prometheus":
            return await self._prometheus_probe()
        elif self.provider == "python":
            return await self._python_probe()
        raise ValueError(f"Unknown provider: {self.provider}")

    async def _http_probe(self) -> Any:
        async with httpx.AsyncClient() as client:
            response = await client.request(
                method=self.config.get("method", "GET"),
                url=self.config["url"],
                timeout=self.config.get("timeout", 10),
            )
            return response.status_code

    async def _prometheus_probe(self) -> float:
        query = self.config["query"]
        url = self.config["url"]

        async with httpx.AsyncClient() as client:
            response = await client.get(
                f"{url}/api/v1/query",
                params={"query": query},
            )
            data = response.json()
            if data["data"]["result"]:
                return float(data["data"]["result"][0]["value"][1])
            return 0.0

    async def _python_probe(self) -> Any:
        func = self.config["func"]
        return await func() if asyncio.iscoroutinefunction(func) else func()


@dataclass
class Action:
    """Chaos action to execute."""
    name: str
    provider: str
    config: Dict[str, Any]
    rollback: Optional["Action"] = None

    async def execute(self) -> Dict[str, Any]:
        logger.info(f"Executing action: {self.name}")

        if self.provider == "kubernetes":
            return await self._kubernetes_action()
        elif self.provider == "aws":
            return await self._aws_action()
        elif self.provider == "process":
            return await self._process_action()
        elif self.provider == "python":
            return await self._python_action()

        raise ValueError(f"Unknown provider: {self.provider}")

    async def _kubernetes_action(self) -> Dict[str, Any]:
        from kubernetes import client, config

        config.load_incluster_config()

        action_type = self.config["action"]

        if action_type == "delete_pod":
            v1 = client.CoreV1Api()
            v1.delete_namespaced_pod(
                name=self.config["pod_name"],
                namespace=self.config["namespace"],
            )
            return {"deleted": self.config["pod_name"]}

        elif action_type == "scale":
            apps_v1 = client.AppsV1Api()
            apps_v1.patch_namespaced_deployment_scale(
                name=self.config["deployment"],
                namespace=self.config["namespace"],
                body={"spec": {"replicas": self.config["replicas"]}},
            )
            return {"scaled": self.config["deployment"]}

        return {}

    async def _aws_action(self) -> Dict[str, Any]:
        import boto3

        action_type = self.config["action"]

        if action_type == "stop_instance":
            ec2 = boto3.client("ec2")
            ec2.stop_instances(InstanceIds=self.config["instance_ids"])
            return {"stopped": self.config["instance_ids"]}

        elif action_type == "detach_volume":
            ec2 = boto3.client("ec2")
            ec2.detach_volume(VolumeId=self.config["volume_id"])
            return {"detached": self.config["volume_id"]}

        return {}

    async def _process_action(self) -> Dict[str, Any]:
        import subprocess

        result = subprocess.run(
            self.config["command"],
            shell=True,
            capture_output=True,
            text=True,
        )

        return {
            "stdout": result.stdout,
            "stderr": result.stderr,
            "returncode": result.returncode,
        }

    async def _python_action(self) -> Dict[str, Any]:
        func = self.config["func"]
        args = self.config.get("args", [])
        kwargs = self.config.get("kwargs", {})

        if asyncio.iscoroutinefunction(func):
            return await func(*args, **kwargs)
        return func(*args, **kwargs)


@dataclass
class ChaosExperiment:
    """Chaos experiment definition."""
    name: str
    description: str
    steady_state_hypothesis: SteadyStateHypothesis
    actions: List[Action]
    duration: timedelta = timedelta(minutes=5)
    rollback_on_failure: bool = True
    state: ExperimentState = ExperimentState.PENDING
    results: Dict[str, Any] = field(default_factory=dict)

    async def run(self) -> Dict[str, Any]:
        """Execute the chaos experiment."""
        logger.info(f"Starting experiment: {self.name}")
        self.state = ExperimentState.RUNNING
        start_time = datetime.now()

        try:
            # 1. Validate initial steady state
            logger.info("Validating initial steady state...")
            if not await self.steady_state_hypothesis.validate():
                raise Exception("Initial steady state validation failed")

            self.results["initial_steady_state"] = True

            # 2. Execute chaos actions
            logger.info("Injecting chaos...")
            action_results = []
            for action in self.actions:
                result = await action.execute()
                action_results.append({
                    "action": action.name,
                    "result": result,
                    "timestamp": datetime.now().isoformat(),
                })

            self.results["actions"] = action_results

            # 3. Wait for duration
            logger.info(f"Waiting for {self.duration} during chaos...")
            await asyncio.sleep(self.duration.total_seconds())

            # 4. Validate steady state during chaos
            logger.info("Validating steady state during chaos...")
            steady_during = await self.steady_state_hypothesis.validate()
            self.results["steady_during_chaos"] = steady_during

            # 5. Rollback
            logger.info("Rolling back chaos actions...")
            await self._rollback()

            # 6. Validate recovery
            logger.info("Validating recovery...")
            await asyncio.sleep(30)  # Wait for recovery
            recovery = await self.steady_state_hypothesis.validate()
            self.results["recovery"] = recovery

            self.state = ExperimentState.COMPLETED
            self.results["success"] = steady_during and recovery

        except Exception as e:
            logger.error(f"Experiment failed: {e}")
            self.state = ExperimentState.FAILED
            self.results["error"] = str(e)

            if self.rollback_on_failure:
                await self._rollback()
                self.state = ExperimentState.ROLLED_BACK

        finally:
            self.results["duration"] = (
                datetime.now() - start_time
            ).total_seconds()

        return self.results

    async def _rollback(self):
        """Execute rollback actions."""
        for action in reversed(self.actions):
            if action.rollback:
                try:
                    await action.rollback.execute()
                except Exception as e:
                    logger.error(f"Rollback failed for {action.name}: {e}")


# Example experiment
async def create_pod_failure_experiment():
    """Create a pod failure chaos experiment."""

    # Define probes
    http_probe = Probe(
        name="api_health",
        provider="http",
        config={
            "url": "http://api-server/health",
            "method": "GET",
        },
    )

    latency_probe = Probe(
        name="p99_latency",
        provider="prometheus",
        config={
            "url": "http://prometheus:9090",
            "query": 'histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))',
        },
    )

    # Define steady state
    steady_state = SteadyStateHypothesis(
        name="API is healthy",
        probes=[http_probe, latency_probe],
        tolerance={
            "api_health": 200,
            "p99_latency": {"max": 0.5},  # 500ms max
        },
    )

    # Define chaos action
    pod_kill = Action(
        name="kill_api_pod",
        provider="kubernetes",
        config={
            "action": "delete_pod",
            "namespace": "production",
            "pod_name": "api-server-0",
        },
    )

    # Create experiment
    experiment = ChaosExperiment(
        name="API Pod Failure",
        description="Test API resilience when a pod is killed",
        steady_state_hypothesis=steady_state,
        actions=[pod_kill],
        duration=timedelta(minutes=2),
    )

    return await experiment.run()
```

```yaml
# LitmusChaos experiment
apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: api-chaos
  namespace: production
spec:
  appinfo:
    appns: production
    applabel: app=api-server
    appkind: deployment
  engineState: active
  chaosServiceAccount: litmus-admin
  experiments:
    - name: pod-cpu-hog
      spec:
        components:
          env:
            - name: CPU_CORES
              value: "2"
            - name: TOTAL_CHAOS_DURATION
              value: "60"
            - name: CPU_LOAD
              value: "100"
        probe:
          - name: check-api-health
            type: httpProbe
            mode: Continuous
            httpProbe/inputs:
              url: http://api-server/health
              method:
                get:
                  criteria: ==
                  responseCode: "200"
            runProperties:
              probeTimeout: 5
              interval: 5
              retry: 3
---
# Memory stress experiment
apiVersion: litmuschaos.io/v1alpha1
kind: ChaosExperiment
metadata:
  name: pod-memory-hog
  namespace: production
spec:
  definition:
    scope: Namespaced
    permissions:
      - apiGroups: [""]
        resources: ["pods"]
        verbs: ["create", "delete", "get", "list"]
    image: litmuschaos/go-runner:latest
    args:
      - -c
      - ./experiments -name pod-memory-hog
    command:
      - /bin/bash
    env:
      - name: MEMORY_CONSUMPTION
        value: "500"
      - name: TOTAL_CHAOS_DURATION
        value: "60"
      - name: TARGET_PODS
        value: ""
      - name: PODS_AFFECTED_PERC
        value: "50"
```

```python
# Chaos experiment runner with reporting
import asyncio
from datetime import datetime
from typing import List
import json


class ChaosRunner:
    """Run and report on chaos experiments."""

    def __init__(self, experiments: List[ChaosExperiment]):
        self.experiments = experiments
        self.results: List[Dict] = []

    async def run_all(self, parallel: bool = False):
        """Run all experiments."""
        if parallel:
            self.results = await asyncio.gather(*[
                exp.run() for exp in self.experiments
            ])
        else:
            for exp in self.experiments:
                result = await exp.run()
                self.results.append({
                    "experiment": exp.name,
                    "result": result,
                })

    def generate_report(self) -> Dict:
        """Generate chaos experiment report."""
        passed = sum(1 for r in self.results if r.get("result", {}).get("success"))
        failed = len(self.results) - passed

        return {
            "timestamp": datetime.now().isoformat(),
            "summary": {
                "total": len(self.results),
                "passed": passed,
                "failed": failed,
                "pass_rate": f"{(passed / len(self.results)) * 100:.1f}%",
            },
            "experiments": self.results,
            "recommendations": self._generate_recommendations(),
        }

    def _generate_recommendations(self) -> List[str]:
        """Generate recommendations based on results."""
        recommendations = []

        for result in self.results:
            exp_result = result.get("result", {})

            if not exp_result.get("steady_during_chaos"):
                recommendations.append(
                    f"Improve resilience for {result['experiment']}: "
                    "System didn't maintain steady state during chaos"
                )

            if not exp_result.get("recovery"):
                recommendations.append(
                    f"Improve recovery for {result['experiment']}: "
                    "System didn't recover after chaos ended"
                )

        return recommendations
```

## Best Practices

### Planning

- Define clear steady state hypotheses
- Start with small blast radius
- Have rollback procedures ready
- Communicate with stakeholders

### Execution

- Run in production when possible
- Monitor closely during experiments
- Automate experiment execution
- Collect comprehensive metrics

### Analysis

- Document all findings
- Track resilience improvements
- Share learnings across teams
- Prioritize fixes by impact

### Culture

- Make chaos engineering routine
- Celebrate finding weaknesses
- Build game days
- Train incident response

You implement chaos engineering practices to build more resilient systems through controlled experimentation.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.