Slack-native GitOps for infrastructure changes across GitHub, Cloudflare, and Doppler.
conCIerge is a Go Slack bot that turns structured Slack requests into reviewed Terraform pull requests. Users request changes in Slack, the bot fetches live Terraform locals from the external jae-labs/terraform repository, validates intent, edits HCL, opens a PR, and posts the request summary back to #concierge.
It does not mutate production directly. The control point stays where it should: normal GitHub review, merge, and CI/CD in the Terraform repository.
Why conCIerge?
- Replaces ad hoc infrastructure requests with structured Slack workflows.
- Keeps infrastructure changes in Git, reviewable, auditable, and reversible.
- Reads live Terraform state from the
jae-labs/terraform repository to populate modals and validate input.
- Supports GitHub repositories, org settings, team membership, Cloudflare DNS, and Doppler projects.
- Uses nonce-protected multi-step Slack flows to avoid stale or duplicated submissions.
- Keeps the apply boundary outside the bot; it prepares code changes, not direct infra mutations.
Quick Start
Prerequisites
- Go
1.25+
- Slack app credentials
- GitHub App credentials with access to the Terraform repository
- Doppler CLI if you use Doppler for local secret injection
Required configuration
Required baseline config:
SLACK_BOT_TOKEN
SLACK_REQUESTS_CHANNEL_ID
GITHUB_APP_ID
GITHUB_APP_INSTALLATION_ID
GITHUB_APP_PRIVATE_KEY
GITHUB_OWNER -- owner of the Terraform repository the bot mutates
GITHUB_REPO -- repository name of the Terraform repository, not this bot repo
SLACK_APP_TOKEN for Socket Mode or SLACK_SIGNING_SECRET for HTTP mode
Run locally
Use Doppler if that is your secret source:
doppler login
doppler setup
lefthook install
doppler run -- go run ./cmd/concierge
Live reload:
air
Build manually:
go build ./cmd/concierge
./concierge
Local development defaults to Slack Socket Mode. Production runs the same binary with SLACK_MODE=http behind nginx and exposes GET /health for uptime checks.
What it manages
| Domain |
Resource |
Actions |
| GitHub |
Repository |
Add, Remove, Update |
| GitHub |
Org Settings |
Update |
| GitHub |
Team Membership |
Add to Team, Remove from Team, Change Role |
| Cloudflare |
DNS Records |
Add, Remove, Update |
| Doppler |
Projects |
Add, Remove, Update |
Why this design
| Capability |
Benefit |
| Slack-first request intake |
Lowers friction for operators and requesters |
| Terraform PR generation |
Preserves review, audit trail, and rollback path |
| HCL parse + render validation |
Reduces malformed output risk |
| Thread-keyed in-memory state |
Keeps multi-step flows isolated per request |
| Nonce-based callback protection |
Rejects stale modal submissions safely |
| GitHub App auth |
Avoids long-lived personal credentials |
slog + OpenTelemetry + Sentry + Alloy |
Duplicates logs/traces intentionally while keeping app instrumentation mostly vendor-neutral |
Observability
Application code emits structured logs through slog and traces/metrics through OpenTelemetry. In production, logs flow to Grafana Alloy through the container logging path and into Loki, while the same application logs are mirrored to Sentry. Traces are exported to Alloy for Tempo and directly to Sentry. Metrics stay Grafana-native through Prometheus scrape plus optional OTLP metrics export into Alloy.
Relevant environment variables:
- defaults:
OTEL_EXPORTER_OTLP_ENDPOINT=127.0.0.1:4317
OTEL_EXPORTER_OTLP_PROTOCOL=grpc
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT falls back to OTEL_EXPORTER_OTLP_ENDPOINT
OTEL_EXPORTER_OTLP_METRICS_PROTOCOL falls back to OTEL_EXPORTER_OTLP_PROTOCOL
SERVICE_VERSION
OTEL_SERVICE_NAME
OTEL_ENVIRONMENT
OTEL_EXPORTER_OTLP_ENDPOINT
OTEL_EXPORTER_OTLP_PROTOCOL
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
OTEL_EXPORTER_OTLP_METRICS_PROTOCOL
SENTRY_DSN
SENTRY_ENVIRONMENT
SENTRY_RELEASE
SENTRY_TRACES_SAMPLE_RATE
CI and releases
| Workflow |
Trigger |
Behavior |
ci.yml |
Pushes to main and pull requests |
Runs formatting, lint, tests, coverage upload, build checks, and security-oriented validation |
release.yml |
Pushes to main |
Builds release artifacts, creates GitHub releases, builds and pushes the container image, and deploys production via the external Ansible repository |
Published release assets:
| Platform |
Asset |
| Linux amd64 |
concierge-linux-amd64 |
| Linux arm64 |
concierge-linux-arm64 |
| macOS amd64 |
concierge-darwin-amd64 |
| macOS arm64 |
concierge-darwin-arm64 |
Documentation
Test
go test ./...
Contributing
See AGENTS.md and the docs in docs/ before changing flow behavior, Terraform file paths, or modal structures. This project has hard coupling to the external jae-labs/terraform repository, so README-level simplification does not remove implementation constraints.
License
See LICENSE.