The documentation you're currently reading is for version 2.4.1. Click here to view documentation for the latest stable version.

Create and Contribute a Pack

Think you’d like to create a StackStorm pack? Great! Here’s how to do it, and contribute it to the community.

Packs have a defined structure. You must follow this structure when creating your own pack. It is also helpful to know while debugging issues with packs.

Anatomy of a Pack

The canonical pack filesystem layout looks like this:

# contents of a pack folder
actions/                 #
rules/                   #
sensors/                 #
aliases/                 #
policies/                #
tests/                   #
etc/                     # any additional things (e.g code generators, scripts...)
config.schema.yaml       # configuration schema
packname.yaml.example    # example of config, used in CI
pack.yaml                # pack definition file
requirements.txt         # requirements for Python packs
requirements-tests.txt   # requirements for python tests
icon.png                 # 64x64 .png icon

At the topmost level are the main folders actions, rules, sensors, aliases and policies, as well as some shared files:

  • pack.yaml - Metadata file that describes and identifies the folder as a pack.
  • config.schema.yaml - Schema that defines configuration elements used by a pack.
  • requirements.txt - File containing a list of Python dependencies. If your pack uses Python actions and/or sensors, you can specify any Python libraries you need here. They will automatically be installed in a pack-specific virtualenv when you install the pack.

Site-specific pack configuration files are stored at /opt/stackstorm/configs/. See configuration schema for more information.


# contents of actions/

The actions folder contains action script files and action metadata files. See Actions and Workflows for specifics on writing actions. Since metadata files and workflow definitions can both be written as YAML, it’s good practice to put the workflow definitions in a separate directory. Note that the lib sub-folder is often used for storing common Python code used by pack actions.


# contents of rules/

The rules folder contains rules. See Rules for specifics on writing rules.


# contents of sensors/

The sensors folder contains sensors. See Sensors for specifics on writing sensors and registering TriggerTypes.


# contents of aliases/

The aliases folder contains Action Aliases. See Action Aliases for specifics on writing Action Aliases.


# contents of policies/

The policies folder contains Policies. See Policies for specifics on writing Policies.

Creating Your First Pack

In the example below, we will create a simple pack named hello_st2. The full example is also available at st2/contrib/hello_st2.

  1. Create the pack folder structure and related files. Let’s keep the metadata files such as pack.yaml, config.schema.yaml, and requirements.txt empty for now:
# Use the name of the pack for the folder name.
mkdir hello_st2
cd hello_st2
mkdir actions
mkdir rules
mkdir sensors
mkdir aliases
mkdir policies
touch pack.yaml
touch requirements.txt

Note: All folders are optional. It is safe to skip a folder or keep it empty. Only create the config.schema.yaml file if it is required. An empty schema file is not valid.

  1. Create the pack definition file, pack.yaml:
ref: hello_st2
name: Hello StackStorm
description: A simple pack containing examples of sensor, rule, and action.
    - example
    - test
version: 0.1.0
author: st2-dev


A note on metadata: StackStorm enforces certain rules about metadata. The version value in pack.yaml must conform to semver:0.2.5, not 0.2. The name value in pack.yaml must only contain letters, digits, and underscores, unless you set the ref value explicitly in pack.yaml. Finally the email attribute in pack.yaml must contain a properly formatted email address.

  1. Create the action. An action consists of meta data, and entrypoint. The following example simply echoes a greeting.

Copy the following content to actions/greet.yaml:

name: greet
pack: hello_st2
runner_type: "local-shell-cmd"
description: Greet StackStorm!
enabled: true
        type: string
        description: Greeting you want to say to StackStorm (i.e. Hello, Hi, Yo, etc.)
        required: true
        position: 1

Copy the following content to actions/

echo "$1, StackStorm!"
  1. Create a sensor. The sample sensor below publishes an event to StackStorm every 60 seconds.

Copy the following content to sensors/sensor1.yaml:

class_name: "HelloSensor"
entry_point: ""
description: "Test sensor that emits triggers."
    name: "event1"
    description: "An example trigger."
      type: "object"

Copy the following content to sensors/

import eventlet

from st2reactor.sensor.base import Sensor

class HelloSensor(Sensor):
    def __init__(self, sensor_service, config):
        super(HelloSensor, self).__init__(sensor_service=sensor_service, config=config)
        self._logger = self.sensor_service.get_logger(name=self.__class__.__name__)
        self._stop = False

    def setup(self):

    def run(self):
        while not self._stop:
            self._logger.debug('HelloSensor dispatching trigger...')
            count = self.sensor_service.get_value('hello_st2.count') or 0
            payload = {'greeting': 'Yo, StackStorm!', 'count': int(count) + 1}
            self.sensor_service.dispatch(trigger='hello_st2.event1', payload=payload)
            self.sensor_service.set_value('hello_st2.count', payload['count'])

    def cleanup(self):
        self._stop = True

    # Methods required for programmable sensors.
    def add_trigger(self, trigger):

    def update_trigger(self, trigger):

    def remove_trigger(self, trigger):
  1. Create a rule. The sample rule below is triggered by an event from the sensor and invokes the action from the samples above.

Copy the following content to rules/rule1.yaml:

name: on_hello_event1
pack: hello_st2
description: Sample rule firing on hello_st2.event1.
enabled: true
    type: hello_st2.event1
    ref: hello_st2.greet
        greeting: Yo
  1. Create an action alias. The sample action alias below aliases the greet action and makes it accessible from ChatOps.

Copy the following content to aliases/alias1.yaml:

name: greet
pack: hello_st2
description: "Greet StackStorm"
action_ref: "hello_st2.greet"
  - "greet {{greeting}}"
  1. Create a policy. The sample policy below limits concurrent operation of the greet action.

Copy the following content to policies/policy1.yaml:

name: greet.concurrency
pack: hello_st2
description: Limits the concurrent executions of the greet action.
enabled: true
resource_ref: hello_st2.greet
policy_type: action.concurrency
    threshold: 10
  1. Install the pack. We encourage using git. If you do so, st2 pack will greatly simplify your pack management. Of course, you can define your own tools and workflow for editing and versioning packs. You’ll need to place the files in /opt/stackstorm/packs and [re-]load the content.

8.1 Use git and pack install (recommended):

# Get the code under git
cd hello_st2
git init && git add ./* && git commit -m "Initial commit"
# Install from local git repo
st2 pack install file:///$PWD

When you make code changes, run st2 pack install again: it will do the upgrade. Once you push it to GitHub, you will install and update it right from there:

st2 pack install

8.2 Copy over and register (if you have special needs and know what you’re doing).

mv ./hello_st2 /opt/stackstorm/packs
st2ctl reload

Congratulate yourself: you have created your first pack. Commands like st2 pack list, st2 action list, st2 rule list and st2 trigger list will show you the loaded content. To check if the sensor triggering action is working, run st2 execution list, there should be an entry for executing hello_st2.greet every minute.

Take it from there. Write an awesome automation, or an inspiring integration pack with your favorite tool. Happy hacking!

Submitting a Pack to the Community

Now that you forged this awesome pack in StackStorm it’s time, and good form, to share your awesomeness with the community. StackStorm Exchange is the place for you and everyone else to share and pull integration packs.

To feature your pack on the StackStorm Exchange, submit a GitHub pull request to the StackStorm Exchange Incubator repository. Our team will review the PR, accept it to the incubator, graduate it to the main “Exchange”, and help you promote it.

Contributors License Agreement

By contributing you agree that these contributions are your own (or approved by your employer) and you grant a full, complete, irrevocable copyright license to all users and developers of the project, present and future, pursuant to the license of the project.

Questions? Problems? Suggestions? Engage!