RunDeck User Manual | Version 1.4.0.2

1 Introduction

1.1 What is this guide about?

Welcome to the RunDeck user guide. This guide was written to help administrators quickly become productive with the RunDeck server and tools.

1.2 What is RunDeck?

RunDeck is open source software that helps you automate ad-hoc and routine procedures in data center or cloud environments. RunDeck provides a number of features that will alleviate time-consuming grunt work and make it easy for you to scale up your scripting efforts.

RunDeck allows you to run tasks on any number of nodes from a web-based or command-line interface. RunDeck also includes other features that make it easy to scale up your scripting efforts including: access control, workflow building, scheduling, logging, and integration with external sources for node and option data.

Already itching to install it? Jump ahead to Installing RunDeck.

1.2.1 Who makes the RunDeck software?

RunDeck is developed on GitHub as a project called dtolabs/rundeck. Many ideas for RunDeck come from DTO Solutions consultants working in the field, however all are welcome to join the project and contribute.

RunDeck is free software and is public under the Apache Software License.

1.3 Getting help

1.4 RunDeck from 30,000 feet

1.4.1 RunDeck features

  • distributed command execution
  • pluggable execution system uses SSH by default
  • multi-step workflows
  • job definition and on demand or scheduled runs
  • graphical console for command and job execution
  • role-based access control policy with support for LDAP/ActiveDirectory
  • history and auditing logs
  • open integration to external host inventory tools
  • command line interface
  • Web API

1.4.2 RunDeck in context

RunDeck is meant to compliment the tools you already use (including frameworks like Puppet, Chef, and Rightscale) and is geared towards helping you automate actions across them. If you currently manage your servers by running commands from the terminal or through scripts that SSH commands in a loop, RunDeck is a more user friendly alternative. Instead of managing node lists in a spreadsheet or wiki page and then having to transcribe the list to where you execute commands, RunDeck acts as a command and control portal that lets you execute commands using features like node filtering and parallel execution.

RunDeck also works well for managing virtual servers, be they from a cloud provider or from locally hosted virtualization software. The node abstraction enabled by the RunDeck command dispatcher helps you cope with managing dynamic environments.

Many automation tasks cross the boundaries of tool sets. For example, deploying software or maintaining an application often involves using tools up and down the management tool chain. RunDeck has a simple to use interface to create multi-step workflows that might call a package manager, configuration management tool, system utilities, or your own scripts. RunDeck is really meant to help glue tools together and in return enable a push button interface you can hand off to others.

1.4.3 RunDeck architecture

RunDeck is a server application you host on a system you designate a central administrative control point. Internally, RunDeck stores job definitions and execution history in a relational database. Output from command and job executions is saved on disk.

RunDeck distributed command execution is performed using SSH. SSH connections are made using key-based authentication. RunDeck server configuration includes settings to define the outbound user allowed by the remote hosts. Remote machines are not required to make SSH connections back to the server.

RunDeck architecture

RunDeck architecture

The RunDeck application itself is a Java-based webapp that runs in its own embedded servlet container. The application provides both graphical interface and network interfaces used by the RunDeck shell tools.

Access to the RunDeck application requires a login and password. The default RunDeck installation uses a flat file user directory containing a set of default logins. Logins are defined in terms of a username and password as well as one or more user groups. An alternative configuration to the flat file user directory, is LDAP (e.g., ActiveDirectory). Users must also be authorized to perform actions like command and job execution. This is controlled by an access control facility that reads policy files defined by the RunDeck administrator. Privilege is granted if a user's group membership meets the requirements of the policy.

Two installation methods are supported:

  • RPM: The RPM is intended for managed installation and provides robust tools that integrate with your environment, man pages, shell tool set in your path, init.d startup and shutdown

  • Launcher: The launcher is intended for quick setup, to get you running right away. Perfect for bootstrapping a project or trying a new feature.

1.5 Feedback

If you find problems with RunDeck, or if you have questions, remarks, or ideas about it, please send an email to the RunDeck mailing list, .

1.6 What's next?

The remainder of the guide will give you a quick conceptual overview, and take you through installation and setup. After you are set up, you will learn about the distributed command dispatcher and how to use it to run ad-hoc commands. From there, you will learn about Jobs, defining multi-step procedures with Job workflows and how to parameterize them with options.

2 Getting Started

This chapter helps new users getting started with RunDeck. We will begin by explaining the basics, covering essential RunDeck concepts and terminology and then move on to installation and finally, setup. At the end of this chapter you should understand what RunDeck is, how you should use it and you should be all setup to do so.

2.1 RunDeck Basics

Several fundamental concepts underly and drive the development of the RunDeck system. If you are a new user, knowing about them will help you use and integrate RunDeck into your environment.

2.1.1 Command dispatching

RunDeck supports a notion called command dispatching wherein a user specifies dispatch criteria along with an action (called a command) and this specification is used to perform a distributed execution.

The command dispatcher is an internal mechanism that looks up node resources meeting specified filtering criteria and then performs the distributed command execution. The command executes in a data context that contains information about the Node resource. Besides node filtering, dispatcher options include parameters to control parallel execution, ordering and error handling.

The command dispatcher supports two methods of command execution:

  • Ad-hoc commands: Execute any shell command or shell script across a set of hosts.
  • Jobs: Encapsulate commands as a named Job and tie them together into multi-step workflows.

RunDeck provides both graphical and command line interfaces to interact with the command dispatcher.

You can also use the Web API to interface with all aspects of the command dispatcher. (See the RunDeck API.)

2.1.2 Resource model

The command dispatcher works in conjunction with a resource model. A resource model is a representation of hosts deployed in your network. A Node is a resource that is either a physical or virtual instance of a network accessible host.

Nodes have a number of basic properties but these properties can be extended to include arbitrary named key value pairs.

You can configure RunDeck to retrieve and store resource model data from multiple sources, and RunDeck defines several resource model document formats to facilitate the transfer of this information.

Resource Model data sources can be local files on disk, or remotely accessible services. A URL resource model source is an external service accessible via the HTTP GET method that returns data in one of the supported resource document formats.

RunDeck currently supports XML and YAML document formats. See Resource Model Document formats).

Each project can be configured to have multiple sources of Resource Model data. See Resource Model Sources.

2.1.3 Authorization

RunDeck enforces an access control policy that grants certain privileges to groups of users. Every action executed through the RunDeck command dispatcher must meet the requirements of an access control policy definition.

Since RunDeck respects the policy definition, you can define role-based authorization to restrict some users to only a subset of actions. This enables a self-service type interface, where some users have access to only a limited set of executable actions.

See: Authorization.

2.1.4 Project

A project is a place to separate management activity. All RunDeck activities occur within the context of a project. Each project has its own resource model and Job store.

Multiple projects can be maintained on the same RunDeck server. Projects are independent from one another, so you can use them to organize unrelated systems within a single RunDeck installation. This can be useful for managing different infrastructures.

2.2 Installing RunDeck

Assuming the system requirements are met, RunDeck can be installed either from source, system package or via the launcher.

2.2.1 System Requirements

The following operating systems are known to support RunDeck:

  • Linux: Most recent distributions are likely to work
  • Windows: XP, Server and above
  • Mac OS X 10.4 or later

Root (or Administrator on Windows) is not required or recommended. We recommend using a dedicated user account such as "rundeck".

If there is need for root access, please set up the RunDeck user to have access via sudo.

2.2.1.1 Java

RunDeck is a Java-Servlet based server and therefore requires the Java runtime.

The install process requires that the latest version of Java 1.6 be installed. Both the Open JDK and Sun/Oracle JVMs can be used. You must have the JAVA_HOME environment variable defined in your environment before running the launcher. The RPM will use the java found on your path. See Setting JAVA_HOME if you want to run a different version of java.

Verify your Java version to check it meets the requirement:

$ java -version
java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04-307-10M3261)
Java HotSpot(TM) 64-Bit Server VM (build 17.1-b03-307, mixed mode)

2.2.1.2 Network access

When the server starts, it binds to several TCP ports by default:

  • 4440 (http)
  • 4443 (https)

To check if the ports are free on a Unix host, run:

netstat -an | egrep '4440|4443' 

If the ports are in use on the server, you will see output similar to below:

tcp46      0      0  *.4440                 *.*                    LISTEN

The installation procedures describe how to choose different ports, if there is a conflict.

In addition, TCP port 22 (by default) needs to be open on the clients for SSH.

Clients should be set up to allow the RunDeck server user to connect to the clients using SSH via public-key authentication. It should not prompt for a password. See Configure remote machine for SSH in the Administration chapter.

There are various ways for installing SSH on Windows; we recommend Cygwin.

2.2.2 Installing from Source

Checkout the sources from GitHub

You can build either the launcher jar (self-running archive), or a RPM.

make

Creates the rundeck-launcher.jar

Build the RPM:

make rpm

To build clean:

make clean

Documentation can be built using: make clean docs. Documentation build requires pandoc. The RPM build depends on the the documentation as well.

2.2.3 Installing with RPM

If you want to install RunDeck on Linux via a binary installer, you can generally do so through the RPM tool that comes with your distribution.

# rpm -i rundeck-1.1.0.noarch.rpm

To install it using yum, first install the yum repo package and then run yum install:

# rpm -Uvh http://rundeck.org/latest.rpm
# yum install rundeck

2.2.4 Installing with Launcher

Use the launcher as an alternative to a system package:

  1. Download the launcher jar file.
  2. Define RDECK_BASE environment variable to the location of the install

    export RDECK_BASE=$HOME/rundeck; # or where you like it
    
  3. Create the directory for the installation.

    mkdir -p $RDECK_BASE 
    
  4. Copy the launcher jar to the installation directory.

    cp rundeck-launcher-1.1.0.jar $RDECK_BASE
    
  5. Change directory and run the jar.

    cd $RDECK_BASE    
    java -jar rundeck-launcher-1.1.0.jar
    
  6. Wait for the Started message.

    2010-11-19 13:35:51.127::INFO:  Started SocketConnector@0.0.0.0:4440
    
  7. Update your shell environment

    PATH=$PATH:$RDECK_BASE/tools/bin
    MANPATH=$MANPATH:$RDECK_BASE/docs/man
    

If you get an error message that resembles the one below, you probably are using an unsupported Java version.

Exception in thread "main" java.lang.UnsupportedClassVersionError: Bad version number in .class file

See the startup and shutdown section for instructions on using the rundeckd shell tool to manage the rundeck launcher process.

2.2.4.1 Launcher Options

The launcher jar can take a number of options to specify how the server should start. If you execute with a "-h" you will see the usage information:

java -jar rundeck-launcher-1.3.0.jar -h

usage: java [JAVA_OPTIONS] -jar rundeck-launcher.jar  [-c PATH] [-d]
       [--installonly] [-s PATH] [-b PATH] [-p PATH] [-h] [-x PATH]
       [--skipinstall] [--serverdir PATH] [--datadir PATH]

Run the rundeck server, installing the necessary components if they do not
exist.
    --skipinstall         Skip the extraction of the utilities from the
                          launcher.
    --installonly         Perform installation only and do not start the
                          server.
 -b,--basedir <PATH>      The basedir
 -c,--configdir <PATH>    The location of the configuration.
 -d                       Show debug information
 -h,--help                Display this message.
 -p,--projectdir <PATH>   The location of Rundeck's project data.
 -s,--sbindir <PATH>      The install directory for the tools used by
                          administrators.
 -x,--bindir <PATH>       The install directory for the tools used by
                          users.

These options can be used to customize the directories used by the launcher. By default all the directories are organized by convention within the current working directory where the launcher jar is located.

2.2.4.2 System Properties

You can also customize the launcher behavior by using some java system properties.

Specify these properties using the normal -Dproperty=value commandline options to the java command:

  • server.http.port The HTTP port to use for the server, default "4440"
  • server.https.port The HTTPS port to use or the server, default "4443"
  • server.hostname Hostname to use for the server, default is the system hostname
  • server.web.context Web context path to use, such as "/rundeck". Default is "/".
  • rdeck.base RunDeck Basedir to use, default is the directory containing the launcher jar
  • server.datastore.path Path to server datastore dir
  • default.user.name Username for default user account to create
  • default.user.password Password for default user account to create
  • rundeck.jaaslogin "true/false" - if true, enable JAAS login. If false, use the realm.properties file for login information.
  • loginmodule.name Custom JAAS loginmodule name to use
  • loginmodule.conf.name Name of a custom JAAS config file, located in the server's config dir.
  • rundeck.config.name Name of a custom rundeck config file, located in the server's config dir.
  • rundeck.ssl.config Path to the SSL config properties file to enable SSL. If not set, SSL is not enabled.

For more information about using SSL, see Administration - Configuring Rundeck for SSL

2.3 Upgrading RunDeck

If you are upgrading RunDeck from a previous version, please read the RunDeck Upgrade Guide.

2.4 First-Time Setup

2.4.1 Logins

RunDeck supports a number of user directory configurations. By default, the installation uses a file based directory, but connectivity to LDAP is also available. See Managing logins in the Administration chapter.

The RunDeck installation process will have defined a set of temporary logins useful during the getting started phase.

  • user: Has access to run commands and jobs but unable to modify job definitions. Password: "user"
  • admin: Belongs to the "admin" group and is automatically granted the "admin" and "user" role privileges. Password: "admin"

2.4.2 Group membership

If you installed RunDeck using the RPM installation method, it will have created a unix group called "rundeck".

$ groups rundeck
rundeck : rundeck

It also made several log files writable to members of the "rundeck" group.

$ ls -l /var/log/rundeck/command.log
-rw-rw-r-- 1 rundeck rundeck 588 Dec  2 11:24 /var/log/rundeck/command.log

If you want to use the RunDeck shell tools, be sure to add that group to the necessary user accounts.

RunDeck shell tool users that do not belong to group, rundeck, will get error messages like so:

$ rd-jobs
log4j:ERROR setFile(null,true) call failed. java.io.FileNotFoundException: /var/log/rundeck/command.log (Permission denied)

Consult the usermod command to modify a user account.

2.5 Summary

You should now have a basic understanding of RunDeck. You should also have a working version of RunDeck on your system and login access. It is now time to learn some RunDeck basics.

3 RunDeck Basics

This chapter covers the basics for using RunDeck. The chapter begins by describing the RunDeck user interfaces, both its graphical and command line. From there it will show you how to set up a project and learn about command execution. You will learn more about using the command dispatcher to control execution and finally, how to find and use history.

3.1 RunDeck Interfaces

RunDeck provides two primary user interfaces:

  • An HTML-based graphical console
  • A suite of shell tools

Both interfaces allow you to view resources, dispatch commands, as well as, store and run jobs.

In addition RunDeck provides a Web API which can be used to interact with the server programattically. See RunDeck API.

3.1.1 Graphical Console

To get started, go to the URL for your RunDeck server. Login to the web app with the credentials defined by the RunDeck user directory configuration.

3.1.1.2 Now running

The "Now running" section appears at the top of the Run and Jobs pages and provides a view into the execution queue. Any currently executing ad hoc command or Job will be listed and include information like the name of the job, when it started, who ran it, and a link to the execution output.

Now running

Now running

Jobs that have been run before also have a progress bar approximating duration.

3.1.2 Shell Tools

RunDeck includes a number of shell tools to dispatch commands, load and run Job definitions and interact with the dispatcher queue. These command tools are an alternative to functions accessible in the graphical console.

dispatch
Execute ad hoc commands and scripts
rd-queue
Query the dispatcher for currently running Jobs and possibly kill them
rd-jobs
List defined jobs as well as load them from text file definitions
run
Invoke the execution of a stored Job
rd-project
Setup a new RunDeck project
rd-setup
(Re-)configure an instance of RunDeck

Consult the online manual pages for options and usage information.

3.2 Project Setup

A RunDeck Project provides a space to manage related management activities.

A Project can be set up either from the graphical console or using the rd-project shell tool.

After logging into the graphical console, you will notice a Project menu in the top navigation bar. If no projects exist, you will be prompted to create a new project.

Create project prompt

Create project prompt

To start with, the only field you need to enter is the Project Name. You can change the other values later from the GUI Admin Page.

After entering your project name, RunDeck initializes it and returns you to the "Run" page.

Projects can be created at any time by going back to the Project menu and selecting the "Create a new project..." item.

Create project menu

Create project menu

The rd-project shell tool can also be used to create a project.

On the RunDeck server, execute the rd-project command and specify a project name, here we use "examples":

rd-project -a create -p examples

After running this command, you can login into the graphical console and see the new project in the project menu.

You can also add configuration properties when you create the project, for example:

rd-project -a create -p examples --project.ssh-keypath=/private/ssh.key

The project setup process generates Project configuration in the server, and a bootstrap resource model.

Run page after new project

Run page after new project

One node will be listed, the RunDeck server host. The server host is distinguished with the word "server" in red text.

3.2.1 Resource model

The Resource Model is the set of available Nodes that RunDeck can dispatch commands to, and their associated metadata. Each RunDeck Project has its own Resource Model.

The initial resource model will contain information just about the RunDeck server host and is useful just for running local commands on the RunDeck server. You can browse the project resource model by going to the "Run" page.

In the shell, you can list the Node resources in a resource model using the shell tool, dispatch. Specify project name using the -p project option.

Here the dispatch command lists the registered server for the "examples" project after the project setup. The -v gives a verbose listing that includes more detail:

$ dispatch -p examples -v   
 strongbad:
    hostname: strongbad
    osArch: x86_64
    osFamily: unix
    osName: Mac OS X
    osVersion: 10.6.2
    tags: ''

Node resources have standard properties, such as "hostname" but these can be extended via attributes. One of the more useful properties is the "tags" property. A tag is a text label that you give to the Node, perhaps denoting a classification, a role the node plays in the environment, or group membership. Multiple tags can be defined for a given node.

The output above shows the "strongbad" node currently has an empty tags property: tags: ''.

It is important to start thinking about node tagging for the nodes you manage because you will use them later when specifying filtering options to drive distributed command dispatch.

Each Project has a configuration file called project.properties, located at this path: $RDECK_BASE/projects/project/etc/project.properties.

This configuration file contains two basic properties for accessing and storing resource model data:

  • project.resources.file: A local file path to read a resource model document
  • project.resources.url: URL to an external resource model source (optional)

In addition, multiple pluggable "Resource Model Sources" can be configured for a project to retrieve additional Resource Model content from other sources. See Resource Model Sources.

You can configure RunDeck to retrieve and store resource model data from any source, so long as it can produce one of the RunDeck resource model document formats. (See Resource Model Document formats.) Set the project.resource.url to the URL resource model source of your choice.

Here's the XML document stored for the "examples" project that corresponds to the output printed by the dispatch -v shown earlier:

<project>
    <node name="strongbad" type="Node" 
      description="the RunDeck server host" tags="" 
      hostname="strongbad" 
      osArch="x86_64" osFamily="unix" osName="Mac OS X" osVersion="10.6.2"
      username="alexh" 
      editUrl="" remoteUrl=""/>
</project>

You'll notice the root node is called project and there is a single node descriptor for "strongbad". The node tag has a number of required and optional attributes. Additional node descriptors can be added by defining new node elements inside the project tag.

The strongbad host does not have any tags defined for it. One or more tags can be defined. Use comma for the delimiter (e.g, tags="tag1,tag2").

Here's an example of a node called "homestar" with just the required attributes:

    <node name="homestar" type="Node" 
      hostname="192.168.1.02" 
      username="alexh" />

The hostname and username values are used for the SSH connection while the name and type are used to define Node identity in the resource model. It is possible to overload the hostname value to include port information (eg, hostname="somehost:2022"). This is useful if your run SSH on a different port.

Chances are you maintain information about your hosts within another tool, perhaps Chef, Puppet, Nagios, Amazon EC2, RightScale or even an in-house database. One of these tools might be considered the authority of knowledge about the nodes deployed in your network. Therefore, it is best to create an interface to the authoritative tool and expose it as RunDeck URL resource model source. This can be done as a simple CGI script that does a transformation from the tool's format to the one RunDeck understands.

Of course, a rudimentary alternative is to maintain this information as an XML document, storing it in a source repository that is periodically exported to Rundeck. This method could be practical if your host infrastructure infrequently changes.

Check the RunDeck web site for URL resource model sources. If you are interested in creating your own, see the Resource model source section in the Integration with External Data Providers chapter.

3.2.2 Resource Model Document formats

RunDeck currently has two resource model document formats built in:

You can enable more formats using Resource Format Plugins.

3.3 Pluggable Resource Model Sources

Each project can have multiple sources for Resource model information, and you can use or write plugins to enable new sources for entries in the Resource model.

You can configure the sources via the GUI from the Admin page, see GUI Admin Page, or by modifying the project configuration file, see Resource Model Sources.

3.4 Command Execution

RunDeck supports two modes of execution: ad-hoc commands and Job.

An ad-hoc command is any system command or shell script executed via the command dispatcher. Ad hoc commands can be executed via a command line utility named dispatch or run from the graphical console.

A Job specifies a sequence of one or more command invocations that can be run once (i.e, is temporary) or named and stored for later use. Stored jobs can be started via the shell tool, run, and their progress checked with rd-queue.

3.4.1 Dispatcher options

Dispatcher execution can be controlled by various types of options.

Execution control

Concurrency is controlled by setting the "threadcount". Execution can continue even if some node fails if the "keepgoing" option is set to true.

Node Filters

Filtering options specify include and exclude filters to determine which nodes from the project resource model to distribute commands to.

Filter Keywords

Keywords are used within they include and exclude patterns. The "tags" keyword additionally can use a boolean operator to combine logical ORs and ANDs.

Filter combinations

All keywords can be combined by specifying the include and exclude options multiple times on the command line.

One can experiment querying the resource model in the graphical console or with the dispatch tool.

3.4.1.1 Filtering nodes graphically

A project's Node resources are displayed in the Run page. Use the project menu in the navigation bar to change to the desired project. After choosing a project, the server node will be filtered by default.

Nodes can be filtered using include and exclude patterns by using the Filter form. The form can be opened by pressing the "Filter" button. Press the triangular disclosure icon to display the form.

Resource filter link

Resource filter link

When the form opens, you will see it divided into an Include section where simple include expressions can be set, as well as, an "Extended Filters..." link where exclude expressions can be made.

Resource filter form

Resource filter form

After filling out the filter form, press "Filter" to generate a new listing. Pressing "Clear" resets the form.

The Include and Exclude filters allow for filtering nodes based on the following keywords: Name, Tags, Hostname, OS Name, OS Family, OS Architecture, OS Version and Type.

Regular expressions can be used for any of the keywords. The .* pattern will match any text.

If more than 20 nodes match the filter, the UI will page the results.

3.4.1.2 Filtering nodes in the shell

dispatch uses the commandline options -I (include) and -X (exclude) to specify which nodes to include and exclude from the base set of nodes. You can specify a single value, a list of values, or a regular expression as the argument to these options.

Examples

List nodes with OS name, Linux:

dispatch -p examples -I os-name=Linux

List Linux nodes but exclude ones with names prefixed "web.":

dispatch -p examples -I os-name=Linux -X "web.*"

List nodes that are tagged both "web" and "prod" :

dispatch -p examples -I tags=web+prod

Here's an example that will execute the apachectl restart command in 10 threads across all nodes tagged "web" and keepgoing in case an error occurs :

dispatch -p examples -I tags=web -K -C 10 -- sudo apachectl restart 

Consult the rd-options(1) manual page for the complete reference on available dispatcher options.

3.4.2 Ad-hoc commands

Typically, an ad-hoc command is a shell script or system executable that you run at an interactive terminal. Ad-hoc commands can be executed via the dispatch shell command or a graphical shell.

3.4.2.1 Shell tool command execution

Use dispatch to execute individual commands or shell script files.

Here dispatch is used to run the Unix uptime command to print system status:

$ dispatch -I os-family=unix -- uptime
Succeeded queueing Workflow execution: Workflow:(threadcount:1){ [command( exec: uptime)] }
Queued job ID: 7 <http://strongbad:4440/execution/follow/7>

The uptime command is queued and executed. The output can be followed by going to the URL returned in the output (eg, http://strongbad:4440/execution/follow/7).

Sometimes it is desirable to execute the command directly, and not queue it 1. Use the --noqueue option to execute and follow the output from the console.

$ dispatch -I os-family=unix  --noqueue -- uptime
[ctier@centos54 dispatch][INFO]  10:34:54 up 46 min,  2 users,  load average: 0.00, 0.00, 0.00
[alexh@strongbad dispatch][INFO] 10:34  up 2 days, 18:51, 2 users, load averages: 0.55 0.80 0.75
[examples@ubuntu dispatch][INFO]  10:35:01 up 2 days, 18:40,  2 users,  load average: 0.00, 0.01, 0.00

Notice, the dispatch command prepends the message output with a header that helps understand from where the output originates. The header format includes the login and node where the dispatch execution occurred.

Execute the Unix whomi command to see what user ID is used by that Node to run dispatched commands:

$ dispatch -I os-family=unix --noqueue -- whoami
[ctier@centos54 dispatch][INFO] ctier
[alexh@strongbad dispatch][INFO] alexh
[examples@ubuntu dispatch][INFO] examples

You can see that the resource model defines each Node to use a different login to execute dispatch commands. That feature can be handy when Nodes serve different roles and therefore, use different logins to manage processes. See the username attribute in resource-v13(5) XML or resource-v13(5) YAML manual page.

The dispatch command can also execute shell scripts. Here's a trivial script that generates a bit of system info:

#!/bin/sh
echo "info script"
echo uptime=`uptime`
echo whoami=`whoami`
echo uname=`uname -a`

Use the -s option to specify the "info.sh" script file:

$ dispatch -I os-family=unix -s info.sh

The dispatch command copies the "info.sh" script located on the server to each "unix" Node and then executes it.

3.4.2.2 Graphical command shell execution

The RunDeck graphical console also provides the ability to execute ad-hoc commands to a set of filtered Node resources. The command prompt can accept any ad-hoc command string you might run via an SSH command or via the dispatch shell tool.

But before running any commands, you need to select the project containing the Nodes you wish to dispatch. Use the project menu to select the desired project name. After the project has been selected you will see a long horizontal textfield labeled "Command". This is the RunDeck ad hoc command prompt.

Ad hoc command prompt

Ad hoc command prompt

To use the command prompt, type the desired ad-hoc command string into the textfield and press the "Run" button. The command will be dispatched to all the Node resources currently listed below the command prompt tool bar. The command prompt also becomes disabled until the execution completes. Output from the command execution will be shown below (see output).

Ad hoc execution output

Ad hoc execution output

You will also notice the ad hoc execution listed in the "Now running" part of the page, located above the command prompt. All running executions are listed there. Each running execution is listed, showing the start time, the user running it, and a link to follow execution output on a separate page.

Now running ad hoc command

Now running ad hoc command

At the bottom of the page, you will see a "History" section containing all executions in the selected project for the last 24 hours. After the execution completes, a new event will be added to the history. A yellow highlight indicates when the command leaves the Now running section and enters the history table.

Run history

Run history

History is organized in summary form using a table layout. The "Summary" column shows the command or script executed. The "Node Failure Count" contains the number of nodes where an error in execution occurred. If no errors occurred, "ok" will be displayed. The "User" and "Time" columns show the user that executed the command and when.

3.4.2.2.1 Following execution output

Ad hoc command execution output is displayed below the command prompt.

This page section provides several views to read the output using different formats.

Tail Output

Displays output messages from the command execution as if you were running the Unix tail -f command on the output log file. By default, only the last 20 lines of output is displayed but this can be expanded or reduced by pressing the "-" or "+" buttons. You can also type in an exact number into the textfield. Ad hoc execution output

Annotated

The annotated mode displays the output messages in the order they are received but labels the each line with the Node from which the message originated. Through its additional controls each Node context can be expanded to show the output it produced, or completely collapsed to hide the textual detail.
Annotated output

Compact

Output messages are sorted into Node specific sections and are not interlaced. By default, the messages are collapsed but can be revealed by pressing the disclosure icon to the right. Node output

3.4.2.2.1.1 Separate execution follow page

Sometimes it is useful to have a page where just the execution output is displayed separately. One purpose is to share a link to others interested in following the output messages. Click the "output >>" link in the "Now running" section to go to the execution follow page.

Also, notice the URL in the location bar of your browser. This URL can be shared to others interested in the progress of execution. The URL contains the execution ID (EID) and has a form like:

 http://rundeckserver/execution/follow/{EID}

After execution completes, the command will have a status:

  • Successful: No errors occurred during execution of the command across the filtered Node set
  • Failed: One or more errors occurred. A list of Nodes that incurred an error is displayed. The page will also contain a link "Retry Failed Nodes..." in case you would like to retry the command.

You can download the entire output as a text file from this page. Press the "Download" link to retrieve the file to your desk top.

3.4.3 Controlling command execution

Parallel execution is managed using thread count via "-C" option. The "-C" option specifies the number of execution threads. Here's an example that runs the uptime command across the Linux hosts with two threads:

dispatch -I os-name=Linux -C 2 -- uptime

The keepgoing and retry flags control when to exit incase an error occurs. Use "-K/-R" flags. Here's an example script that checks if the host has port 4440 in the listening state. If it does not, it will exit with code 1.

#!/bin/sh
netstat -an | grep 4440 | grep -q LISTEN
if [ "$?" != 0 ]; then
echo "not listening on 4440"
exit 1;
fi
echo  listening port=4440, host=`hostname`;

Commands or scripts that exit with a non-zero exit code will cause the dispatch to fail unless the keepgoing flag is set.

$ dispatch -I os-family=unix -s /tmp/listening.sh --noqueue
[alexh@strongbad dispatch][INFO] Connecting to centos54:22
[alexh@strongbad dispatch][INFO] done.
[ctier@centos54 dispatch][INFO] not listening on 4440
error: Remote command failed with exit status 1

The script failed on centos54 and caused dispatch to error out immediately.

Running the command again, but this time with the "-K" keepgoing flag will cause dispatch to continue and print on which nodes the script failed:

$ dispatch  --noqueue -K -I tags=web -s /tmp/listening.sh
[alexh@strongbad dispatch][INFO] Connecting to centos54:22
[alexh@strongbad dispatch][INFO] done.
[ctier@centos54 dispatch][INFO] not listening on 4440
[ctier@centos54 dispatch][ERROR] Failed execution for node: centos54: Remote command failed with exit status 1
[alexh@strongbad dispatch][INFO] listening port=4440, host=strongbad
[alexh@strongbad dispatch][INFO] Connecting to 172.16.167.211:22
[alexh@strongbad dispatch][INFO] done.
[examples@ubuntu dispatch][INFO] not listening on 4440
[examples@ubuntu dispatch][ERROR] Failed execution for node: ubuntu: Remote command failed with exit status 1
error: Execution failed on the following 2 nodes: [centos54, ubuntu]
error: Execute this command to retry on the failed nodes:
    dispatch -K -s /tmp/listening.sh -p examples -I
    name=centos54,ubuntu

3.4.4 Queuing commands to RunDeck

By default, commands or scripts executed on the command line by dispatch are queued as temporary jobs in RunDeck. The dispatch command is equivalent to a "Run and Forget" action in the graphical console.

The script below is a long running check that will conduct a check periodically waiting a set time between each pass. The script can be run with or without arguments as the parameters are defaulted inside the script:

$ cat ~/bin/checkagain.sh 
#!/bin/bash
iterations=$1 secs=$2 port=$3
echo "port ${port:=4440} will be checked ${iterations:=30} times waiting ${secs:=5}s between each iteration" 
i=0
while [ $i -lt ${iterations} ]; do
  echo "iteration: #${i}"
  netstat -an | grep $port | grep LISTEN && exit 0
  echo ----
  sleep ${secs}
  i=$(($i+1))
done
echo "Not listening on $port after $i checks" ; exit 1

Running dispatch causes the execution to queue in RunDeck and controlled as temporary Job. The -I centos54 limits execution to just the "centos54" node:

$ dispatch -I centos54 -s ~/bin/checkagain.sh 
Succeeded queueing workflow: Workflow:(threadcount:1){ [command( scriptfile: /Users/alexh/bin/checkagain.sh)] }
Queued job ID: 5 <http://strongbad:4440/execution/follow/4>

To pass arguments to the script pass them after the "--" (double dash):

$ iters=5 secs=60 port=4440
$ dispatch -I centos54 -s ~/bin/checkagain.sh -- $iters $secs $ports

3.4.5 Tracking execution

Queued ad-hoc command and temporary or saved Job executions can be tracked from the "Run" page in the "Now Running" area at the top of the page.

Execution can also be tracked using the rd-queue shell tool.

$ rd-queue -p project
Queue: 1 items
[5] workflow: Workflow:(threadcount:1){[command( scriptfile: /Users/alexh/bin/checkagain.sh)]} <http://strongbad:4440/execution/follow/5>

Each job in the execution queue has an execution ID. The example above shows one item with the ID, 5.

Running jobs can also be killed via rd-queue kill. Specify execution ID using the "-e" option:

$ rd-queue kill -e 5
rd-queue kill: success. [5] Job status: killed

3.4.6 Plugins

RunDeck supports a plugin model for the execution service, which allows you to fully customize the way that a particular Node, Project or your entire RunDeck installation executes commands and scripts remotely (or locally).

By default RunDeck uses an internal plugin to perform execution via SSH for remote nodes, and local execution on the RunDeck server itself.

Plugins can be installed by copying them to the libext directory of your RunDeck installation.

Plugins are used to add new "providers" for particular "services". The services used for command execution on nodes are the "node-executor" and "file-copier" services.

To use a particular plugin, it must be set as the provider for a service by configuring the framework.properties file, the project.properties file, or by adding attributes to Nodes in your project's resources definitions. For more about configuring the providers, see Using Providers.

The internal SSH command execution plugin is described below, and more information about plugins can be found in the RunDeck Plugins chapter.

3.4.6.1 SSH Plugin

RunDeck by default uses SSH to execute commands on remote nodes, SCP to copy scripts to remote nodes, and locally executes commands and scripts for the local (server) node.

The SSH plugin expects each node definition to have the following properties in order to create the SSH connection:

  • hostname: the hostname of the remote node. It can be in the format "hostname:port" to indicate that a non-default port should be used. The default port is 22.
  • username: the username to connect to the remote node.

When a Script is executed on a remote node, it is copied over via SCP first, and then executed. In addition to the SSH connection properties above, these node attributes can be configured for SCP:

  • file-copy-destination-dir: The directory on the remote node to copy the script file to before executing it. The default value is C:/WINDOWS/TEMP/ on Windows nodes, and /tmp for other nodes.
  • osFamily: specify "windows" for windows nodes.

In addition, for both SSH and SCP, you must also have the private key of the public/private keypair for the remote node available on the server. See Configuring SSH Private Keys.

The SSH plugin is used by default for non-local nodes, however you can also configure it explicitly using these provider names:

  • NodeExecutor provider: jsch-ssh
  • FileCopier provider: jsch-scp

The Local plugin is used by default on the local (server) node. You configure the local plugin if necessary with the provider name local.

3.4.6.2 Included Plugins

Two plugin files are included with the default RunDeck installation for your use in testing or development. (See Pre-Installed Plugins)

3.5 History

History for queued ad-hoc commands, as well as, temporary and saved Job executions is stored by the RunDeck server. History data can be filtered and viewed inside the "History" page.

History page

History page

3.5.1 Filtering event history

By default, the History page will list history for the last day's executions. The page contains a filter control that can be used to expand or limit the executions.

The filter form contains a number of fields to limit search:

  • Within: Time range. Choices include 1 day, 1 week, 1 month or other (given a start after/before to ended after/before).
  • Name: Job title name.
  • Project: Project name. This may be set if the project menu was used.
  • User: User initiating action.
  • Summary: Message text.
  • Result: Success or failure status.
History filter form

History filter form

After filling the form pressing the "Filter" button, the page will display events matching the search.

Filters can be saved to a menu that makes repeating searches more convenient. Click the "save this filter..." link to save the filter configuration.

3.5.2 Event view

History for each execution contains the command(s) executed, dispatcher options, success status and a link to a file containing all the output messages.

Event view

Event view

If any errors occurred, the "Node Failure Count" column will show the number of nodes in red text. A bar chart indicates the percent failed.

Event view

Event view

3.6 Tips and Tricks

3.6.1 Saving filters

Each of the filter controls provides the means to save the current filter configuration. Press the "save this filter..." link to give it a name. Each saved filter is added to a menu you can access the next time you want that filter configuration.

3.6.2 Auto-Completion

If you use the Bash shell, RunDeck comes with a nice auto-completion script you can enable. Add this to your .bashrc file:

source $RDECK_BASE/etc/bash_completion.bash

Press the Tab key when you're writing a dispatch command, and it should return a set of suggestions for you to pick from:

$ dispatch <tab><tab>

3.7 Summary

At this point, you can do basic RunDeck operations - setup a project, define and query the project resource model, execute ad-hoc commands, run and save Jobs and view history.

Next, we'll cover one of RunDeck's core features: Jobs.

4 Jobs

In previous sections of this manual, you learned how to execute ad-hoc commands across a filtered set of Node resources. This chapter introduces a fundamental RunDeck feature, Jobs. But first, one might ask why introduce another layer over ad-hoc command execution.

Here are some issues that might arise over time:

Jobs provide a means to encapsulate a procedure in a logically named Job. A Job is a configuration representing the steps in a procedure, a Node filter specification, and dispatcher execution control parameters. Jobs access is governed by an access control policy that describes how users are granted authorization to use Jobs.

RunDeck lets you organize and execute Jobs, and observe the output as the Job is running. You can view a list of the currently running Jobs that is dynamically updated as the Jobs progress. Jobs can also be killed if they need to be stopped.

Each Job has a record of every time it has been executed, and the output from those executions can be viewed.

The next sections describes how to navigate and run existing Jobs. In later sections, the topic of Job creation will be covered.

If you want to skip ahead, you can go straight to Creating Jobs.

4.1 Job groups

As many jobs will accumulate over time, it is useful to organize Jobs into groups. A group is a logical set of jobs, and one job group can exist inside another. RunDeck displays job lists as a set of folders corresponding to the group structure your jobs define.

Beyond organizing jobs, groups assist in defining access control policy, as we'll cover later in the Authorization chapter.

4.2 Job UUIDs

When created, each new job will be assigned a unique UUID. If you are writing the Job definition using one of the supported formats you can assign the UUID yourself.

You can use the UUID to make sure that when you rename or change the group for your job in your job definition, it will modify the correct job in the server.

The UUID is also useful when porting Job definitions between RunDeck instances.

(Note: RunDeck also assigns each Job an internal "ID" value, although this value is not portable between RunDeck instances. As of RunDeck 1.3+ the UUID should be used in lieu of ID.)

4.3 Listing and filtering Jobs

All Job activity begins on the main "Jobs" page inside RunDeck. After logging in, press the "Jobs" button in the top navigation bar and any Jobs you are authorized to see will be displayed.

If the Jobs were defined inside groups, you will see the listing grouped into a folder like structure. These folders represent the Job groups described earlier. You can navigate these folders by pressing the folder icon to reveal its contents.

Once you have navigated to a Job, you will see its name, possibly its description and a summary total of how many times it has been executed.

Clicking on the job name will will expand the window to show the Job detail. You will see a button bar containing icons representing the actions you are able to perform. Other Job detail will include what command(s) it will run, filter expressions and other dispatcher options.

4.3.1 Filtering Jobs

The Job page lets you search for Jobs using the Filter option.

Click the "Filter" link to show the filter options:

Job filter form

Job filter form

This will show the Filter fields. Enter a value in any of the filter fields:

  • Job Name: the name of the job
  • Group: the name of the job group
  • Description: Job description text

You can type a substring or a regular expression in any of these fields.

After pressing the "Filter" button, the Job list will be filtered to include only the matching jobs.

Job filtered list

Job filtered list

To refine the filter, click on the blue-outlined Filter description, and change the filter fields.

To reset the filter and go back to the full job page, click the "Clear" button in the Filter fields.

4.4 Viewing Job detail

From a filtered job listing, a Job's detail can be previewed by hovering the mouse pointer over the Job's name. A popup view contains the Job's detail. Click outside the popup to close it.

Job detail popup

Job detail popup

Pressing the link for the Job name will navigate to a separate page where job detail and a button control bar is displayed. These buttons enable users to delete, copy, edit export or run the Job.

Job detail page

Job detail page

The buttons displayed on the control bar reflect the authorization policy enforced for the user.

The information in the Job detail view includes:

  • Name, description and group
  • Execution statistics like when the job was last run, it's average success rate, and duration
  • Details including project name and workflow steps, and log level

Pressing the "Show Matches" link will display the list of Nodes where the Job will run.

4.5 Running a Job

Jobs can be run from the shell or from the graphical console.

From the command line, use the run shell tool. Here's an example that starts a hypothetical job named "restart" belonging in the "apps/web" Job group in project "myproject":

$ run -j apps/web/restart -p myproject
Job execution started:
[51] restart <http://strongbad:4440/execution/follow/51>

From the graphical console, any stored job can be started from the Jobs page. Navigate to the desired Job from the filtered listing and then press the green "Run" icon to immediately queue and run the Job. If you do not see the Run icon, it means your login does not have "run" privileges.

Job run button

Job run button

If you navigated to the Job's detail page, you press the "Run" button from there.

Job run button

Job run button

After the Run button has been pressed, a dialog will open where you can choose execution options.

4.5.1 Choose execution options

Jobs can be defined to prompt the user for options. This page contains a form presenting any of these Job options.

Some options will have default values while others may present you with a menu of choices. Some options are optional while others are required. Lastly, their might be a pattern governing what values are acceptable.

If there are any such Job options, you can change them here before proceeding with the execution.

When you are ready, press "Run Job Now". The job will enter the execution queue and you can track its execution in the Now running section.

4.5.2 Following Running Jobs

Once you have started running a Job, you can follow the Job's output in the Execution Follow page.

On the Jobs page, look in the "Now running" section and click the "output >>" link in the row with the desired Job name.

If you pressed the "run" button from the Job's detail page, your browser will already have been directed to the Execution Follow page.

4.6 Creating Jobs

RunDeck allows you to define two kinds of Jobs.

  • Temporary: A temporary Job defines a set of commands to execute and a node filter configuration.
  • Saved: A saved job also defines a set of commands to execute and dispatcher options but can be given a name and stored in a group. Additionally, saved Jobs can be given an execution schedule.

From the Jobs, page press the "New Job" button to begin creating a Job.

New Job button

New Job button

4.6.1 Temporary Jobs

A temporary job is a bit like an ad-hoc command except you get more control over how the commands will execute plus the execution can be better tracked within the RunDeck webapp.

To create a temporary job, begin by logging in to the RunDeck graphical console, and press the "Jobs" tab.

  1. Locate the "New Job" button in the right hand corner and press it to display the "Create New Job" form.
  2. A job is defined in terms of one or more workflow steps. In the Workflows area, click the "Add a step" link.
  3. Workflow steps can be one of several types. Click the "Script" workflow step type.
  4. A script type can be any script that can be executed on the target hosts. Type in the "info" shell script we executed earlier using dispatch.
  5. At the bottom of the form, push the "Run and Forget" button to begin execution.
  6. Execution output can be followed on the subsequent page.
Temporary job form

Temporary job form

4.6.2 Saved Jobs

Running ad hoc commands and temporary jobs are a typical part of day to day administrative work. Occasionally, ad-hoc commands become routine procedures and if were reusable, would become more valuable. These jobs could be handed off to others in the team or invoked from within other Jobs. RunDeck provides an interface to declare and save jobs, both graphically or declared with an XML file.

4.6.3 Simple saved job

For the first saved Job example, create a Job that calls the info script.

  1. Like in the earlier example, begin by pressing the "New Job" button.
  2. Within the new job form:
    • Select "Yes" for the "Save this job?" prompt. Pressing Yes reveals a form to define a name, group and description for the job.
    • For "Job Name", enter "info" and for the "Group", enter "adm/resources".
    • If you want to specify your own UUID you can enter it in the field. Otherwise a unique value will be set for you.
    • Providing a description will be come helpful to other users to understand the intent and purpose for the Job.
    • Check the box for "Dispatch to Nodes"
    • Choose the "Node Exclude Filters" and enter the name of your RunDeck server. This will cause the job to run on just the remote Nodes (eg., centos54 and ubuntu).
    • Type in and info script
    • Save the Workflow step
    • Press the "Create" button at the bottom of the page. Simple saved job form
  3. After the the job is created, the browser is directed to the Jobs page. The folder structure reflecting the group naming will show one Job.
    • Navigate through the folders buttons to the new job
  4. Notice the green arrow button.
    • Press the button to run the Job. Simple saved job
  5. Press the "Run Job Now" button to begin execution.
    • The job will be queued and executed.
  6. Look in the "Now running" section.
    • Press the "output >>" link to go to the execution follow page. Simple saved job output

4.6.4 Node dispatching and filtering

When you create a job you can choose between either running the job only locally (on the RunDeck server), or dispatching it to multiple nodes (including the RunDeck server if you want).

In the GUI, the "Dispatch to Nodes" checkbox lets you enable node dispatching. When you click this box you are presented with the Node Filtering interface:

Node Filtering interface

Node Filtering interface

You can click the different filter fields "Name", and "Tags" to enter filter values for those fields. As you update the values you will see the "Matched Nodes" section updated to reflect the list of nodes that will match the inputs. You can click "More" to see more of the available inclusion filters, and you can click "Extended Filters" to enter exclusion filters for the same fields.

You can set the maximum number of simultaneous threads to use by changing the "Thread Count" box. A value of 1 means all node dispatches happen sequentially, and any greater value means that the node dispatches will happen in parallel.

If you set "Keep going on error?" to "Yes", then if any node dispatches fail for any reason, the rest will continue to be executed until all have been executed. At the end of the workflow for all nodes, the Job Execution will fail if any of the nodes had failed.

If you leave it at the default value of "No", then if any node dispatches fail for any reason, no further dispatches will be executed and the Job Execution will fail immediately.

4.6.4.1 Dynamic node filters

In addition to entering static values that match the nodes, you can also use more dynamic values.

If you have defined Options for the Job (see Job Options), you can use the values submitted by the user when the job is executed as part of the node filtering.

Simply set the filter value to ${option.name}, where "name" is the name of the option.

When the job is executed, the user will be prompted to enter the value of the option, and that will then be used in the node filter to determine the nodes to dispatch to.

Note: Since the dynamic option value is not set yet, the "Matched Nodes" shown in the node filtering input may indicate that there are "None" matched. Also, when the Job is executed, you may see a message saying "Warning: The Node filters specified for this Job do not match any nodes, execution may fail." The nodes matched will be determined after the user enters the option values.

4.7 Scheduled Jobs

Saved jobs can be configured to run on a periodic basis. If you want to create a Scheduled Job, select Yes under "Schedule to run repeatedly?"

Scheduled job simple form

Scheduled job simple form

The schedule can be defined in a simple graphical chooser or Unix crontab format.

To use the simple chooser, choose an hour and minute. You can then choose "Every Day" (default), or uncheck that option and select individual days of the week. You can select "Every Month" (default) or unselect that option and choose specific months of the year:

If the crontab time and date format is preferred, enter a cron expression.

Scheduled job crontab form

Scheduled job crontab form

Use the crontab syntax referenced here: CronExpression

After the Job has been updated to include a schedule, a clock icon will be displayed when the Job is listed:

Scheduled job icon

Scheduled job icon

4.8 Job Notifications

You can configure notifications to occur when a Job Execution finishes with either success or failure.

If you want to receive notifications, click Yes under "Send Notification?".

Notification form

Notification form

You can enable notifications for either Success or Failure, and either notification by email, or by webhooks. Click the checkbox next to the type of notification to enable.

Notifications enabled

Notifications enabled

Enter either comma-separated email addresses for email notification, or comma-separated URLs for webhook notification.

When the Job finishes executing, all "success" notifications will be triggered if the Job is successful. Otherwise, all "failure" notifications will be triggered if the Job fails or is cancelled.

4.9 Job history

In the Jobs page, you can see the outcome of previous executions of Jobs by clicking the "Executions" link for the Job.

Job executions link

Job executions link

This returns a filtered history pertaining to that Job. You can click on any past execution in the list to see the full execution state.

Job executions matches

Job executions matches

From the Job detail page, one can also see previous execution history.

4.10 Killing Jobs

Jobs that are currently running can be Killed immediately.

WARNING: This feature should be used with caution, as it forcibly kills the Java Thread that the Job is running on. It may result in the RunDeck server becoming flaky. It is a deprecated feature of Java that is not recommended to be used, so do so only when extremely necessary.

From the History view Now Running section, or in the Job execution follow page, click on the "Kill Job Now" button for the running Job.

When prompted "Really kill this job?" Click the "Yes" button.

The Job will terminate with a "Killed" completion status.

See also: rd-queue.

4.11 Deleting Jobs

In the Job detail page, click the red "X" icon for to delete the Job.

Job delete button

Job delete button

Click "Yes" when it says "Really delete this Job?"

4.12 Updating and copying Jobs

All of the data you set when creating a job can be modified (except UUID). To edit a Job, you can click the Pencil icon:

Job edit button

Job edit button

Similarly, to Copy a Job definition to a new Job, press the Copy button.

Job copy button

Job copy button

4.13 Exporting Job definitions

Job definitions created inside the RunDeck graphical console can be exported to XML or YAML file formats and be used for later import.

Two methods exist to retrieve the Job definitions: via RunDeck's graphical interface, and via the rd-jobs shell tool.

In the Job detail page, locate the icon with a document symbol in the toolbar. It is labeled "Download Job definition file" in the mouse tool tip. Clicking on the icon will let you choose either XML or YAML format to download the definition.

Job export button

Job export button

Click the preferred format to initiate the file download to your browser.

If you prefer to use the command line, open a shell on the RunDeck server. Run the rd-jobs command to write it to disk. By default, rd-jobs will dump all Job definitions to one file. To limit it to just a single Job specify its name with -n or its ID with -i:

rd-jobs -p project -n "job-name" -f job.xml

This will store the results in the "job.xml" file.

To export it in YAML format, specify the -F option:

rd-jobs -p project -n "job-name" -F yaml -f job.yaml

This will export in the YAML document format file.

The XML and YAML document formats are described here:

Consult the rd-jobs(1) manual page for additional command usage.

4.14 Importing Job definitions

If you have a "job.xml" file (See above) and want to upload it via the GUI web interface, you can do so.

Click on the New Job" button in the Job list.

In the "Create New Job" form, click on the button that says "Upload Definition..." on the right side:

Job import button

Job import button

Click the Choose File button and choose your job.xml file to upload.

Job import form

Job import form

Choose an option where it says "When a job with the same name already exists:":

  • Update - this means that a job defined in the xml will overwrite any existing job with the same name
  • Skip - this means that a job defined in the xml will be skipped over if there is an existing job with the same name
  • Create - this means that the job defined in the xml will be used to create a new job if there is an existing job with the same name.

Click the Upload button. If there are any errors with the Job definitions in the XML file, they will show up on the page.

4.15 Summary

After reading this chapter, you should be familiar with RunDeck Jobs and able to find and run them. You should understand how to create temporary and saved jobs and understand how to find their history. Finally, you should be aware of how to export and import Job definitions as XML documents.

Next, we'll cover how to create multi-step procedures using Job Workflows.

5 Job Workflows

The Job's most basic feature is its ability to execute one or more commands across a set of nodes. This sequence of commands is called a workflow, and each step in the workflow is defined as an invocation to a command.

The steps of the Job workflow are displayed when viewing a Job's detail from a Job listing or within the Job editor form.

5.1 Workflow definition

Workflows can be defined within the RunDeck graphical console or as an XML or YAML document that is loaded to the server.

The graphical console provides an authoring environment where steps can be added, edited, removed or reordered.

Users preferring to define Jobs in a text format should refer to the two format definitions:

It is also possible to author Jobs inside the graphical console and then export the definition as a file using the rd-jobs shell tool (rd-jobs(1)).

See Exporting Job definitions and Importing Job definitions.

5.2 Workflow control settings

Workflow execution is controlled by two important settings: Keepgoing and Strategy.

Workflow controls

Workflow controls

Keepgoing: This manages what to do if a step incurs and error:

  • No: Fail immediately (default)
  • Yes: Continue to next step

The default is to fail immediately but depending on the procedure at hand you can choose to have the execution continue.

Strategy: Controls the order of execution of steps and command dispatch to nodes: Node-oriented and Step-oriented.

  • Node-oriented: Executes the full workflow on each node before the next node. (default)
  • Step-oriented: Executes each step on all nodes before the next node.

The following illustrations contrast the strategies showing how three steps proceed across two nodes.

Node-oriented flow illustrated:

1.   NodeA    step#1
2.     "      step#2
3.     "      step#3
4.   NodeB    step#1
5.     "      step#2
6.     "      step#3

Step-oriented flow illustrated:

1.   NodeA    step#1
2.   NodeB      "
3.   NodeA    step#2
4.   NodeB      "
5.   NodeA    step#1
6.   NodeB      "

The process you are automating will determine which strategy is correct, though the node-oriented flow is more commonplace.

5.3 Workflow steps

The following sections describe how to construct a workflow as a set of steps that call commands of different types.

When creating a new Job definition, the Workflow form will be set with defaults and have no workflow steps defined. The workflow editor will have a form open asking to enter a shell command as the first step.

Add a step

Add a step

To add new steps simply press the "Add a step" link inside the workflow editor form. This will prompt you with a dialog asking which kind of workflow step you would like to add. Each kind of step has its own form. When you are done filling out the form, press "Save" to add it to the sequence. Pressing "Cancel" will close the form and leave the sequence unchanged.

Workflow step types

Workflow step types

New steps are always added to the end of the sequence. See Reordering steps for directions on modifying the step order.

The next several sections describe the specification of each kind of command step.

5.3.1 Command step

Use the command step to call system commands. This is the default type of workflow step when creating a Job. Enter any command string you would type at the terminal on the remote hosts.

Command step type

Command step type

This is similar to calling the command with dispatch:

dispatch [filter-options] -- command

5.3.2 Script step

Execute the supplied shell script content. Optionally, can pass an argument to the script specified in the lower text field.

Script step type

Script step type

This is similar to calling the command with dispatch:

dispatch [filter-options] --stdin -- args <<EOF 
script content here 
EOF

5.3.3 Script file step

Executes the script file local to the sever to the filtered Node set. Arguments can be passed to the script by specifying them in the lower text field.

Script file step type

Script file step type

This is similar to calling the script file with dispatch:

dispatch [filter-options] -s scriptfile -- args

5.3.4 Job reference step

To call another saved Job, create a Job Reference step. Enter the name of the Job and its group.

Job step type

Job step type

The Job Reference form provides a Job browser to make it easier to select from the existing set of saved Jobs. Click the "Choose A Job..." link and navigate to the desired Job.

Finally, if the Job defines Options, you can specify them in the commandline arguments text field and can include variable expansion to pass any input options for the current job. Format:

-optname <value> -optname <value> ...

The format for specifying options is exactly the same as you would pass to the run commandline tool, and you can substitute values of input options to the current job. For example:

-opt1 something -opt2 ${option.opt2}

This would set the value "something" for the Job's "opt1" option, and then pass the "opt2" option directly from the top-level job to the Job reference.

This is similar to calling the other Job with run:

run [filter-options] -j group/jobname -- -opt1 something -opt2 somethingelse

If the Job has required Options that are not specified on the arguments line, then a "defaultValue" of that option will be used if it is defined. If a required option does not have a default value, then the execution will fail because the option is not specified.

5.4 Reordering steps

The order of the Workflow steps can be modified by hovering over any step and then clicking and dragging the double arrow icon to the desired position. A blue horizontal bar helps highlight the position where the Job will land.

Job step reorder

Job step reorder

After releasing the select Job, it will land in the desired position and the step order will be updated.

If you wish to Undo the step reordering, press the "Undo" link above the steps.

The "Redo" button can be pressed to reapply the last undone change.

Press the "Revert All Changes" button to go back to the original step order.

5.5 Save the changes

Once the Workflow steps have been defined and order, changes are permanently saved after pressing the "Create" button if new or the "Update" button if the Job is being modified.

5.6 Summary

At this point you should understand what a Job workflow is, the kinds of steps they can contain and how to define a workflow.

Next, we'll cover more about RunDeck's Job Option features.

6 Job Options

Any command or script can be wrapped as a Job. Creating a Job for every use case will proliferate a large number of Jobs differing only by how the Job calls the scripts. These differences are often environment or application version related. Other times only the person running the Job can provide the needed information to run the Job correctly.

Making your scripts and commands data driven, will also make them more generic and therefore, reusable in different contexts. Rather than maintain variations of the same basic process, letting Jobs be driven by a model of options from externally provided data will lead to better abstraction and encapsulation of your process.

RunDeck Jobs can be configured to prompt a user for input by defining one or more named options. An option models a named parameter that can be required or optional and include a range of choices that will be presented to the user when the Job is run.

Users supply options by typing in a value or selecting from a menu of choices. A validation pattern ensures input complies to the option requirement. Once chosen, the value chosen for the option is accessible to the commands called by the Job.

Option choices can be modeled as a static set or from a dynamic source. Static choices can be modeled as a comma separated list in the job definition. When option values must be dynamic, the Job can be defined to use a URL to retrieve option data from an external source. Enabling Jobs to access external sources via URL opens the door to integrating RunDeck with other tools and incorporating their data into Job workflows.

6.1 Prompting the user

The obvious effect from defining Job options is their appearance to the user running the Job. Users will be presented a page called "Choose Execution Options..." where input and menu choices must be configured.

Command line users executing Jobs via the run shell tool also will specify options as an argument string.

It is worth spending a moment to consider how options become part of the user interface to Jobs and give some thought to this next level of procedure formalization.

  • Naming and description convention: Visualize how the user will read the option name and judge its purpose from the description you supply.
  • Required options: Making an option required means the Job will fail if a user leaves it out.
  • Input restrictions and validation: If you need to make the option value be somewhat open ended consider how you can create safeguards to control their choice.

6.2 Options editor

Options can be created for any stored Job. The Job edit page contains an area displaying a summary to existing options and a link to add new ones or edit existing ones.

Add option link

Add option link

The option summary shows each option and its default value if it defines them.

Clicking the "edit" link opens the options editor.

Option editor

Option editor

The options editor displays an expanded summary for each defined option. Each option is listed with its usage summary, description, values list and any restrictions. Pressing the "Add an option" link will open a form to define a new parameter. Pressing the "Close" link will collapse the options editor and return back to the summary view.

Moving the mouse over any row in the options editor reveals links to delete or edit the highlighted option. Pressing the remove icon will display a prompt confirming you want to delete that option from the Job. Clicking the "edit" link opens a new form that lets you modify all aspects of that option.

Options can also be defined as part of a job definition and later loaded to the RunDeck server. See job-v20(5)(XML) and job-yaml-v12(5)(YAML) and rd-jobs(1) manual pages if you prefer using an textual Job definition.

6.3 Defining an option

New options can be defined by pressing the "Add an option" link while existing ones can be changed by pressing their "edit" link.

Option edit form

Option edit form

The option definition form is organized into several areas:

Identification

Here you provide the option's name and description. The name becomes part of acceptable arguments to the Job while the description will be provided as help text to users running the Job.

The Default Value will be pre-selected in the GUI when the option is presented.

Allowed values

Allowed values provide a model of possible choices. This can contain a static list of values or a URL to a server providing option data. Values can be specified as a comma separated list as seen above but can also be requested from an external source using a "remote URL" See below.

Restrictions

Defines criteria on which input to accept or present. Option choices can be controlled using the "Enforced from values" restriction. When set "true", RunDeck will only present a popup menu. If set "false", a text field will also be presented. Enter a regular expression in the "Match Regular Expression" field the Job will evaluate when run.

Requirement

Indicates if the Job can only run if a choice is provided for that Option. Choosing "No" states the option is not required Choose "Yes" to state the option is required.

If a Default Value is set for the option, then this value will automatically be set for the option if it is Required, even if not specified among the arguments when executing a job via the command-line or API.

Multi-valued

Defines if the user input can consist of multiple values. Choosing "No" states that only a single value can chosen as input. Choosing "Yes" states that the user may select multiple input values from the Allowed values and/or enter multiple values of their own. The delimiter string will be used to separate the multiple values when the Job is run.

Once satisfied with the option definition, press the "Save" button to add it to the Job definition. Pressing the "Cancel" button will dismiss the changes and close the form.

6.4 Remote option values

A model of option values can be retrieved from an external source. When the valuesUrl is specified for an Option, then the model of allowed values is retrieved from the specified URL.

This is useful in a couple of scenarios when RunDeck is used to coordinate process that depend on other systems:

  • Deploying packages or artifacts produced by a build or CI server, e.g. Hudson.
    • A list of recent Hudson build artifacts can be imported as Options data, so that a User can pick an appropriate package name to deploy from a list.
  • Selecting from a set of available environments, defined in a CMDB
  • Any situation in which input variables for your Jobs must be selected from some set of values produced by a different system.

See Chapter 9 - Option Model Provider.

6.5 Script usage

Option values can be passed to scripts as an argument or referenced inside the script via a named token. Option values can be accessed in one of several ways:

Value passed as an environment variable:

Bash: $RD_OPTION_NAME 2

Value passed as an argument to a script:

Commandline Arguments: ${option.name}

Value referenced as a replacement token inside the script:

Script Content: @option.name@

A single example helps illustrate these methods. Imagine a trivial script is wrapped in a Job named "hello" and has an option named "message".

The "hello" Job option signature would be: -message <>.

Option usage

Option usage

Here's the content of this simple script.

    #!/bin/sh    
echo envvar=$RD_OPTION_MESSAGE ;# read from environment
echo args=$1 ;# comes from argument vector
echo message=@option.message@ ;# replacement token

When the user runs the "hello" job they will be prompted for the "message" value.

Option entered

Option entered

Let's assume they entered the word "howdy" in response. The output of the Job will be:

envar=howdy
args=howdy    
message=howdy    

It's important to know what happens if the option isn't set. This can happen if you define an option that is not required and do not give it a default value.

Let's imagine the Job was run without a message option supplied, the output would look like this:

envar=
args=
message=@option.message@

Here are some tips to deal with this possibility:

Environment variable:

As a precaution you might test existence for the variable and perhaps set a default value. To test its existence you might use:

 test -s  $RD_OPTION_NAME

You might also use a Bash feature that tests and defaults it to a value:

 ${RD_OPTION_NAME:=mydefault} 
Replacement token
If the option is unset the token will be left alone inside the script. You might write your script a bit more defensively and change the implementation like so:
        message=@option.message@
if [ "$message" == "@option.message@" ] ; then
message=mydefault
fi

6.6 Calling a Job with options

Jobs can be invoked from the command line using the run shell tool or as a step in another Job's workflow.

The format for specifying options is -name value.

Using the run command pass them after the double hyphen:

run -i jobId -- -paramA valA -paramB valB
run -j group/name -p project -- -paramA valA -paramB valB

Inside an XML definition, insert them as an arg element:

<command>
<jobref group="test" name="other tests">
<arg line="-paramA valA -paramB valB"/>
</jobref>
</command>

Consult the run(1) and job-v20(5) manual pages for additional information.

6.7 Summary

After reading this chapter you should understand how to run Jobs with options, as well as, add and edit them. If you are interested in generating option data for one of your jobs, see the option model provider section in the Examples chapter.

7 RunDeck by example

This chapter presents working examples reflecting a variety of solutions you can create with RunDeck. Helping you apply concepts and features introduced in earlier chapters is the focus of these examples. Rather than make the examples abstract, they are set in the context of Acme Anvils, a fictitious organization that manages an online application.

7.1 Acme Anvils

Acme Anvils is a hypothetical start up selling new and used anvils from their web site. Two teams inside the company are involved with the development and support of the anvil sales application. Being a new company, there isn't much control over access to the live environment. Either team can make changes to systems which has led to mistakes and outages. Because the senior management is so enthusiastic, they push the teams to deliver new features as frequently as possible. Unfortunately, this has led to another problem: the Acme Anvil web site is an unstable memory hog and requires occasional restarts.

There are actually two methods to the restart procedure depending on the problem: "kill" versus "normal". The "kill" restart is required when the application becomes totally unresponsive. The "normal" restart occurs when the application needs to free memory.

Depending on the urgency or the staff on hand, either a developer or an administrator conducts the restart, albeit differently. Because the developers write the software, they understand the restart requirements from an application perspective. The administrators on the other hand, are not always informed of these requirements but are well versed in restarting the application from a systems perspective. This has led to a divergence in procedures and has become the main source of problems that affect their customers.

An administrator, tired of the late night calls to restart the application, and frustrated by the knowledge gap between operations and development has decided to take the initiative come up with a better approach.

7.2 RunDeck set up

The administrator chooses a machine with access to the servers in the live environment and installs the RunDeck software there.

A project called "anvils" is created to manage the application support activities.

The administrator creates the project using the rd-project shell tool though this could be done with the RunDeck GUI (see (project setup). After logging into the RunDeck server, the command is run:

rd-project -p anvils -a create

This initialized the "anvils" project in RunDeck so it only contains information about the server node. Adding information about the nodes deployed in the live environment is the next step (see resource model).

The environment has five nodes: anv1-anv5. Anvils is a three tier application and has web, application and database components installed across the five nodes.

Additionally, the administrator decides to incorporate a recent convention to use different system logins to execute SSH commands to control running application components. The web component are run as the "www" user while the app and database components run as user "anvils".

With this information in hand, the administrator prepares the project resource model using the resource-v13(5) XML or resource-v13(5) YAML document format. The file listing below contains the node definitions for the five nodes -- anv1, anv2, anv3, anv4, anv5:

File listing: resources.xml

<?xml version="1.0" encoding="UTF-8"?>

<project>
  <node name="anv1" type="Node"
     description="an anvils web server" 
     hostname="anv1.acme.com"  username="www" tags="web"/>
  <node name="anv2" type="Node" 
     description="an anvils web server" 
     hostname="anv2.acme.com"  username="www" tags="web"/>
  <node name="anv3" type="Node" 
     description="an avnils app server" 
     hostname="anv3.acme.com"  username="anvils" tags="app"/>
  <node name="anv4" type="Node" 
     description="an anvils app server" 
     hostname="anv4.acme.com"  username="anvils" tags="app"/>
  <node name="anv5" type="Node" 
     description="the anvils database server" 
     hostname="anv5.acme.com"  username="anvils" tags="db"/> 
</project>

Reviewing the XML content one sees the XML tag set represent the host information described above. A logical name for each node is defined with the name attribute (eg name="anv1"). The address used by SSH is set with hostname (eg hostname="anv1.acme.com") while the login used to execute SSH commands has been specified with the username attribute (username="www" vs username="anvils"). The value for the tags attribute reflects the node function (tags="web" vs tags="app").

The administrator saves the file and places it in a path of his choice. To make RunDeck aware of it, the administrator modifies the project configuration file, $RDECK_BASE/projects/anvils/etc/project.properties, modifying the project.resources.file setting :

project.resources.file = /etc/rundeck/projects/anvils/resources.xml

With the resources file in place and the project configuration updated, the administrator has finished with the resource model preparation and can begin dispatching commands.

List all the nodes in the anvils project by opening the Filter and typing .* in the Name field and then press "Filter". You should see a listing of 6 nodes.

Anvils resources

Anvils resources

7.3 Tag classification and command dispatching

With tags that describe application role, commands can be targeted to specific sub sets of nodes without hard coding any hostnames. The dispatch command's listing feature illustrates how tag filtering selects particular node sets in the shell:

Use the tags keyword to list the web nodes:

dispatch -p anvils -I tags=web
anv1 anv2

List the app nodes:

dispatch -p anvils -I tags=app
anv3 anv4

List the db nodes:

dispatch -p anvils -I tags=db
anv5

Use the "+" (AND) operator to list the web and app nodes:

dispatch -p anvils -I tags=web+app
anv1 anv2 anv3 anv4

Exclude the web and app nodes:

dispatch -p anvils -X tags=web+app
anv5

Using a wildcard for node name, list all the nodes:

dispatch -p anvils -I '.*' 
anv1 anv2 anv3 anv4 anv5 

Here's an example using filters in the graphical console:

Anvils filtered list

Anvils filtered list

Filtering with tags provides an abstraction over hostnames and lets the administrator think about scripting process using loose classifications. New nodes can be added, others decommissioned while others given new purpose, and the procedures stay unchanged because they are bound to the filtering criteria.

This simple classification scheme will allow the developers and administrators to share a common vocabulary when talking about the kinds of nodes supporting the Anvils application.

7.4 Jobs

Jobs are a convenient method to establish a library of routine procedures. By its nature, a saved Job encapsulates a process into a logically named interface. Jobs can begin as a single item workflow that calls a small or large shell script but evolve into a multi-step workflow. One job can also call another job as a step in its workflow. Using this approach one can view each Job as a reusable building block upon which more complex automation can be built.

The administrator decides Jobs can be used to encapsulate procedures to manage the restart process. Both developers and administrators can collaborate on their definition and evolution and maintenance.

Two sets of scripts are already in use to manage the startup and shutdown procedures. Rather than force the issue as to which one is correct or superior, the administrator focuses on creating a skeleton to more easily present how scripts can be encapsulated by the job workflow. After demonstrating this simple framework, the administrator can discuss how to incorporate the best of both script implementations into the Job definitions.

For the skeleton, the administrator creates simple placeholder scripts that merely echo their intent and the arguments passed to the them. Two scripts - start.sh and stop.sh - represent the two steps of the restart process.

Scripts:

File listing: start.sh

#!/bin/sh
# Usage: $0 
echo Web started.

File listing: stop.sh

#!/bin/sh
# Usage: $0 [normal|kill]
echo Web stopped with method: $1.

Because either the normal or kill can be specified for the "method" option, the Jobs will need to pass the user's choice as an argument to the script.

There is no script for the restart process itself since that will be defined as a Job workflow.

7.4.1 Job structure

With an idea of the restart scripts in mind, the next step is to define a job to encapsulate the restart procedure. Though the overall goal is to provide a single restart procedure, for the sake of reusability, it might be preferred to break each step of the process into separate jobs.

Using this approach the administrator imagines the following jobs:

  • start: call the start.sh script to start the web service
  • stop: call the stop.sh script to stop the web service
  • Restart: calls the jobs: stop, start

Since the restart procedure is the primary focus, it is capitalized for distinction.

The extra complexity from defining a job for every individual step can pay off later, if those steps can be recombined with future jobs to serve later management needs. How far a process is decomposed into individual jobs is a judgement balancing maintenance requirements and the desire for job reuse.

7.4.2 Job grouping

Though not a requirement, it is helpful to use job groups and have a convention for naming them. A good convention assists others with a navigation scheme that helps them remember and find the desired procedure.

The administrator chooses to create a top level group named "/anvils/web/" where the web restart related jobs will be organized.

anvils/
`-- web/
    |-- Restart
    |-- start
    `-- stop

After choosing the "anvils" project users will see this grouping of jobs.

Anvils job group

Anvils job group

7.5 Job option

To support specifying the restart method to the scripts, the the three jobs will declare an option named "method". Without such a parameter, the administrator would be forced to duplicate restart Jobs for both the kill and normal stop methods.

Another benefit from defining the job option is the ability to display a menu of choices to the user running the job. Once chosen, the value selected by the menu is then passed to the script.

7.5.1 Allowed values

An option can be defined to only allow values from a specified list. This places safe guards on how a Job can be run by limiting choices to those the scripts can safely handle.

The administrator takes advantage of this by limiting the "method" option values to just "normal" or "kill" choices.

The screenshot below contains the Option edit form for the "method" option. The form includes elements to define description and default value, as well as, Allowed Values and Restrictions.

Option editor for method

Option editor for method

Allowed values can be specified as a comma separated list as seen above but can also be requested from an external source using a "remote URL".

Option choices can be controlled using the "Enforced from values" restriction. When set "true", the RunDeck UI will only present a popup menu. If set "false", a text field will also be presented. Use the "Match Regular Expression" form to validate the input option.

Here's a screenshot of how RunDeck will display the menu choices:

Option menu for method

Option menu for method

7.5.2 Script access to option data

Option values can be passed to scripts as an argument or referenced inside the script using a named token. For example, the value for the "method" option selection can be accessed in one of several ways:

Value referenced as an environment variable:

  • Bash: $CT_OPTION_METHOD

Value passed in the argument vector to the executed script or command via the scriptargs tag:

  • Commandline Arguments: ${option.method}

Value represented as a named token inside the script and replaced before execution:

  • Script Content: @option.method@

7.6 Job workflow composition

With an understanding of the scripts and the option needed to control the restart operation, the final step is to compose the Job definitions.

While each job can be defined graphically in RunDeck, each can succinctly be defined using an XML file conforming to the job-v20(5) document format. This document contains a set of tags corresponding to the choices seen in the RunDeck GUI form.

Below are the XML definitions for the jobs. One or more jobs can be defined inside a single XML file but your convention will dictate how to organize the definitions. The files can be named any way desired and do not have to correspond to the Job name or its group.

File listing: stop.xml

<joblist>   
    <job> 
       <name>stop</name>  
       <description>the web stop procedure</description>  
       <loglevel>INFO</loglevel>  
       <group>anvils/web</group>  
       <context> 
           <project>anvils</project>  
             <options> 
               <option name="method" enforcedvalues="true"
                       required="true" 
                   values="normal,kill"/> 
               </options> 
       </context>  
       <sequence threadcount="1" keepgoing="false" strategy="node-first"> 
         <command> 
           <script><![CDATA[#!/bin/sh
echo Web stopped with method: $1.]]></script>  
            <scriptargs>${option.method}</scriptargs> 
         </command> 
       </sequence>  
       <nodefilters excludeprecedence="true"> 
         <include> 
          <tags>web</tags> 
          </include> 
       </nodefilters>  
       <dispatch> 
         <threadcount>1</threadcount>  
         <keepgoing>false</keepgoing> 
       </dispatch> 
     </job>
</joblist>

Defines Job, /anvils/web/stop, and executes the shell script to Nodes tagged "web". Using the scriptargs tag, the shell script is passed a single argument, ${option.method}, containing the value chosen in the Job run form.

File listing: start.xml

<joblist>   
   <job> 
     <name>start</name>  
     <description>the web start procedure</description>  
     <loglevel>INFO</loglevel>  
     <group>anvils/web</group>  
    <context> 
      <project>anvils</project>  
        <options> 
         <option name="method" enforcedvalues="true" required="true" 
          values="normal,kill" /> 
       </options> 
    </context>  
    <sequence threadcount="1" keepgoing="false" strategy="node-first"> 
     <command> 
      <script><![CDATA[#!/bin/sh
 echo Web started. after a $1 shutdown]]></script>  
       <scriptargs>${option.method}</scriptargs> 
     </command> 
  </sequence>  
    <nodefilters excludeprecedence="true"> 
      <include> 
        <tags>web</tags> 
      </include> 
   </nodefilters>  
   <dispatch> 
     <threadcount>1</threadcount>  
     <keepgoing>false</keepgoing> 
   </dispatch> 
  </job>
</joblist>

Defines Job, /anvils/web/start, that also executes a shell script to Nodes tagged "web". The shell script is passed a single argument, ${option.method}, containing the value chosen in the Job run form.

File listing: restart.xml

<joblist>   
   <job> 
     <name>Restart</name>  
     <description>restart the web server</description>  
     <loglevel>INFO</loglevel>  
     <group>anvils/web</group>  
     <context> 
       <project>anvils</project>  
         <options> 
           <option name="method" enforcedvalues="true" required="false" 
          values="normal,kill" /> 
        </options> 
     </context>  
     <sequence threadcount="1" keepgoing="false" strategy="node-first"> 
      <command> 
        <jobref name="stop" group="apps/web"> 
          <arg line="-method ${option.method}"/> 
        </jobref> 
      </command>  
      <command> 
        <jobref name="start" group="apps/web"> 
          <arg line="-method ${option.method}"/> 
        </jobref> 
      </command> 
    </sequence>  
    <nodefilters excludeprecedence="true"> 
     <include> 
       <tags>web</tags> 
     </include> 
    </nodefilters>  
     <dispatch> 
       <threadcount>1</threadcount>  
       <keepgoing>true</keepgoing> 
     </dispatch> 
   </job>   
</joblist>

Defines Job, /anvils/web/Restart, that executes a sequence of Job calls, using the jobref tag.

Saving the XML definitions files located on the RunDeck server, one can load them using the rd-jobs command.

Run the rd-jobs load command for each job definition file:

rd-jobs load -f start.xml
rd-jobs load -f stop.xml
rd-jobs load -f restart.xml

The rd-jobs list command queries RunDeck and prints out the list of defined jobs:

rd-jobs list -p anvils
Found 3 jobs:
- Restart - 'the web restart procedure'
- start - 'the web start procedure'
- stop - 'the web stop procedure'

Of course, the jobs can be viewed inside the RunDeck graphical console by going to the Jobs page. Hovering over the "Restart" job name reveals job detail.

Anvils restart jobs

Anvils restart jobs

You will see the composition of the "Restart" job as a workflow calling the jobs: stop and start. The "Restart" job passes the -method option value to the lower level stop and start Jobs.

7.7 Running the job

The Jobs can be run from the RunDeck graphical console by going to the "Jobs" page. From there, navigate to the "Anvils/web" job group to display the three stored Jobs.

Clicking the "Run" button for the Restart job, will display the options selection page. The menu for the "method" option displays the two choices: "normal" and "kill". No other choices can be made, nor a textfield for free form entry, because the "method" option was defined with the restriction "enforced from allowed values".

Restart run page

Restart run page

The jobs can also be started from the command line using the run shell tool. The job group and name are specified using the "-j" parameter. Any options the Job supports are supplied after the "--" (double dash) parameter. (The "-p" parameter specifies the project, but it can be left out if there is only one project available.)

Run Restart specifying the method, "normal":

run -j "anvils/web/Restart" -p anvils -- -method normal

Run Restart specifying the method, "kill":

run -j "anvils/web/Restart" -p anvils -- -method kill

7.8 Job access control

Access to running or modifying Jobs is managed in an access control policy defined using the aclpolicy document format (aclpolicy-v10(5)). This file contains a number of policy elements that describe what user group is allowed to perform which actions. The Authorization section of the Administration chapter covers this in detail.

The administrator wants to use the aclpolicy to define two levels of access. The first level, has limited privilege and allows for just running jobs. The second level, is administrative and can modify job definitions.

Policies can be organized into more than one file to help organize access by group or pattern of use. The normal RunDeck install will define two user groups: "admin" and "user" and have a generated a policy for the "admin" group.

The Acme administrator decides to create a policy that allows users in the "user" group to run commands just in the "anvils" and "anvils/web" Job groups. We can employ the "user" login and group as it was also included in the normal install.

To create the aclpolicy file for the "user" group:

cp $RDECK_BASE/etc/admin.aclpolicy $RDECK_BASE/etc/user.aclpolicy

Modify the and elements as shown in the example below. Notice that just workflow_read,workflow_run actions are allowed.

$ cat $RDECK_BASE/etc/user.aclpolicy
<policies>
<policy description="User group access policy.">
<context project="*">
<command group="anvils" job="*" actions="workflow_read,workflow_run"/>
<command group="anvils/web" job="*" actions="workflow_read,workflow_run"/>
</context>
<by>
<group name="user"/>
</by>
</policy>
</policies>

Restart RunDeck to load the new policy file (see startup and shutdown).

rundeckd restart

Once the RunDeck webapp has started, login as the "user" user (the password is probably "user"). Just the Jobs in the "anvils" group are displayed in the Jobs page. The "user" user does is not allowed to access jobs outside of "/anvils group.

Notice the absence of the "New Job" button that would be displayed if logged in as "admin". Job creation is an action not granted to "user". Notice also, that the button bar for the listed Jobs does not include icons for editing or deleting the Job. Only workflow_read and workflow_actions were allowed in the user.aclpolicy file.

8 Administration

8.1 Startup and shutdown

RunDeck installation includes a control script used for starting and stopping the RunDeck server process. The control script provides a number of actions:

rundeckd [start|stop|restart|condrestart|status]

8.1.1 RPM

The RPM installation includes the placement of the boot control script that will automatically start RunDeck when the system boots.

The script is located here: /etc/init.d/rundeckd

Startup

/etc/init.d/rundeckd start

Shutdown

/etc/initd./rundeckd stop

8.1.1.1 Setting JAVA_HOME

When using the RPM, by default rundeck will use java found in your path. Various RPM based distributions provide ways of managing which version of java is found. CentOS uses /usr/sbin/alternatives and the processing of setting alternatives can be found here: http://wiki.centos.org/HowTos/JavaOnCentOS.

If you have installed a JDK or JRE in a unique directory and do not want to alter the global system configuration, then simply setting JAVA_HOME before running any command will use the version of java found in JAVA_HOME/bin. Updating /etc/rundeck/profile with JAVA_HOME is another option as well.

8.1.2 Launcher

The Launcher installation generates the script into the RDECK_BASE directory.

The script is located here: $RDECK_BASE/server/sbin/rundeckd.

Startup

$RDECK_BASE/server/sbin/rundeckd start

Shutdown

$RDECK_BASE/server/sbin/rundeckd stop

You may choose to incorporate this script into your server's operating system specific boot process.

8.2 Configuration

8.2.1 Configuration layout

Configuration file layout differs between the RPM and Launcher installation methods. See RPM layout and Launcher layout for details.

8.2.1.1 RPM layout

/etc/rundeck
|-- admin.aclpolicy
|-- framework.properties
|-- log4j.properties
|-- profile
|-- project.properties
|-- jaas-loginmodule.conf
|-- log4j.properties
|-- realm.properties
|-- rundeck-config.properties
`-- ssl
    |-- ssl.properties
    |-- keystore (not packaged)
    `-- truststore (not packaged)

8.2.1.2 Launcher layout

$RDECK_BASE/etc
|-- admin.aclpolicy
|-- framework.properties
|-- log4j.properties
|-- profile
`-- project.properties
$RDECK_BASE/server/config
|-- jaas-loginmodule.conf
|-- realm.properties
`-- rundeck-config.properties

8.2.2 Configuration files

Configuration is specified in a number of standard RunDeck configuration files generated during the installation process.

See the Configuration layout section for where these files reside for RPM and Launcher installations.

The purpose of each configuration file is described in its own section.

8.2.2.1 admin.aclpolicy

Administrator access control policy defined with a "aclpolicy(5)" XML document.

This file governs the access for the "admin" group and role.

See Authorization for information about setting up policy files for other user groups.

8.2.2.2 framework.properties

Configuration file used by shell tools and core RunDeck services. This file will be created for you at install time.

Some important settings:

  • framework.node.hostname: Hostname of the RunDeck server node
  • framework.node.name: Name (identity) of the RunDeck server node
  • framework.projects.dir: Path to the directory containing RunDeck Project directories. Default is $RDECK_BASE/projects.
  • framework.var.dir: Base directory for output and temp files used by the server and CLI tools. Default is $RDECK_BASE/var.
  • framework.logs.dir: Directory for log files written by core services and RunDeck Server's Job executions. Default is $RDECK_BASE/var/logs
  • framework.server.username: Username for connection to the RunDeck server
  • framework.server.password: Password for connection to the RunDeck server
  • framework.rundeck.url: Base URL for RunDeck server.

Resource Provider settings:

  • framework.resources.allowedURL.X: a sequence of regular expressions (for X starting at 0 and increasing). These are matched against requested providerURL values when the /project/name/resources/refresh API endpoint is called. See Refreshing Resources for a Project.

SSH Connection settings:

  • framework.ssh.keypath: Path to the SSH private key file used for SSH connections
  • framework.ssh.user: Default username for SSH Connections, if not overridden by Node specific value.
  • framework.ssh.timeout: timeout in milliseconds for SSH connections and executions. The default is "0" (no timeout). You can modify this to change the maximum time allowed for SSH connections.

Other settings:

  • framework.log.dispatch.console.format: Default format for non-terse node execution logging run by the dispatch CLI tool.

8.2.2.3 log4j.properties

RunDeck uses log4j as its application logging facility. This file defines the logging configuration for the RunDeck server.

8.2.2.4 profile

Shell environment variables used by the shell tools. This file contains several parameters needed during the startup of the shell tools like umask, Java home and classpath, and SSL options.

8.2.2.5 project.properties

RunDeck project configuration file. One of these is generated at project setup time.

PropertyDescription
project.resources.fileA local file path to read a resource model document
project.resources.urlThe URL to an external Resource Model Source.(Optional)
project.resources.allowedURL.XA sequence of regular expressions (for X starting at 0 and increasing).
resources.source.N...Defines a Resource model source see Resource Model Sources.

The project.resources.allowedURL.X values are matched against requested providerURL values when the /project/name/resources/refresh API endpoint is called. See Refreshing Resources for a Project.

8.2.2.6 jaas-loginmodule.conf

JAAS configuration for the RunDeck server. The listing below shows the file content for a normal RPM installation. One can see it specifies the use of the PropertyFileLoginModule:

RDpropertyfilelogin {
  org.mortbay.jetty.plus.jaas.spi.PropertyFileLoginModule required
  debug="true"
  file="/etc/rundeck/realm.properties";
};

8.2.2.7 realm.properties

Property file user directory when PropertyFileLoginModule is used. Specified from jaas-loginmodule.conf.

8.2.2.8 rundeck-config.properties

The primary RunDeck webapp configuration file. Defines default loglevel, datasource configuration, role mapping, and GUI customization.

8.2.2.8.1 Notification email settings

The URL and From: address used in email notifications are managed via the settings located in the rundeck-config.properties file.

The two properties are:

  • grails.serverURL
  • grails.mail.default.from

Here's an example:

grails.serverURL=https://node.fully.qualified.domain.name:4443
grails.mail.default.from=deployer@domain.com

8.2.3 GUI Admin Page

The RunDeck GUI has an Admin Page which contains lets you view and manage some configuration options. If you have admin role access, when you log in you will see an "Admin" link in the header of the page near your username:

Admin page link

Admin page link

Clicking on this link will take you to the Admin Page:

Admin page

Admin page

This page contains links to two sub-pages, and configuration information about the currently selected Project.

8.2.3.1 System Information Page

The System Information page gives you a breakdown of some of the RunDeck server's system statistics and information:

System Info Page

System Info Page

This information is also available via the API: API > System Info

8.2.3.2 User Profiles Page

The User Profiles page lists all User Profile records in the system. User Profiles are used to store some user preferences, and can be used to generate API Tokens for admin users.

User Profiles Page

User Profiles Page

8.2.3.3 Project Configuration

The selected project will be displayed with basic configuration options, and the list of configure Resource Model Sources, as well as the default Node Executor and File Copier settings.

If you click on "Configure Project", you will be taken to the Project Configuration form.

Project Configuration Form

Project Configuration Form

The first two fields allow configuration of some simple project basics.

First, you can enter a URL for a Resource Model Source, which will be used as a URL Resource Model Source with default configuration options.

Secondly, you can enter the Default SSH Key File, which is the private SSH Key file used by default for SSH and SCP actions. If you are not using SSH or SCP you do not have to enter one.

There are then several more sections: Resource Model Sources, Default Node Executor, and Default File Copier sections. These are described below:

8.2.3.4 Resource Model Sources Configuration

This section lets you add and modify Resource Model Sources for the project.

To add a new one, click "Add Source". You are prompted to select a type of source. The list shown will include all of the built-in types of sources, as well as any Plugins you have installed.

Add Resource Model Source

Add Resource Model Source

When you click "Add" for a type, you will be shown the configuration options for the type.

Configure Resource Model Source

Configure Resource Model Source

You can then click "Cancel" or "Save" to discard or add the configuration to the list.

Each item you add will be shown in the list:

Configured Source

Configured Source

To edit an item in the list click the "Edit" button. To delete an item in the list click the "Delete" button.

Each type of Resource Model Source will have different configuration settings of its own. The built-in Resource Model Source providers are shown below.

You can install more sources as plugins, see Resource Model Source Plugins.

8.2.3.4.1 File Resource Model Source

This is the File Resource Model Source configuration form:

File Resource Model Source

File Resource Model Source

See File Resource Model Source Configuration for more configuration information.

8.2.3.4.2 Directory Resource Model Source

Allows a directory to be scanned for resource document files. All files with an extension supported by one of the Resource Model Document Formats are included.

Directory Resource Model Source

Directory Resource Model Source

See Directory Resource Model Source Configuration for more configuration information.

8.2.3.4.3 Script Resource Model Source

This source can run an external script to produce the resource model definitions.

Script Resource Model Source

Script Resource Model Source

See Script Resource Model Source Configuration for more configuration information.

8.2.3.4.4 URL Resource Model Source

This source performs a HTTP GET request on a URL to return the resource definitions.

URL Resource Model Source

URL Resource Model Source

See URL Resource Model Source Configuration for more configuration information.

8.2.3.5 Default Node Executor Configuration

When RunDeck executes a command on a node, it does so via a "Node Executor". The most common built-in Node Executor is the "SSH" implementation, which uses SSH to connect to the remote node, however other implementations can be used.

Select the Default Node Executor you wish to use for all remote Nodes for the project:

Default Node Executor Choice

Default Node Executor Choice

You can install more types of Node Executors as plugins, see Node Execution Plugins.

8.2.3.6 Default File Copier Configuration

When RunDeck executes a script on a node, it does so by first copying the script as a file to the node, via a "File Copier". (It then uses a "Node Executor" to execute the script like a command.)

The most common built-in File Copier is the "SCP" implementation, which uses SCP to copy the file to the remote node, however other implementations can be used.

Select the Default File Copier you wish to use for all remote Nodes for the project:

Default File Copier Choice

Default File Copier Choice

You can install more types of File Copiers as plugins, see Node Execution Plugins.

8.3 Logs

Depending on the installer used, the log files will be under a base directory:

  • RPM: /var/log/rundeck
  • Launcher: $RDECK_BASE/server/logs

The following files will be found in the log directory:

 .
 |-- command.log
 |-- rundeck.audit.log
 |-- rundeck.jobs.log
 |-- rundeck.options.log
 |-- rundeck.log
 `-- service.log

Different facilities log to their own files:

  • command.log: Shell tools log their activity to the command.log
  • rundeck.audit.log: Authorization messages pertaining to aclpolicy
  • rundeck.job.log: Log of all job definition changes
  • rundeck.options.log: Logs remote HTTP requests for Options JSON data
  • rundeck.log: General RunDeck application messages
  • service.log: Standard input and output generated during runtime

See the #log4j.properties section for information about customizing log message formats and location.

8.4 Backup and recovery

While running, export the Job definitions if you do not have these in source control:

  1. Export the jobs. You will have to do this for each project

    rd-jobs list -f /path/to/backup/dir/project1/jobs.xml -p project1
    rd-jobs list -f /path/to/backup/dir/project2/jobs.xml -p project2
    ...
    
  2. Stop the server. See: startup and shutdown. (RunDeck data file backup should only be done with the server down.)

    rundeckd stop
    
  3. Copy the data files. (Assumes file datastore configuration). The location of the data directory depends on the installation method:

    • RPM install: /var/lib/rundeck/data
    • Launcher install: $RDECK_BASE/server/data

      cp -r data /path/to/backup/dir
      
  4. Copy the log (execution output) files.

    • RPM install: /var/lib/rundeck/logs
    • Launcher install: $RDECK_BASE/var/logs

      cp -r logs /path/to/backup/dir
      
  5. Start the server

     rundeckd start
    

8.4.1 Recovery

  1. Stop the server. See: startup and shutdown. (RunDeck recovery should only be done with the server down.)

    rundeckd stop
    
  2. Restore data/logs dir from backup (Refer to above for appropriate log/data path):

    cp -r /path/to/backup/logs logspath
    cp -r /path/to/backup/data datapath
    
  3. Start the server:

    rundeckd start
    
  4. Reload the Job definitions. You will have to do this for each project:

    rd-jobs load -f /path/to/backup/dir/project1/jobs.xml -p project1
    rd-jobs load -f /path/to/backup/dir/project2/jobs.xml -p project2
    

8.5 Relational Database

You can configure RunDeck to use a RDB instead of the default file-based data storage.

You must modify the server/config/rundeck-config.properties file, to change the dataSource configuration, and you will have to add the appropriate JDBC driver JAR file to the lib directory.

8.5.1 Enable rdbsupport

First, you must enable the rundeck.v14.rdbsupport property:

#note, make sure this is set to "true" if you are using Oracle or Mysql
rundeck.v14.rdbsupport=true

This makes RunDeck use table/field names that are compatible with Oracle/Mysql.

Note: It is safe to set this to true if you are using the default file based backend, but only for a fresh install. It will cause a problem if you set it to true for an existing Rundeck 1.3 HSQLDB database. Make sure it is set to "false" or is absent from your config file if you are upgrading from Rundeck 1.3 and using the filesystem storage.

8.5.2 Customize the Datasource

The default dataSource is configured for filesystem storage using HSQLDB:

dataSource.url = jdbc:hsqldb:file:/var/lib/rundeck/data/grailsdb;shutdown=true

Here is an example configuration to use an Oracle backend:

dataSource.url = jdbc:oracle:thin:@localhost:1521:XE
dataSource.driverClassName = oracle.jdbc.driver.OracleDriver
dataSource.username = dbuser
dataSource.password = dbpass
dataSource.dialect = org.hibernate.dialect.Oracle10gDialect

Here is an example configuration to use Mysql:

dataSource.url = jdbc:mysql://myserver/rundeckdb
dataSource.username = dbuser
dataSource.password = dbpass

8.5.3 Add the JDBC Driver

Copy the appropriate JDBC driver, such as "ojdbc14.jar" for Oracle into the server lib dir:

cp ojdbc14.jar $RDECK_BASE/server/lib

Or:

cp mysql-connector-java-5.1.17-bin.jar $RDECK_BASE/server/lib

8.6 SSH

RunDeck uses SSH for remote execution. You do not need to have root account access on either the server or the remote hosts.

8.6.1 SSH configuration requirements

  • The SSH configuration requires that the RunDeck server machine can ssh commands to the client machines.
  • SSH is assumed to be installed and configured appropriately to allow this access.
  • No passphrase should be set.
  • SSH should not prompt for a password. There are many resources available on how to configure ssh to use public key authentication instead of passwords such as: Password-less logins with OpenSSH or How-To: Password-less SSH

8.6.2 SSH key generation

  • The RunDeck installation can be configured to use RSA or DSA type keys.

Here's an example of SSH RSA key generation on a Linux system:

$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/demo/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/demo/.ssh/id_rsa.
Your public key has been saved in /home/demo/.ssh/id_rsa.pub.
The key fingerprint is:
a7:31:01:ca:f0:62:42:9d:ab:c8:b7:9c:d1:80:76:c6 demo@ubuntu
The key's randomart image is:
+--[ RSA 2048]----+
| .o . .          |
|.  * . .         |
|. = =   .        |
| = E     .       |
|+ + o   S .      |
|.o o .   =       |
|  o +   .        |
|   +             |
|                 |
+-----------------+

8.6.3 Configuring remote machine for SSH

To be able to directly ssh to remote machines, the SSH public key of the client should be shared to the remote machine.

Follow the steps given below to enable ssh to remote machines.

The ssh public key should be copied to the authorized_keys file of the remote machine. The public key will be available in ~/.ssh/id_rsa.pub file.

The authorized_keys file should be created in the .ssh directory of the remote machine.

The file permission of the authorized key should be read/write for the user and nothing for group and others. To do this check the permission and change it as shown below.

$ cd ~/.ssh
$ ls -la
-rw-r--r--   1 raj  staff     0 Nov 22 18:14 authorized_keys

$ chmod 600 authorized_keys 
$ ls -la
-rw-------   1 raj  staff     0 Nov 22 18:14 authorized_keys

The permission for the .ssh directory of the remote machine should be read/write/execute for the user and nothing for the group and others. To do this, check the permission and change it as shown below.

$ ls -la
drwxr-xr-x   2 raj  staff    68 Nov 22 18:19 .ssh
$ chmod 700 .ssh
$ ls -la
drwx------   2 raj  staff    68 Nov 22 18:19 .ssh

If you are running RunDeck on Windows, we heartily recommend using Cygwin on Windows as it includes SSH and a number of Unix-like tools that are useful when you work in a command line environment.

8.6.4 Configuring SSH private keys

The built-in SSH connector allows the private key to be specified in several different ways. You can configure it per-node, per-project, or per-RunDeck instance.

When connecting to the remote node, RunDeck will look for a property/attribute specifying the location of the private key file, in this order, with the first match having precedence:

  1. Node level: ssh-keypath attribute on the Node. Applies only to the target node.
  2. Project level: project.ssh-keypath property in project.properties. Applies to any project node by default.
  3. RunDeck level: framework.ssh-keypath property in framework.properties. Applies to all projects by default.
  4. RunDeck level: framework.ssh.keypath property in framework.properties. Applies to all projects by default (included for compatibility with Rundeck < 1.3). (default value: ~/.ssh/id_rsa).

8.6.5 Passing environment variables through remote command

To pass environment variables through remote command dispatches, it is required to properly configure the SSH server on the remote end. See the AcceptEnv directive in the "sshd_config(5)" manual page for instructions.

Use a wild card pattern to permit RD_ prefixed variables to provide open access to RunDeck generated environment variables.

8.7 Managing logins

8.7.1 realm.properties

These instructions explain how to manage user credentials for RunDeck in the realm.properties file.

The default RunDeck webapp handles user authentication via its container, which in turn is configured to pull its user authentication from the $RDECK_BASE/server/config/realm.properties file. This file is created at the time that you install the server.

Assuming it wasn't modified, your realm.properties file will probably look something like this:

#
# This file defines users passwords and roles for a HashUserRealm
#
# The format is
#  <username>: <password>[,<rolename> ...]
#
# Passwords may be clear text, obfuscated or checksummed.  
#
# This sets the default user accounts for the RunDeck apps
#
admin:admin,user,admin
user:user,user

Adding additional users

You may wish to have additional users with various privileges rather than giving out role accounts to groups. You may also want to avoid having the passwords in plaintext within the configuration file.

To accomplish this, you'll need a properly hashed or encrypted password to use in the config. On the RunDeck server, move into the directory that contains your installation and pass the username and password to the Password utility. In this example, we'll setup a new user named "jsmith", with a password of "mypass":

$ cd $RDECK_BASE
$ java -cp server/lib/jetty-6.1.21.jar:server/lib/jetty-util-6.1.21.jar org.mortbay.jetty.security.Password jsmith mypass
OBF:1xfd1zt11uha1ugg1zsp1xfp
MD5:a029d0df84eb5549c641e04a9ef389e5
CRYPT:jsnDAc2Xk4W4o

Then add this to the realm.properties file with a line like so:

jsmith: MD5:a029d0df84eb5549c641e04a9ef389e5,user,admin

Then restart RunDeck to ensure it picks up the change and you're done.

8.7.2 Active Directory

note Because the underlying security mechanism relies on JAAS, you are free to use what ever JAAS provider you feel is suitable for your environment.

  1. Setup the LDAP login module configuration file

    Create a jaas-activedirectory.conf file in the same directory as the jaas-loginmodule.conf file.

    • RPM install: /etc/rundeck/
    • Launcher install: $RDECK_BASE/server/config
    activedirectory {
        com.dtolabs.rundeck.jetty.jaas.JettyCachingLdapLoginModule required
        debug="true"
        contextFactory="com.sun.jndi.ldap.LdapCtxFactory"
        providerUrl="ldap://localhost:389"
        bindDn="cn=Manager,dc=rundeck,dc=com"
        bindPassword="secret"
        authenticationMethod="simple"
        forceBindingLogin="true"
        userBaseDn="ou=users,dc=rundeck,dc=com"
        userRdnAttribute="cn"
        userIdAttribute="cn"
        userPasswordAttribute="unicodePwd"
        userObjectClass="user"
        roleBaseDn="ou=roles,dc=rundeck,dc=com"
        roleNameAttribute="cn"
        roleMemberAttribute="member"
        roleObjectClass="group"
        cacheDurationMillis="300000"
        reportStatistics="true";
        };
    

Note: The bindDn and bindPassword must escape any special characters with \ character. Special characters include \ (backslash), as well as ! (exclamation).

  1. To override the default JAAS configuration file, you will need to supply the RunDeck server with the proper path to the new one, and a loginmodule.name Java system property to identify the new login module by name.

    The JAAS configuration file location is specified differently between the Launcher and the RPM.

    For the Launcher: the loginmodule.conf.name Java system property is used to identify the name of the config file, which must be located in the $RDECK_BASE/server/config dir.

    You can simply specify the system properties on the java commandline:

    java -Dloginmodule.conf.name=jaas-activedirectory.conf \
        -Dloginmodule.name=activedirectory \
        -jar rundeck-launcher-x.x.jar
    

    Otherwise, if you are starting the Launcher via the supplied rundeckd script, you can modify the RDECK_JVM value in the $RDECK_BASE/etc/profile file to add two JVM arguments:

    export RDECK_JVM="-Dloginmodule.conf.name=jaas-activedirectory.conf \
        -Dloginmodule.name=activedirectory"
    

    Note: more information about using the launcher and useful properties are under Getting Started - Launcher Options.

    For the RPM installation: the absolute path to the JAAS config file must be specified with the java.security.auth.login.config property.

    Update the RDECK_JVM in /etc/rundeck/profile by changing the following two JVM arguments:

    export RDECK_JVM="-Djava.security.auth.login.config=/etc/rundeck/jaas-loginmodule.conf \
           -Dloginmodule.name=RDpropertyfilelogin \
    

    to

    export RDECK_JVM="-Djava.security.auth.login.config=/etc/rundeck/jaas-activedirectory.conf \
           -Dloginmodule.name=activedirectory \
    
  2. Restart rundeckd

    sudo /etc/init.d/rundeckd restart

  3. Attempt to logon

    If everything was configured correctly, you will be able to access RunDeck using your AD credentials. If something did not go smoothly, look at /var/log/rundeck/service.log for stack traces that may indicate what is wrong.

8.7.2.1 Communicating over secure ldap (ldaps://)

The default port for communicating with active directory is 389, which is insecure. The secure port is 686, but the LoginModule describe above requires that the AD certificate or organizations CA certificate be placed in a truststore. The truststore provided with rundeck /etc/rundeck/ssl/truststore is used for the local communication between the cli tools and the rundeck server.

Before you can establish trust, you need to get the CA certificate. Typically, this would require a request to the organization's security officer to have them send you the certificate. It's also often found publicly if your organization does secure transactions.

Another option is to interrogate the secure ldap endpoint with openssl. The example below shows a connection to paypal.com on port 443. The first certificate is the machine and that last is the CA. Pick the last certificate.

note that for Active Directory, the host would be the Active Directory server and port 686.
note Certificates are PEM encoded and start with -----BEGIN CERTIFICATE----- end with -----END CERTIFICATE----- inclusive.

$ openssl s_client -showcerts -connect paypal.com:443
CONNECTED(00000003)
depth=1 C = US, O = "VeriSign, Inc.", OU = VeriSign Trust Network, OU = Terms of use at https://www.verisign.com/rpa (c)09, CN = VeriSign Class 3 Secure Server CA - G2
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/C=US/ST=California/L=San Jose/O=PayPal, Inc./OU=Information Systems/CN=paypal.com
   i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)09/CN=VeriSign Class 3 Secure Server CA - G2
-----BEGIN CERTIFICATE-----
MIIFDjCCA/agAwIBAgIQL0NdM6l74HplIwrcygDcCTANBgkqhkiG9w0BAQUFADCB
tTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwOTEvMC0GA1UEAxMm
VmVyaVNpZ24gQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzIwHhcNMTAwNTAz
MDAwMDAwWhcNMTIwNjExMjM1OTU5WjB/MQswCQYDVQQGEwJVUzETMBEGA1UECBMK
Q2FsaWZvcm5pYTERMA8GA1UEBxQIU2FuIEpvc2UxFTATBgNVBAoUDFBheVBhbCwg
SW5jLjEcMBoGA1UECxQTSW5mb3JtYXRpb24gU3lzdGVtczETMBEGA1UEAxQKcGF5
cGFsLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArlvu+86iVb4RXdX+
8MjmGynNSl+Hu2/ZJ7nU1sj5O2jASWwFH7PFUv10qlRtL+gi3Rjw+zFN958iUetz
ef4CxQYf52PA7Uj9YlFEzLz7f8UDotu4WNLM3QGbLrqS28pPb2qKyyOQDvwNpI1c
Jt4JDa0ofVnCdICZEnf+cJB121MCAwEAAaOCAdEwggHNMAkGA1UdEwQCMAAwCwYD
VR0PBAQDAgWgMEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly9TVlJTZWN1cmUtRzIt
Y3JsLnZlcmlzaWduLmNvbS9TVlJTZWN1cmVHMi5jcmwwRAYDVR0gBD0wOzA5Bgtg
hkgBhvhFAQcXAzAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2lnbi5j
b20vcnBhMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAfBgNVHSMEGDAW
gBSl7wsRzsBBA6NKZZBIshzgVy19RzB2BggrBgEFBQcBAQRqMGgwJAYIKwYBBQUH
MAGGGGh0dHA6Ly9vY3NwLnZlcmlzaWduLmNvbTBABggrBgEFBQcwAoY0aHR0cDov
L1NWUlNlY3VyZS1HMi1haWEudmVyaXNpZ24uY29tL1NWUlNlY3VyZUcyLmNlcjBu
BggrBgEFBQcBDARiMGChXqBcMFowWDBWFglpbWFnZS9naWYwITAfMAcGBSsOAwIa
BBRLa7kolgYMu9BSOJsprEsHiyEFGDAmFiRodHRwOi8vbG9nby52ZXJpc2lnbi5j
b20vdnNsb2dvMS5naWYwDQYJKoZIhvcNAQEFBQADggEBADbOGDkzZy22y+fW4OR7
wkx+1E3BxnRMZYx89OOykzTEUt2UV5DVuccUbqxTxg9/4pKMYJLywYn9UIOPHpwx
fbvMQNpdqV3JSuGMTwpROrMvC3bT13aCxxDnozeCjd/lH74m6G5ef2EUd3m5Y+iC
fMPo2NMrVyQYOCtpJurh9Tre1gQFHUYAXw8ty0YxfMoR/7FwYbd4spiZJwL2Mvfn
9gn24dWuKY7JaFutomwOM78rGzBDZZ/spEx9rcNa3OuVHcqBamnnXQZlZJilj4LE
buMBx8ti5Oqy4z1u1vzA8HalseiZerqFtBGOIakXdto8qLnwYEHQvVa/ih5iTsi3
Ja8=
-----END CERTIFICATE-----
 1 s:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)09/CN=VeriSign Class 3 Secure Server CA - G2
   i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority - G2/OU=(c) 1998 VeriSign, Inc. - For authorized use only/OU=VeriSign Trust Network
-----BEGIN CERTIFICATE-----
MIIGLDCCBZWgAwIBAgIQbk/6s8XmacTRZ8mSq+hYxDANBgkqhkiG9w0BAQUFADCB
wTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTwwOgYDVQQL
EzNDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
IC0gRzIxOjA4BgNVBAsTMShjKSAxOTk4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1
dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
cmswHhcNMDkwMzI1MDAwMDAwWhcNMTkwMzI0MjM1OTU5WjCBtTELMAkGA1UEBhMC
VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU
cnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQgaHR0cHM6Ly93
d3cudmVyaXNpZ24uY29tL3JwYSAoYykwOTEvMC0GA1UEAxMmVmVyaVNpZ24gQ2xh
c3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQDUVo9XOzcopkBj0pXVBXTatRlqltZxVy/iwDSMoJWzjOE3JPMu
7UNFBY6J1/raSrX4Po1Ox/lJUEU3QJ90qqBRVWHxYISJpZ6AjS+wIapFgsTPtBR/
RxUgKIKwaBLArlwH1/ZZzMtiVlxNSf8miKtUUTovStoOmOKJcrn892g8xB85essX
gfMMrQ/cYWIbEAsEHikYcV5iy0PevjG6cQIZTiapUdqMZGkD3pz9ff17Ybz8hHyI
XLTDe+1fK0YS8f0AAZqLW+mjBS6PLlve8xt4+GaRCMBeztWwNsrUqHugffkwer/4
3RlRKyC6/qfPoU6wZ/WAqiuDLtKOVImOHikLAgMBAAGjggKpMIICpTA0BggrBgEF
BQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLnZlcmlzaWduLmNvbTAS
BgNVHRMBAf8ECDAGAQH/AgEAMHAGA1UdIARpMGcwZQYLYIZIAYb4RQEHFwMwVjAo
BggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL2NwczAqBggrBgEF
BQcCAjAeGhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMDQGA1UdHwQtMCsw
KaAnoCWGI2h0dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMtZzIuY3JsMA4GA1Ud
DwEB/wQEAwIBBjBtBggrBgEFBQcBDARhMF+hXaBbMFkwVzBVFglpbWFnZS9naWYw
ITAfMAcGBSsOAwIaBBSP5dMahqyNjmvDz4Bq1EgYLHsZLjAlFiNodHRwOi8vbG9n
by52ZXJpc2lnbi5jb20vdnNsb2dvLmdpZjApBgNVHREEIjAgpB4wHDEaMBgGA1UE
AxMRQ2xhc3MzQ0EyMDQ4LTEtNTIwHQYDVR0OBBYEFKXvCxHOwEEDo0plkEiyHOBX
LX1HMIHnBgNVHSMEgd8wgdyhgcekgcQwgcExCzAJBgNVBAYTAlVTMRcwFQYDVQQK
Ew5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy
eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5
OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYD
VQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrghB92f4Hz6getxB5Z/uniTTGMA0G
CSqGSIb3DQEBBQUAA4GBAGN0Lz1Tqi+X7CYRZhr+8d5BJxnSf9jBHPniOFY6H5Cu
OcUgdav4bC1nHynCIdcUiGNLsJsnY5H48KMBJLb7j+M9AgtvVP7UzNvWhb98lR5e
YhHB2QmcQrmy1KotmDojYMyimvFu6M+O0Ro8XhnF15s1sAIjJOUFuNWI4+D6ufRf
-----END CERTIFICATE-----
---
Server certificate
subject=/C=US/ST=California/L=San Jose/O=PayPal, Inc./OU=Information Systems/CN=paypal.com
issuer=/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)09/CN=VeriSign Class 3 Secure Server CA - G2
---
No client certificate CA names sent
---
SSL handshake has read 3039 bytes and written 401 bytes
---
New, TLSv1/SSLv3, Cipher is DES-CBC3-SHA
Server public key is 1024 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DES-CBC3-SHA
    Session-ID: A8AAA4F22E9A4B3F12F76303464643525178846D96CA0BC0B81F35368BF55B89
    Session-ID-ctx: 
    Master-Key: 9F767B91FC2450E291CBB21E3438CA9A73FE8D5B825AD98F821F5EB912C088DFB66FCBF2D53591E2D1ED77E9B6A22504
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    Start Time: 1295242116
    Timeout   : 300 (sec)
    Verify return code: 20 (unable to get local issuer certificate)
---
^C

Once a certificate has been obtained. There are two options for adding the certificate. The first involves updating the truststore for the JRE. If that is not possible or not desirable, then one can set the truststore to be used by the jvm, using any arbitrary truststore that contains the appropriate certificate.

Both options require importing a certificate. The following would import a certificate called, AD.cert into the /etc/rundeck/ssl/truststore.

keytool -import -alias CompanyAD -file AD.cert -keystore /etc/rundeck/ssl/truststore -storepass adminadmin 

To add the certificate to the JRE, locate the file $JAVA_HOME/lib/security/cacerts and run

keytool -import -alias CompanyAD -file AD.cert -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit 

To verify your CA has been added, run keytool list and look for CompanyAD in the output.

keytool -list -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit

Refer to: http://download.oracle.com/javase/1.5.0/docs/tooldocs/solaris/keytool.html for more information how how to import a certificate.

Finally, in your ldap-activedirectory.conf be sure to change the providerUrl to be ldaps://ad-server. Including the port is optional as the default is 686.

8.7.2.2 Redundant Connection Options

providerUrl can take multiple, space delimited, urls. For example:

 providerUrl=ldaps://ad1 ldaps://ad2  

Use this to provide connection redundancy if a particular host is unavailable.

8.8 Authorization

Two dimensions of information dictate authorization inside RunDeck:

  • group memberships assigned to a user login.
  • access control policy that grants access to one or more policy actions to a group or user.

The section on managing logins discusses how to assign group memberships to users.

The remainder of this section will describe how to use the access control policy.

Note from the project team: The authorization layer is an early work in progress. Please share your ideas on the IRC or mailing list.

8.8.1 Access control policy

Access to running or modifying Jobs is managed in an access control policy defined using the aclpolicy YAML document. This file contains a number of policy elements that describe what user group is allowed to perform which actions.

Please read over this document for information on how to define it, and how to grant access for certain actions to certain resources:

Policies can be organized into more than one file to help organize access by group or pattern of use. The normal RunDeck install will have generated a policy for the "admin" group. Not all users will need to be given "admin" access level to control and modify all Jobs. More typically, a group of users will be given access to just a subset of Jobs.

File listing: admin.aclpolicy example

description: Admin project level access control. Applies to resources within a specific project.
context:
  project: '.*' # all projects
for:
  resource:
    - equals:
        kind: job
      allow: [create] # allow create jobs
    - equals:
        kind: node
      allow: [read,create,update,refresh] # allow refresh node sources
    - equals:
        kind: event
      allow: [read,create] # allow read/create events
  adhoc:
    - allow: [run,kill] # allow running/killing adhoc jobs
  job: 
    - allow: [read,update,delete,run,kill] # allow read/write/delete/run/kill of all jobs
  node:
    - allow: [read,run] # allow read/run for all nodes
by:
  group: admin

---

description: Admin Application level access control, applies to creating/deleting projects, admin of user profiles, viewing projects and reading system information.
context:
  application: 'rundeck'
for:
  resource:
    - equals:
        kind: project
      allow: [create] # allow create of projects
    - equals:
        kind: system
      allow: [read] # allow read of system info
    - equals:
        kind: user
      allow: [admin] # allow modify user profiles
  project:
    - match:
        name: '.*'
      allow: [read,admin] # allow view/admin of all projects
by:
  group: admin

The example policy document above demonstrates the access granted to the users in group "admin".

Two separate policies define two levels of access control. The first is the "project" context, which allows access to actions on resources within a specific project. The second is the "application" level context, which allows access to things like creating projects, access to projects, managing users, and access to system information.

8.8.2 Specific Resources and Resource Types

As described in the aclpolicy-v10(5) definition, access is granted or denied to specific "resources". Resources can take two forms:

  • A specific resource, with a type and properties
  • Resource types, which applies to all resources of a specific type or "kind"

For example, you might want to restrict access to a job or jobs within a certain group. This corresponds to specific "job" resources with a "group" property matching a certain pattern.

You might also want to restrict who can create new jobs. Since a new job does not exist yet, you cannot create a rule for this action to apply to an existing job. Which means this corresponds to a generic resource with a "kind" called "job".

8.8.3 Special API Token Authentication group

Clients of the Web API may use the Token Authentication method. These clients are placed in the special authorization group called api_token_group.

api_token_group
Special role given to all API Token authenticated access.

8.8.4 RunDeck resource authorizations

RunDeck declares a number of actions that can be referenced inside the access control policy document.

The actions and resources are divided into project scope and application scope:

8.8.4.1 Application Scope Resources and Actions

You define application scope rules in the aclpolicy, by declaring this context:

context:
  application: 'rundeck'

These are the Application scope actions that can be allowed or denied via the aclpolicy:

  • Creating Projects ('create' action on a resource type with kind 'project')
  • Reading system information ('read' action on a resource type with kind 'project')
  • Administering user profiles ('admin' action on a resource type of kind 'user')
  • Reading specific projects ('read' action on a project with a specific name)
  • Administering specific projects ('admin' action on a project with a specific name

The following table summarizes the generic and specific resources and the actions you can restrict in the application scope:

Application scope generic type actions
TypeResource KindPropertiesActionsDescription
resourceprojectnonecreateCreate a new project
resourcesystemnonereadRead system information
resourceusernoneadminModify user profiles
Application scope specific resource actions
TypePropertiesActionsDescription
project"name"readView a project in the project list
project"name"adminModify project configuration

8.8.4.2 Project Scope Resources and Actions

You define project scope rules in the aclpolicy by declaring this context:

context:
  project: "(regex)"

The regex can match all projects using ".*", or you can simply put the project name.

Note that for projects not matched by an aclpolicy, no actions will be granted to users.

Also note that to hide projects completely from users, you would need to grant or deny the "read" access to the project in the Application Scope.

These are the Application scope actions that can be allowed or denied via the aclpolicy:

  • Create Jobs ('create' action on a resource type with kind 'job')
  • Read Node data ('read' action on a resource type with kind 'node')
  • Update/Refresh node data ('create','update','refresh' action on a resource type with kind 'node')
  • Read history events ('read' action on a resource type with kind 'event')
  • Create history events ('create' action on a resource type with kind 'event')
  • Run adhoc jobs ('run' action on 'adhoc' resources)
  • Kill adhoc jobs ('kill' action on 'adhoc' resources)
  • Any Action on Jobs (actions on 'job' resources, see below)

The following table summarizes the generic and specific resources and the actions you can restrict in the project scope:

Project scope generic type actions
TypeResource KindActionsDescription
resourcejobcreateCreate a new Job
"nodereadRead node information
""createCreate new node entries
""updateModify node entries
""refreshRefresh node entry from a URL
"eventreadRead history event information
""createCreate arbitrary history event entries
Project scope specific resource actions
TypePropertiesActionsDescription
adhocrunRun and adhoc execution
"killKill an adhoc execution
job"name","group"readView a Job
"updateModify a job
"deleteDelete a job
"runRun a job
"killKill a running job
"createCreate the matching job
node"rundeck_server", "nodename", ...readView the node in the UI
"runRun jobs/adhoc on the node

Recall that defining rules for a resource type is done in this way:

for:
  resource:
    - equals:
        kind: 'project'
      allow: [create]

Whereas defining rules for specific resources of a certain type is done in this way:

for:
  job:
    - equals:
        name: bob
      allow: [run]

Note, for node resources, the properties available are all the attributes that are defined on the node, so you can apply authorizations based on tag, osName, hostname, etc. The special rundeck_server property will be set to "true" for the RunDeck server node only, and "false" for all other nodes.

8.8.4.3 Access control policy actions example

Below is an example policy document demonstrating policy actions to create limited access for a group of users. Users in the group "restart_user", are allowed to run three jobs in the "adm" group, Restart, stop and start. By allowing run but not read, the "stop" and "start" jobs will not be visible.

File listing: restart_user.aclpolicy example

description: Limited user access for adm restart action
context:
  project: '.*'
for:
  job:
    - equals:
        group: 'adm'
        name: 'Restart'
      allow: [run,read]
    - equals:
        group: 'adm'
        name: 'stop'
      allow: [run]
    - equals:
        group: 'adm'
        name: 'start'
      allow: [run]
by:
  group: [restart_user]

8.8.5 Troubleshooting access control policy

After defining an aclpolicy file to grant access to a particular group of users, you may find them getting "unauthorized" messages or complaints that certain actions are not possible.

To diagnose this, begin by checking two bits:

  1. The user's group membership. This can be done by going to the user's profile page in RunDeck. That page will list the groups the user is a member.
  2. Read the messages inside the rundeck.audit.log log file. The authorization facility generates fairly low level messages describing how the policy is matched to the user context.

For each entry in the audit log, you'll see all decisions leading up to either a AUTHORIZED or a REJECTED message. It's not uncommon to see REJECTED messages followed by AUTHORIZED. The important thing is to look at the last decision made.

8.8.6 Authorization caveats

  • aclpolicy changes do not require a restart.

8.9 Configuring Rundeck for SSL

This document describes how to configure Rundeck for SSL/HTTPS support, and assumes you are using the rundeck-launcher standalone launcher.

  1. Before beginning, do a first-run of the launcher, as it will create the base directory for Rundeck and generate configuration files.

    cd $RDECK_BASE;  java -jar rundeck-launcher-1.1.0.jar
    

This will start the server and generate necessary config files. Press control-c to shut down the server.

  1. Using the keytool command, generate a keystore for use as the server cert and client truststore. Specify passwords for key and keystore:

    keytool -keystore etc/keystore -alias rundeck -genkey -keyalg RSA -keypass admin -storepass admin
    

Be sure to specify the correct hostname of the server as the response to the question "What is your first and last name?". Answer "yes" to the final question.

You can pass all the answers to the tool on the command-line by using a HERE document.

Replace the first line "Venkman.local" with the hostname for your server, and use any other organizational values you like:

    keytool -keystore etc/keystore -alias rundeck -genkey -keyalg RSA -keypass adminadmin -storepass adminadmin  <<!
    Venkman.local
    devops
    My org
    my city
    my state
    US
    yes
    !
  1. CLI tools that communicate to the Rundeck server need to trust the SSL certificate provided by the server. They are preconfigured to look for a truststore at the location: $RDECK_BASE/etc/truststore. Copy the keystore as the truststore for CLI tools:

    cp etc/keystore etc/truststore
    
  2. Modify the ssl.properties file to specify the location of the keystore and the appropriate passwords:

    vi server/config/ssl.properties
    

An example ssl.properties file (from the RPM package).

    keystore=/etc/rundeck/ssl/keystore
    keystore.password=adminadmin
    key.password=adminadmin
    truststore=/etc/rundeck/ssl/truststore
    truststore.password=adminadmin
  1. Configure client properties. Modify the file $RDECK_BASE/etc/framework.properties and change these properties:

    • framework.server.url
    • framework.rundeck.url
    • framework.server.port

Set them to the appropriate https protocol, and change the port to 4443, or to the value of your -Dserver.https.port runtime configuration property.

  1. Launch the rundeck launcher and tell it where to read the ssl.properties

    java -Drundeck.ssl.config=$RDECK_BASE/server/config/ssl.properties -jar rundeck-launcher-1.1.0.jar
    

You can change port by adding -Dserver.https.port:

    java -Drundeck.ssl.config=$RDECK_BASE/server/config/ssl.properties -Dserver.https.port=1234 rundeck-launcher-1.1.0.jar

If successful, you will see a line indicating the SSl connector has started:

Started SslSocketConnector@0.0.0.0:4443

8.9.1 Securing passwords

Passwords do not have to be stored in the ssl.config. If they are not set, then the server will prompt on the console for a user to enter the passwords.

If you want the server to start without prompting then you need to set the passwords in the config file.

The passwords stored in ssl.properties can be obfuscated so they are not in plaintext:

Run the jetty "Password" utility:

$ java -cp server/lib/jetty-6.1.21.jar:server/lib/jetty-util-6.1.21.jar org.mortbay.jetty.security.Password <password>

This will produce two lines, one starting with "OBF:"

Use the entire OBF: output as the password in the ssl.properties file, eg:

key.password=OBF:1lk2j1lkj321lj13lj

8.9.2 Troubleshooting keystore

Some common error messages and causes:

java.io.IOException: Keystore was tampered with, or password was incorrect

A password specified in the file was incorrect.

2010-12-02 10:07:29.958::WARN: failed SslSocketConnector@0.0.0.0:4443: java.io.FileNotFoundException: /Users/greg/rundeck/etc/keystore (No such file or directory)

The keystore/truststore file specified in ssl.properties doesn't exist

8.9.3 Optional PEM export

You can export the PEM formatted server certificate for use by HTTPS clients (web browsers or e.g. curl).

Export pem cacert for use by e.g. curl:

keytool -export -keystore etc/keystore -rfc -alias rundeck > rundeck.server.pem

8.10 Customizing RunDeck GUI

You can modify some display features of the RunDeck GUI by setting these properties in the rundeck-config.properties file:

PropertyDescriptionExample
rundeck.gui.titleTitle shown in app headerTest App
rundeck.gui.logoLogo icon path relative to webapps/rundeck/images dirtest-logo.png
rundeck.gui.logo-widthIcon width for proper display (32px is best)32px
rundeck.gui.logo-heightIcon height for proper display (32px is best)32px
rundeck.gui.titleLinkURL for the link used by the app header icon.http://rundeck.org
rundeck.gui.helpLinkURL for the "help" link in the app header.http://rundeck.org/ docs
rundeck.gui.realJobTreeDisplaying a real tree in the Jobs overview instead of collapsing empty groups. Default: truefalse

8.11 Customizing configuration for scale

Note: This section is early in its development.

8.11.1 File descriptors

The RunDeck server process opens a number of files during normal operation. These include system and java libraries, logs, and sockets. Your system restricts the number of open file handles per process but these limitations can be adjusted.

If your installation attempts to exceed the limit, you will see an error like the one shown below in your service.log file.

Too many open files 

On Linux nodes

List the current limit with the ulimit command:

ulimit -n

If the limit is low (eg 1024) it should be raised.

You can get the current number of open file descriptors used by the RunDeck server process with lsof:

losf -p <rundeck pid> | wc -l

Increase the limit for a wide margin. Edit /etc/security/limits.conf file to raise the hard and soft limits. Here they are raised to 65535 for the "rundeck" system account:

rundeck hard nofile 65535
rundeck soft nofile 65535

The system file descriptor limit is set in /proc/sys/fs/file-max. The following command will increase the limit to 65535:

echo 65535 > /proc/sys/fs/file-max

In a new shell, run the ulimit command to set the new level:

ulimit -n 65535

The ulimit setting can be set in the rundeckd startup script, or profile.

Restart RunDeck.

8.11.2 Java heap size

The rundeckd startup script sets initial and maximum heap sizes for the server process. For many installations it will be sufficient.

If the Rundeck JVM runs out of memory, the following error occurs:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

Heap size is governed by the following startup parameters: -Xms<initial heap size> and -Xmx<maximum heap size>

You can increase these by updating the RunDeck profile. To see the current values, grep the profile for the Xmx and Xms patterns:

  • Launcher installs:

    egrep '(Xmx|Xms)' $RDECK_BASE/etc/profile
    
  • RPM installs:

    egrep '(Xmx|Xms)' /etc/rundeck/profile
    

The default settings initialized by the installer sets these to 1024 megabytes maximum and 256 megabytes initial:

export RDECK_JVM="$RDECK_JVM -Xmx1024m -Xms256m"

Sizing advice

Several factors drive memory usage in RunDeck:

  • User sessions
  • Concurrent threads
  • Concurrent jobs
  • Number of managed nodes

For example, if your installation has dozens of active users that manage a large environment (1000+ nodes), and has sufficient system memory, the following sizings might be more suitable:

export RDECK_JVM="$RDECK_JVM -Xmx4096m -Xms1024m -XX:MaxPermSize=256m"

8.11.3 Quartz job threadCount

The maximum number of threads used by RunDeck for concurrent jobs is set in the quartz.properties file. By default, this is set to 10.

  • RPM install: /var/lib/rundeck/server/exp/webapp/WEB-INF/classes/quartz.properties
  • Launcher install: $RDECK_BASE/server/exp/webapp/WEB-INF/classes/quartz.properties

To change the maximum threadCount modify this file and alter the line:

org.quartz.threadPool.threadCount = 20

Set the threadCount value to the max number of threads you want to run concurrently.

Please refer to the Quartz site for detailed information: Configuration - Thread Pool

8.11.4 JMX instrumentation

You may wish to monitor the internal operation of your RunDeck server via JMX.

JMX provides introspection on the JVM, the application server, and classes all through a consistent interface. These various components are exposed to the management console via JMX managed beans — MBeans for short.

Note: For more background information on JMX, see "Java theory and practice: Instrumenting applications with JMX.".

Enable local JMX monitoring by adding the com.sun.management.jmxremote flag to the startup parameters in the profile.

export RDECK_JVM="$RDECK_JVM -Dcom.sun.management.jmxremote"

You use a JMX client to monitor JMX agents. This can be a desktop GUI like JConsole run locally.

jconsole <rundeck pid>

For instructions on remote JMX monitoring for Grails, Spring and log4j see: Grails in the enterprise. # Integration with External Data Providers

RunDeck can integrate with external data by configuring the use of Providers or Sources. Providers are third-party services or systems that export data that RunDeck can import. Additionally, RunDeck supports an external Editor for Node data.

RunDeck makes use of common data formats (XML, JSON & YAML). Third-party software may produce these formats natively, however it is typical to have to massage the output of one system into the appropriate format to be consumed by RunDeck. Since URLs and HTTP are a lowest-common-denominator for communication, RunDeck only requires that the data Providers make this data available as a file at a URL or on the local disk.

There are a few types of external integration:

Resource Model Source

Provides a set of Nodes in XML or YAML format. E.g. a CMDB or hosted virtual machines service. RunDeck can be configured to use a different provider for each Project, and can refresh the Resources it uses from this provider.

Resource Editor

Provides a web-based editor to manage the Node definitions. RunDeck can link to this editor from the Run page, and has optional JavaScript interactions to make editing externally-managed Node resources integrated with the RunDeck GUI.

Option Model Provider

Provides a dataset in JSON format, used as input option values for Jobs. Each Job Option can be configured to load the set of allowed input values from a remote service, and the RunDeck GUI will prompt the user to choose from those values when running a Job.

8.12 Resource Model Source

The Resource model source is a way to transfer Node definitions from other systems, tools or services into RunDeck. The means of providing the Resource model data can be done in whichever way suits your environment best.

RunDeck supports plugins to provide different kinds of sources, but has built-in support for URLs or File based sources.

Resource model data is a set of Node descriptors, each with a uniquely identifying name. In addition to Name, some pieces of metadata are required (like hostname, and username), and some are optional.

(See Resource Model Document Formats for more information on what format the files need to be in.)

The Resource model data is stored on the server as a set of files. Each Project in RunDeck has at least a single Resources file, and may have multiple additional sources (such as a URL or a directory containing multiple files). All of these sources will be combined into the set of all Nodes that are available for the project. Each node's metadata can define how to connect to it and run commands.

8.12.1 Requirements

In order to provide the Resource model data to RunDeck:

  1. The data must be in one of the supported Resource Model Document Formats
  2. Each Node entry must have a unique name value. You may have to convert the external system's identifier to be unique, or create one yourself.

This means you can provide the data in the way that best suits your specific use-case. Some examples:

  • Hand-crafted XML/YAML data, which you could store in a version control system. The URL for the file in the VCS repository would be provided to RunDeck.
    • To update the data you would commit changes to your VCS, and then tell RunDeck to refresh.
  • Data generated from a custom CMDB or other software, and stored on disk.
    • You could do this with a cron-job, or via some external trigger. RunDeck will simply read the resource.xml/resource.yaml file identified in the configuration file.
  • Data generated from a simple CGI script which interfaces with another third-party or external service.
    • You could run Apache and host a simple CGI script. The CGI script would communicate to some other system and then return the XML/YAML content. You could tell RunDeck to refresh the Resource model, which would in turn cause the CGI to access the external data and return the reformatted content.
  • Using a Resource Model Source Plugin, the data could come from some other external source

The Resource model data does not have to include the RunDeck server Node, as it is implicitly included.

8.12.2 Configuration

Resource model sources are defined on a per-project basis, in the project.properties file.

The only required configuration value is project.resources.file, which defines a single file containing resource model data stored on-disk. Each new project will have a good default location, but you may change either the location or the file extension. The file extension determines the format of the data. (See Resource Model Document Formats.)

project.resources.file = ..

This file path is where RunDeck will read the contents from, and also where it will store it to if refreshing from a remote URL.

You may also specify a URL, which will be automatically retrieved and stored in a cache file. The Resource Model data within the content is merged with the previous file.

project.resources.url = http://...

This configures the remote URL for loading the Resources model data.

In addition, multiple Resource Model Source Plugin can be configured to add additional sources of Resource Model data.

8.12.3 Implementations and Examples

8.12.3.1 Simple VCS URL resource model source

Putting the resources.xml/resources.yaml file under the control of a source code management tool is a simple solution to controlling and tracking change to the resources.xml file. Any changes will be committed and the commit messages become an audit log. Most source code management tools provide a web interface to retrieve file revisions based on a URL and thus make it accessible as a resource model source.

Going back to the Acme Anvils Example section, imagine the administrator decides the VCS approach is a good first step to control versioning for the anvils resource model. Acme is a subversion user and installed viewvc to give web access to the repository.

First, the current resources.xml is added to the repository and committed:

svn add resources.xml http://svn.acme.com/ops/anvils/resources.xml
svn commit -m "added resource model for anvils" resources.xml

To test access, the administrator downloads the latest revision (ie, "HEAD") via the "viewvc" interface.

 curl http://svn.acme.com/viewvc/ops/anvils/resources.xml?revision=HEAD

Next, the anvils project.properties configuration file is modified to reference the URL to retrieve the "HEAD" revision:

project.resources.file = /etc/rundeck/projects/anvils/resources.xml
project.resources.url  = http://svn.acme.com/viewvc/ops/anvils/resources.xml?revision=HEAD

This configuration specifies the anvils resource model will be retrieved from project.resources.url and then stored at project.resources.file. Now, anytime RunDeck refreshes the anvils resource model, it will request the resources.xml file from the viewvc URL, obtaining the latest revision.

8.12.3.2 Amazon EC2 Nodes

Amazon's EC2 (Elastic Cloud Compute) is a cloud service in wide use for dynamic infrastructure; it is easy to start up and shut down Node "Instances" in the cloud.

For RunDeck, we would like to have a way of querying the EC2 service to see what EC2 Instances are available for use as RunDeck Nodes.

Amazon has a well-defined API for communication with their services, which allows us to pull out the EC2 data, and generate XML.

For this purpose, DTO Labs has created a Java-based implementation of this mechanism as the java-ec2-nodes project.

Use is fairly simple:

  1. Unpack the distribution file "java-ec2-nodes-0.1-bin.zip". This contains the required java Libs and a Perl based CGI script.
  2. Create an AWSCredentials.properties to specify your AWS credentials. (Available at this page.) Place the file within the expanded java-ec2-nodes directory. This file should contain:

    accessKey=<your access key>
    secretKey=<your secret key>
    
  3. Place the generatenodes.cgi file within a webroot folder of an Apache server, and configure Apache to allow Options +ExecCGI for that folder.
  4. Modify the "$basedir" variable in generatenodes.cgi to point to the dir containing the zip contents you unpacked.

Finally, you should be able to do HTTP GET for the CGI (e.g. http://myserver/scripts/generatenodes.cgi) and see an XML file returned. Note that the CGI allows query parameters to be used as API filters, e.g. ?tag:mytag=myvalue. (These filters are specific to the EC2 API.)

Once you have the CGI producing valid XML, you can set the project.resources.url property in your project's project.properties file to be the URl to the CGI.

Finally, within RunDeck, you can Refresh the Nodes from within the Run tab. You should see a Node entry for each EC2 Instance that is available.

You can easily manage the set of Nodes that gets returned from EC2 by organizing them by use of EC2 Tags, and applying query Filters to the EC2 API query.

In the EC2 interface, modify an Instance and add a Tag. Set the Tag name to "RunDeck-Project" and the value to "MyProject" (or your project name).

Then modify the URL used as your project.resources.url, to specify a query parameter of ?tag:RunDeck-Project=MyProject. Then RunDeck will only see those Instances with that tag as Nodes within that RunDeck project.

More configuration is available for the java-ec2-nodes project.

8.12.3.3 Third party URL resource model sources

URL Resource model sources can be developed by third parties to integrate RunDeck with their tools.

Check the list on our wiki: https://github.com/dtolabs/rundeck/wiki/Resource-model-providers.

8.13 Option model provider

The Option model provider is a mechanism to allow the Options defined for a Job to have some of the possible input values provided by a remote service or database.

Option model providers are configured on a per-Option basis (where a Job may have zero or more Options).

8.13.1 Requirements

  1. Options model data must be JSON formatted.
  2. It must be accessible via HTTP or on the local disk for the RunDeck server.
  3. It must be in one of two JSON structures, either:
    • An array of string values
    • OR, an array of Maps, each with two entries, name and value.

8.13.2 Configuration

Each Option entry for a Job can be configured to get the set of possible values from a remote URL. If you are authoring the Jobs via job.xml file format, simply add a valuesUrl attribute for the <option>. If you are modifying the Job in the RunDeck web GUI, you can entry a URL in the "Remote URL" field for the Option.

e.g.:

<option valuesUrl="http://site.example.com/values.json" ...

Note: File URL scheme is also acceptable (e.g, file:/path/to/job/options/optA.json).

The value data must be returned in JSON data format described below.

8.13.3 JSON format

Three styles of return data are supported: simple list, simple object, and a name/value list. For a simple list, the list values will be displayed in a pop-up list when running the Job. If a simple object or name/value pairs are returned, then the name will be displayed in the list, but the value will be used as the input.

Examples

Simple List:

["x value for test","y value for test"]

This will populate the select menu with the given values.

Simple Object:

{ "Name": "value1", "Name2":"value2" }

This will populate the select menu to show the names and use the values.

Name Value List:

[
  {name:"X Label", value:"x value"},
  {name:"Y Label", value:"y value"},
  {name:"A Label", value:"a value"}
] 

8.13.4 Variable expansion in remote URLs

The URL declared for the "valuesUrl" can embed variables which will be filled with certain job context items when making the remote request. This helps make the URLs more generic and contextual to the Job.

Two types of expansions are available, Job context, and Option context.

To include job information in the URL, specify a variable of the form ${job.property}.

Properties available for Job context:

  • name: Name of the Job
  • group: Group of the Job
  • description: Job description
  • project: Project name
  • argString: Default argument string for a job

To include Option information in the URL, specify a variable of the form ${option.property}:

Properties available for Option context:

  • name: Name of the current option

Examples

http://server.com/test?name=${option.name}

Passes the option name as the "name" query parameter to the URL.

http://server.com/test?jobname=${job.name}&jobgroup=${job.group}

Passes the job name and group as query parameters.

8.13.5 Remote request failures

If the request for the remote option values fails, then the GUI form will display a warning message:

In this case, the option will be allowed to use a textfield to set the value.

8.13.6 Implementations and Examples

The following two sections describe examples using simple CGI scripts that act as option model providers.

8.13.6.1 Hudson artifacts option provider

An end-to-end release process often requires obtaining build artifacts and publishing them to a central repository for later distribution. A continuous integration server like Hudson makes identifying the build artifacts a simple Job configuration step. The Hudson API provides a network interface to obtain the list of artifacts from successful builds via a simple HTTP GET request.

Acme builds its artifacts as RPMs and has configured their build job to identify them. The operations team wants to create Jobs that would allow them to choose a version of these artifacts generated by the automated build.

A simple CGI script that requests the information from Hudson and then generates a JSON document is sufficient to accomplish this. The CGI script can use query parameters to specify the Hudson server, hudson job and artifact path. Job writers can then specify the parameterized URL to the CGI script to obtain the artifacts list as an options model and present the results as a menu to Job users.

The code listing below shows the the CGI script essentially does a call to the curl command to retrieve the XML document containing the artifacts information and then parses it using xmlstarlet.

File listing: hudson-artifacts.cgi

#!/bin/bash
# Requires: curl, xmlstarlet
# Returns a JSON list of key/val pairs
#
# Query Params and their defaults
hudsonUrl=https://build.acme.com:4440/job
hudsonJob=ApplicationBuild
artifactPath=/artifact/bin/dist/RPMS/noarch/

echo Content-type: application/json
echo ""
for VAR in `echo $QUERY_STRING | tr "&" "\t"`
do
  NAME=$(echo $VAR | tr = " " | awk '{print $1}';);
  VALUE=$(echo $VAR | tr = " " | awk '{ print $2}' | tr + " ");
  declare $NAME="$VALUE";
done

curl -s -L -k $hudsonUrl/${hudsonJob}/api/xml?depth=1 | \
  xmlstarlet sel -t -o "{" \
    -t -m "//build[result/text()='SUCCESS']" --sort A:T:L number  \
    -m . -o "&quot;Release" -m changeSet/item -o ' ' -v revision -b \
    -m . -o ", Hudson Build " -v number -o "&quot;:" \
    -m 'artifact[position() = 1]' -o "&quot;" -v '../number' -o $artifactPath -o "{" -b \
    -m 'artifact[position() != last()]' -v 'fileName' -o "," -b \
    -m 'artifact[position() = last()]' -v 'fileName' -o "}&quot;," \
    -t -o "}"

After deploying this script to a CGI enabled directory on the operations web server, it can be tested directly by requesting it using curl.

curl -d "hudsonJob=anvils&artifactPath=/artifact/bin/dist/RPMS/noarch/" \
    --get http://opts.acme.com/cgi/hudson-artifacts.cgi

The server response should return JSON data resembling the example below:

[ 
  {name:"anvils-1.1.rpm", value:"/artifact/bin/dist/RPMS/noarch/anvils-1.1.rpm"}, 
  {name:"anvils-1.2.rpm", value:"/artifact/bin/dist/RPMS/noarch/anvils-1.2.rpm"} 
]   

Now in place, jobs can request this option data like so:

 <option name="package" enforcedvalues="true" required="true"
    valuesUrl="http://ops.acme.com/cgi/hudson-artifacts.cgi?hudsonJob=anvils"/> 

The RunDeck UI will display the package names in the menu and once selected the Job will have the path to the build artifact on the Hudson server.

8.13.6.2 Yum repoquery option model provider

Yum is a great tool for automating RPM package management. With Yum, administrators can publish packages to the repository and then use the yum client tool to automate the installation of packages along with their declared dependencies. Yum includes a command called repoquery useful for querying Yum repositories similarly to rpm queries.

Acme set up their own Yum repository to distribute application release packages. The Acme administrator wants to provide an option model to Jobs that need to know what packages provide a given capability.

The code listing below shows it is a simple wrapper around the repoquery command that formats the results as JSON data.

File listing: yum-repoquery.cgi

#!/bin/bash
# Requires: repoquery
# 
# Query Params and their defaults
repo=acme-staging
label="Anvils Release"
package=anvils
max=30
#
echo Content-type: application/json
echo ""
for VAR in `echo $QUERY_STRING | tr "&" "\t"`
do
  NAME=$(echo $VAR | tr = " " | awk '{print $1}';);
  VALUE=$(echo $VAR | tr = " " | awk '{ print $2}' | tr + " ");
  declare $NAME="$VALUE";
done

echo '{'
repoquery --enablerepo=$repo --show-dupes \
  --qf='"${label} %{VERSION}-%{RELEASE}":"%{NAME}-%{VERSION}-%{RELEASE}",' \
  -q --whatprovides ${package} | sort -t - -k 4,4nr | head -n${max}
echo '}'

After deploying this script to the CGI enabled directory on the operations web server, it can be tested directly by requesting it using curl.

curl -d "repo=acme&label=Anvils&package=anvils" \
    --get http://ops.acme.com/cgi/yum-repoquery.cgi

The server response should return JSON data resembling the example below:

TODO: include JSON example

Now in place, jobs can request the option model data like so:

 <option name="package" enforcedvalues="true" required="true"
    valuesUrl="http://ops.acme.com/cgi/yum-repoquery.cgi?package=anvils"/> 

The RunDeck UI will display the package names in the menu and once selected, the Job will have the matching package versions.

8.14 Resource Editor

The Resource Editor integration is a way to link to a third-party system used for managing Node definitions from within RunDeck. Each Node entry in the resources.xml or resources.yaml can define a URL to provide an "Edit" link that will appear in the RunDeck Run page for that Node.

This allows you to make use of the Resource Model Source in a more seamless way. RunDeck will load the Resource model from the third-party Provider system, and users of RunDeck can click straight to the Editor for those Nodes. The Provider and the Editor could be the same system, or they could both be custom CGI scripts that integrate with a third system.

Some teams have acquired or developed tools to manage information about the hosts deployed in their networks. These tools have interfaces to not just view but also modify the data about these hosts. Though there is no widely used common standard adopted by users of these tools, it is possible to map the data to meet the needs of RunDeck resource models.

8.14.1 Definition

The RunDeck resource model document format and the resource-yaml-v13 format provide two attributes that help connect the dots between the RunDeck UI and the editing interface provided by the external data management tool. They can use editUrl or remoteUrl attributes to specify the remote URL. The URLs can embed properties about the node to expand prior to being loaded, which allows you to e.g. submit query parameters using the node name.

editUrl

Specifies a URL to a remote site which will allow editing of the Node. When specified, the Node resource will display an "Edit" link in the RunDeck GUI and clicking it will open a new browser page for the URL.

remoteUrl

Specifies a URL for a remote site which will be loaded in an iframe within a RunDeck page. Clicking the "Edit" link for the Node will load content from the site within the current RunDeck page, allow you to perform your edit at the remote site, and has optional JavaScript hooks to report the state of the editing process back to the RunDeck page for a more streamlined user interface.

8.14.2 Using properties

Properties of the Node can be embedded in the URL and expanded prior to use. The syntax is:

${node.property}

Available properties are:

name, hostname, os-name, os-version, os-family, os-arch, username, description, tags, project

You can embed these properties within the url like this:

http://mycmdb:8080/node/edit?name=${node.name}

8.14.3 Using remoteUrl

Using the remoteUrl lets you embed another site into an iframe within the RunDeck page, and optionally allows communication back to the RunDeck page about the state of the editing process.

If you want to embed the remote site without having to make any changes to the remote page content, you can do so simply by specifying the remoteUrl to use. When the user clicks "Edit" the site will load within an iframe, and the user can perform whatever actions on the site are necessary. After they are done they will have to manually click the "Close" button on the RunDeck page to close the iframe.

If you want the user interface in RunDeck to be more streamlined, you will have to be able to modify the web pages produced by the remote site to add simple Javascript calls to communicate back to the RunDeck page. The JavaScript hooks are designed to not add much burden to the developer of the remote site or system, so they are optional.

8.14.3.1 Streamlining the interface

If the remote site implements some Javascript messaging conforming to a simple optional protocol, then the user interface between RunDeck and the remote site can be made more seamless.

RunDeck lets the remote site inform it when the following steps occur:

  • The user begins editing a Node
  • The user saves the Node changes successfully and is finished
  • The user cancels the Node changes, or otherwise has finished without saving
  • An error occurs and an error message should be shown.

Due to web browser security restrictions, direct communication between different webpages can only be done through use of the postMessage method.

The remote page can send these messages simply with this javascript:

<script type="text/javascript">
    if(window.self!=window.parent){
        window.parent.postMessage("...message...","http://rundeckserver:port");
    }
</script>

window.parent will be the enclosing browser window when the site is loaded within an iframe. This script simply checks whether the page is loaded in an iframe before sending the message.

The first argument to postMessage is one of the message codes shown below. The second argument is the expected "origin", meaning the URL scheme, server and port of the server receiving the message. You can specify "*" to include any site that may be loading the content, but you may want to restrict it to your RunDeck installation's scheme, hostname and port.

RunDeck can receive the following messages sent by the remote site:

rundeck:node:edit:started

Sent as soon as the remote edit URL is loaded and indicates that the remote Site understands the messaging protocol and has loaded the correct edit page. You would probably send this on the "edit" or "form" page for the targetted node.

rundeck:node:edit:error or rundeck:node:edit:error:An error message

Sent if some error occurs. The remote editing form will close and the error message (if any) will be shown. You would probably send this on the "edit" or "view" page if there is an error locating the targeted Node or loading anything required for the edit process.

The next two messages are only valid after the "started" message has already been received:

rundeck:node:edit:finished:true

Sent after the remote form has been saved without errors. This indicates that the editing process is done and has completed with saved changes. You would probably send this on the "view" or "show" page for the targeted node if the save operation was successful.

rundeck:node:edit:finished:false

Sent after the remote form has been either cancelled or discarded without changes. This indicates that the editing process is done but no changes were made. You would probably send this on the "view" or "show" for the targeted node (if your site simply shows the node view again) or "list" page (if your site goes back to a list of resources) if the user hits "cancel".

Any message not shown here that is received by RunDeck after it has received the "started" message will be considered unexpected and the editing process will close the iframe.

The user will also have the option to close and cancel the remote editing process at any time.

Note that sending the "error" or "finished" message will close the editing session and all subsequent messages will be ignored.

TODO: The JavaScript code to communicate back to RunDeck could be bundled into a simple widget script file for easier inclusion on remote sites.

8.14.4 Examples

Here are some examples of using the editUrl and remoteUrl in a resources.xml/resources.yaml file:

Specify a simple URL for editing, which will simply produce a link:

<node name="venkman" editUrl="http://mycmdb:8080/node/edit" ... />

Specify a URL for editing, with embedded "name" property as a parameter:

<node name="venkman" editUrl="http://mycmdb:8080/node/edit?name=${node.name}" ... />

Specify a remote URL with embedded "name" and "project" properties as parameters:

<node name="venkman" remoteUrl="http://mycmdb:8080/node/edit?name=${node.name}&amp;project=${node.project}" ... />

Specify a remote URL with embedded "name" property as part of the path:

<node name="venkman" remoteUrl="http://mycmdb:8080/node/edit/${node.name}"  ... />

In YAML, some examples:

Specify a remote URL with embedded "name" and "project" properties as parameters:

venkman:
  nodename: venkman
  remoteUrl: http://mycmdb:8080/node/edit?name=${node.name}&amp;project=${node.project}

Specify a remote URL with embedded "name" property as part of the path:

venkman:
  nodename: venkman
  remoteUrl: "http://mycmdb:8080/node/edit/${node.name}

8.14.4.1 Simple site integration

The ndbtest project on github provides an example of how the remote Resource Editor can integrate with RunDeck using JavaScript.

This project is a simple Grails application which provides a database of Node data. The standard web-based user flow is:

  • List all nodes.
  • Edit a Node with the edit page. From here the User can:
    • Cancel the Node changes
      • Goes to the Node show page
    • Save the Node changes
      • Result is successful
        • Goes to the Node show page
      • Result fails, so display an Error message (either on the edit page or the list page)

We want the Node's "edit" link in RunDeck to go directly to an edit page, so the remoteUrl for each Node entry then should be a URL to link to this page, for example:

remoteUrl="http://localhost:8080/node/edit?name=${node.name}&amp;project=${node.project}"

The code below shows that the name & project are used to select the correct node from the database, even though the built-in identifier is an ID number:

  • NodeController.groovy:51.

    • Note that if there is no Node found with the specified values, then the response will be to set an error message and then show the list page.

So the JavaScript for integrating with RunDeck is then added to the following pages in this system:

  • node/edit.gsp
    • If an error has occurred, it posts an error message starting on Line 27
    • Otherwise, it posts the started message starting on line 34
  • node/show.gsp
    • If the node save was successful, send the finished:true message, starting at line 21.
    • Otherwise send the finished:false message starting at line 28.
  • node/list.gsp
    • If an error has occurred, it posts an error message starting on line 20.

To complete the round-trip of editing a Node and then showing the results back in RunDeck, the ndbtest project would have to export XML formatted Resource data, and then your RunDeck project.properties file would have to point to the appropriate URL. (This is left as an exercise to the reader.)

8.15 Webhooks

RunDeck Jobs can be configured to POST data to a webhook URL when they succeed or fail.

When a RunDeck Job webhook notification is triggered, the server will send a POST request to one or more configured URLs. The request will contain XML content containing information about the Execution that has finished. The request will also contain special HTTP Headers to include some information about the notification and the Execution. You can also configure your URLs to have property tokens that will be replaced with specific details about the Job, Execution or Notification prior to the webhook request being submitted.

8.15.1 Execution Notification Content

The content of the POST request will be XML, with a single <notification> root element. This element will contain <executions..><execution>...</execution></executions> content. This inner content is of the same format as the XML returned from the Web API for Execution information. See the chapter API - Listing Running Executions for more information.

Attributes of the notification element will include:

trigger

The type of notification trigger. Either "success" or "failure".

executionId

The ID of the Execution

status

The result status of the Execution. Either "succeeded", "failed" or "aborted".

Example

<notification trigger="success" executionId="[ID]" status="[STATUS]">
    <executions count="1">
        <execution ...>
            ...
        </execution>
    </executions>
</notification>

8.15.2 Execution Notification Headers

The POST request will also contain several custom HTTP headers, providing another way to receive some of the webhook information:

X-RunDeck-Notification-Trigger

The notification trigger type, either "success" or "failure".

X-RunDeck-Notification-Execution-ID

The Execution ID

X-RunDeck-Notification-Execution-Status

The status of the execution, either "succeeded", "failed", or "aborted".

8.15.3 Execution Notification URL Token Expansion

As well, the URLs configured for the webhook notification may contain tokens that will be expanded with values taken from the associated job and execution, such as ${job.name}.

Available tokens for expansion are:

job.PROPERTY

Properties about the Job, including:

name

the Job name

group

The Job group, or a blank string

id

the Job Id

project

the Project name

execution.PROPERTY

Properties about the Execution, including:

id

The Execution ID

user

The user who executed the job

status

The execution status, one of "succeeded","failed",or "aborted"

notification.trigger

The trigger associated with the notification, one of "success" or "failure".

So for example, this URL:

http://server/callback?id=${execution.id}&status=${execution.status}&trigger=${notification.trigger}

Will have the tokens replaced with the appropriate values prior to making the webhook request.

9 RunDeck API

RunDeck provides a Web API for use with your application.

The API is defined in the document RunDeck API.

10 RunDeck Plugins

Plugins for RunDeck contain new Providers for some of the Services used by the RunDeck core.

RunDeck comes with some built-in providers for these services, but Plugins let you write your own, or use third-party implementations.

RunDeck currently comes installed with a few useful plugins: script-plugin and stub-plugin. See Pre-installed plugins for more info.

10.1 Installing Plugins

Installation of plugins is simple:

Put the plugin file, such as plugin.jar or some-plugin.zip, into the RunDeck server's libext dir:

cp some-plugin.zip $RDECK_BASE/libext

The plugin is now enabled, and any providers it defines can be used by nodes or projects.

The RunDeck server does not have to be restarted.

10.2 Uninstalling or Updating Plugins

You can simply remove the plugin files from $RDECK_BASE/libext to uninstall them.

You can overwrite an old plugin with a newer version to update it.

10.3 About Plugins

Plugins are files that contain one or more Service Provider implementations. Each plugin file could contain multiple Providers for different types of services, however typically each plugin file would contain only providers related in some fashion.

RunDeck includes a number of "built-in" providers, as well as a few "included" plugin files.

In this document "plugin" and "provider" are used somewhat interchangably. When referring to an actual file containing the provider implementations we will say "plugin file".

RunDeck Providers and Plugin Files

RunDeck Providers and Plugin Files

10.4 Types of Plugins

RunDeck supports several different types of plugins to perform different kinds of services.

10.4.1 Node Execution Plugins

These plugins define ways of executing commands on nodes, and copying files to nodes.

More information:

10.4.2 Resource Model Source Plugins

These plugins define mechanisms for retrieving Resource Model information from a specific kind of source (such as a URL, file, or set of files in a directory).

More information:

10.4.3 Resource Format Plugins

These plugins define parsers and generators for different document formats, and are used by the Resource Model Source Plugins, as well as other parts of the RunDeck system.

More information:

10.5 About Services and Providers

The RunDeck core makes use of several different "Services" that provide functionality for the different steps necessary to execute workflows, jobs, and commands across multiple nodes.

Each Service makes use of "Providers". Each Provider has a unique "Provider Name" that is used to identify it, and most Services have default Providers unless you specify different ones to use.

RunDeck Services and Providers

RunDeck Services and Providers

Services fall into different categories, which determine how and where they are used.

Service Categories:

  1. Node Execution services - providers of these services operate in the context of a single Node definition, and can be configured at Node scope or higher:

    1. Node Executor - these providers define ways of executing a command on a Node (local or remote)
    2. File Copier - these providers define ways of copying files to a Node.
  2. Project services

    1. Resource Model Source - (aka "Resource Providers") these define ways of retrieving Node resources for a Project
  3. Global services (framework level)

    1. Resource Format Parser - these define document format parsers
    2. Resource Format Generators - these define document format generators

Specifics of how providers of these plugins work is listed below.

RunDeck Plugins can contain more than one Provider.

10.6 Using Providers

10.6.1 Node Execution Services

The two Node services, Node Executor and File Copier, are both configured similarly. They are configured for particular nodes on a node-specific basis, or set as a default provider for a project or for the system.

If multiple providers are defined the most specific definition takes precedence in this order:

  1. Node specific
  2. Project scope
  3. Framework scope

10.6.1.1 Node Specific

To enable a provider for a node, add an attribute to the node definition.

Node Executor provider attributes:

node-executor

specifies the provider name for a non-local node.

local-node-executor

specifies the provider name for the local (server) node.

FileCopier provider attributes:

file-copier

specifies the provider by name for a non-local node.

local-file-copier

specifies the provider by name for the local (server) node.

Example Node in YAML specifying stub NodeExecutor and FileCopier:

remotehost:
    hostname: remotehost
    node-executor: stub
    file-copier: stub

10.6.1.2 Project or Framework Scope

Node Executor

You can define the default connection providers to use for nodes at either the Project or Framework scope (or both). To do so, configure any of the following properties in the project.properties or the framework.properties files.

service.NodeExecutor.default.provider

Specifies the default NodeExecutor provider for remote nodes

service.NodeExecutor.default.local.provider

Specifies the default Node Executor provider for the local node.

File Copier

service.FileCopier.default.provider

Specifies the default File Copier provider for remote nodes.

service.FileCopier.default.local.provider

Specifies the default File Copier provider for the local node.

Example project.properties to set default local providers to stub:

service.NodeExecutor.default.local.provider=stub
service.FileCopier.default.local.provider=stub

10.6.2 Resource Model Sources

The Resource Model Sources providers can be configured for a single project in the project.properties file.

You can define multiple Resource Model Sources for the project, and can mix and match the specific providers depending on your needs.

When you define multiple Source providers in a project, then the resulting set of Nodes will effectively be a merge of all the sources, in the order in which they are declared. This means that if two or more Sources provide a definition of a node with the same name, then the definition from lowest Source in the list will be used.

The order that the providers are loaded (and thus the nodes are merged) is:

  1. project.resources.file: A File Model Source with default configuration.
  2. project.resources.url: A URL Model Source with default configuration. (optional)
  3. All resources.source.N configurations in order starting at 1

10.6.2.1 Resource Model Source configuration

The project.properties file for each project allows you to configure the Resource Model Sources in these ways:

  • Define project.resources.file - this file path is used as a File Source path, with autogeneration and includeServerNode both true.
  • Define project.resources.url - this URL is used as a URL Source url, with caching enabled

You may also define a list of more sources in this way:

Starting at index 1, define these properties for your Source numbered N:

resources.source.N.type=<provider-name>
resources.source.N.config.<property>=<value>
resources.source.N.config.<property2>=<value2>
...

Using one of the available Resource Model Source provider names for the <provider-name> value. For each Resource Model Source provider, you can specify the configuration properties for the source.

Example project.properties configuration of a default File provider, and two other providers:

project.resources.file=/home/rundeck/projects/example/etc/resources.xml

resources.source.1.type=url
resources.source.1.url=http://server/nodes.yaml

resources.source.2.type=directory
resources.source.2.directory=/home/rundeck/projects/example/resources

10.6.3 Resource Format Generators and Parsers

Resource Format Generators and Parsers define support for file formats that can be generated from or parsed into a set of Resource Node definitions.

These are used by other parts of the system, such as the Resource Model Sources.

There is no configuration necessary to use these providers, however the specific Provider Name that each generator and parser defines has to be known in order to make use of the provider. The specific Provider Name is used as the "format name" when you want to use the parser or generator.

For example, to enable a particular Resource Format parser to be used by a File Resource Model Source (see File Resource Model Source Configuration), you should specify the Provider Name for the parser as the format for the source:

resources.source.1.format=myformat

This would specify the use of "myformat" provider.

In other cases, the exact name of the provider may not be known (for example when loading content from a remote URL). Each Generator and Parser must define a list of MIME Type strings and file extensions that they support. These are used to determine which parser/generator is to be used.

10.7 When Node Execution Service providers are invoked

RunDeck executes Command items on Nodes. The command may be part of a Workflow as defined in a Job, and it may be executed multiple times on different nodes.

Currently three "kinds" of Command items can be specified in Workflows:

  1. "exec" commands - simple system command strings
  2. "script" commands - either embedded script content, or server-local script files can be sent to the specified node and then executed with a set of input arguments.
  3. "jobref" commands - references to other Jobs by name that will be executed with a set of input arguments.

RunDeck uses the NodeExecutor and FileCopier services as part of the process of executing these command types.

The procedure for executing an "exec" command is:

  1. load the NodeExecutor provider for the node and context
  2. call the NodeExecutor#executeCommand method

The procedure for executing a "script" command is:

  1. load the FileCopier provider for the node and context
  2. call the FileCopier#copy* method
  3. load the NodeExecutor provider for the node and context
  4. Possibly execute an intermediate command (such as "chmod +x" on the copied file)
  5. execute the NodeExecutor#executeCommand method, passing the filepath of the copied file, and any arguments to the script command.

10.8 Built-in providers

RunDeck uses a few built-in providers to provide the default service:

10.8.1 Node Execution services

For NodeExecutor, these providers:

local

local execution of a command

jsch-ssh

remote execution of a command via SSH, requiring the "hostname", and "username" attributes on a node.

For FileCopier, these providers:

local

creates a local temp file for a script

jsch-scp

remote copy of a command via SCP, requiring the "hostname" and "username" attributes on a node.

10.8.2 Resource Model Sources

RunDeck includes these built-in providers in the core installation:

file

Uses a file on the file system, in any of the supported Resources formats.

url

GETs a URL, and expects one of the supported Resources formats.

directory

looks at all files in a directory for suppored file extensions, and internally uses the file provider for each file that matches.

script

Executes a script and parses the output as one of the supported formats

To configure these providers, refer to Resource Model Source configuration and use the following configuration properties.

10.8.2.1 File Resource Model Source Configuration

The file Resource Model Source provider reads a file in one of the supported Resource Model Document Formats.

Configuration properties for file Resource Model Source provider
NameValueNotes
filefile pathPath to a file on disk.
formatformat nameCan be used to declare the format explicitly. Otherwise the format is determined from the file's extension.
requireFileExiststrue/falseIf true and the file is missing, causes a failure to load the nodes. (Default: false)
includeServerNodetrue/falseIf true, include the Project's server node automatically. (Default: false)
generateFileAutomaticallytrue/falseIf true, create the file automatically if it is missing. (Default: false)

The value of format must be one of the supported Resource Model Document Formats. The built-in formats are: resourcexml or resourceyaml, but any format provided by a Resource Format Plugin can be specified as well.

Example:

resources.source.1.type=file
resources.source.1.file=/home/rundeck/projects/example/etc/resources2.xml
resources.source.1.format=resourcexml
resources.source.1.requireFileExists=true
resources.source.1.includeServerNode=true
resources.source.1.generateFileAutomatically=true

10.8.2.2 URL Resource Model Source Configuration

The url Resource Model Source provider performs a HTTP GET request to retrieve the Nodes definition.

Configuration properties:

Configuration properties for url Resource Model Source provider
NameValueNotes
urlURLA valid URL, either http:, https: or file: protocol.
cachetrue/falseIf true, use ETag/Last-Modified information from the server to only download new content if it has changed. If false, always download the content. (Default: true)
timeoutsecondsNumber of seconds before request fails due to timeout. 0 means no timeout. (Default: 30)

The Resource Model Document Format that is used is determined by the MIME type sent by the remote server. The built-in formats accept "*/xml" and "*/yaml" and "*/x-yaml". See Resource Format Plugin.

Example:

resources.source.1.type=url
resources.source.1.url=file:/home/rundeck/projects/example/etc/resources2.xml
resources.source.1.cache=true
resources.source.1.timeout=0

10.8.2.3 Directory Resource Model Source Configuration

The directory Resource Model Source provider lists all files in a directory, and loads each one that has a supported file extension as File Resource Model Source with all default configuration options.

Configuration properties for directory Resource Model Source provider
NameValueNotes
directorydirectory pathAll files in the directory that have a supported file extension will be loaded

Example:

resources.source.2.type=directory
resources.source.2.directory=/home/rundeck/projects/example/resources

10.8.2.4 Script Resource Model Source Configuration

The script Resource Model Source provider executes a script file and reads the output of the script as one of the supported Resource Model Document Formats.

Configuration properties for script Resource Model Source provider
NameValueNotes
fileScript file pathIf required by the interpreter, the file should be executable
interpreterCommand or interpreter to usee.g. "bash -c"
argsAdditional arguments to passThe arguments will be added after the script file name to the executed commandline
formatFormat nameMust be used to declare the format explicitly.

The script will be executed in this way:

[interpreter] file [args]

All output on STDOUT will be passed to a Resource Format Parser to parse. The format specified must be available.

Example:

resources.source.2.type=script
resources.source.2.file=/home/rundeck/projects/example/etc/generate.sh
resources.source.2.interpreter=bash -c
resources.source.2.args=-project example
resources.source.2.format=resourceyaml

10.8.3 Resource Format services

Resource Format services (Generators and Parsers) typically come in matched pairs, with both a parser and generator for the same format name.

RunDeck includes these built-in providers in the core installation:

resourcexml

Supports the Resource XML document format: resource-v13(5) XML.

Supported MIME types:

  • Generator: "text/xml"
  • Parser: "*/xml"

Supported File extensions:

  • ".xml"
resourceyaml

Supports the Resource YAML document format: resource-v13(5) YAML.

Supported MIME types:

  • Generator: "text/yaml", "text/x-yaml", "application/yaml", "application/x-yaml"
  • Parser: "*/yaml", "*/x-yaml"

Supported File extensions:

  • ".yml", ".yaml"

10.9 Pre-installed plugins

RunDeck comes with two pre-installed plugins that may be useful, and also serve as examples of plugin development and usage.

10.9.1 script-plugin

The script-plugin includes these providers:

  • script-exec for the NodeExecutor service
  • script-copy for the FileCopier service

(Refer to Using Providers to enable them.)

This plugin provides the ability to specify an external script or command to perform a remote or local execution of a Rundeck command, and remote or local file copies.

It can be a replacement for the built-in SSH-based remote execution and SCP-based file-copy mechanism to allow you to user whatever external mechanism you wish.

Note: this plugin offers similar functionality to the Script Plugin Development model. You may want to use this plugin to test your scripts, and then later package them into a standalone plugin using that model.

10.9.1.1 Configuring script-exec

To configure the plugin you must specify a commandline string to execute. Optionally you may specify a directory to be used as the working directory when executing the commandline string, and a shell to invoke the command.

You can configure these across all projects (framework-wide), a single project (project-wide), or specifically for each node, with the most specific configuration value taking precedence.

10.9.1.2 Configuring the command for script-exec

For Framework and Project-wide, configure a property in either the framework.properties or project.properties files:

plugin.script-exec.default.command
Specifies the default system command to run

For node-specific add an attribute named script-exec to the node.

script-exec
Specifies the system command to run

See Defining the script-exec command for what to specify for this property.

10.9.1.3 Configuring the working directory

For Framework and Project-wide, configure a property in either the framework.properties or project.properties files:

plugin.script-exec.default.dir
Specifies the default working directory for the execution

For node-specific add an attribute named script-exec-dir to the node.

script-exec-dir
Specifies the default working directory for the execution (optional)

10.9.1.4 Configuring the shell

For Framework and Project-wide, configure a property in either the framework.properties or project.properties files:

plugin.script-exec.default.shell
Specifies the shell to use to interpret the command, e.g. "bash -c" or "cmd.exe /c"

For node-specific add an attribute named script-exec-shell to the node.

script-exec-shell
Specifies the shell to use to interpret the command, e.g. "bash -c" or "cmd.exe /c" (optional)

10.9.1.5 Defining the script-exec command

The value of this property or attribute should be the complete commandline string to execute in an external system process.

You can use Data context properties as you can in normal Rundeck command execution, such as ${node.name} or ${job.name}.

In addition, the plugin provides these new data context properties:

exec.command

The command that the workflow/user has specified to run on the node

exec.dir

The working directory path if it is configured for the node or in a properties file

Example:

If you wanted to run some external remote connection command ("/bin/execremote") in lieu of the built-in ssh command, you could specify these attributes for node:

mynode:
    node-executor: script-exec
    script-exec: /bin/execremote -host ${node.hostname} -user ${node.username} -- ${exec.command}

If the command you want to run requires special handling (such as quoting or other interpretation) you may want to have a shell execute it. In which case you could specify the shell to use:

mynode:
    node-executor: script-exec
    script-exec-shell: bash -c
    script-exec: ssh -o "some quoted option" ${node.username}@${node.hostname} ${exec.command}

At run time, the properties specified would be expanded to the values for the specific node and command string to execute.

OR, you could specify a default to apply to all nodes within the project.properties file located at $RDECK_BASE/projects/NAME/etc/project.properties.

script-exec.default.command= /bin/execremote -host ${node.hostname} \
    -user ${node.username} -- ${exec.command}

Similarly for the $RDECK_BASE/etc/framework.properties file to apply to all projects.

10.9.1.6 Requirements for the script-exec command

The command run by by the script plugin is expected to behave in the following manner:

  • Exit with a system exit code of "0" in case of success.
  • Any other exit code indicates failure

Note: all output from STDOUT and STDERR will be captured as part of the Rundeck job execution.

10.9.1.7 Configuring script-copy

To configure script-copy you must specify a commandline string to execute. Optionally you may specify a directory to be used as the working directory when executing the commandline string, and a shell to use to interpret the command.

You must also specify the filepath on the target node where the copied file will be placed, which can be done in two different ways.

You can configure these across all projects (framework-wide), a single project (project-wide), or specifically for each node, with the most specific configuration value taking precedence.

10.9.1.8 Configuring the command for script-copy

For Framework and Project-wide, configure these properties in either the framework.properties or project.properties files:

plugin.script-copy.default.command
Specifies the default system command to run

For node-specific add these attributes to the node.

script-copy
Specifies the system command to run

See Defining the script-copy command for what to specify for this property.

10.9.1.9 Configuring the working directory

For Framework and Project-wide, configure a property in either the framework.properties or project.properties files:

plugin.script-copy.default.dir
Specifies the default working directory for the execution

For node-specific add an attribute named script-copy-dir to the node.

script-copy-dir
Specifies the default working directory for the execution (optional)

10.9.1.10 Configuring the shell

For Framework and Project-wide, configure a property in either the framework.properties or project.properties files:

plugin.script-copy.default.shell
Specifies the shell to run the command (optional)

For node-specific add an attribute named script-copy-shell to the node.

script-copy-shell
Specifies the shell to run the command (optional)

10.9.1.11 Configuring the remote filepath

For Framework and Project-wide, configure a property in either the framework.properties or project.properties files:

plugin.script-copy.default.remote-filepath
Specifies the full path of the copied file.

For node-specific add an attribute named script-copy-remote-filepath to the node.

script-copy-remote-filepath
Specifies the full path of the copied file.

See Defining the script-copy filepath for what to specify for this property.

10.9.1.12 Defining the script-copy command

The value of this property or attribute should be the complete commandline string to execute in an external system process.

You can use Data context properties as you can in normal Rundeck command execution, such as ${node.name} or ${job.name}.

In addition, the plugin provides these new data context properties:

file-copy.file

The local filepath that should be copied to the remote node

file-copy.filename

The name of the file without any path information.

Example:

If you wanted to run some external remote connection command ("/bin/copyremote") in lieu of the built-in SCP command, you could specify these attributes for node:

mynode:
    file-copier: script-copy
    script-copy: /bin/copyremote -host ${node.hostname} -user ${node.username} -- ${file-copy.file} ${node.destdir}

At run time, the properties specified would be expanded to the values for the specific node and command string to execute.

OR, you could specify a default to apply to all nodes within the project.properties file located at $RDECK_BASE/projects/NAME/etc/project.properties.

script-copy.default.command= /bin/copyremote -host ${node.hostname} -user ${node.username} -- ${file-copy.file} ${node.destdir}

Similarly for the $RDECK_BASE/etc/framework.properties file to apply to all projects.

10.9.1.13 Defining the script-copy filepath

The value of this property or attribute should be the complete filepath on the target node where the copied file is placed. This is to tell the FileCopier service where the remote file exists after your script copies it over, so that it can later be executed.

You can do this in two ways, either as a configuration property as described here, or via output from your script, as described under Requirements of script-copy command.

You can use Data context properties as you can in normal Rundeck command execution, such as ${node.name} or ${job.name}.

In addition, the plugin provides these new data context properties:

file-copy.file

The local filepath that should be copied to the remote node

file-copy.filename

The name of the file without any path information.

Example:

Using the "/bin/copyremote" example from above, we need to set the script-copy-remote-filepath to the location on the remote node where the file is copied. Our example copies ${file-copy.file} to the location ${node.destdir}. This is an attribute on the Node that we assume to be configured with a directory path.

We need to set the script-copy-remote-filepath to the location on the remote node where the file will exist after being copied. We know the filename of the file is available as ${file-copy.filename}, so we set it to ${node.destdir}/${file-copy.filename}:

mynode:
    file-copier: script-copy
    script-copy: /bin/copyremote -host ${node.hostname} -user ${node.username} -- ${file-copy.file} ${node.destdir}
    script-copy-remote-filepath: ${node.destdir}/${file-copy.filename}

At run time, the properties specified would be expanded to the values for the specific node and command string to execute.

OR, you could specify a default to apply to all nodes within the project.properties file located at $RDECK_BASE/projects/NAME/etc/project.properties.

script-copy.default.remote-filepath= ${node.destdir}/${file-copy.filename}

Similarly for the $RDECK_BASE/etc/framework.properties file to apply to all projects.

10.9.1.14 Requirements of script-copy command

The command executed by script-copy is expected to behave in the following manner:

  • Exit with an exit code of "0" to indicate success
  • Exit with any other exit code indicates failure
  • Either
    • Output the filepath of the copied file on the target node as the first line of output on STDOUT OR
    • Define the "remote-filepath" as described above

10.9.1.15 Example Scripts

Here are some example scripts to show the some possible usage patterns.

Example script-exec:

Node definition:

mynode:
    node-executor: script-exec

Project config project.properties file:

plugin.script-exec.default.command: /tmp/myexec.sh ${node.hostname} ${node.username} -- ${exec.command}

Contents of /tmp/myexec.sh:

#!/bin/bash

# args are [hostname] [username] -- [command to exec...]

host=$1
shift
user=$1
shift
command="$*"

REMOTECMD=ssh

exec $REMOTECMD $user@$host $command

Example script-copy:

Node definition:

mynode:
    file-copier: script-copy
    destdir: /some/node/dir

System-wide config in framework.properties:

plugin.script-copy.default.command: /tmp/mycopy.sh ${node.hostname} ${node.username} ${node.destdir} ${file-copy.file}

Contents of /tmp/mycopy.sh:

#!/bin/bash

# args are [hostname] [username] [destdir] [filepath]

host=$1
shift
user=$1
shift
dir=$1
shift
file=$1

name=`basename $file`

# copy to node
CPCMD=scp

exec $CPCMD $file $user@$host:$dir/$name > /dev/null || exit $?

echo "$dir/$name"

Example system ssh replacement:

This example uses the system's "ssh" and "scp" commands to perform node execution and file copying, and doesn't make use of an external script file:

Node-only configuration:

mynode:
    hostname: mynode
    username: user1
    node-executor: script-exec
    script-exec: ssh -o "StrictHostKeyChecking no" ${node.username}@${node.hostname} ${exec.command}
    script-exec-shell: bash -c
    file-copier: script-copy
    destdir: /tmp
    script-copy-shell: bash -c
    script-copy: scp ${file-copy.file} ${node.username}@${node.hostname}:${node.destdir}
    script-copy-remote-filepath: ${node.destdir}/${file-copy.filename}

This could all be set as defaults in the project.properties file, such as:

# set default node executor
service.NodeExecutor.default.provider=script-exec

# set script-exec defaults
plugin.script-exec.default.command=ssh -o "StrictHostKeyChecking no" ${node.username}@${node.hostname} ${exec.command}
plugin.script-exec.default.shell=bash -c

#set default file copier
service.FileCopier.default.provider=script-copy

#set script-copy defaults
plugin.script-copy.default.command=scp ${file-copy.file} ${node.username}@${node.hostname}:${node.destdir}
plugin.script-copy.default.shell: bash -c
plugin.script-copy.default.remote-filepath: ${node.destdir}/${file-copy.filename}

In which case your node definitions could be as simple as:

mynode:
    hostname: mynode
    username: user1
    destdir: /tmp

10.9.2 stub-plugin

The stub-plugin includes these providers:

  • stub for the NodeExecutor service
  • stub for the FileCopier service

(Refer to Using Providers to enable them.)

This plugin does not actually perform any remote file copy or command execution, instead it simply echoes the command that was supposed to be executed, and pretends to have copied a file.

This is intended for use in testing new Nodes, Jobs or Workflow sequences without affecting any actual runtime environment.

You can also test some failure scenarios by configuring the following node attributes:

stub-exec-success="true/false"

If set to false, the stub command execution will simulate command failure

stub-result-code

Simulate the return result code from execution

You could, for example, disable or test an entire project's workflows or jobs by simply setting the project.properties node executor provider to stub.

11 Plugin Development

This is a work in progress, and the plugin system is likely to change.

There are currently two ways to develop plugins:

  1. Develop Java code that is distributed within a Jar file. See Java plugin development.
  2. Write shell/system scripts that implement your desired behavior and put them in a zip file with some metadata. See Script Plugin Development.

Either way, the resultant plugin archive file, either a .jar java archive, or a .zip file archive, will be placed in the $RDECK_BASE/libext dir.

11.1 Java Plugin Development

Java plugins are distributed as .jar files containing the necessary classes for one or more service provider, as well as any other java jar dependency files.

The .jar file you distribute must have this metadata within the main Manifest for the jar file to be correctly loaded by the system:

  • Rundeck-Plugin-Version: 1.0
  • Rundeck-Plugin-Archive: true
  • Rundeck-Plugin-Classnames: classname,..
  • Rundeck-Plugin-Libs: lib/something.jar ... (optional)

Each classname listed must be a valid "Provider Class" as defined below.

11.1.1 Provider Classes

A "Provider Class" is a java class that implements a particular interface and declares itself as a provider for a particular RunDeck "Service".

Each plugin also defines a "Name" that identifies it for use in RunDeck. The Name of a plugin is also referred to as a "Provider Name", as the plugin class is a provider of a particular service.

You should choose a unique but simple name for your provider.

Each plugin class must have the "com.dtolabs.rundeck.core.plugins.Plugin" annotation applied to it.

@Plugin(name="myprovider", service="NodeExecutor")
public class MyProvider implements NodeExecutor{
...

Your provider class must have at least a zero-argument constructor, and optionally can have a single-argument constructor with a com.dtolabs.rundeck.core.common.Framework parameter, in which case your class will be constructed with this constructor and passed the Framework instance.

You may log messages to the ExecutionListener available via ExecutionContext#getExecutionListener() method.

You can also send output to System.err and System.out and it will be captured as output of the execution.

11.1.2 Jar Dependencies

If your Java classes require external libraries that are not included with the RunDeck runtime, you can include them in your .jar archive. (Look in $RDECK_BASE/tools/lib to see the set of third-party jars that are available for your classes by default at runtime).

Specify the Rundeck-Plugin-Libs attribute in the Main attributes of the Manifest for the jar, set the value to a space-separated list of jar file names as you have included them in the jar.

E.g.:

Rundeck-Plugin-Libs: lib/somejar-1.2.jar lib/anotherjar-1.3.jar

Then include the jar files in the Plugin's jar contents:

META-INF/
META-INF/MANIFEST.MF
com/
com/mycompany/
com/mycompany/rundeck/
com/mycompany/rundeck/plugin/
com/mycompany/rundeck/plugin/test/
com/mycompany/rundeck/plugin/test/TestNodeExecutor.class
lib/
lib/somejar-1.2.jar
lib/anotherjar-1.3.jar

11.1.3 Available Services:

  • NodeExecutor - executes a command on a node
  • FileCopier - copies a file to a node
  • ResourceModelSource - produces a set of Node definitions for a project
  • ResourceFormatParser - parses a document into a set of Node resources
  • ResourceFormatGenerator - generates a document from a set of Node resources

11.2 Provider Lifecycle

Provider classes are instantiated when needed by the Framework object, and the instance is retained within the Service for future reuse. The Framework object may exist across multiple executions, and the provider instance may be reused.

Provider instances may also be used by multiple threads.

Your provider class should not use any instance fields and should be careful not to use un-threadsafe operations.

11.2.1 Node Executor Providers

A Node Executor provider executes a certain command on a remote or local node.

Your provider class must implement the com.dtolabs.rundeck.core.execution.service.NodeExecutor interface:

public interface NodeExecutor {
    public NodeExecutorResult executeCommand(ExecutionContext context, 
        String[] command, INodeEntry node) throws ExecutionException;
}

A Node Executor can be me made Configurable on a per-project basis via the Web GUI by implementing the com.dtolabs.rundeck.core.plugins.configuration.Describable interface. It is up to your plugin implementation to use configuration properties from the FrameworkProject instance to configure itself. You must also be sure to return an appropriate mapping in the getPropertiesMapping method of the Description interface to declare the property names to be used in the project.properties file.

More information is available in the Javadoc.

11.2.2 File Copier Providers

A File Copier provider copies a file or script to a remote or local node.

Your provider class must implement the com.dtolabs.rundeck.core.execution.service.FileCopier interface:

public interface FileCopier {
    public String copyFileStream(final ExecutionContext context, InputStream input, INodeEntry node) throws
        FileCopierException;

    public String copyFile(final ExecutionContext context, File file, INodeEntry node) throws FileCopierException;

    public String copyScriptContent(final ExecutionContext context, String script, INodeEntry node) throws
        FileCopierException;
}

A File Copier can be me made Configurable on a per-project basis via the Web GUI by implementing the com.dtolabs.rundeck.core.plugins.configuration.Describable interface. It is up to your plugin implementation to use configuration properties from the FrameworkProject instance to configure itself. You must also be sure to return an appropriate mapping in the getPropertiesMapping method of the Description interface to declare the property names to be used in the project.properties file.

More information is available in the Javadoc.

11.2.3 Resource Model Source Providers

A Resource Model Source provider is actually a Factory class. An instance of your Resource Model Source provider will be re-used, so each time a new Resource Model Source with a new configuration is required, your Factory class will be invoked to produce it.

Your provider class must implement the com.dtolabs.rundeck.core.resources.ResourceModelSourceFactory interface:

public interface ResourceModelSourceFactory {
    /**
     * Return a resource model source for the given configuration
     */
    public ResourceModelSource createResourceModelSource(Properties configuration) throws ConfigurationException;
}

A Resource Model Source provider can also be Configurable via the Web GUI by implementing the com.dtolabs.rundeck.core.plugins.configuration.Describable interface. This allows you to return a descriptor of the configuration parameters for your plugin, which is used by the GUI to render a web form. The properties the user configures are stored in the project.properties configuration file, and are passed to your factory method as the configuration properties.

More information is available in the Javadoc.

11.2.4 Resource Format Parser and Generator Providers

Resource format Parser and Generator providers are used to serialize a set of Node resources into a textual format for transport or storage.

Each Parser and Generator must declare the set of filename extensions (such as "xml" or "json") that it supports, as well as the set of MIME types that it supports (such as "text/xml" or "application/json".) This lets other services retrieve the appropriate parser or generator when all that is known about the source or destination of serialized data is a filename or a MIME type.

For Parsers, your provider class must implement the com.dtolabs.rundeck.core.resources.format.ResourceFormatParser interface:

public interface ResourceFormatParser {
    /**
     * Return the list of file extensions that this format parser can parse.
     */
    public Set<String> getFileExtensions();

    /**
     * Return the list of MIME types that this format parser can parse. This may include wildcards such as
     * "*&#47;xml".
     */
    public Set<String> getMIMETypes();

    /**
     * Parse a file
     */
    public INodeSet parseDocument(File file) throws ResourceFormatParserException;

    /**
     * Parse an input stream
     */
    public INodeSet parseDocument(InputStream input) throws ResourceFormatParserException;
}

For Generators, your provider class must implement the com.dtolabs.rundeck.core.resources.format.ResourceFormatGenerator interface:

public interface ResourceFormatGenerator {

    /**
     * Return the list of file extensions that this format generator can generate
     */
    public Set<String> getFileExtensions();

    /**
     * Return the list of MIME types that this format generator can generate. If more than one
     * are returned, then the first value will be used by default if necessary.
     */
    public List<String> getMIMETypes();

    /**
     * generate formatted output
     */
    public void generateDocument(INodeSet nodeset, OutputStream stream) throws ResourceFormatGeneratorException,
        IOException;
}

More information is available in the Javadoc.

11.3 Script Plugin Development

Script plugins can provide the same services as Java plugins, but they do so with a script that is invoked in an external system processes by the JVM.

These Services support Script Plugins:

  • NodeExecutor
  • FileCopier
  • ResourceModelSource

Note: Currently, the Resource Format Parser and Generator services do not support Script Plugins.

You must create a zip file with the following structure:

[name]-plugin.zip
\- [name]-plugin/ -- root directory of zip contents, same name as zip file
   |- plugin.yaml -- plugin metadata file
   \- contents/
      |- ...      -- script or resource files
      \- ...

Here is an example:

$ unzip -l example-1.0-plugin.zip 
Archive:  example-1.0-plugin.zip
  Length     Date   Time    Name
 --------    ----   ----    ----
        0  04-12-11 11:31   example-1.0-plugin/
        0  04-11-11 15:31   example-1.0-plugin/contents/
     2142  04-11-11 15:31   example-1.0-plugin/contents/script1.sh
     1591  04-11-11 13:10   example-1.0-plugin/contents/script2.sh
      576  04-12-11 10:58   example-1.0-plugin/plugin.yaml
 --------                   -------
     4309                   5 files

The filename of the plugin zip must end with "-plugin.zip" to be recognized as a plugin archive. The zip must contain a top-level directory with the same base name as the zip file (sans ".zip").

The file plugin.yaml must have this structure:

# yaml plugin metadata

name: plugin name
version: plugin version
rundeckPluginVersion: 1.0
author: author name
date: release date
providers:
    - name: provider
      service: service name
      plugin-type: script
      script-interpreter: [interpreter]
      script-file: [script file name]
      script-args: [script file args]

The main metadata that is required:

  • name - name for the plugin
  • version - version number of the plugin
  • rundeckPluginVersion - Rundeck Plugin type version, currently "1.0"
  • providers - list of provider metadata maps

These are optional:

  • author - optional author info
  • date - optional release date info

This provides the necessary metadata about the plugin, including one or more entries in the providers list to declare those providers defined in the plugin.

11.3.1 Provider metadata

Required provider entries:

  • name - provider name
  • service - service name, one of these valid services:
    • NodeExecutor
    • FileCopier
    • ResourceModelSource
  • plugin-type - must be "script" currently.
  • script-file - must be the name of a file relative to the contents directory

For ResourceModelSource service, this additional entry is required:

Optional entries:

  • script-interpreter - A system command that should be used to execute the script. This can be a single binary path, e.g. /bin/bash, or include any args to the command, such as /bin/bash -c.
  • script-args - the arguments to use when executing the script file.

11.3.2 Configurable Resource Model Source Script Plugin

The ResourceModelSource service allows the plugins to be configured via the RunDeck Web GUI. You are thus able to declare configuration properties for your plugin, which will be displayed as a web form when the Project is configured, or can be manually configured in the project.properties file.

You can use these metadata entries to declare configuration properties for your plugin:

Create a config entry in each provider definition, containing a sequence of map entries for each configuration property you want to define. In the map entry include:

  • type - The type of property. Must be one of:
    • String
    • Boolean must be "true" or "false"
    • Integer
    • Long
    • Select must be on of a set of values
    • FreeSelect may be one of a set of values
  • name - Name to identify the property
  • title - Title to display in the GUI (optional)
  • description - Description to display in the GUI (optional)
  • required - (true/false) if true, require a non-empty value (optional)
  • default - A default value to use (optional)
  • values - A comma-separated list of values to use for Select or FreeSelect. Required for Select/FreeSelect.

When your script is invoked, each configuration property defined for the plugin will be set as config.NAME in the data context passed to your script (see below).

Here is an example providers section for a Resource Model Source plugin that asks for two input properties from the user and produces "resourceyaml" formatted output:

providers:
    - name: mysource
      service: ResourceModelSource
      plugin-type: script
      script-interpreter: bash -c
      script-file: generate.sh
      resource-format: resourceyaml
      config:
        - type: Integer
          name: count
          title: Count
          description: Enter the number of nodes to generate
        - type: FreeSelect
          name: flavor
          title: Flavor
          description: Select a flavor
          required: true
          default: vanilla
          values: vanilla,blueberry,strawberry,chocolate

11.3.3 How script plugin providers are invoked

When the provider is used for node execution or file copying, the script file, interpreter, and args are combined into a commandline executed by the system in this pattern:

[interpreter] [filename] [args...]

If the interpreter is not specified, then the script file is executed directly, and that means it must be acceptable by the system to be executed directly (include any necessary #! line, etc).

script-args can contain data-context properties such as ${node.name}. Additionally, the specific Service will provide some additional context properties that can be used:

  • NodeExecutor will define ${exec.command} containing the command to be executed
  • FileCopier will define ${file-copy.file} containing the local path to the file that needs to be copied.
  • ResourceModelSource will define ${config.KEY} for each configuration property KEY that is defined.

In addition, all of the data-context properties that are available in the script-args are provided as environment variables to the script or interpreter when it is executed.

Environment variables are generated in all-caps with this format:

RD_[KEY]_[NAME]

The KEY and NAME are the same as ${key.name}. Any characters in the key or name that are not valid Bash shell variable characters are replaced with underscore '_'.

Examples:

  • ${node.name} becomes $RD_NODE_NAME
  • ${node.some-attribute} becomes $RD_NODE_SOME_ATTRIBUTE
  • ${exec.command} becomes $RD_EXEC_COMMAND
  • ${file-copy.file} becomes $RD_FILE_COPY_FILE

11.3.4 Script provider requirements

The specific service has expectations about the way your provider script behaves:

  • Exit code of 0 indicates success
  • Any other exit code indicates failure
For NodeExecutor

All output to STDOUT/STDERR will be captured for the job's output

For FileCopier

The first line of output of STDOUT MUST be the filepath of the file copied to the target node. Other output is ignored. All output to STDERR will be captured for the job's output.

For ResourceModelSource

All output on STDOUT will be captured and passed to the p


  1. The "--noqueue" flag is useful for testing and debugging execution but undermines visibility since execution is not managed through the central execution queue.

  2. To pass environment variables through remote command dispatches, it is required to properly configure the SSH server on the remote end. See the AcceptEnv directive in the "sshd_config(5)" manual page for instructions. Use a wild card pattern to permit RD_ prefixed variables to provide open access to RunDeck generated environment variables.