Blueprint YAML format
This topic provides a reference for the DevOps as Code YAML file structure for a blueprint. You can review the publicly-available blueprint files alongside the content in this topic to get a better understanding of how fields, values and options are specified.
By default, the XL CLI is configured to access the read-only Deploy/Release public blueprint repository provided in the Deploy/Release public software distribution site. The source files for the blueprints are stored in the blueprints repository on GitHub.
You can also see the curated list of Blueprints provided by XebiaLabs that includes links to GitHub readme files with details for each blueprint.
For more information about the available blueprint command flags, refer to xl blueprint command details.
Root YAML fields
All blueprint YAML files have the following root fields:
Field name | Expected value | Examples | Required? |
---|---|---|---|
apiVersion | xl/v2 | - | Yes |
kind | Blueprint | - | Yes |
metadata | - | See below | No |
spec | - | See below | Yes |
Metadata fields
Field name | Expected value | Examples | Required? |
---|---|---|---|
name | - | Sample Project | No |
description | - | A long description that describes the blueprint project | No |
author | - | My Company | No |
version | - | 2.0 | No |
instructions | - | You need to start your Docker containers before applying the blueprint | No |
Spec fields
Fields in the spec
section include parameters and files.
Parameters fields
Parameters are defined by the blueprint creator in the blueprint.yaml
file and can be used in the blueprint template files. If no value is defined for a parameter in the blueprint.yaml
file, the user will be prompted to enter its value during execution of the blueprint. By default, parameter values will be used to replace variables in template files during blueprint generation.
Field name | Expected value(s) | Examples | Default Value | Required? | Description |
---|---|---|---|---|---|
name | - | AppName | - | Yes | Parameter name, to be used in template placeholders |
type | Input SecretInput Select Confirm Editor SecretEditor File SecretFile | - | Required when value is not set | Type of the prompt input. See Spec field notes for more information on this parameter. | |
prompt | - | What is your application name? | - | Required when value is not set | Question to prompt. |
value | - | eu-west-1 /!expr "Foo == 'foo' ? 'A' : 'B'" | - | No | If present, the user will not be asked a question to provide a value |
default | - | eu-west-1 /!expr "Foo == 'foo' ? 'A' : 'B'" | - | No | Default value. Will be presented during the question prompt. Also will be the variable value if question is skipped. |
description | - | Application name. Will be used in various AWS resource names | - | No | If present, will be used instead of the default question text |
label | - | Application name | - | - | If present, will be used instead of name in summary table. |
options | - | - eu-west-1 - us-east-1 - us-west-1 - label: us west 1 value: us-west-1 -!expr "Foo == 'foo' ? ('A', 'B') : ('C', 'D')" | - | Required for the Select input type | Set of options for the Select input type. Can consist of any number of text values, label/value pairs, or values retrieved from an expression. |
validate | !expr tag | !expr "regex('[a-z]*', paramName)" | - | No | Validation expression to be verified at the time of user input, any combination of expressions and expression functions can be used. The current parameter name must be passed to the validation function. Expected result of the expression evaluated is type boolean. |
promptIf | - | CreateNewCluster /!expr "CreateNewCluster == true" | - | No | If this question is needed to be asked of user, and depends on the value of another, the promptIf field can be defined. A valid variable name should be given and the variable name used should have been defined before order-wise.Expression tags also can be used, but the expected result should always be boolean. Should not be set along with value . |
saveInXlvals | true or false | - | true for SecretInput , SecretEditor and SecretFile fields. False for other fields. | No | If true, output parameter will be included in the values.xlvals output file. SecretInput , SecretEditor and SecretFile parameters will always be written to secrets.xlvals file regardless of what you set for this field |
replaceAsis | true or false | - | false | No | SecretInput , SecretEditor or SecretFile field values are normally not directly used in Go template files. Instead they will be referred using !value ParameterName syntax. If replaceAsIs is set to true , output parameter will be used as a raw value instead of with the !value tag in Go templates. Useful in cases where parameter will be used with a post-process function in any template file. This parameter is only valid for SecretInput , SecretEditor or SecretFile fields; for other fields it will produce a validation error. |
revealOnSummary | true or false | - | false | No | If set to true , the value will be present on the summary table. This parameter is only valid for SecretInput fields; for other fields it will produce a validation error. |
Spec field notes
Note 1: If the type is
SecretInput
,SecretEditor
orSecretFile
the parameter is saved in asecrets.xlvals
file so that they won't be checked into the GIT repository and will not be replaced by actual values in the template files by default.
Note 2: For thetype
field, theFile
type does not support thevalue
parameter. Also, thedefault
parameter for this field expects to have a file path instead of a final value string.
Note 3: Parameters withSecretInput
,SecretEditor
orSecretFile
type support default values as well.
When aSecretInput
,SecretEditor
orSecretFile
parameter question is being presented, the default value will be shown on the prompt as raw text; and if the user enters an empty response for the question this default value will be used instead.
Types
The types that can be used for inputs are:
Input
: Used for simple text or number inputs.SecretInput
: Used for simple secret or password inputs. These are by default saved insecrets.xlvals
files so that they won't be checked in the GIT repo and will not be replaced with actual values in the template files.Select
: Used for select inputs where user can choose from given options.Confirm
: Used for boolean inputs.Editor
: Used for multiline or complex text input.SecretEditor
: Used for multiline or complex secret inputs. These are by default saved insecrets.xlvals
files so that they won't be checked in the GIT repo and will not be replaced with actual values in the template files.File
: Used for fetching the content of a given file path.SecretFile
: Used for fetching the content of a given file path and treat it as secret. These are by default saved insecrets.xlvals
files so that they won't be checked in the GIT repo and will not be replaced with actual values in the template files.
Files fields
Field name | Expected value(s) | Examples | Default Value | Required | Description |
---|---|---|---|---|---|
path | - | xebialabs/xlr-pipeline.yaml | - | Yes | File/template path to be copied/processed |
renameTo | - | xebialabs/xlr-pipeline-new.yaml | - | No | The name to be used for the output file |
writeIf | - | CreateNewCluster /!expr "CreateNewCluster == true" | - | No | This file will only be generated when the value of a parameter or function returns true. A valid parameter name should be given and the parameter name used should have been defined. Expression tags can also be used, but the expected result should always be boolean. |
IncludeBefore/IncludeAfter fields for composability
includeBefore
/IncludeAfter
values will decide if the blueprint should be composed before or after the master blueprint. This will affect the order in which the parameters will be presented to the user and the order in which files are written. Entries in before/after will stack based on the order of definition. For more information, see Blueprint composability.
Field name | Expected value(s) | Examples | Default Value | Required | Description |
---|---|---|---|---|---|
blueprint | - | aws/monolith | - | Yes | The full path of the blueprint to be composed; will be looked up from the currently used repository. |
includeIf | - | CreateNewCluster /!expr "CreateNewCluster == true" | - | No | This blueprint will only be included when the value of a parameter or expression returns true. A valid parameter name should be given and the parameter name used should have been defined. Expression tags can also be used if the returned value is a boolean. |
parameterOverrides | Parameter definition | - | - | No | Overrides fields of the parameters defined on the blueprint included. This allows you to force the system to skip any question by providing a value for it or by overriding its promptIf . Can override everything except name and type fields. |
fileOverrides | File definition | - | - | No | Can be used to override fields of any file definition in the blueprint being composed. This allows you to force the system to skip any file by overriding its writeif or rename a file by providing a renameTo . Can override everything except the path field. |
The following generic example shows a blueprint.yaml
using Includes
to compose multiple blueprints:
apiVersion: xl/v2
kind: Blueprint
metadata:
name: Composed blueprint
version: 2.0
spec:
parameters:
- name: Foo
prompt: what is value for Foo?
files:
- path: xlr-pipeline.yml
writeIf: !expr "Foo == 'foo'"
includeBefore: # the `aws/datalake` will be executed first followed by the current blueprint.yaml
# we will look for `aws/datalake` in the current-repository being used
- blueprint: aws/datalake
# with 'parameterOverrides' we can provide values for any parameter in the blueprint being composed. This way we can force to skip any question by providing a value for it
parameterOverrides:
# we are overriding the value and promptIf fields of the TestFoo parameter in the `aws/datalake` blueprint
- name: TestFoo
value: hello
promptIf: !expr "3 > 2"
# 'fileOverrides' can be used to skip files and can be conditional using dependsOn
fileOverrides:
- path: xld-environment.yml.tmpl
writeIf: !expr "false" # we are skipping this file
- path: xlr-pipeline.yml
renameTo: xlr-pipeline-new.yml # we are renaming this file since the current blueprint.yaml already has this file defined in the file section above
includeAfter: # the `k8s/environment` will be executed after the current blueprint.yaml
# we will look for `k8s/environment` in the current-repository being used
- blueprint: k8s/environment
parameterOverrides:
- name: Test
value: hello2
fileOverrides:
- path: xld-environment.yml.tmpl
writeIf: !expr "false"
Supported custom YAML tags
This section describes function and expression tags that you can use with blueprints.
Expression tag (!expr
)
Blueprints support custom expressions to be used within parameter definitions, file declarations, and includeBefore/includeAfter. The expression
tag can be used in the parameter/parameterOverrides fields default
, value
, promptIf
, options
, validate
; the file/fileOverrides field writeIf
, and the includeBefore/includeAfter field includeIf
.
You can use a parameter defined in the parameters section inside an expression. Parameter names are case sensitive and you should define the parameter before it is used in an expression. In other words, you cannot refer to a parameter that will be defined after the expression is defined in the blueprint.yaml
file or in an included blueprint.
Custom expression syntax
!expr "EXPRESSION"
Operators and types supported
- Modifiers:
+
-
/
*
&
|
^
**
%
>>
<<
- Comparators:
>
>=
<
<=
==
!=
=~
!~
- Logical operators:
||
&&
- Numeric constants, as 64-bit floating point (
12345.678
) - String constants (single quotes:
'foobar'
) - Date constants (single quotes, using any permutation of RFC3339, ISO8601, Ruby date, or Unix date. Date parsing is automatically tried with any string constant.)
- Boolean constants:
true
andfalse
- Parenthesis to control order of evaluation
(
)
- Arrays (anything separated by
,
within parenthesis:(1, 2, 'foo')
) - Prefixes:
!
-
~
- Ternary conditional:
?
:
- Null coalescence:
??
See MANUAL.md from govaluate for more information on what types each operator supports.
Types
The supported types are float64
, bool
, string
, and arrays
. When using expressions to return values for options
, ensure that the expression returns an array. When using expressions on dependsOnTrue
and dependsOnFalse
fields, ensure that it returns boolean.
Escaping characters
You can escape characters for parameters that have spaces, slashes, pluses, ampersands or other characters that may be interpreted as special.
For example:
"response-time < 100"
This would be parsed as "[response] minus [time] is less than 100" whereas the intention is for "response-time" to be a variable that simply includes a dash.
You can work around this in two ways:
Method 1: Escape the entire parameter name
Example:
"[response-time] < 100"
Method 2: Use backslashes to escape only the minus sign
Example:
"response\\-time < 100"
You can use backslashes anywhere in an expression to escape the very next character. Square-bracketed parameter names can be used instead of plain parameter names at any time.
Available custom functions for expressions
Function | Parameters | Examples | Description |
---|---|---|---|
strlen | Parameter or Text(string) | - !expr "strlen('Foo') > 5" - !expr "strlen(FooParameter) > 5" | Get the length of the given string variable |
max | Parameter or numbers(float64, float64) | - !expr "max(5, 10) > 5" - !expr "max(FooParameter, 100)" | Get the maximum of the two given numbers |
min | Parameter or numbers(float64, float64) | - !expr "min(5, 10) > 5" - !expr "min(FooParameter, 100)" | Get the minimum of the two given numbers |
ceil | Parameter or number(float64) | - !expr "ceil(5.8) > 5" - !expr "ceil(FooParameter) > 5" | Ceil the given number to nearest whole number |
floor | Parameter or number(float64) | - !expr "floor(5.8) > 5" - !expr "floor(FooParameter) > 5" | Floor the given number to nearest whole number |
round | Parameter or number(float64) | - !expr "round(5.8) > 5" - !expr "round(FooParameter) > 5" | Round the given number to nearest whole number |
randPassword | String | - !expr "randPassword()" | Generates a 16-character random password |
string | Parameter or number(float64) | - !expr "string(103.4)" | Converts variable or number to string |
regex | - Pattern text- Value to test | - !expr "regex('[a-zA-Z-]*', ParameterName)" | Tests given value with the provided regular expression pattern. Return true or false . Note that \ needs to be escaped as \\\\ in the patterns used. |
isFile | File path string | - !expr "isFile('/test/dir/file.txt')" | Checks if the file exists or not |
isDir | Directory path string | - !expr "isDir('/test/dir')" | Checks if the directory exists or not |
isValidUrl | URL text | - !expr "isValidUrl('http://xebialabs.com/')" | Checks if the given URL text is a valid URL or not. This function only checks the structure of the URL, not its status code or availability. |
awsCredentials | Attribute text:- IsAvailable - AccessKeyID - SecretAccessKey - ProviderName | - !expr "awsCredentials('IsAvailable')" | System-wide defined AWS credentials can be accessed with this function. IsAvailable attribute returns true or false based on if the AWS configuration file can be found in the system or not. The rest of the attributes return the text value read from AWS configuration file. AWS_PROFILE env variable can be set to change the active AWS profile system-wide. |
awsRegions | - AWS service name- Index of the result list [optional] | - !expr "awsRegions('ecs', 2)" | Returns list of AWS regions that are available for the given AWS service. If the second parameter is not provided, the function will return the whole list. |
k8sConfig | - K8s Config attribute name(ClusterServer /ClusterCertificateAuthorityData /ClusterInsecureSkipTLSVerify /ContextCluster /ContextNamespace /ContextUser /UserClientCertificateData /UserClientKeyData /IsAvailable )- Context name [optional] | - !expr "k8sConfig('IsAvailable')" - !expr "k8sConfig('ClusterServer', 'myContext')" | Returns the k8s config attribute value from the config file read from the system. For IsAvailable attribute, a true or false value will be returned. If context name is not defined, current-context will be read from the config file. |
Blueprint YAML example
Here is an example of a blueprint.yaml
file using expressions for complex behaviors:
apiVersion: xl/v2
kind: Blueprint
metadata:
name: Blueprint Project
description: A Blueprint project
author: XebiaLabs
version: 1.0
spec:
parameters:
- name: Provider
prompt: what is your Kubernetes provider?
type: Select
options:
- AWS
- GCP
- Azure
default: AWS
- name: Service
prompt: What service do you want to deploy?
type: Select
options:
- !expr "Provider == 'GCP' ? ('GKE', 'CloudStorage') : (Provider == 'AWS' ? ('EKS', 'S3') : ('AKS', 'AzureStorage'))"
default: !expr "Provider == 'GCP' ? 'GKE' : (Provider == 'AWS' ? 'EKS' : 'AKS')"
- name: K8sClusterName
prompt: What is your Kubernetes cluster name
type: Input
promptIf: !expr "Service == 'GKE' || Service == 'EKS' || Service == 'AKS'"
default: !expr "k8sConfig('ClusterServer')"
# AWS specific variables
- name: UseAWSCredentialsFromSystem
prompt: Do you want to use AWS credentials from your ~/.aws/credentials file?
type: Confirm
promptIf: !expr "Provider == 'AWS' && awsCredentials('IsAvailable')"
- name: AWSAccessKey
type: SecretInput
prompt: What is the AWS Access Key ID?
promptIf: !expr "Provider == 'AWS' && !UseAWSCredentialsFromSystem"
default: !expr "awsCredentials('AccessKeyID')"
- name: AWSAccessSecret
prompt: What is the AWS Secret Access Key?
type: SecretInput
promptIf: !expr "Provider == 'AWS' && !UseAWSCredentialsFromSystem"
default: !expr "awsCredentials('SecretAccessKey')"
- name: AWSRegion
type: Select
prompt: "Select the AWS region:"
promptIf: !expr "Provider == 'AWS'"
options:
- !expr "awsRegions('ecs')"
default: !expr "awsRegions('ecs', 0)"
files:
- path: xld-k8s-infrastructure.yml
writeIf: !expr "Service == 'GKE' || Service == 'EKS' || Service == 'AKS'"
- path: xld-storage-infrastructure.yml
writeIf: !expr "Service == 'CloudStorage' || Service == 'S3' || Service == 'AzureStorage'"
Go templates
You can use GoLang templating in blueprint template files (.tmpl
). See the following cheatsheet for more information how to use GoLang templates.
Support for additional Sprig functions is included in the templating engine, as well as a list of custom functions. The table below describes additional functions that are currently available.
Function | Example | Description |
---|---|---|
kebabcase | `.AppName | kebabcase` |
Parameters marked as secret
cannot be used with Go template functions and Sprig functions as their values will not be directly replaced in the templates.
Blueprint repository
Remote blueprint repositories are supported for fetching blueprint files.
- Running the
xl
command for the first time will generate a default configuration file in your home directory (~/.xebialabs/config.yaml
). This file includes the default Deploy/Release Blueprint repository URL. - The XL-CLI configuration file can be updated manually or appropriate command line flags can also be passed when running the command in order to specify a different remote blueprint repository. Please refer to the XL-CLI documentation for detailed configuration and command line flag usage.
- You can manually update the
config.yaml
file. - You can also use the appropriate command line flags when running the command in order to specify a different remote blueprint repository.
for more information, see Manage blueprint repositories.
Blueprint answers file
When testing blueprints, or when there are too many blueprint questions to answer through a command line, you can use an answers file to supply responses to blueprint questions. The flags -a (answers)
and -s (strict-answers)
, as described in the XL-CLI documentation. The answers file format is expected to be YAML.
Example answers.yaml
:
AppName: TestApp
ClientCert: |
FshYmQzRUNbYTA4Icc3V7JEgLXMNjcSLY9L1H4XQD79coMBRbbJFtOsp0Yk2btCKCAYLio0S8Jw85W5mgpLkasvCrXO5
QJGxFvtQc2tHGLj0kNzM9KyAqbUJRe1l40TqfMdscEaWJimtd4oygqVc6y7zW1Wuj1EcDUvMD8qK8FEWfQgm5ilBIldQ
ProvisionCluster: true
AWSAccessKey: accesskey
AWSAccessSecret: accesssecret
DiskSize: 100.0
When using answers files with the --strict-answsers
flag, any command line input can be bypassed and blueprints can be fully automated. For more information on how to automate tests for blueprints with answers files and test case files, refer to Blueprint testing.
When an answers file is provided, it will be used in the same order as the command line input. As usual, while preparing a value for the parameter the steps will be:
- If the
promptIf
field exists, answers are evaluated and based on the boolean result, decided whether or not to continue. - If the
value
field is present in the parameter definition, regardless of the answers file value, thevalue
field value is going to be used. - If the answers file is present and the
value
parameter is found within, it will be used. - If none of the above is present and the parameter is not skipped due to a condition, the user will be asked to provide input through the command line if
--strict-answers
is not enabled.