Documentation
Production setup and operations for GitHub and GitLab integrations, including OAuth, webhook security, and policy enforcement.
How It Works
ZeroBillBot runs as a webhook-driven service for both GitHub pull requests and GitLab merge requests. It inspects changed IaC files, estimates monthly cost impact, and posts status feedback back into the provider.
- Receive PR/MR webhook event from GitHub or GitLab.
- Load repo config from
.costbot.yml(or defaults). - Fetch changed file content from PR head/base commits.
- Detect cloud provider(s) and parse resources.
- Price resources and compute total monthly delta.
- Apply warn/fail policy thresholds.
- Upsert a single bot comment and update commit/MR status checks.
If pricing data is unavailable for a resource, the comment includes a fallback notice so engineers can review assumptions.
Provider Modes
ZeroBillBot currently supports two production provider paths with shared policy logic:
- GitHub: GitHub App installation with webhook + check runs.
- GitLab: OAuth install flow with webhook registration and commit status updates.
For GitLab, both OAuth credentials and webhook secrets are required. OAuth grants authorization, while webhooks deliver MR events to the bot.
Getting Started
1) Install a provider integration
Install ZeroBillBot on GitHub or start GitLab setup from /github/setup?provider=gitlab.
2) Link your installation to your dashboard account
If your installation is not linked to a ZeroBillBot account yet, PR comments include a setup link to
/github/setup?installation_id=.... Link once to manage limits, billing, and policy thresholds from the dashboard.
3) Open a PR/MR with IaC changes
Add or modify Terraform, CloudFormation, or ARM template files. The bot runs automatically and posts results on the PR/MR.
.costbot.yml Reference
The config file must be named .costbot.yml and placed in the repository root.
currency: USD
region: ap-southeast-1
planPath: terraform/plan.json
threshold:
warn_if_over: 10
fail_if_over: 25
exemptions:
paths: []
labels: []
commit_flags:
- "cost-allow:"
services:
include:
- lambda
- storage_api
ignore: []
catalog:
- name: lambda
unit: requests
monthly_usage: 2500000
rate: 0.0000003
notes: x86 runtime with team-defined blended monthly rate
- name: storage_api
unit: requests
monthly_usage: 800000
rate: 0.0000021
notes: internal service cost model
caps:
ec2:
max_instance_hourly: 0.2
ebs:
gp3:
max_iops: 3000
max_throughput_mb_s: 250
rds:
max_instance_hourly: 0.5
slackWebhook: "https://hooks.slack.com/services/..."
Default behavior: warn at $10 monthly delta and fail at $25 monthly delta.
The dashboard writes the same configuration shape as .costbot.yml: thresholds, notifications,
included services, and the dynamic services.catalog entries that define usage and rate.
Pro and Enterprise users can also save the same configuration as dashboard defaults per linked
installation. When both exist, the repository-level .costbot.yml wins and the dashboard
config acts as a fallback.
Legacy usage.aws settings are still accepted for older repositories, but new setups should use
services.catalog so the dashboard and YAML stay aligned.
Supported IaC
Full cost analysis
- Terraform plan JSON (highest priority when present).
- Terraform source files (
.tf,.tf.json,.tfvars). - CloudFormation templates (
.yaml/.json). - Azure ARM templates (
.json).
Detection only (analysis not yet implemented)
- CDK / Pulumi / Serverless / SAM / generic Kubernetes-style templates.
For unsupported template types, ZeroBillBot still comments that IaC was detected and marks the check as neutral.
PR Output & Policies
The bot publishes one comment titled Cost Impact Analysis with provider, region, pricing date,
total monthly delta, and a resource table.
- Success: delta stays under warn threshold.
- Warning: delta is above warn threshold.
- Blocked: delta is above fail threshold.
The Check Run summary mirrors this decision so branch protection can enforce the policy.
On GitLab, blocked policy outcomes can also mark the merge request as draft when draft enforcement is enabled.
Example PR comment format
This is the same structure posted by the server (including blocked and fallback-pricing cases):
## 💰 Cost Impact Analysis
**Region:** us-east-1 | **Pricing as of:** fallback
📈 **Estimated monthly cost increase: $1054.86**
❌ **BLOCKED**: Cost change exceeds warning threshold of $10, Cost change exceeds failure threshold of $25
### Resource Changes
| Service | Resource | Action | Monthly Δ | Notes |
|---------|----------|--------|-----------|-------|
| ec2 | `t3.2xlarge` | ➕ create | +$242.94 | Instance type: t3.2xlarge |
| ec2 | `t3.large` | ➕ create | +$60.74 | Instance type: t3.large |
| ec2 | `t3.medium` | ➕ create | +$30.37 | Instance type: t3.medium |
---
*Estimates based on on-demand pricing as of fallback. Actual costs may vary.*
*Thresholds: warn if > $10, fail if > $25* Plan limits
Linked installations are usage-gated by plan. When a monthly scan limit is reached, the bot posts a limit-reached message and sets the check to neutral.
Troubleshooting
No comment posted
- Confirm the provider integration is installed on that repo/project.
- Confirm the PR includes IaC files.
- Check provider permissions for PR/MR and commit status updates.
- Review webhook deliveries in GitHub or GitLab settings.
Config is ignored
- Filename must be exactly
.costbot.yml. - Place it at repository root.
- Use the keys shown above (
threshold, notthresholds).
Need help? Email contact@virtualverselabs.com or connect on LinkedIn.