5

I heard that puppet need to be installed on server side, not just desktop side, from where we want to launch commands on the servers.

My question: Are there any other methods for using puppet? I mean we don't want to install it on server side, just run scripts from our Desktop on the servers..

  • Puppet is designed to operate fromthe host it is installed. What you are looking for is a different tool. – Spack May 14 '14 at 8:57
  • 1
    If you're worried about massive deployment of Puppet clients to your different nodes, you can always set up passwordless ssh via public keys and have a server-side script loop over your client nodes installing the Puppet client on each. – Joseph R. May 16 '14 at 16:45
  • Can you expand what you're looking for a bit? We want to help but it's not entirely clear what you're aiming for here. For example what in your minds qualifies as "touching a server"? – slm May 16 '14 at 17:52
  • how about adopting a masterless puppet and hosting the puppet binary in shared file system as NFS. you could also host your manifests and data (e.g. hieradata) in the shared file system, and/or still use a version control system for them. – Hend Aug 28 '14 at 23:47
7

You can use puppet in a master-less mode, but your servers will still need to have the puppet client installed. Details on setting this up are discussed in this blog post titled: Scaling Puppet with Git.

The article shows how you can go about setting up a Git repo to maintain your Puppet manifest files (.pp) and then just run Puppet manually to apply them.

Example

package { "screen":
  ensure => installed,
}

Simply save this as something.pp and run it with Puppet:

$ sudo puppet -v something.pp 
info: Applying configuration version '1264090058'
notice: //Package[screen]/ensure: created

But this method is still very much in line with the client/server model that you'd typically see with a Puppet deployment.

There's also this thread from the puppet-users mailing list titled: Re: [Puppet Users] Master-less : What do I lose? which may shed light on some other options. I also found this blog post titled: Puppet Without Masters which also discusses options for doing what you're looking for.

I'd also direct you to this post titled: Configuration management: push vs. pull which discusses the differences in the approaches when doing configuration management. Puppet is strictly speaking a pull solution, so what you're proposing will be difficult using it, since what you're looking for sounds more like a push solution from your desktops to your servers.

There are other solutions if you truly want to go with a push methodology but that's beyond the scope of your question.

1

I will detail my comment here, with my actual suggestion.

My main assumption is that you don't want to install Puppet on the client nodes because of their sheer number. If you can't "touch them" because of a permissions issue, then I doubt you can push configuration at all, whether via Puppet or any other method.

You can configure ssh to log in to a machine without a password using ssh-keygen like so:

[user@host]$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again: 
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:
xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx user@host
The key's randomart image is:
+--[ RSA 2048]----+
|          E++.+. |
|           -./ . |
|      .     = o  |
|       o   o     |
|        X +      |
|       . $ +     |
|          0 .    |
|        . .S     |
|       ..cb..    |
+-----------------+

Make sure to leave the passphrase empty (so the script using this ssh will need no password).

As a second step, you need to copy the public key to all of the hosts:

while IFS= read -r host; do
    ssh-copy-id -i ~/.ssh/id_rsa.pub "$host"
done < hostnames_file

where I assume hostnames_file has one host name per line listing all the hosts you want to configure.

This script will most likely ask for your password as many times as there are hosts but this will happen only once when you're setting up the keys.

If your user happens to have their home directory shared among all clients (via NFS for example), you can instead do this:

cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

Now you should set up passwordless sudo access to the apt-get command (or yum or pacman or whatever package manager you choose) for the user you have just configured passwordless ssh for. Now it's as simple as:

while IFS= read -r host;do
    ssh "$host" 'sudo apt-get install puppet' # also, modify puppet.conf
end < hostnames_file

Note that you can use this method as a rudimentary form of configuration management as well*, but it's much more fragile than using Puppet or Chef or similar.

References


(*) Just replace sudo apt-get install puppet with whatever command(s) you wish to run on all your nodes.

1

The typical puppet model consists of a puppet master and the puppet clients. That said, it is possible to skip the puppet master completely and just use the puppet clients by themselves. (Called masterless puppet modules).

To do this, you wrap the puppet apply command in a bash script.

Here is a simple example of a masterless puppet manifest which compiles the latest version of redis from source, then creates an RPM.

https://github.com/spuder/fpm-redis


Here is a more complex example we use at my company called builder. You can watch the presentation about it here:

https://www.youtube.com/watch?v=EFByexKKkIE

Builder is just a script that any developer can apply on any VM which will automatically install a product suite via puppet. It is closed source, but I will try my best to explain the basic architecture.

It is written so that when the developer executes builder, they are prompted for which version and edition of the software they want to install.

$ sudo ./builder.sh
"Welcome to Builder"

1) Enterprise
2) Basic
3) Quit
Please select an edition: 1

"You have selected: Enterprise"

1) 7.5.0
2) 7.6.0
3) 7.7.0
4) 7.8.0
5) Quit
Please select a release: 2

"You have selected 7.6.0, applying manifests"

One of the advantages of wrapping your puppet manifest in a bash script like this, is that you can simply write your own facter variables which can later be used. Looking at the simple example from github/spuder/fpm-redis :

Prepend the variables with an upper case 'FACTER'

cat fpm-redis
#!/bin/bash
export FACTER_REDIS_VERSION='2.8.8'
puppet apply ./manifests/init.pp

The puppet manifest can then refer to the lowercase variable (the word 'FACTER_' is stripped off automatically).

cat ./manifests/init.pp

class foo {
  file { "${::redis_version}":
      ensure => file,
      content => 'foo'
  }
}
include foo

Going back at the builder code, it is modularized so that there is a directory for each product that needs to be installed. This way you can define property files.

$ tree /tmp/builder
|
build
    \_ Enterprise.prop
    \_ Basic.prop
|
packages
    \_ java_7
      \_ manifests
                 \_ init.pp

    \_ java_6
      \_ manifests
                 \_ init.pp
    \_ foo
      \_ manifests
                 \_ init.pp
|
builder.sh

The property files are just bash script that contain environment variables, and also a list of puppet manifests to apply. Sometimes packages need to be installed in a particular order, so they are divided into pre and post operations.

$ cat Enterprise.prop

    PRE_APPLY_LIST= "build/java_6/manifests/init.pp \
                     build/foo/manifests/init.pp"
    POST_APPLY_LIST= "build/foobar/manifests/init.pp"
    export FACTER_FOO='bar'
    export FACTER_DB_PASSWORD='correct horse battery staple'

$ cat Basic.prop

    PRE_APPLY_LIST= "build/java_7"
    export FACTER_HERP='derp'

Going back to the menu prompt mentioned earlier. Builder generated the list of menu options by iterating over the build directory.

$ cat /tmp/builder.sh

# prompt the user for which product
OPTIONS=`ls build/*.prop`
for opt in $OPTIONS
do
  PP_APPLY=$opt
  break
done

# import the variables from the property file
source $PP_APPLY

# install the desired packages
puppet apply $PRE_APPLY_LIST
puppet apply $POST_APPLY_LIST

This is a great way to leverage the advantages of puppet, without needing a puppet master.

  • If I am not completely misunderstanding the question, the OP already has a Puppet master and would like to push manifests on nodes that don't have a Puppet agent installed. – Joseph R. May 17 '14 at 14:39
  • @JosephR. The phrase "we don't want to install it on server side" lead me to believe that they already have puppet on their desktops, and don't want to setup a puppet master. – spuder May 17 '14 at 17:00
  • and "we want to launch commands on the servers" leads me to think that these boxes, otherwise used as servers, are actually the clients in this scenario. – Joseph R. May 17 '14 at 18:24
1

It seems that you are looking for a Configuration Management (CM) or Deployment Management (DM) tool for which you don't have to install agent software in remote machines that you want to manage.

Without an agent model, another method must be used to access remote machines, and this is usually SSH, with public key or password authentication.

For this purpose, there are some candidates you can try:

Ansible

Ansible uses SSH, no agent required, the configuration files are in INI format. Ansible itself is written in Python.

(R)?ex

(R)?ex uses SSH, no agent required, configuration file can be written in plain Perl, in INI format, or using template like YAML or Template::ToolKit. (R)?ex itself is written in Perl.

Fabric

Fabric uses SSH, no agent required, configuration files are written in pure Python. Fabric itself is written in Python.

Salt Stack

Salt Stack is another awesome tool, you can use salt-ssh to deploy without requiring an agent, although salt-minion is also available. Configuration is mostly written in YAML. Salt itself is written in Python.


A simple demo in my machine, using (R)?ex:

$ rex -H localhost uptime
[2014-05-17 00:46:03] INFO - Running task uptime on localhost
[2014-05-17 00:46:03] INFO - Connecting to localhost:22 (cuonglm)
[2014-05-17 00:46:03] INFO - Connected to localhost, trying to authenticate.
[2014-05-17 00:46:04] INFO - Successfully authenticated on localhost.
gnouc
 00:46:04 up  2:35,  4 users,  load average: 0.68, 0.59, 0.56
[2014-05-17 00:46:04] INFO - Exiting Rex...
[2014-05-17 00:46:04] INFO - Cleaning up...

SSH only

Once you have SSH set up, you can also perform the same functions without these tools, by using ssh directly:

$ ssh localhost 'echo $HOSTNAME; uptime'
gnouc
 00:51:29 up  2:41,  4 users,  load average: 0.17, 0.33, 0.45
0

Puppet is designed to manage packages, files, and services. (Called the trifecta). If you want to manage these things without a puppet master, you could use one of the following applications.


kafo

A ruby gem that takes yaml config files and generates a directory structure and puppet manifests to install any application.

https://github.com/theforeman/kafo

It was created by the makers of the forman. It is how they generated their installer.


fpm

fpm is the best way to quickly create rpm's and deb packages. It can also create stand alone (masterless) puppet manifests. At the time of this writing, it is still experimental.

You didn't specify exactly what type of scripts you are trying to run. If you are managing a package, file, or service, then you likely would have good luck creating applications with kafo.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.