In short
If running your setup twice breaks something or creates a duplicate, you can never safely rerun it after a failure. Idempotent code gives the same end result whether you run it once or fifty times.
Applying the same IaC configuration multiple times should converge to the same end state without unintended side effects — the same idempotency principle from Phase 5's scripting, now applied to infrastructure.

Think of it like this
The lift call button
Press the lift button once and a lift comes. Press it ten more times out of impatience and still only one lift comes. The button means 'I want a lift here', not 'send another lift'. Idempotent IaC works the same: it states what you want, not what to do.
Watch it happen
Running the same setup twice
useradd deploy
1/5The first run of a plain script creates the user. Fine so far.
The big ideas
What you need to know
Desired state, not steps
Say 'nginx installed, version X', not 'run apt install'. The tool checks and only acts on the difference.
Safe retries
If a run fails halfway, you just run it again. Idempotent steps that already succeeded are skipped.
Check, then act
Writing your own scripts? Test before changing: does the user exist, is the line already in the file?
Watch the escape hatches
Ansible's shell and command modules and Terraform's local-exec are not idempotent unless you make them so.
See it in code
Walk through the code
1# Not idempotent: second run fails or duplicates2useradd deploy3echo 'export PATH=$PATH:/opt/app' >> /home/deploy/.bashrc4 5# Idempotent: check first, then act6id deploy >/dev/null 2>&1 || useradd deploy7grep -qxF 'export PATH=$PATH:/opt/app' /home/deploy/.bashrc \8 || echo 'export PATH=$PATH:/opt/app' >> /home/deploy/.bashrc1/3Run twice: useradd errors out, and the PATH line is appended a second time.
Run as root on a throwaway VM or container. In Ansible, the user and lineinfile modules do these checks for you.
Save yourself the pain
Common mistakes
Oops
Reaching for shell: in Ansible because it's quicker to write.
Do this instead
Use the proper module, or add creates:, removes: or changed_when: so Ansible knows when the command really changed something.
Oops
Assuming a tool is idempotent so your code must be too.
Do this instead
Prove it: run everything twice in CI. The second run should report zero changes.
Your mission
The second-run test
Quick check
Which of these is idempotent?
Go deeper
- 1Apply the same Terraform or Ansible configuration twice and confirm the second run makes no changes.
- 2Learn why non-idempotent infrastructure code is dangerous to re-run after a partial failure.
- 3Understand this is a core design goal of both Terraform and Ansible, not an accident.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.