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 XebiaLabs public blueprint repository provided in the XebiaLabs 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 or SecretFile the parameter is saved in a secrets.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 the type field, the File type does not support the value parameter. Also, the default parameter for this field expects to have a file path instead of a final value string.
Note 3: Parameters with SecretInput, SecretEditor or SecretFile type support default values as well.
When a SecretInput, SecretEditor or SecretFile 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 in secrets.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 in secrets.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 in secrets.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 and false
  • 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 details 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"

Note: 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 details how to use GoLang templates.

Support for additional Sprig functions is included in the templating engine, as well as a list of custom XL functions. The table below describes additional functions that are currently available.

Function Example Description
kebabcase .AppName | kebabcase Convert string to use kebab case (separated by -)

Note: 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 XebiaLabs 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 details, 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, the value 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.