# ansible / monitoring / prometheus
Install Node Exporter without touching the host by hand
One playbook fetches the release, creates a locked-down service account, wires up systemd, and leaves you with a metrics endpoint — reproducible on every box you run it against.
Why this playbook holds up
Built around three properties that matter for anything running unattended on a server: idempotency, isolation, and portability. Every task uses a native Ansible module — no shell one-liners to babysit, no drift between runs. Run it once or run it a hundred times; the end state doesn't change.
Safe to re-run
Tasks check current state before acting, so a second run against an already-configured host changes nothing.
No distro assumptions
Works against any systemd-based Linux host — swap hosts: localhost for an inventory group and it scales the same way.
The full task list
--- - name: Install node exporter hosts: localhost become: yes vars: node_exporter_version: "1.8.1" tasks: - name: Download and extract node exporter unarchive: src: "https://github.com/prometheus/node_exporter/releases/download/v{{ node_exporter_version }}/node_exporter-{{ node_exporter_version }}.linux-amd64.tar.gz" dest: /tmp remote_src: yes - name: Copy node exporter binary copy: src: "/tmp/node_exporter-{{ node_exporter_version }}.linux-amd64/node_exporter" dest: /usr/local/bin/node_exporter mode: '0755' remote_src: yes - name: Create node exporter user user: name: node_exporter shell: /sbin/nologin system: yes create_home: no - name: Create systemd service file copy: dest: /etc/systemd/system/node_exporter.service content: | [Unit] Description=Node Exporter After=network.target [Service] User=node_exporter ExecStart=/usr/local/bin/node_exporter [Install] WantedBy=multi-user.target - name: Reload systemd command: systemctl daemon-reload - name: Enable and start node exporter service: name: node_exporter state: started enabled: yes
Run order
- fetch
Download and extract the release into
unarchive, remote_src/tmp. - place
Move the binary to
copy, mode 0755/usr/local/binand mark it executable. - isolate
Create a no-login system account to run the service as.
user, /sbin/nologin - wire
Write the unit file and register it with systemd.
copy + daemon-reload - run
Enable on boot and start the service now.
service, enabled + started
Confirm it's actually up
Two checks are enough: is the systemd unit reporting active, and is the metrics endpoint answering. If both check out, Prometheus can scrape the host.
Lessons from running this in production
YAML is indentation-sensitive — use spaces consistently, never tabs, or the parser fails before a single task runs.
Centralize the version in vars so a bump is a one-line change, not a find-and-replace across the file.
Every task here is idempotent by construction — safe to re-run against a host that's already configured.