What are advanced Flow files?

Last updated: July 14, 2025

Tip: Learn how to reference flow files in AWS S3: Remote File Path Rules

Structure of variable definitions, flow file stages, and nested actions that call on variables.

Advanced Flow files use globalVariables, stageVariables, property substitution, namespaced "included" files, an endStage which always runs, Flow Conditionals in stage or actions, decomposed/nested flow files, and bash -c "chained | commands".

Structure

The header contains all variable definitions and references to external files containing variable definitions.

The stages contain individual actions that run commands, such as checks run and update.

endStage: Once actions run, the endStage section runs. Common commands included here are status and history. If the flow file contains errors, endStage still runs and tells you why it failed to run successfully.

In any stage, you can specify variables, conditional behavior, and other properties of advanced flow files.

What are advanced Flow files?

Example Flow File

liquibase.flowvariables.yaml

Defines variables that you can use in other flow files.

########## LIQUIBASE FLOWFILE ########## ########## learn more http://docs.liquibase.com/flow ########## ## NOTE: This example yaml file of key:value variables is injected into examples/liquibase.advanced.flow file ## using the "include" ability. It will be given the namespace "DATES" but could be given any namespace. PROJNAME: "MyFlowProj" THISDATE: "2022-11-28T15-00-20"

liquibase.advanced.flowfile.yaml

Includes command arguments, global arguments, and a referenced include file (YAML).

########## LIQUIBASE FLOW FILE ########## ########## learn more http://docs.liquibase.com/flow ########## ## NOTE: This is an advanced example flowfile, compared to the other sample at examples/liquibase.flowfile.yaml #### HOW TO USE THIS FILE: #### example for CLI: liquibase flow --flow-file=liquibase.advanced.flowfile.yaml #### example for ENV Var: LIQUIBASE_FLOW_FLOW_FILE=liquibase.advanced.flowfile.yaml ## Advanced options show in this file include: #### non-default name of 'liquibase.advanced.flowfile.yaml' (use by setting flowfile property to this name) #### use of 'include' to inject namespaced yaml files of key: val variables #### use of globalVariables and stageVariables #### use of globalArgs and cmdArgs #### use of property substitution #### use of a nested flowfile (in this case in the endStage, but could be elsewhere) #### use of if: conditional which allows a -type: shell or -type: liquibase command to run ###### In the example below, we set an environment variable LIQUIBASE_CURRENT_TARGET, such as 'export LIQUIBASE_CURRENT_TARGET=dev' ###### This could be determined dynamically, of course, from the build tools, bu tthis is simpler for this example "if:" conditional #### use of shell commands in a -type: shell block. ###### command: bash -c "the shell command || and its chained commands && go in the quotes" ######## #### POTENTIAL use of environment variables: ###### DATETIME STAMP ######## In this file, you could replace ${FLOWVARS.THISDATE} with an env var, such as ${LIQUIBASE_THISDATE} set via .bash_profile ######## for example 'export LIQUIBASE_THISDATE=$( date +'%Y-%m-%dT%H-%M-%S' )' ## Bring in and namespace an external file with yaml 'key: val' pairs for use in this file ## The variables will be used as ${namespace.variablename}, seen in this example as ${FLOWVARS.PROJNAME} include: FLOWVARS: liquibase.flowvariables.yaml ## Set up some global variables for property substitution in ANY stage globalVariables: DIRNAME: "./${FLOWVARS.PROJNAME}_${FLOWVARS.THISDATE}" STATUSFILE: "status.txt" UPDATELOG: "update.log" HISTORYFILE: "history.txt" ## Start of the stages. stages: ## A prep stage. There can be more than one stage if desired. stage-prep: actions: - type: shell command: bash -c "mkdir -p ${DIRNAME}" ## Another stage. stage-dowork: ## set up vars for property substitution in THIS stage only stageVariables: VERBOSESTATE: TRUE actions: # Do a validate command - type: liquibase command: validate # Tell me what is pending a deployment - type: shell command: bash -c "liquibase --show-banner false --outputfile ./${DIRNAME}/${STATUSFILE} status --verbose ${VERBOSESTATE}" # This is the structured way to setup a liquibase command, if you dont want to run it as one 'bash -c' command #- type: liquibase # command: status # globalArgs: # outputfile: "${DIRNAME}/${STATUSFILE}" # showbanner: false # cmdArgs: {verbose: "${VERBOSESTATE}"} # And then save a version in detail, if env var LIQUIBASE_FILE_OUTPUT == 1 - type: shell command: bash -c "echo 'LIQUIBASE_ env vars ' && env | grep 'LIQUIBASE_' " - type: liquibase ## if this var LIQUIBASE_CURRENT_TARGET is "dev", then the updatesql will run if: "${LIQUIBASE_CURRENT_TARGET} == dev" command: updatesql globalArgs: {outputfile: "${DIRNAME}/${UPDATELOG}"} - type: shell ## if this var LIQUIBASE_CURRENT_TARGET is not "dev", then the message will be displayed if: "${LIQUIBASE_CURRENT_TARGET} != dev" command: echo "No output files created. Set env var LIQUIBASE_CURRENT_TARGET to dev to trigger file creation." # Policy Checks for changelog - type: liquibase command: checks run cmdArgs: {checks-scope: changelog} # Run update - type: liquibase command: update # Policy Checks for database - type: liquibase command: checks run cmdArgs: {checks-scope: database} # Create a history file - type: liquibase command: history globalArgs: {outputfile: "${DIRNAME}/${HISTORYFILE}"} ## The endStage ALWAYS RUNS. ## So put actions here which you desire to perform whether previous stages' actions succeed or fail. ## If you do not want any actions to ALWAYS RUN, simply delete the endStage from your flow file. endStage: actions: - type: liquibase ## Notice this is a flow command in a flow file, and it called a 'nested' flowfile, which in this case lives in the same dir, but could be elsewhere command: flow cmdArgs: {flowfile: liquibase.endstage.flow}

liquibase.endstage.flow

In this example, we run some final commands in an endStage file. The endStage always runs, so you can use it for processes that you want to run after every deployment. For example, see the following example of content in liquibase.endstage.flow.

########## LIQUIBASE FLOW FILE ########## ########## learn more http://docs.liquibase.com/flow ########## ## NOTE: This example flowfile is called from the examples/liquibase.advanced.flowfile.yaml file ## While it could be run on its own, this file is designed to show that flow-files can be decomposed ## into separate files as makes sense for your use cases. stages: cleanuptheDB: actions: # Clear out the database - type: liquibase command: dropAll # Check that database is empty by seeing what is ready to be deployed - type: liquibase command: status cmdArgs: {verbose: TRUE} ## The endStage ALWAYS RUNS. ## So put actions here which you desire to perform whether previous stages' actions succeed or fail. ## If you do not want any actions to ALWAYS RUN, simply delete the endStage from your flow file, ## as it has been deleted here in this liquibase.endStage.flow file.

Note: You can also keep all your actions in a single flow file. However, using a main flow file to call on other flow files is a modular approach that can keep you organized.

Introduction to Flows

Remote files on AWS with Flows