Pack Configuration

Note

All information on this page refers to the config files in the /opt/stackstorm/configs/ directory.

config.yaml files inside the pack directory were deprecated in StackStorm v1.5. As of version 2.4, pack registration will fail with ERROR logs if the pack contains config.yaml.

If you are still using config.yaml, you MUST migrate to the new style.

Packs can use a configuration file to set values that are common to resources in the pack, e.g. API credentials, connection details, limits, and thresholds. These values are available to actions and sensors at run-time.

The difference between pack configuration and action parameters is that configuration usually contains values which are common to all the resources in the pack, and rarely change. Action parameters are dynamically provided with each action invocation, and may change - e.g. they may come from a rule mapping some input event.

Pack configuration follows an infrastructure as code approach, and is stored in a YAML format file in a special directory (by default /opt/stackstorm/configs). Each pack defines its own schema for this configuration file.

Basic Concepts and Terminology

Configuration Schema

The configuration schema is a YAML formatted file which defines the schema for that pack’s configuration file. This schema is written by the pack author and contains information about every available configuration item (name, type, is value a secret, etc). The file is named config.schema.yaml and is located in the root of the pack directory (/opt/stackstorm/packs/<mypack>/).

Here is an example schema file:

---
  api_key:
    description: "API key"
    type: "string"
    required: true
  api_secret:
    description: "API secret"
    type: "string"
    secret: true
    required: true
  region:
    description: "API region to use"
    type: "string"
    required: true
    default: "us-east-1"
  private_key_path:
    description: "Path to the private key file to use"
    type: "string"
    required: false

In this example, the configuration consists of 4 items (api_key, api_secret, region and private_key_path).

Note that api_secret value is marked as secret which means this value will be stored encrypted in the datastore if a dynamic value is used (more on dynamic values can be found below).

In addition to ‘flat’ configs as shown above, schemas also support nested objects. For example:

---
  consumer_key:
    description: "Your consumer key."
    type: "string"
    required: true
    secret: true
  consumer_secret:
    description: "Your consumer secret."
    type: "string"
    required: true
    secret: true
  access_token:
    description: "Your access token."
    type: "string"
    required: true
    secret: true
  access_token_secret:
    description: "Your access token secret."
    type: "string"
    required: true
    secret: true
  sensor:
    description: "Sensor specific settings."
    type: "object"
    required: false
    additionalProperties: false
    properties:
      device_uids:
        type: "array"
        description: "A list of device UIDs to poll metrics for."
        items:
          type: "string"
        required: false

In this example, the config file can contain a sensor item which is an object with a single device_uuids attribute.

Configuration File

The configuration file is a YAML formatted file which contains site-specific configuration values. This file can contain ‘static’ or ‘dynamic’ values. The configuration file is named <pack name>.yaml and located in the /opt/stackstorm/configs/ directory. File ownership should be st2:st2.

For example, for a pack named libcloud, the configuration file is located at /opt/stackstorm/configs/libcloud.yaml.

This example configuration matches the configuration schema above:

---
  api_key: "some_api_key"
  api_secret: "{{st2kv.user.api_secret}}"  # user-scoped configuration value which is also a secret as declared in config schema
  region: "us-west-1"
  private_key_path: "{{st2kv.system.private_key_path}}"  # global datastore value

Configuration files are not read dynamically at run-time. Instead, they must be registered, and values are then loaded into the StackStorm DB. They are registered in the same way as other resources by running st2ctl reload/st2-register-content script. For configs, you need to run this script with the --register-configs flag:

sudo st2ctl reload --register-configs

Or:

sudo st2-register-content --register-configs

When loading and registering configs using the commands described above, static values in the config file are validated against the schema. If no schema exists, validation is not performed.

Keep in mind that only static values in the config are validated. Dynamic values (those using Jinja notation to reference values in the datastore) are resolved during run-time, so they can’t be validated during the register/load phase.

Static Configuration Values

A static configuration value is one which is loaded from the config file and used as-is.

Dynamic Configuration Value

Note

Currently, only strings (string types) support dynamic configuration values.

A dynamic configuration value is one that contains a Jinja template expression. This template expression is evaluated during run-time and resolves to a name (key) of the Datastore value. This datastore value is then used as the configuration value.

Dynamic configuration values offer additional flexibility, and include support for user-scoped datastore values. This is useful when you want to use different configuration values, based upon the user who invoked the action.

In the config, dynamic configuration values are referred to as shown below:

---
  api_secret: "{{st2kv.user.api_secret}}"  # user-scoped configuration value which is also a secret as declared in config schema
  private_key_path: "{{st2kv.system.private_key_path}}"  # global datastore value

api_secret is a user-scoped dynamic configuration value which means that the user part will be replaced by the username of the user who triggered the action execution.

Dynamic configuration values are stored in the datastore and are configured using the CLI or API.

If a value is marked as secret in the config schema, it will need to be stored encrypted in the datastore. When setting the value, the --encrypt flag should be used, as shown below:

st2 key set api_secret "my super secret api secret" --scope=user --encrypt

See more about storing secrets in datastore here.

In the above example, private_key_path is a regular dynamic configuration value, which means that a datastore item corresponding to this key (private_key_path) will be loaded from the datastore.

In this case, using the CLI, the value would be set as displayed below:

st2 key set private_key_path "/home/myuser/.ssh/my_private_rsa_key"

Configuration Loading and Dynamic Value Resolving

The configuration file is loaded at registration. Dynamic values are resolved during run-time. For sensors, this is when the sensor container spawns a subprocess for a sensor instance and for actions it is when the action is executed.

When resolving and loading user-scoped configuration values, the authenticated user who triggered the action execution is used for the context when resolving the value.

Configuring Dynamic Configuration Values Using the CLI

Dynamic pack configuration values can be manipulated in the same way as any other datastore item using the st2 key set of CLI commands.

Configuring a Regular (non user-scoped) Dynamic Configuration Value

Regular dynamic configuration values can be configured by an administrator or any user:

st2 key set <key name> <key value>

# For example
st2 key set private_key_path "/home/myuser/.ssh/my_private_rsa_key"

To view a value, use the st2 key get command:

st2 key get <key name>

# For example
st2 key get private_key_path

Keep in mind that secret values will be masked by default.

Configuring a User-scoped Dynamic Configuration Value

Dynamic configuration values can be configured by each user themselves or by an administrator for any available system user:

st2 key set --scope=user [--encrypt] <key name> <key value>

# For example (authenticated as "user1")
st2 key set --scope=user default_region "us-west-1"
st2 key set --scope=user --encrypt api_secret user1_api_secret

# For example (authenticated as "user2")
st2 key set --scope=user default_region "us-east-1"
st2 key set --scope=user --encrypt api_secret user2_api_secret

# For example (authenticated as administrator, setting a value for "user1" and "user2")
st2 key set --scope=user --user=user1 default_region "us-west-1"
st2 key set --scope=user --user=user2 default_region "us-east-1"

Similarly to above, you can use the st2 key get command to view values. The same rules which apply to set also apply to get (users can only see values which are local to them, administrators can see all the values, secrets are masked by default).

Limitations

There are some limitation with dynamic config values and the {{st2kv.user.key_name}} context you should be aware of.

Dynamic Config Values

Right now only the string type is supported for dynamic config values. This was done intentionally to keep the feature simple and fully compatible with the existing datastore operations (this means you can re-use the same API, CLI commands, etc.).

To work around this (in case you want to use a non-string value) you can store a JSON serialized version of your value in the datastore and then de-serialize it in the action/sensor code.

If this turns out to be a big problem for many users, we will consider introducing support for arbitrary types, but this would most likely mean we will need to implement a new API and CLI commands for managing dynamic config values. That’s something we want to avoid.

User Context

User context is right now only available for actions which are triggered via the StackStorm API.

This means that dynamic config values which utilize {{st2kv.user.some_value}} notation will only resolve to the correct user when an action is triggered through the API.

The reason for that is that the user context is currently only available in the API. If an action is triggered via a rule, user context is not available. In this case, {{st2kv.user}} will resolve to the system user (by default, stanley).

We plan to address this in a future release, but we haven’t decided on the best approach yet, so your feedback is welcome. Whatever approach we go with, carrying the user context with a trigger and mapping this external user to the StackStorm user will require some additional work on the user side.