FortiSOAR Discussions

FortiSOAR Playbook Development Best Practices

FortiSOAR  patented playbook design experience provides a visual drag/drop graphical user interface (GUI) and a low-code rapid development mode that allows users of all types to easily create custom playbooks.

Even the most complicated playbook flows do not require technical coding skills, all you need to be is a cybersecurity enthusiast!!

In our endeavor to build around your playbook development energy, starting a thread, to encourage playbook development best practices. Come join us, to add on to this thread of facts, that helps strengthen the security fabric.

FortiSOAR Playbook Development Best Practices


As can be seen in attached image, do not duplicate entire step results into one more variable. This results in doubling up the memory and storage requirements, if the step output is huge.

This default enrichment for Virus Total, for example, duplicates the entire enrichment data into a vt_data variable. Subsequently, this is not even consumed by the playbook.

However, the effects are significant, because the enrichment playbooks mostly run in DEBUG mode; run in large numbers; and have large outputs in response.


adding a few more and encouraging community to add the ones they have established


1) First Step (after Trigger), should always be Set Variable and named as "Configuration".

FortiSOAR team uses this as a convention to define all the tunables such as vt_reputation_threshold. Basically anything which one anticipates to be changed/tuned in the future, should be declared as a variable in this section.

CTO (SOAR Business) | VP of Engineering

2) Using Message Feature - Every Step in the playbook has a Message Feature. Anything you put here as static or dynamic text becomes the comment to alert (or whichever record the playbook is executing). We use this extensively to put comments as if a human would add to the case. This keeps the stream of comments readable -- and hint, it would be used in the future by AI.


See these screenshots:




CTO (SOAR Business) | VP of Engineering

  1. Set Variable Step (named as Configuration) should be the first step after trigger step.
  2. Instead of hardcoding values in all steps, all tuneable variable for a playbook should be defined in the Configuration(Set Variable Step) step and used as variables in the subsequent steps.
  3. Variable names to be in camel casing if they are of two words, in case more than two words then use snake case for better readability.
  4. Playbook Step Name should be in Initcaps format (e.g “Fetch Email Incident” instead of “Fetch email incident”)
  5. On Update Trigger playbooks should require Condition to avoid infinite looping of playbook  .
  6. Playbook naming could follow a pattern, module name > action > sub-action.


                      Parent Playbook: QRadar > Fetch Offenses

                      Reference Playbook: > QRadar > Fetch Offenses > Create Alert

  1. Playbooks name and description should indicate what the playbook does. Tags on the playbook can indicate the trigger type of the playbook
  2. Notes and tips can be added in the description field of steps whenever there is a comment that can help explain the step for maintainability.
  3. Playbook collections should be grouped as per functionality. All utility playbooks can be referenced from multiple collections should be kept in a common utils collection
  4. All triage, enrichment, and investigation playbooks should run on post-create triggers
  5. For Decision Step, User should add info for the branch tooltip which will be executed if the condition is satisfied

1. Try adding tags for all the Playbooks, like "subroutine" for child Playbook, "OnCreate" for Playbooks having On Create Trigger steps, "Schedule" for Playbook which are periodically executed.

2. Group the Playbook steps according to their functionality by using the Block Feature. It will help the other person to understand the basic flow of the Playbook before deep diving into it.

3. Make sure the Execution priority of the Playbook is set accordingly, like

  • Data Ingestion Playbooks have High priority so that without any delay the data is available in FortiSOAR
  • Investigation Playbooks can have priority as Medium, so that on need basis Playbooks are not in the long queue
  • Enrichment Playbooks can have priority as Low, so that whenever there no High/Medium priority playbooks are in queue to be executed then only it get executed. As these playbook will be executing every now and then and will unnecessary keep the important Playbook in the long queue.


Abhinav Goel

I'd add:
- Add a variable for each connector action to store vars.result. This simplify debugging since previous steps (vars.steps.*) are not usable in the Jinja Editor

- The sensitive playbooks should all be private so only selected individuals can run them

Playbook Execution Logs should be purged as frequently to avoid performance degradation 

- For playbooks that have dual triggers (for example referenced and manual) and require  input record(s) it's always a good idea to keep the input in vars.input.records when referenced, so to have a consistent input data regardless of how the playbook was triggered  

- playbooks versioning is very useful especially for complex workflows


Thanks a bunch!! This comes as a great addition for the FortiSOAR Community!