Git Hooks: Automate Quality Before It Reaches the Repo

Git hooks are scripts that run at specific points in the Git workflow. They’re the first line of defense against bad commits — catching issues before they pollute your repository history. Set them up once, forget about them, and let automation enforce quality. Hook Types Client-side hooks (your machine): pre-commit — Before commit is created prepare-commit-msg — Before commit message editor opens commit-msg — After commit message is entered pre-push — Before push to remote Server-side hooks (repository server): ...

February 23, 2026 Â· 6 min Â· 1086 words Â· Rob Washington

Ansible Playbook Patterns: Writing Automation That Doesn't Break

Ansible’s simplicity is seductive. YAML tasks, SSH connections, no agents. But simple playbooks become complex fast, and poorly structured automation creates more problems than it solves. These patterns help you write Ansible that scales with your infrastructure. Idempotency: Safe to Run Twice Every task should be safe to run repeatedly with the same result: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # Idempotent - creates file if missing, no-op if exists - name: Create config directory file: path: /etc/myapp state: directory mode: '0755' # Not idempotent - appends every run - name: Add config line shell: echo "setting=value" >> /etc/myapp/config # Idempotent version - name: Add config line lineinfile: path: /etc/myapp/config line: "setting=value" Use Ansible modules over shell commands. Modules are designed for idempotency. ...

February 23, 2026 Â· 6 min Â· 1235 words Â· Rob Washington

LLM API Integration Patterns: Building Reliable AI-Powered Features

Adding an LLM to your application sounds simple: call the API, get a response, display it. In practice, you’re dealing with rate limits, token costs, latency spikes, and outputs that occasionally make no sense. These patterns help build LLM features that are reliable, cost-effective, and actually useful. The Basic Call Every LLM integration starts here: 1 2 3 4 5 6 7 8 9 10 11 from openai import OpenAI client = OpenAI() def ask_llm(prompt: str) -> str: response = client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": prompt}], temperature=0.7 ) return response.choices[0].message.content This works for demos. Production needs more. ...

February 23, 2026 Â· 7 min Â· 1302 words Â· Rob Washington

CI/CD Pipelines: From Commit to Production Safely

Continuous Integration and Continuous Deployment transform code changes into running software automatically. Done well, you push code and forget about it — the pipeline handles testing, building, and deploying. Done poorly, you spend more time fighting the pipeline than writing code. The Pipeline Stages C o m m i t → B u i l d → T e s t → S e c u r i t y → A r t i f a c t → D e p l o y → V e r i f y Each stage is a gate. Fail any stage, stop the pipeline. ...

February 23, 2026 Â· 6 min Â· 1182 words Â· Rob Washington

GitOps Workflow Patterns: Infrastructure as Pull Requests

GitOps sounds simple: put your infrastructure in Git, let a controller sync it to your cluster. In practice, there are a dozen ways to get it wrong. Here’s what works. The Core Principle Git is the source of truth. Not the cluster. Not a dashboard. Not someone’s kubectl session. D e v e l o p e r s → i n G g i l t ↑ e → s o C u o r n c t e r o l l e r → C l u s t e r If the cluster state doesn’t match Git, the controller fixes it. If someone manually changes the cluster, the controller reverts it. This is the contract. ...

February 22, 2026 Â· 6 min Â· 1250 words Â· Rob Washington

Ansible Idempotency Patterns: Write Playbooks That Don't Break Things

The promise of Ansible is simple: describe your desired state, run the playbook, and the system converges to that state. Run it again, nothing changes. That’s idempotency—and it’s harder to achieve than it sounds. Here’s how to write playbooks that won’t surprise you on the second run. The Problem: Commands That Lie The command and shell modules are where idempotency goes to die: 1 2 3 # ❌ BAD: Always reports "changed", even when nothing changed - name: Create database command: createdb myapp This fails on the second run because the database already exists. Worse, it always shows as “changed” even when it shouldn’t run at all. ...

February 21, 2026 Â· 5 min Â· 998 words Â· Rob Washington

Ansible Role Design Patterns: Building Reusable Automation

Ansible playbooks get messy fast. Roles fix this by packaging related tasks, variables, and handlers into reusable units. But bad roles are worse than no roles — they hide complexity without managing it. Here’s how to design roles that actually help. The Basic Structure r o l m e y s _ t h d v t f m / r a a e a e i e o s m n m f m r m m c l s t m l k a d a a a s a p o e c a a e s i l i u i / i l n s r / i / / n e n l n n a f / i n . r . t . . t i p . y s y s y y e g t y m / m / m m s . . m l l l l j s l 2 h # # # # # # # E E D R J S R n v e o i t o t e f l n a l r n a e j t e y t u a i - l v 2 c m p t t a e o r r t f t i i v i e i a n g a a m l d t g r b p e a e i l l s t r a e a a e b s t d l e a e ( s n t s h d a i s ( g d k l h e s o e p w r e e n s p d t r e e n p c c r e i e d e c e s e n d c e e n ) c e ) Only create directories you need. An empty handlers/ is noise. ...

February 19, 2026 Â· 8 min Â· 1576 words Â· Rob Washington

LLM Prompt Engineering for DevOps Automation

LLMs are becoming infrastructure. Not just chatbots — actual components in automation pipelines. But getting reliable, parseable output requires disciplined prompt engineering. Here’s what works for DevOps use cases. The Core Problem LLMs are probabilistic. Ask the same question twice, get different answers. That’s fine for chat. It’s terrible for automation that needs to parse structured output. The solution: constrain the output format and validate aggressively. Pattern 1: Structured Output with JSON Mode Most LLM APIs now support JSON mode. Use it. ...

February 19, 2026 Â· 6 min Â· 1138 words Â· Rob Washington

Secrets Rotation Automation: Stop Letting Credentials Rot

That database password hasn’t changed in three years. The API key in your config was committed by someone who left two jobs ago. The SSL certificate expires next Tuesday and nobody knows. Secrets rot. Rotation automation fixes this. Why Rotate? Static credentials are liability: Leaked credentials stay valid until someone notices Compliance requires it (PCI-DSS, SOC2, HIPAA) Blast radius grows the longer a secret lives Offboarded employees may still have access Automated rotation means: ...

February 19, 2026 Â· 8 min Â· 1636 words Â· Rob Washington

Ansible Playbook Patterns: Writing Maintainable Infrastructure Code

Ansible playbooks can quickly become unwieldy spaghetti. Here are battle-tested patterns for writing infrastructure code that scales with your team and your infrastructure. The Role Structure That Actually Works Forget the minimal examples. Real roles need this structure: r └ o ─ l ─ e s w ├ │ ├ │ ├ │ │ │ │ ├ │ ├ │ ├ │ └ / e ─ ─ ─ ─ ─ ─ ─ b ─ ─ ─ ─ ─ ─ ─ s e d └ v └ t ├ ├ ├ └ h └ t └ f └ m └ r e ─ a ─ a ─ ─ ─ ─ a ─ e ─ i ─ e ─ v f ─ r ─ s ─ ─ ─ ─ n ─ m ─ l ─ t ─ e a s k d p e a r u m / m s m i c s l m l n s s / m / l a a / a n o e e a a g / s a t i i i s n r r i t i l i s n n n t f v s n e n - n / . . . a i i / . s x p . y y y l g c y / . a y m m m l u e m c r m l l l . r . l o a l y e y n m m . m f s l y l . . m j c l 2 o n # # # # # # # f # D R E P C S R D e o n a o e e e f l t c n r s p a e r k f v t e u y a i i a n l v g g c r d t a p e u e t e r o r / n v i i i a m r c a a n n t a e i r b t s i n l e i l t o a o s a e - a n g a b s l e d l j l f m e ( u a i e h s h s t l n a i t i e t n ( g o s d l h i n l o e n e w r c r e l s s p u t r d e e p c s r e e d c e e n d c e e n ) c e ) The key insight: tasks/main.yml should only contain includes: ...

February 17, 2026 Â· 7 min Â· 1328 words Â· Rob Washington