Best practices
4 minute read
The CloudBolt OneFuse Platform leverages the Jinja2 templating language to allow our customers to define logic around how a module is to be consumed inside of a OneFuse Policy. These templates can be extremely powerful and can define very granularly exactly how OneFuse Policies should be consumed by an Upstream Provider.
However, the OneFuse Platform was designed to simplify your automation journey, so these best practices will help to better define how to mitigate complexity when building OneFuse Policies.
Resources
For additional information surrounding the concepts discussed in this document:
- OneFuse Docs: Concept of Templating and Templating guide
- SwaggerHub API: OneFuse Templating
Prerequisites
The OneFuse Platform has a built-in Template Preview feature that allows platform users to test in real time what the results of a Policy would be in their environment. To be able to leverage this feature, you first need to create a Property Set that represents what a request might look like for your environment. Before creating Policies, one or more Property Sets should be in place to be used when testing your Template syntax.
- Determine what properties you will be passing to and consuming within OneFuse Policies.
- Create a Property Set containing those properties.
- Whenever creating OneFuse Policies, select an Active Property Set from the lower right-hand corner of the OneFuse UI.
Recommendations
Required properties
Learn more via Filters: required
The required filter allows OneFuse customers to define what properties need to be passed into the Policy for the Policy to execute. This enables the ability to fail a Policy request if the Upstream Providers have not passed in all required properties as defined by the Policy.
When creating Policies, thought should be given as to whether each property is required for your use case, and if so:
- The
| requiredfilter should be applied to those properties. - Each
| requiredfilter should include the message to return if the required property is not passed in.
In the example below, the ‘Naming Template’ field value below for a Naming Policy specifies which properties are required. If any of the required properties are not passed to the generate name request, a failure will occur and return a message to the user letting them know which properties were missed.
{{ nameLocation | required('nameLocation is required') }}{{ nameEnv | required('nameEnv is required') }}{{ nameOS | required('nameOS is required') }}{{ nameApp | required('nameApp is required') }}
Logical statements (if/else) for properties
Learn more via Control Structures: if
When leveraging the Template Engine, you can make logical decisions about the outcome of that Policy directly in templatable fields. If you must include a logical statement that has more than three levels to the logic in a templatable field, you may want to consider splitting these out into separate OneFuse Policies to make it easier to troubleshoot failed Policy executions.
The following example would be better suited as four separate OneFuse Policies, which could then be invoked by Template Engine logic on the Upstream Provider. By having more than three logical decisions in a templatable field, troubleshooting Policy failures can be more difficult.
{# Example OneFuse Scripting Policy: Script Template field #}
{% if app == 'apache %}
{# <my script to install apache> #}
{% elif app == 'wordpress' %}
{# <my script to install wordpress> #}
{% elif app == 'nginx' %}
{# <my script to install nginx> #}
{% elif app == 'opencart' %}
{# <my script to install opencart> #}
{% endif %}
A better solution would be to create one OneFuse Policy for each “application”.
- OneFuse Scripting Policy with name: apache
- OneFuse Scripting Policy with name: wordpress
- OneFuse Scripting Policy with name: nginx
- OneFuse Scripting Policy with name: opencart
From the Upstream Provider, you can leverage the Template Engine to call the appropriate OneFuse Policy.
#Upstream Provider: VMware Aria Automation 8.1+/Cloud
#Example Cloud Template YAML
# Execute OneFuse Scripting Policy dynamically
# <EBSExecutionString> is replaced with ComputeProvisionPostLate
# -- Property Name
# <CustomID> is replaced with Application
# -- Property Value
# <OneFuse Endpoint Name> is onefuse
# <Scripting Policy Name> is {{ application }}
# Upon Deploy, user will select the Application, that will execute the corresponding Scripting Policy, see line 37
name: Simple Example
inputs:
application:
type: string
title: Application
description: Select an Application
enum:
- apache
- nginx
- opencart
- wordpress
default: apache
resources:
Cloud_Machine_1:
type: Cloud.Machine
properties:
image: CentOS7
flavor: small
count: 1
OneFuse_ScriptingPolicy_Trigger_ComputeProvisionPostLate: 'true' # Trigger Property
OneFuse_ScriptingPolicy_ComputeProvisionPostLate_Application: 'onefuse:{{ application }}'