Website: seanseannery.github.io/opsfile
It's a cli tool, essentially like make and makefiles but for sharing and executing live-operations / on-call commands for the repo. Simply create an Opsfile in your repo with common on-call commands your team uses and run it with ops [env] <command>.
brew tap seanseannery/opsfile https://github.com/seanseannery/opsfile
brew install seanseannery/opsfile/opsfileAfter tapping, brew upgrade seanseannery/opsfile/opsfile keeps ops up to date.
npm install -g github:seanseannery/opsfileRequires Node.js ≥ 14. Downloads the correct platform binary from the latest GitHub release on install.
To upgrade, re-run the same command. To uninstall: npm uninstall -g opsfile.
curl -fsSL https://seanseannery.github.io/opsfile/install.sh | bashDetects your OS, downloads the correct binary from the latest GitHub release, and installs to /usr/local/bin/ops.
Download ops.exe directly from the releases page.
- Less Stress: quickly find logs during a live outage instead of having to google that k8s flag you keep forgetting.
- Reduced agentic context / token usage: have agents run ops scripts instead of googling the correct aws cli command every time.
- Knowledge Sharing: Share common commands with your team for easier onboarding and debugging
- Encapsulation: keep your Makefile small and focused on CI/CD tasks
Makefiles are a great way to build, test, spin-up local dev environments, and other common CI actions without having to memorize the associated maven/docker/npm/gradle/k8s specifics. Additionally, makefiles make it easy to onboard new engineers to the repo and share common CI scripts with teammates.
In my experience, the other commands and scripts that often get passed around are the operational/on-call tasks. Checking logs, getting IP addresses or instance counts, viewing dashboards, etc. I get paged and I need to tail logs, or suppress an alarm, or get instance IPs under pressure. But it's not fun remembering the 5 cli arguments kubectl needs to display logs for a specific container while my manager is asking for a status update on the outage. Additionally, Makefiles aren't the right place for non-ci commands like that.
So rather than copy/pasting gists with bash aliases from team member to team member, or creating a "tools" repo with a bunch of adhoc scripts that doesn't get maintained, I thought I would create a tool, based on an established model (make), to improve live operations on a service and make it more standardized, shareable, and easier.
Create an Opsfile in your repo root. Its just like makefile syntax. Below is a simple example.
# Variables — prefix with environment name to scope them
prod_AWS_ACCOUNT=1234567
preprod_AWS_ACCOUNT=8765431
# Commands — define per-environment shell lines
# Use "default" as a fallback when env-specific block is absent
tail-logs:
default:
aws cloudwatch logs --tail $(AWS_ACCOUNT)
local:
docker logs myapp --follow
list-instance-ips:
prod:
aws ec2 --list-instances
preprod:
aws ecs cluster --list-instances
# Shell environment variables are injected automatically using the same $(VAR) syntax.
# No declaration needed — if ops cant find in the Opsfile, it will fall back to env variables
show-profile:
default:
echo "Using AWS profile: $(AWS_PROFILE)"Tip
There are more sample Opsfile examples in the /examples folder.
Warning
Be sure not to include any secrets or access keys into your Opsfile as they could get shared visibly once committed to the repo. Instead you can inject your secrets using the --env-file flag or environment variables.
Use the -e / --env-file flag to load secrets from a .env-format file at invocation time, keeping them out of your Opsfile and version control.
# Load secrets from a specific file
ops -e .env.prod prod rollback
# By default, ops auto-loads .ops_secrets.env from the Opsfile directory (silent no-op if absent)
ops prod rollbackThe env file uses the same NAME=value format as Opsfile variables. Env-scoped keys (e.g. prod_DB_PASSWORD) are supported. Values can be quoted with single or double quotes, and # comments are allowed.
# .ops_secrets.env
DB_PASSWORD=hunter2
prod_API_TOKEN="sk-prod-abc123"
staging_API_TOKEN="sk-staging-xyz789"Important notes:
- The
-eflag must appear before the environment and command positionals - Only one
-eper invocation — an explicit-ereplaces the default.ops_secrets.env - Add
.ops_secrets.envto your.gitignore --dry-runwill print resolved commands including injected values — be cautious with secrets
```bash
ops [flags] <your_environment> <your_command> [any-command-args]
```
| Flag | Short | Description |
|------|-------|-------------|
| `--directory <path>` | `-D <path>` | Use the Opsfile in the given directory instead of searching parent directories |
| `--env-file <path>` | `-e <path>` | Load variables from a `.env`-format file (defaults to `.ops_secrets.env` if present) |
| `--dry-run` | `-d` | Print the resolved commands without executing them |
| `--silent` | `-s` | Execute commands without printing output |
| `--list` | `-l` | List available commands and environments defined in the Opsfile, then exit |
| `--version` | `-v` | Print the ops version, commit, and build platform, then exit |
| `--help` | `-?`, `-h` | Show usage information, then exit |
ops --list- discover available commands and environments in the Opsfile:Commands Found in [./Opsfile]: Environments: default local preprod prod Commands: show-profile Using AWS profile tail-logs Tail CloudWatch logs list-instance-ips List the private IPs of running instancesops preprod instance-count- get the number of cloud instances in your preprod clusterops prod open-dashboard- open grafana/kibana/datadog/cloudwatch dashboard in your browserops local logs- tail logs for your local running docker environment to debugops prod k8s -namespace myspace- runs kubectl top on the provided namespace
Tip
If you want, you could even alias the ops+env command in your terminal profile to make it even more user friendly
$> alias prod="ops prod"
$> prod tail-logsTip
To save even more AI tokens / context, you can create a skill or plugin for your repo, or include command details in AGENTS.md or CLAUDE.md
$> claude 'analyze my projects Opsfile and add a table of commands and supported environments to CLAUDE.md for operational debugging'For tips on how to set up dev environment, build, test, and how to follow PR and community best practices. Please read CONTRIBUTING.md