How to deploy applications (in .tar.gz) with Puppet?

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.


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).