configuration-generator
Configuration Generator
A config file is an interface between a human operator and a running system. It should read like a document, not a database dump.
Step 1 — Identify the config consumer
The consumer dictates the format and the idioms. Don't guess.
| Consumer | Format | Look for existing example at |
|---|---|---|
| Your own app | Whatever the loader expects — check the code | config.py, settings.py, Config.java |
| nginx / Apache | Custom block syntax | /etc/nginx/sites-available/ |
| Postgres / MySQL | INI-like key = value |
postgresql.conf / my.cnf — copy the header |
| Prometheus / Grafana | YAML | Their docs have a canonical minimal example — start there |
| Linters (eslint, ruff, golangci) | Tool-specific (JSON/TOML/YAML) | Run <tool> --init first; edit its output |
Logging (log4j, logback, Python logging) |
XML / YAML / dictConfig |
The framework ships a default — diff against it |
Step 2 — Separate secrets from config
The first question for every key: does this belong in version control?
| Goes in config file (committed) | Goes in env / secret store (NOT committed) |
|---|---|
| Feature flags, log levels, ports | API keys, passwords, tokens |
| Service URLs (non-secret) | Database connection strings with credentials |
| Timeouts, pool sizes, retry counts | Signing keys, certificates' private halves |
| Anything that differs by design intent | Anything that differs by who's allowed to know |
For every secret, emit a placeholder with a loud comment:
database:
host: db.internal
port: 5432
# DATABASE_PASSWORD is read from env — NEVER commit a real value here
password: ${DATABASE_PASSWORD}
Step 3 — Layer by environment
One base config, per-environment overlays that only contain differences:
config/
base.yaml ← everything
staging.yaml ← only what differs from base (3 keys, not 300)
production.yaml ← only what differs from base
If the app doesn't support layered loading, generate full per-env files — but also generate a diff so drift is visible.
Defaults — what to emit when the user doesn't say
| Setting domain | Safe default | Rationale |
|---|---|---|
| Log level | INFO (prod), DEBUG (dev) |
DEBUG in prod leaks + floods |
| Timeouts | Always set one — 30s if no better info | Infinite timeout = hung thread |
| Connection pools | Small (10) — tune up with evidence | Oversized pools thrash the DB |
| TLS | On, TLS 1.2 minimum | Plaintext is never the right default |
| Bind address | 127.0.0.1 unless the thing needs to be reachable |
0.0.0.0 is an exposure, not a default |
| Retry count | 3, with backoff | 0 retries is brittle; infinite is a DoS on yourself |
Worked example
Input: "Generate a Python logging config — JSON to stdout in prod, human-readable to console in dev, nothing below INFO in prod."
Output (logging.yaml, loaded via logging.config.dictConfig):
version: 1
disable_existing_loggers: false
formatters:
human:
format: "%(asctime)s %(levelname)-7s %(name)s — %(message)s"
json:
(): pythonjsonlogger.jsonlogger.JsonFormatter
format: "%(asctime)s %(levelname)s %(name)s %(message)s"
handlers:
console:
class: logging.StreamHandler
stream: ext://sys.stdout
formatter: ${LOG_FORMAT:-human} # set LOG_FORMAT=json in prod
root:
level: ${LOG_LEVEL:-INFO}
handlers: [console]
One file, two env vars switch behavior. Dev runs with no env set → human, INFO. Prod sets LOG_FORMAT=json.
Edge cases
- The tool has no config file — it's all CLI flags: Generate a wrapper script or a Makefile target. The "config" is the invocation.
- Config is read from a database / remote service: You're generating seed data, not a file. Emit the INSERT statements or the API calls.
- The user wants a Kubernetes ConfigMap: It's still just a config file with YAML wrapping. Generate the inner content first, then wrap. →
config-consistency-checkerto ensure the ConfigMap matches the Deployment's env mappings.
Do not
- Do not invent keys the consumer doesn't read. Every key must map to something the code actually loads. Unknown keys are silent lies.
- Do not put a real secret in an "example" config. Not even a "clearly fake" one like
password: changeme— those get deployed. - Do not emit a config without comments. The operator reading this at 3am needs to know what each section does.
- Do not bind to
0.0.0.0by default. Make the operator opt into exposure. - Do not generate every possible key with its default value. Emit only what differs from the tool's default — a 400-line config where 390 lines are defaults hides the 10 that matter.
Output format
## Files
<path>
<code block with config — commented>
## Environment variables referenced
- <VAR>: <purpose> (secret: <yes|no>)
## What you still need to set
- <anything that's a placeholder>
More from santosomar/general-secure-coding-agent-skills
code-review-assistant
Performs structured code review on a diff or file set, producing inline comments with severity levels and a summary. Checks correctness, error handling, security, and maintainability — in that priority order. Use when reviewing a pull request, when the user asks for a code review, when preparing code for merge, or when a second opinion is needed on a change.
15dependency-resolver
Diagnoses and resolves package dependency conflicts — version mismatches, diamond dependencies, cycles — across npm, pip, Maven, Cargo, and similar ecosystems. Use when install fails with a resolution error, when two packages require incompatible versions of a third, or when upgrading one dependency breaks another.
4ci-pipeline-synthesizer
Generates CI pipeline configs by analyzing a repo's structure, language, and build needs — GitHub Actions, GitLab CI, or other platforms. Use when bootstrapping CI for a new repo, when porting from one CI to another, when the user asks for a pipeline that builds and tests their project, or when wiring in security gates.
3api-design-assistant
Reviews and designs API contracts — function signatures, REST endpoints, library interfaces — for usability, evolvability, and the principle of least surprise. Use when designing a new public interface, when reviewing an API PR, when the user asks whether a signature is well-designed, or when planning a breaking change.
2code-refactoring-assistant
Executes refactorings — extract method, inline, rename, move — in small, behavior-preserving steps with a test between each. Use when the user wants to restructure working code, when cleaning up after a feature lands, or when a smell has been identified and needs fixing.
2code-smell-detector
Identifies code smells — structural patterns that correlate with maintainability problems — and explains why each matters in context. Use when reviewing a PR for structural quality, when the user asks what's wrong with a piece of code that isn't buggy, or when prioritizing refactoring targets.
2