11

I'm a beginner with Puppet and I would like to know if I'm on the right way to deploy applications with Puppet.

The applciations are in a tar.gz file which contains a file with the version number. So, I do this to deploy (I go on the server and do a client restart to pick up the new tarball):

nodes.pp

node 'server1.domain.com' inherits basenode {
    apps { apps:
            version => 56,
            apps_name => "apps_tarball.tgz",
    }


init.pp (modules)

exec {"apps_wget":
            command => "/usr/bin/wget http://web_server/${version}-${apps_name} -O /tmp/${container_zip_name}",
            unless  => "test -f /tmp/${version}-${apps_name}",
            require => [ Package["wget"] ],
    }

exec {"apps_unzip":
            cwd     => "/usr/local/apps/path",
            command => "/usr/bin/unzip /tmp/${version}-${apps_name}",
            unless  => "test -f /usr/local/apps/path/apps-version-${version}",
            require => [ Package["unzip"], Exec["container_wget"] ],
    }

But, when I want to upgrade, I don't know to say Puppet to delete the old directory? For example, If I want to upgrade version 56 to 57: I must delete the 56's version directory.

I heard about Capristrano and it seems to be better to use Puppet for managinig packages, config files and using Capristrano to deploy apps, isn't it?

Thanks.

1
  • I use the module forge.puppetlabs.com to manage downloading/decompressing/placing things which are only available as tarballs. It works great.
    – jrjohnson
    Commented Feb 24, 2014 at 18:02

5 Answers 5

0

I would like to know if I'm on the right way to deploy applications with Puppet.

No, you are not.

You should use the package management available on your operating system. If your software is in tar.gz format, you should re-package it locally as .deb, .rpm or whatever.

If the software is something developed locally, you should use whatever build/deploy tools are available for it.

3
  • 11
    In a perfect world, admins will take the time to create packages from tarballs. In the real world, my experience has shown this does not happen. Our clients install many applications, sometimes very large applications, from tarballs and have no intention of changing this.
    – EmmEff
    Commented Jan 14, 2015 at 18:34
  • 5
    @EmmEff That's not a difference between perfect world and real world. That's a difference between "We are stuck to old ways and not ready for automatic configuration management" places and places where configuration management does work. I have seen both -- and even seen the latter turn into the former with a change of admins. Commented Jan 23, 2015 at 3:54
  • 5
    You have the right to your opinion. My observations in the real world are different than that.
    – EmmEff
    Commented Feb 4, 2015 at 15:12
13

You might want to try using fpm to make RPMs or DEBs of your tarballs; it's really simple to use, and you don't have to understand anything about the package formats you don't want to.

To answer your original question, the right way to deploy applications with Puppet is to make Puppet do as little work as possible; any complicated exec resources that download and extract tarballs are bound to be very, very brittle, and making Puppet just yum install a package is much healthier long-run.

2
  • I knew what I was doing was so very wrong. But rpm building has always scared me away. fpm is my salvation. Thank you Handyman5. f-yeah.
    – 8None1
    Commented Jan 7, 2014 at 4:50
  • 1
    great comment. Rather than preaching "use rpm" you provided a simple "use a fake rpm and use this simple tool to achieve it". Commented Mar 28, 2017 at 9:48
6

I would try very hard to bundle up the app as an RPM or .deb package and build a yum or apt repository to hold the packages. The packaging up of a tarball or zip that you're just opening up into a directory is pretty easy (but should be a separate question). The packaging available that way tracks versions nicely and handles all sorts of things that just opening up a tarball won't handle well.

If I really really couldn't build a proper package I would do something like this:

nodes.pp:

node 'server1.domain.com' inherits basenode {
    apps { apps:
            version    => 56,
            oldversion => 55,
            apps_name  => "apps_tarball.tgz",
    }

init.pp (modules):

file {
   [ "/usr/local/apps/path/apps-version-${oldversion}", "/tmp/${oldversion}-${apps_name}" ]:
            recurse => true,
            ensure  => absent;
}
exec {
      "apps_wget_${apps_name}":
            command   => "/usr/bin/wget http://web_server/${version}-${apps_name} -O /tmp/${container_zip_name}",
            logoutput => on_failure,
            creates   => "/tmp/${version}-${apps_name}",
            require   => [ Package["wget"] ];

      "apps_unzip_${apps_name}":
            cwd     => "/usr/local/apps/path",
            command => "/usr/bin/unzip /tmp/${version}-${apps_name}",
            creates => "/usr/local/apps/path/apps-version-${version}",
            require => [ Package["unzip"], Exec["container_wget"], Exec["apps_wget_${apps_name}] ];
}

Another alternative is to simply use a recursive puppet resource like:

file {
    "/usr/local/apps/path/":
      source => "puppet:///modules/modulename/apps/path",
      ensure => directory,
      replace => true,
      purge   => true,
      recurse => true;
}

(where you've already untarred things correctly on the puppet master. Probably also require whatever package is running the service and notify whatever service it's running out of).

0
file { "/usr/local/apps/path/apps-version-${old-version}":
    ensure => absent
}

As an aside, doing everything as execs is kinda ugly, and can be hard to troubleshoot when things start breaking; if you can, maybe keep extracted versions of the app files on the puppet server, and use a recursive file resource to retrieve?

0

I certainly favor packaging the tarball (RPM or whatever), but a few hints:

To delete the old version you can simply delete all versions but the one you are installing. With a recent enough bash and extglob enabled you can rm -r /usr/local/apps/path/apps-version-!(${version}). Beware of wiping out config files and such. You can make the exec refreshonly => true and then notify it from the installation exec.

You can use the creates attribute instead of unless => 'test -f ...'. A but more understandable.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .