Wednesday, August 27, 2014

Multisite with SaltStack

You have a site being deployed by SaltStack but you need to add multisiteness to it. This can mean you need to run multiple uwsgi instances (one per domain) which run wsgi app with different settings, have multiple nginx configurations, different users (one per domain) etc, etc. The problem is you cannot simply include nginx or uwsgi formula twice with different parameters just because salt doesn't support it. One has following options:
  1. Use loops in jinja templates. But every formula needs to support it, pillar data is complicated is this case
  2. Use multiple salt-minion instances (one per domain), see minionswarm.py on how to implement this. Most appealing if you need to setup on one node unrelated components, for instance, web service and database, minion in this case corresponds to the component but not to the node
  3. Use grains in pillar templates to change pillar data according to grains data, see Role-based infrastructure. Best for multisites because they differ a little
Pillar data example:
{% set site_id = grains['site_id'] %}

username: XXX
site_id: {{ site_id }}

django:
  git_url: git@XXX.git
  settings: settings_{{ site_id }}
  chdir: /home/XXX/XXX
  media_root: /home/XXX/uploads

nginx:
  server_name: {{ site_id }}.com
  media_root: /home/XXX/uploads
  media_location: /uploads

uwsgi:
  chdir: /home/XXX/XXX
  env: DJANGO_SETTINGS_MODULE=settings_{{ site_id }}
  harakiri: 90
  pythonpath: /home/XXX/XXX
And salt states doesn't change. From jenkins one can run
salt XXX grains.setval site_id site1
salt XXX state.highstate pillar="{git_rev: '$GIT_COMMIT'}"
salt XXX grains.setval site_id site2
salt XXX state.highstate pillar="{git_rev: '$GIT_COMMIT'}"
salt XXX file.blockreplace /home/XXX/static/version.txt "#-- jenkins info below this line ---" "#-- jenkins info above this line ---" "BUILD_NUMBER $BUILD_NUMBER BUILD_ID $BUILD_ID" True

No comments:

Post a Comment