Steps and actions are the building blocks of workflows in Keep Workflow Engine. While they share a similar structure and syntax, the difference between steps and actions is mostly semantic:

  • Steps: Focused on querying data or triggering fetch-like operations from providers (e.g., querying databases, fetching logs, or retrieving information).
  • Actions: Geared toward notifying or triggering outcomes, such as sending notifications, updating tickets, or invoking external services.

Together, steps and actions allow workflows to both gather the necessary data and act upon it.


General Structure

Both steps and actions are defined using a similar schema:

Steps

Used for querying or fetching data.

Step uses the _query method of each provider.

steps:
  - name: <step-name>
    provider:
      type: <provider-type>
      config: <provider-config>
      with:
        <provider-specific-parameters>

Actions

Used for notifications or triggering effects.

Action uses the _notify method of each provider.


actions:
  - name: <action-name>
    provider:
      type: <provider-type>
      config: <provider-config>
      with:
        <provider-specific-parameters>

Examples

Fetch data from a MySQL database


steps:
  - name: get-user-data
    provider:
      type: mysql
      config: "{{ providers.mysql-prod }}"
      with:
        query: "SELECT * FROM users WHERE id = 1"
        single_row: true

Retrieve logs from Datadog

steps:
  - name: get-service-logs
    provider:
      type: datadog
      config: "{{ providers.datadog }}"
      with:
        query: "service:keep and @error"
        timeframe: "1h"

Query Kubernetes for running pods


steps:
  - name: get-pods
    provider:
      type: k8s
      config: "{{ providers.k8s-cluster }}"
      with:
        command_type: get_pods

Send an email

actions:
  - name: send-email
    provider:
      type: email
      config: "{{ providers.email }}"
      with:
        to: "[email protected]"
        subject: "Account Updated"
        body: "Your account details have been updated."

Send a Slack Message

actions:
  - name: notify-slack
    provider:
      type: slack
      config: "{{ providers.slack-demo }}"
      with:
        message: "Critical alert received!"

Create a ticket in ServiceNow

actions:
  - name: create-servicenow-ticket
    provider:
      type: servicenow
      config: "{{ providers.servicenow }}"
      with:
        table_name: INCIDENT
        payload:
          short_description: "New incident created by Keep"
          description: "Please investigate the issue."

Combining Steps and Actions

A workflow typically combines steps (for querying data) with actions (for notifications or outcomes).

Here’s few examples:

Query and Notify

workflow:
  id: query-and-notify
  description: "Query a database and notify via Slack"
  steps:
    - name: get-user-data
      provider:
        type: mysql
        config: "{{ providers.mysql-prod }}"
        with:
          query: "SELECT email FROM users WHERE id = 1"
          single_row: true

  actions:
    - name: send-notification
      provider:
        type: slack
        config: "{{ providers.slack-demo }}"
        with:
          message: "User email: {{ steps.get-user-data.results.email }}"

Alert and Incident Management

workflow:
  id: alert-management
  description: "Handle alerts and create incidents"
  steps:
    - name: get-alert-details
      provider:
        type: datadog
        config: "{{ providers.datadog }}"
        with:
          query: "service:keep and @alert"
          timeframe: "1h"

  actions:
    - name: create-incident
      provider:
        type: servicenow
        config: "{{ providers.servicenow }}"
        with:
          table_name: INCIDENT
          payload:
            short_description: "Alert from Datadog: {{ steps.get-alert-details.results.alert_name }}"
            description: "Details: {{ steps.get-alert-details.results.alert_description }}"

Error Handling and Retries

Both steps and actions support error handling to ensure workflows can recover from failures.


steps:
  - name: fetch-data
    provider:
      type: http
      with:
        url: "https://api.example.com/data"
    on-failure:
      retry:
        count: 3
        # Retry every 5 seconds
        interval: 5