An old documented way of preventing services from starting immediately after installation in Debian/Ubuntu is using the RUNLEVEL environment variable to trick the runlevel helper into returning a response that the system isn't fully running, such as:
# RUNLEVEL=1 apt-get install nginx
Sadly this doesn't work in newer versions of Debian/Ubuntu, the official way is to use the policy helper script /usr/sbin/policy-rc.d and return a 101 exit code. This is a a bit more inconvenient - having to temporarily create this file only to remove it after installing the package.
Fortunately there is an alternative - policyrcd-script-zg2. Install the package:
$ sudo apt-get install policyrcd-script-zg2
Create a new script which returns a 101 exit code, I've created it as /usr/local/sbin/policy-donotstart:
#!/bin/sh exit 101
Then make it executable:
$ sudo chmod 755 /usr/local/sbin/policy-donotstart
When installing packages where you don't want the service to immediately start, use the POLICYRCD environment variable:
# POLICYRCD=/usr/local/sbin/policy-donotstart apt-get install nginx
The service will install, but you'll a message similar to:
invoke-rc.d: policy-rc.d denied execution of start.
For Ansible, you can add environment variables to any task:
- name: Install nsd apt: pkg=nsd install_recommends=no environment: POLICYRCD: /usr/local/sbin/policy-donotstart
Now you can safely install a package, configure it, and then start it once you've got all the correct files in place - all with a convenient environment variable.