Assuming that you have a set of scripts that can be executed to configure the machine in the way that you want, you can, as ebal suggested, run them at the end of /etc/rc.local (or your distribution's equivalent). That script is executed at the end of the boot process, just before getty is spawned by init.
I suggest that you add towards the end of /etc/rc.local something like:
test -x /sbin/system-setup-step1.sh && /sbin/system-setup-step1.sh && reboot
test -x /sbin/system-setup-step2.sh && /sbin/system-setup-step2.sh && reboot
test -x /sbin/system-setup-step3.sh && /sbin/system-setup-step3.sh && reboot
# ... for however many steps are needed for your use case
Then, at the end of each of those scripts, remove the execute bit as an indication that it no longer needs to be executed (but leave the script on disk in case the user wants to see what it did), and store the name of the script somewhere, then check the previously executed script at the top of the next script in the sequence. For example, here's what
system-setup-step2.sh might look like:
test $(cat /var/tmp/last-system-setup-step) = "system-setup-step1.sh" || exit 1
# ... do stuff ...
# indicate that this doesn't need to run again
/bin/chmod -x "$0"
printf '%s' $(basename "$0") > /var/tmp/last-system-setup-step
# finished successfully
Adjust the test condition near the top for each script.
This way, the system will reboot however many times are required, and at the end will pass right through all those
test conditions and reach a login prompt (or whatever else you might have configured) because none of the scripts will have the execute bit set. If something goes wrong, the configuration and rebooting process will simply stop.
In the original image, make sure that /var/tmp/last-system-setup-step exists and is empty, to avoid annoying errors.
Note that the above is untested (written in browser), but should get the gist across.