{"id":13585536,"url":"https://github.com/ngine-io/chaotic","last_synced_at":"2025-04-05T16:04:01.349Z","repository":{"id":48467942,"uuid":"233554418","full_name":"ngine-io/chaotic","owner":"ngine-io","description":"Chaos for Clouds","archived":false,"fork":false,"pushed_at":"2025-03-24T14:29:55.000Z","size":163,"stargazers_count":69,"open_issues_count":6,"forks_count":6,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-29T15:09:12.056Z","etag":null,"topics":["chaos-engineering","chaos-monkey","cloudscale-ch","cloudstack","digital-ocean","digitalocean","exoscale","fault-injection","hashicorp-nomad","hetzner-cloud","proxmox","vultr"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ngine-io.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["resmo"],"custom":["paypal.me/resmo"]}},"created_at":"2020-01-13T09:07:34.000Z","updated_at":"2025-03-20T10:06:21.000Z","dependencies_parsed_at":"2023-02-12T23:31:50.713Z","dependency_job_id":"350a106f-d243-418e-8495-0b58c53aeebd","html_url":"https://github.com/ngine-io/chaotic","commit_stats":null,"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngine-io%2Fchaotic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngine-io%2Fchaotic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngine-io%2Fchaotic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngine-io%2Fchaotic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ngine-io","download_url":"https://codeload.github.com/ngine-io/chaotic/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247361614,"owners_count":20926642,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chaos-engineering","chaos-monkey","cloudscale-ch","cloudstack","digital-ocean","digitalocean","exoscale","fault-injection","hashicorp-nomad","hetzner-cloud","proxmox","vultr"],"created_at":"2024-08-01T15:04:59.990Z","updated_at":"2025-04-05T16:04:01.325Z","avatar_url":"https://github.com/ngine-io.png","language":"Python","funding_links":["https://github.com/sponsors/resmo","paypal.me/resmo"],"categories":["Tools","Python","Operational Extensions","Utilities","Infrastructure setup"],"sub_categories":["Rust","Misc","Automation and Infrastructure Management"],"readme":"![license](https://img.shields.io/pypi/l/chaotic-ngine.svg)\n![python versions](https://img.shields.io/pypi/pyversions/chaotic-ngine.svg)\n![status](https://img.shields.io/pypi/status/chaotic-ngine.svg)\n[![pypi version](https://img.shields.io/pypi/v/chaotic-ngine.svg)](https://pypi.org/project/chaotic-ngine/)\n![PyPI - Downloads](https://img.shields.io/pypi/dw/chaotic-ngine)\n\n# Chaotic - Chaos for Clouds\n\nChaotic evaluates a plan, how it will bring chaos in your Cloud environment.\n\nDepending on the Cloud API used, it may kill allocations (Hashicorp Nomad), reboot or stop/start virtual machines in your Cloud environment.\n\nWith no arguments given, Chaotic runs as a \"one shot\" meant to be executed as cron job. Passing `--periodic` runs it as daemon with configurable interval `--interval 5` in minutes (1 is the default).\nNOTE: The config is re-read on every interval, no need to restart the service after changing the config.\n\n## Clouds\n\nCurrently implemented Clouds:\n\n- DigitalOcean\n- Vultr\n- Hetzner Cloud\n- Proxmox KVM\n- CloudStack\n- Hashicorp Nomad\n- cloudscale.ch\n\n## Install\n\n```\npip3 install -U chaotic-ngine\n```\n\n## Configure\n\nCreate a file named `config.yaml` or use the env var `CHAOTIC_CONFIG` to point to a config file (also see the example directory):\n\n```\nexport CHAOTIC_CONFIG=config_nomad.yaml\n```\n\n### Exclude times\n\nDefine times when the bot should not doing real actions (it will run in dry-run):\n\n```yaml\n---\nkind: ...\nexcludes:\n  weekdays:\n    - Sun\n    - Sat\n  times_of_day:\n    - 22:00-08:00\n    - 11:00-14:00\n  days_of_year:\n    - Jan01\n    - Apr01\n    - May01\n    - Aug01\n    - Dec24\n  ```\n\n### CloudStack\n\nChaotic will stop a server selected by an optional filter tag and stop/start it with a delay of a configurable time (default 60s).\n\n```\nexport CLOUDSTACK_API_KEY=\"...\"\nexport CLOUDSTACK_API_SECRET=\"...\"\nexport CLOUDSTACK_API_ENDPOINT=\"...\"\n```\n\n```yaml\n---\nkind: cloudstack\ndry_run: false\nconfigs:\n\n  # Optional, filter tag\n  tag:\n    key: chaos\n    value: enabled\n\n  # Optional, 60 seconds is the default\n  wait_before_restart: 60\n```\n\n### Vultr\n\nChaotic will stop a server selected by an optional filter tag and stop/start it with a delay of a configurable time (default 60s).\n\n```\nexport VULTR_API_KEY=\"...\"\n```\n\n```yaml\n---\nkind: vultr\ndry_run: true\nconfigs:\n\n  # Optional instance tag filter\n  tag: \"chaos=opt-in\"\n\n  # Optional, 60 seconds is the default\n  wait_before_restart: 60\n```\n\n### Cloudscale.ch\n\nChaotic will stop a server selected by an optional filter tag and stop/start it with a delay of a configurable time (default 60s).\n\n\n#### Config\n\n```\nexport CLOUDSCALE_API_TOKEN=\"...\"\n```\n\n```yaml\n---\nkind: cloudscale_ch\ndry_run: true\nconfigs:\n\n  # Optional server tag filter\n  filter_tag: \"chaos=opt-in\"\n\n  # Optional, 60 seconds is the default\n  wait_before_restart: 60\n```\n\n### Hetzner Cloud\n\nChaotic will stop a server selected by an optional filter label and stop/start it with a delay of a configurable time (default 60s).\n\n#### Config\n\n```\nexport HCLOUD_API_TOKEN=...\n```\n\n```yaml\n---\nkind: hcloud\ndry_run: false\nconfigs:\n\n  # Optional server label filter\n  label: \"chaos=enabled\"\n\n  # Optional, 60 seconds is the default\n  wait_before_restart: 60\n```\n\n### DigitalOcean Cloud\n\nChaotic will stop a droplet selected by an optional filter tag and stop/start it with a delay of a configurable time (default 60s).\n\n#### Config\n\n```\nexport DIGITALOCEAN_ACCESS_TOKEN=...\n```\n\n```yaml\n---\nkind: digitalocean\ndry_run: false\nconfigs:\n\n  # Optional droplet tag filter\n  tag: \"chaos:enabled\"\n\n  # Optional, 60 seconds is the default\n  wait_before_restart: 60\n```\n\n### Nomad Job\n\nChaotic will send an allocation signal to an allocation in the available namespaces selected by an allow list.\n\n#### Config\n\n```\nexport NOMAD_ADDR=http://nomad.example.com:4646\n```\n\n```yaml\n---\nkind: nomad\ndry_run: true\nconfigs:\n  experiments:\n    - job\n\n  # Signals to choose from\n  signals:\n    - SIGKILL\n\n  # Optional: namespace allowlist\n  namespace_allowlist:\n    - example-prod\n    - foobar-prod\n\n  # Optional: namespace denylist\n  namespace_denylist:\n    - default\n\n  # Optional: job type skip list\n  job_type_skiplist:\n    - system\n    - batch\n    - sysbatch\n\n  # Optional: job name skip list\n  job_skiplist:\n    - my-job-name\n\n  # Optional: Add a meta tag in your nomad job \"chaotic\" = False to opt-out\n  job_meta_opt_key: chaotic\n```\n\n### Nomad Node\n\nChaotic will drain a node and set it to be ineligible for some time.\n\n#### Config\n\n```\nexport NOMAD_ADDR=http://nomad.example.com:4646\n```\n\n```yaml\n---\nkind: nomad\ndry_run: true\nconfigs:\n  experiments:\n    - node\n\n  # Optional: Node drain deadline in seconds, default 10\n  node_drain_deadline_seconds: 15\n\n  # Optional: Skip nodes in these classes\n  node_class_skiplist:\n    - storage\n\n  # Optional: Skip nodes with these names\n  node_skiplist:\n    - node1\n    - node5\n\n  # Optional: Wait for this amount of seconds before set node to be eligible again, default 60\n  node_wait_for: 100\n\n  # Optional: Also drain system jobs, default false\n  node_drain_system_jobs: true\n\n  # Optional: Drain multiple nodes in one run in percent, fallback 1 node\n  node_drain_amount_in_percent: 30\n\n```\n\n### Proxmox KVM\n\nChaotic will stop a VM stop/start it with a delay of a configurable time (default 60s).\n\n```\nexport PROXMOX_API_HOST=\"pve1.example.com\"\nexport PROXMOX_API_USER=\"root@pam\"\nexport PROXMOX_API_PASSWORD=\"...\"\n```\n\n```yaml\n---\nkind: proxmox_kvm\ndry_run: false\nconfigs:\n\n  # Optional: Do not shutdown VMs having a lower uptime in minutes\n  min_uptime: 60\n\n  # Optional: Do not shutdown VMs in this name list\n  denylist:\n    - my-single-vm\n\n  # Optional: 60 seconds is the default\n  wait_before_restart: 60\n```\n\n## Run\n\n### CLI\n```\nchaos-ngine\n```\n### Docker\n\nOne shot:\n\n```\ndocker run -ti --rm -v $PWD/examples/config_nomad.yaml:/app/config.yaml -e TZ=Europe/Zurich -e NOMAD_ADDR=$NOMAD_ADDR --name chaotic ghcr.io/ngine-io/chaotic:latest\n```\n\nAs service:\n\n```\ndocker run -ti --rm -v $PWD/examples/config_nomad.yaml:/app/config.yaml -e TZ=Europe/Zurich -e NOMAD_ADDR=$NOMAD_ADDR --name chaotic ghcr.io/ngine-io/chaotic:latest --periodic\n```\n\n## Logs\nWhat you should see (e.g. for kind cloudscale.ch):\n```\n2021-06-09 09:01:25,433 - cloudscale.log:INFO:Started, version: 0.6.2\n2021-06-09 09:01:25,433 - cloudscale.log:INFO:Using profile default\n2021-06-09 09:01:25,433 - cloudscale.log:INFO:API Token used: xyz...\n2021-06-09 09:01:25,433 - chatic:INFO:Querying with filter_tag: None\n2021-06-09 09:01:25,433 - cloudscale.log:INFO:HTTP GET to https://api.cloudscale.ch/v1/servers\n2021-06-09 09:01:25,651 - cloudscale.log:INFO:HTTP status code 200\n2021-06-09 09:01:25,652 - chatic:INFO:Choose server app3\n2021-06-09 09:01:25,653 - chatic:INFO:Stopping server app3\n2021-06-09 09:01:25,653 - cloudscale.log:INFO:HTTP POST to https://api.cloudscale.ch/v1/servers/d5628484-a6eb-4ea9-b3ef-ba8da2bb9fe0/stop\n2021-06-09 09:01:26,336 - cloudscale.log:INFO:HTTP status code 204\n2021-06-09 09:01:26,336 - chatic:INFO:Sleeping for server 60\n2021-06-09 09:02:26,393 - cloudscale.log:INFO:HTTP POST to https://api.cloudscale.ch/v1/servers/d5628484-a6eb-4ea9-b3ef-ba8da2bb9fe0/start\n2021-06-09 09:02:26,955 - cloudscale.log:INFO:HTTP status code 204\n2021-06-09 09:02:26,956 - chatic:INFO:done\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fngine-io%2Fchaotic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fngine-io%2Fchaotic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fngine-io%2Fchaotic/lists"}