A collaborative AWS EC2 management system that prevents accidental (or premature) shutdowns through a team vote, with automatic IP handling and audit logging.
Scenario: Your development team shares an AWS EC2 instance. Someone wants to shut it down to save costs, but others might still be working. How do you prevent disruptions while maintaining cost efficiency?
Solution: A democratic (unanimousβbyβdefault) voting system where all connected users must agree before shutdown, with automatic safety checks, IP synchronization, and transparent logging.
- π³οΈ Unanimous Voting (Default): All connected users must vote YES or the instance stays online (solo initiator autoβpasses)
- π Dynamic Public IP Handling:
start_server.bat/shutdown_server.batauto-resolve & persist changing EC2 IPs intoconfig.bat - π₯ Config β team.map Sync: Windows client generates and uploads
~/.quorumstop/team.map(authoritative list) before votes - π§© Separation of Concerns: Client batch scripts + minimal server shell script (
vote_shutdown.sh) - π‘ AWS Helper Library:
lib_ec2.batencapsulates state & public IP lookups (quiet/value modes for composition) - βοΈ Idempotent Config Rewriter:
lib_update_config.batsafely replaces only theSERVER_IPline (dedupes & marker based) - π¦ /auto and /debug Modes: Non-interactive automation or deep diagnostics (
start_server.bat /debug,shutdown_server.bat /auto) - π Transparent Output: Structured console status, optional rich emoji UI serverβside (toggle with
--plain) - π Team Roster Variables:
TEAM_COUNT,DEVn_IP,DEVn_NAMEdrive generated map (no manual server edits needed) - π§ͺ Connectivity Self-Test:
test_aws.batvalidates CLI, identity, and EC2 describe permissions - π Safe Defaults: Any missing vote or explicit NO blocks shutdown; root credential warnings surfaced
- π Audit Trail: Server logs voting lifecycle to
/var/log/quorumstop-votes.log(bestβeffort permissions)
New? First skim the Installation Guide for AWS CLI setup, credentials, security group rules, and detailed step explanations, then return here for the condensed flow.
- Clone
git clone https://github.com/Obad94/aws-ec2-quorumstop.git cd aws-ec2-quorumstop - Run Setup Wizard (recommended β creates/updates
scripts\config.bat):tools\setup-wizard.bat
- Answer prompts (instance id, region, key path, team IPs/names, your identity).
- Re-run anytime to add/change teammates.
- (Manual copy/edit is deprecated; only use it if the wizard cannot run in your environment.)
- Test AWS Environment
scripts\test_aws.bat
- Start / Update Instance
scripts\start_server.bat
- Deploy / Update Server Vote Script (after first start or when script changes)
scripts\deploy_vote_script.bat /debug
- Skips upload if hashes match (use
/forceto override) - Sets executable + symlink
/usr/local/bin/vote_shutdown
- Skips upload if hashes match (use
- Initiate Shutdown Vote (later when done working):
scripts\shutdown_server.bat
- Windows 10/11
- AWS CLI v2 configured (leastβprivilege IAM user/role: describe/start/stop EC2)
- One EC2 instance (Ubuntu recommended) accessible via SSH key
- Public IPs of teammates (static or current) for allowβlisting & mapping
config.bat adds structured variables:
set TEAM_COUNT=3
set DEV1_IP=203.0.113.10
set DEV1_NAME=Alice
set DEV2_IP=203.0.113.20
set DEV2_NAME=Bob
set DEV3_IP=203.0.113.30
set DEV3_NAME=Carol
During shutdown_server.bat, a fresh team.map is built from these and uploaded. Server script loads it (overrides internal fallbacks) so you rarely need to edit vote_shutdown.sh.
Windows Batch Layer
ββ start_server.bat (state + IP sync)
ββ shutdown_server.bat (vote initiation + AWS stop)
ββ sync_team.bat (team.map generation & upload)
ββ lib_ec2.bat / lib_update_config.bat (helpers)
ββ config.bat (local, untracked)
β AWS CLI (state/IP)
SSH (initiates vote) β vote_shutdown.sh (loads ~/.quorumstop/team.map) β vote dir / log β decision β aws ec2 stop-instances
- User runs
shutdown_server.bat - Public IP revalidated &
config.batpatched if changed - Team roster synced to server (
~/.quorumstop/team.map) - Server auto-records initiator YES, broadcasts vote window (default 60s)
- Each connected user votes (
vote_shutdown yes|no) - REQUIREMENT: Unanimous YES of all connected users (non-vote counts as NO)
- Solo initiator (no other SSH sessions) = auto PASS
- On PASS β 30s grace β
stop-instances; else abort
Adjust unanimity by editing logic near the final result block in
server/vote_shutdown.sh.
Ideal for shared dev / staging EC2 hosts where interactive work occurs sporadically and cost control matters. Not a production HA orchestration replacement.
| Runtime Pattern | Approx Uptime | Est. t3.medium Monthly |
|---|---|---|
| Always on | 100% | $35+ |
| Voted Off Nights | ~50β60% | $15β20 |
| Aggressive Off | ~30β40% | $10β14 |
| Connected Users | YES | NO | Nonβvoters | Result |
|---|---|---|---|---|
| Alice | 1 | 0 | 0 | PASS (solo) |
| Alice,Bob | 2 | 0 | 0 | PASS |
| Alice,Bob | 1 | 1 | 0 | FAIL |
| A,B,C | 3 | 0 | 0 | PASS |
| A,B,C | 2 | 0 | 1 | FAIL (missing) |
| A,B,C | 2 | 1 | 0 | FAIL (explicit NO) |
Rule: Any NO or any abstention (non-vote) causes failure.
- No AWS secrets stored server-side
- Key-only SSH, strict least privilege recommended
- Root credential use visibly warned in
test_aws.bat - Voting artifacts cleaned after completion
- Log file restricted (640) where possible
| Script | Purpose |
|---|---|
scripts/start_server.bat |
Start instance, wait for state, sync IP |
scripts/shutdown_server.bat |
Run vote then stop instance on pass |
scripts/deploy_vote_script.bat |
Upload/update vote_shutdown.sh (hash compare, symlink) |
scripts/lib_ec2.bat |
Query state/public IP (quiet/value modes) |
scripts/lib_update_config.bat |
Safe SERVER_IP rewrites |
scripts/sync_team.bat |
Generate & upload team.map |
scripts/test_aws.bat |
Environment & permission diagnostics |
scripts/view_config.bat |
Summarize active config |
tools/setup-wizard.bat |
Interactive generator/updater for config.bat |
Flags:
start_server.bat [/auto] [/debug]
shutdown_server.bat [/auto] [/debug]
deploy_vote_script.bat [/debug] [/force]
vote_shutdown.sh [--plain] yes|no|status|debug|help
tools\setup-wizard.bat [--auto] (env var driven)
PRs welcome: clarify docs, add optional majority/supermajority mode examples, improve portability (PowerShell, Bash variants), unit test helpers.
MIT β see LICENSE.
- Issues: https://github.com/Obad94/aws-ec2-quorumstop/issues
- Discussions: https://github.com/Obad94/aws-ec2-quorumstop/discussions
Quick Commands:
scripts\view_config.bat
scripts\start_server.bat
scripts\deploy_vote_script.bat /debug
scripts\shutdown_server.bat
scripts\test_aws.batMade with care for collaborative teams focused on cost & continuity.