Search code examples
salt-project

Configuring Salt SLS files for multiple OS and versions


I'm trying to learn Salt and want to set up a deployment mechanism for new VMs.

Currently each VM will have a hostname based on the software and version I wat to install, so:

  • app-101-1 - Will be an Ubuntu VM with the app software, ver 1.0.1, installed from a local rpm.
  • app-101-2 - Will be a CentOS VM the same app software and version but a different rpm because it's a CentOS machine.
  • dev-231-1 - Will have the dev software, ver 2.3.1, installed from a different local rpm.

You get the idea.

These RPMs will differ based on application, app version, O/S type and O/S revision:

  • app-1.0.1-rhel-6-x86_64.tar.gz
  • app-1.0.1-ubuntu-14-x86_64.tar.gz
  • app-1.0.2-rhel-6-x86_64.tar.gz
  • dev-3.2.1-rhel-7-x86_64.tar.gz

I would like the Salt config to be as simple as possible, but ideally I don't want to have a separate SLS file each RPM. So far I have my top.sls as:

base:
  'host:app-101*':
    - match: grain
    - app-101

This works, it matches VMs who's names start with "app-101".

I also have an app-101.sls file that looks like:

app:
  'G@os:CentOS and G@osrelease:6.*':
    - match: compound

  file.managed:
    - name: /home/user/app-1.0.1-rhel-6-x86_64.tar.gz
    - source: salt://sw/app-1.0.1-rhel-6-x86_64.tar.gz

  cmd.run:
    - name: "tar xvzf /home/user/app-1.0.1-rhel-6-x86_64.tar.gz; rpm -ivh /home/user/app-101/*rpm"
    - creates: /usr/local/sbin/app

The compound statement doesn't work at all although the file.managed and cmd.run parts do copy the tar ball to the VM and install the RPMs extracted from it, so any comments on that would be appreciated, especially around what is wrong with the compound statement .

However, is there a nicer way to do this? I would expect to be able to have a single SLS file for each app, or at least for each app+version, that can distinguish between the OS name and version and upload/install the right files. Compound statements seem to be the obvious way to go but I can't get them to work, and if I can I still don't see how I can have multiple sets of files in a single SLS file, but maybe I am missing the point here.


Solution

  • Thanks to @nbari for pointing me in the right direction. The problem (it turns out) was how to create and use Jinja(?) variables in SLS files. I ended up with this, which does the job nicely:

    $ cat app-101.sls
    {% set apvar = salt['grains.filter_by'] ( {
      'Debian': {'osver': 'ubuntu-14.04', 'pkgend': 'deb', 'pkginst': 'dpkg -i'},
      'RedHat': {'osver': 'rhel-6', 'pkgend': 'rpm', 'pkginst': 'rpm -ivh'},
    }, default = 'RedHat') %}
    
    app:
      file.managed:
        - name: /home/user/app-1.0.1-{{ apvar.osver }}-x86_64.tar.gz
        - source: salt://sw/app-1.0.1-{{ apvar.osver }}-x86_64.tar.gz
    
      cmd.run:
        - name: "cd /home/user; tar xvzf /home/user/app-1.0.1-{{ apvar.osver }}-x86_64.tar.gz; {{apvar.pkginst }} /home/user/app-101/*.{{ apvar.pkgend }}"
        - creates: /usr/local/sbin/app
    

    There are still faults with this, like: - The assumption that you can install multiple software bundles with one command (rpm -i *rpm or dpkg -i *deb) - The expectation that after untarring the bundle, the packages will be in a specific subdir.

    However this works for me, for now, and hopefully will help others.

    I should note that I have not yet been able to try this out on a Debian server since my Debian minion software is not working correctly, but the outpu from the RedHat suggests that it will work OK.