Deploy a service

As with other deployment tasks, do the setup tasks before (and the cleanup tasks after) the steps below. If you run into trouble, read the Troubleshoot guide.

1. Run Salt function

To deploy a service, indicate the desired target and the state.apply function, for example:

./ 'docs' state.apply

To limit the output to changes and failures, add a --state-output=changes option, for example:

./ --state-output=changes option 'docs' state.apply

To run a specific state file, run, for example:

./ 'docs' state.sls elasticsearch

To run a specific SLS ID, run, for example:

./ '*' state.sls_id root_authorized_keys core.sshd

If the output has an error of Unable to detect Python-2 version, you don’t have Python 2.7 in your PATH. To fix this, if you use pyenv, run, for example:

pyenv shell system

The state.apply function often completes within one minute. You can ignore this warning: DeprecationWarning: encoding is deprecated, Use raw=False instead.


If you want to check whether a deployment is simply slow (frequent) or actually stalled (rare), watch Salt’s activity.

2. Check Salt output

Look for these lines at the end of the output in the primary terminal:

Summary for docs
Succeeded: ## (changed=#)
Failed:     0


  1. Check that the app is still responding in your web browser.
  2. If there are any failed states, look for each in the output (red text) (or search for Result: False) and debug.
  3. If there are any changed states, look for each in the output (blue text) (or grep for Changes:   \n[^\n-]) and verify the changes.

Common changed states are:

Function: service.running, ID: apache2
Apache was reloaded

For a Django app, common changed states are:

Function: git.latest
A new commit was deployed
Function:, Name: . .ve/bin/activate; pip-sync -q –pip-args “–exists-action w”
Requirements were installed
Function:, Name: . .ve/bin/activate; python migrate –settings … –noinput
Django migrations were applied
Function:, Name: . .ve/bin/activate; python collectstatic –settings … –noinput
Static files were collected
Function:, Name: . .ve/bin/activate; python compilemessages –settings … –
Message catalogs were compiled
Function: service.running, ID: uwsgi
uWSGI was reloaded

States that always report changes:

  •, unless onchanges is specified
  • pip.installed, if upgrade is set
  • postgres_privileges.present, if object_name is ALL

3. Manual cleanup

If you changed the server name of a virtual host that uses HTTPS, you will need to Acquire SSL certificates for the new server name.

If you removed a Salt configuration, follow the linked steps to cleanup manually.