Project 2: Idempotent Web Tier Bootstrap

Converge package and service state reliably so repeated runs remain stable.

Quick Reference

Attribute Value
Difficulty Level 1
Time Estimate 6-10 hours
Main Programming Language YAML (Ansible playbook)
Alternatives Shell (for comparison only)
Coolness Level 2
Business Potential 2. Micro-SaaS / Pro Tool
Prerequisites P01 inventory baseline
Key Topics Desired state, idempotency, service management

1. Learning Objectives

  1. Build your first convergent playbook.
  2. Prove idempotency by comparing first and second run recaps.
  3. Separate package installation concerns from service lifecycle concerns.
  4. Document deterministic verification for web tier readiness.

2. All Theory Needed (Per-Concept Breakdown)

2.1 Desired State vs Imperative Steps

Fundamentals Imperative scripts run steps; desired-state automation asserts outcomes. Idempotent modules compute drift and apply only required changes.

Deep Dive into the concept In production, partial failures are normal. Desired-state automation makes reruns safe. Imperative scripts often cannot distinguish already-correct state from missing state, causing duplicate side effects.

How this fit on projects Core to P02, reused in P03, P06, P07.

Definitions & key terms

  • Convergence
  • Drift
  • Changed vs ok

Mental model diagram

declared state -> compare -> mutate only if mismatch -> stable rerun

How it works

  1. Read package/service status.
  2. Apply minimal changes.
  3. Report changed only on real mutation.

Minimal concrete example

# pseudocode
- ensure package: present
- ensure service: started + enabled

Common misconceptions

  • “First success means automation is done.”

Check-your-understanding questions

  1. Why is second-run stability the key test?

Check-your-understanding answers

  1. It proves drift correction rather than repeated mutation.

References

  • Ansible desired state docs.

3. Project Specification

3.1 What You Will Build

A web bootstrap playbook that:

  • installs web package
  • ensures service enabled and running
  • validates endpoint or service state

3.2 Functional Requirements

  1. First run converges from blank state.
  2. Second run shows no unnecessary change.
  3. Service check passes on all target hosts.

3.3 Non-Functional Requirements

  • Reliability: safe reruns.
  • Portability: supports at least two Linux families.
  • Clarity: readable task names and outputs.

3.4 Example Usage / Output

$ ansible-playbook -i inventory.ini web_bootstrap.yml
... changed=2 failed=0

$ ansible-playbook -i inventory.ini web_bootstrap.yml
... changed=0 failed=0

3.7 Real World Outcome

3.7.1 How to Run

ansible-playbook -i inventory.ini web_bootstrap.yml --check --diff
ansible-playbook -i inventory.ini web_bootstrap.yml
ansible-playbook -i inventory.ini web_bootstrap.yml

3.7.2 Golden Path Demo

First run changes state. Second run is stable.

3.7.3 Failure Demo

If service package name is wrong, task fails with explicit package-not-found message and no hidden retries.


4. Solution Architecture

4.1 High-Level Design

inventory -> package convergence -> service convergence -> verification

4.2 Key Components

Component Responsibility Decision
Package task Install required package Use module, not shell
Service task Start + enable explicit state
Verification Check readiness deterministic output

5. Implementation Guide

5.3 The Core Question You’re Answering

“Can this baseline playbook be rerun indefinitely without operational noise?”

5.4 Concepts You Must Understand First

  1. Desired state semantics.
  2. Module idempotency model.
  3. Service startup/enable differences.

5.5 Questions to Guide Your Design

  1. Which tasks should ever be changed after steady state?
  2. How do you verify readiness beyond process-up?

5.6 Thinking Exercise

Map expected recap counts for first run vs second run.

5.7 The Interview Questions They’ll Ask

  1. How do you prove idempotency?
  2. Why avoid shell wrappers for package installs?
  3. What is safe rollback for this change?

5.8 Hints in Layers

  • Hint 1: Add become where needed.
  • Hint 2: Keep package names variable-driven.
  • Hint 3: Validate service state after converge.
  • Hint 4: Preserve both run recaps as evidence.

5.9 Books That Will Help

Topic Book Chapter
Ansible basics Ansible for DevOps playbook intro
Linux services How Linux Works service management

5.10 Implementation Phases

  • Phase 1: package convergence.
  • Phase 2: service convergence.
  • Phase 3: idempotency verification.

6. Testing Strategy

6.2 Critical Test Cases

  1. Clean host first run.
  2. Immediate second run.
  3. Host with preinstalled package and stopped service.

7. Common Pitfalls & Debugging

Pitfall Symptom Solution
Wrong package name package task fails OS-family variable map
unconditional restart service changes every run handler or explicit state

8. Extensions & Challenges

  • Add distro-aware package abstraction.
  • Add HTTP health endpoint verification.
  • Add canary-only mode using limit/serial.

9. Real-World Connections

This pattern is the foundation for every baseline server role in production platform teams.


10. Resources

  • Ansible playbook docs
  • Ansible check mode docs
  • Ansible package/service module docs

11. Self-Assessment Checklist

  • I can explain why run two is stable.
  • I can explain each changed result.
  • I can recover from a partial failure safely.

12. Submission / Completion Criteria

Minimum: convergent playbook + two run recaps.

Full: includes validation and distro variance notes.

Excellence: includes measurable runtime and zero-noise steady state.