In part 2, I showed you how to build a standard munki package and then how you could extend this concept and create a completely custom package. But with great power, comes great responsibility. Here are some best practices for using a custom DEP configuration, some ideas to try and things to watch out for.


User Experience

  • Give the user some kind of notification that their machine is being enrolled into a management framework. Optionally send them another notification when their machine is ready to be used.
  • Try to keep the bootstrapping under 3-5 minutes. Anything over this will become annoying.

Signed Package

  • Try to keep it as modular/light as you can.
  • Attempt to download external resources (if needed) outside of the package or in a way that the package itself does not have to be continually maintained. (monolithic vs dynamic packaging)
  • Log everything. Should an error occur during the bootstrapping process, you need the user to be able to articulate what happened. Unlike imaging, you cannot just start the process over again.
  • Create a fail-safe in case of install failures.


  • Make as much software as you can self-service. If you can, make all software self-service.
  • Delay any potential Apple software updates until after your dep bootstrap is finished.
  • Don’t force any reboots during your dep bootstrapping.


  • Profiles signed/encrypted by the MDM are non-removable if flagged correctly. Profiles installed by Chef/Puppet/Munki can be removed via the profiles command. If you want to ensure a setting is 100% managed (Ex: munki’s primary URL), use the MDM’s tooling. Chances are they support custom profiles.


User Experience

  • Don’t take over the user’s active session to inform the user that the bootstrapping process is running. This will only annoy your customers.


  • Don’t deploy large applications like Xcode or Microsoft Office during your DEP bootstrap. This will only annoy your customers and lengthen the time to finish.

Clever things to try:

  • Caffeinate your machines during DEP bootstrapping to ensure they don’t go to sleep: /usr/bin/caffeinate
  • Utilize Yo for your bootstrap status. You can use persistent notifications.
  • Utilize Outset to run scripts in the user context.
  • Create a munki dep manifest that installs only the absolute minimum amount of tooling you need. Instead of using munki’s bootstrapping method, call munki with the –id flag. /usr/local/munki/managedsoftwareupdate --id dep. If utilizing this approach, don’t bother pre-installing the munki icons.
  • Managed Software will not automatically looks for updates when a munki run has recently ran. You can force this to happen by removing the LastCheckDate value from /Library/Preferences/Managed Installs.plist.
  • You can speed up the next munki run by triggering a quiet run /usr/local/munki/managedsoftwareupdate --checkonly --quiet.

Things to keep in mind:

  • A distribution package with multiple flat packages will perform all operations in order. All preinstall scripts will run first, followed by the files being installed, and finally all postinstall scripts will run. If you have any dependencies between the packages, they may fail or you will have unintended side effects. If you need to utilize pre/postinstall scripts, be cautious and test often.
  • If you use chef to manage your launch agents/launch daemons, make sure that you do this after munki has finished running or before, but never during. Killing these daemons will break a munki run.
  • If you need to enforce FileVault encryption, you will more than likely need to have your users reboot 1-2 times. Handle this outside of your dep bootstrapping process to lower the chances of race conditions.

  • Have fun. This is new territory and there won’t be much documentation until more people start using this methodology.

Table Of Contents