A Practical First Automation Project, End to End
Build a complete first automation project: inventory, an idempotent playbook, a dry-run, a real apply, and a scheduled re-converge.
Netbay Cloud Team
Netbay Engineering
On this page
Every automation skill in this series is easier to absorb as one small, working system than as a pile of commands. So this final post walks a complete first project end to end: a single web server that is bootstrapped by Ansible, health-checked, and re-converged nightly. By the end you will have an inventory, a playbook, a dry-run habit, and a scheduled job — the same skeleton that scales to whole fleets.
Step 1: The Inventory
Provision one Ubuntu server, note its IP, and create the inventory file. This is the single source of truth for the fleet:
[app]
app01 ansible_host=10.0.0.31 ansible_user=deploy
[app:vars]
ansible_python_interpreter=/usr/bin/python3Deploy your SSH key to the box while provisioning so that ansible_user=deploy can log in. At Netbay you can add the public key during deployment, which means no extra SSH setup before the first playbook run.
Step 2: The Playbook
Write a playbook that installs the web stack, writes a health endpoint, and verifies it answers — idempotent by construction because every module declares a target state:
- name: First project bootstrap
hosts: app
become: true
tasks:
- name: Install nginx and curl
ansible.builtin.apt:
name:
- nginx
- curl
state: present
update_cache: true
- name: Write the health endpoint
ansible.builtin.copy:
content: "ok"
dest: /usr/share/nginx/html/healthz
mode: "0644"
- name: Start nginx
ansible.builtin.service:
name: nginx
state: started
enabled: true
- name: Verify the endpoint answers
ansible.builtin.uri:
url: http://localhost/healthz
return_content: trueEvery module here is convergent: installing is a no-op once nginx exists, the health endpoint file is exact-match, and the service is started and enabled. Run it twice and the second run reports changed for nothing.
Step 3: Dry-Run, Apply, Verify
Never skip the rehearsal. The check pass costs seconds, and the habit is what keeps you brave later:
ansible-playbook -i hosts.ini playbooks/site.yml --check
ansible-playbook -i hosts.ini playbooks/site.yml
curl -fsS http://app01/healthz && echo "healthy"Read the diff the check presents, then apply, then confirm the endpoint from outside the box. If the curl fails, the failure is caught in a sandbox-sized project, which is precisely where you want your first mistakes.
Step 4: Schedule the Re-Converge
Drift will happen: a manual edit on the box, a half-finished deploy, sunlight. A nightly re-converge turns the playbook into a safety net that repairs drift automatically. Wire it with a systemd timer, as covered earlier in this series, pointing at the same playbook:
[Unit]
Description=Nightly converge of app tier
[Timer]
OnCalendar=*-*-* 03:30:00
Persistent=true
[Install]
WantedBy=timers.targetEvery morning the playbook runs, compares reality to the declared state, and repairs whatever drifted during the day, with the change logged the way an audit trail should be.
Takeaway
That is the whole craft, end to end: an inventory, an idempotent playbook, a dry-run before every apply, and a scheduled safety net that converges nightly. Once this loop runs unattended for a week, graduate it to the roles, tags, testing gates, and state discipline from the rest of the series — the skeleton stays the same, only the payload grows. Provision your first test server right now on netbayhosts.in and have all five steps done before coffee gets cold.
Keep reading
Follow along on a real VPS
Deploy Linux in under 60 seconds
These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.
Deploy an instance