Terraform Without Tears: How I Turned an LLM Into a DevOps Teammate That Writes Dockerfiles, K8s Manifests and CI/CD Pipelines
Infrastructure work is 20% architecture and 80% remembering the exact syntax of volumeMounts vs volumeDevices, whether it's depends_on or dependsOn, and why the pod is in CrashLoopBackOff again. An LLM won't replace your judgment, but it absolutely kills the syntax archaeology. Below is a working collection of DevOps prompts — Docker, Kubernetes, CI/CD, Terraform — each with a real example and the routine it removes. Treat every output as a draft: validate with docker build, kubectl apply --dry-run=server, terraform validate and tflint before it touches prod.
1. Hardened multi-stage Dockerfile from a project tree
Drops the guesswork of picking a base image, ordering layers, and creating a non-root user.
Prompt:
You are a senior DevOps engineer. Given this project tree and package.json,
write a multi-stage Dockerfile for Node 20: builder stage with dev deps,
runtime stage on node:20-alpine, non-root user `app` (uid 10001),
HEALTHCHECK hitting /health, and explicit ENV NODE_ENV=production.
Explain each layer and why it's ordered that way.
Example output excerpt:
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:20-alpine AS runtime
RUN addgroup -g 10001 app && adduser -u 10001 -G app -D app
WORKDIR /app
COPY --from=builder --chown=app:app /app/dist ./dist
COPY --from=builder --chown=app:app /app/node_modules ./node_modules
USER app
HEALTHCHECK CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "dist/main.js"]
Removes: 20 minutes of hunting for the right adduser flags on Alpine.
2. Image diet audit
Prompt:
Here is my Dockerfile and `docker history` output. Identify the 3 biggest
size contributors, propose concrete replacements (distroless, alpine,
multi-stage, .dockerignore entries), and estimate savings per layer.
Pairs with docker history --no-trunc myimage:latest. Removes: blind docker-slim experiments.
3. Kubernetes Deployment + Service + HPA bundle
Prompt:
Generate a Kubernetes 1.30 manifest set for a stateless API:
Deployment (3 replicas, requests cpu 100m/mem 128Mi, limits cpu 500m/mem 512Mi),
Service ClusterIP, HPA on cpu 70%. Use apps/v1 and autoscaling/v2.
Add readinessProbe on /ready and livenessProbe on /live.
Always run kubectl apply --dry-run=server -f app.yaml. Removes: copy-pasting from old repos with deprecated extensions/v1beta1.
4. CrashLoopBackOff triage
Prompt:
Pod is in CrashLoopBackOff. Here are `kubectl describe pod` and `kubectl logs --previous`.
Rank the 5 most likely causes, map each to a diagnostic command,
and tell me the fastest one to run first.
Removes: 40 minutes of scrolling Stack Overflow at 2 a.m.
5. Terraform module skeleton
Prompt:
Write a reusable Terraform module for an S3 bucket with versioning,
server-side encryption (AES256), and public access block.
Files: main.tf, variables.tf, outputs.tf, versions.tf pinning aws >= 5.0.
Add a README with a usage example.
Validate with terraform init && terraform validate && tflint. Removes: boilerplate from scratch each time.
6. Terraform plan review
Prompt:
Here is `terraform plan` output. Flag every destructive change (destroy/replace),
explain why the resource is being replaced, and propose a safer alternative
(create_before_destroy, lifecycle ignore_changes) where appropriate.
Removes: the classic "why is my RDS instance being recreated?" heart attack.
7. GitHub Actions pipeline with cache and matrix
Prompt:
Write a GitHub Actions workflow for a Node app: lint, test, build Docker image,
push to GHCR on main only. Use actions/checkout@v4, setup-node@v4 with
npm cache, docker/build-push-action@v6 with buildx cache (type=gha).
Add a matrix over Node 20 and 22.
Removes: reinventing cache keys for the tenth time.
8. Pipeline failure decoder
Prompt:
CI failed. Here are the logs (last 100 lines) and the workflow YAML.
Identify the failing step, root cause, and give me a minimal diff to fix it.
Removes: log spelunking when the error is buried under 300 lines of npm noise.
9. Secrets hygiene check
Prompt:
Review this workflow and Dockerfile for secret leakage: hardcoded tokens,
secrets echoed in logs, secrets passed as build ARGs (visible in image history).
Propose the fix using GitHub OIDC or env vars at runtime.
Removes: the post-incident scramble after a token lands in a public image layer.
10. Helm values diff
Prompt:
Compare these two values.yaml files for the same chart. List every changed key,
the resulting Kubernetes object it affects, and whether the change is rolling-safe.
Removes: eyeballing 400-line YAML diffs before a release.
11. Compose for local dev parity
Prompt:
Write docker-compose.yml matching our prod stack: app, postgres:16, redis:7,
with healthchecks and depends_on conditions so app waits for db readiness.
Use named volumes and .env for secrets.
Removes: "works on my machine" drift.
12. Terraform state and drift explainer
Prompt:
Explain this `terraform plan` drift output in plain English for a junior dev.
What changed outside Terraform, and what's the safest remediation path?
Removes: the weekly "someone clicked in the AWS console" meeting.
Takeaways
An LLM is a syntax accelerator, not an approver. The pattern that works: paste real context (logs, plans, trees), ask for a diff plus rationale, then gate everything through the real validators — docker build, kubectl --dry-run=server, terraform validate, tflint, actionlint. That keeps the 80% of mechanical work off your plate while you keep the 20% that actually needs a human brain. Start with prompt #4 next time a pod dies — you'll feel the difference immediately.
Comments