Writing a custom provider definition
Create an empty directory and make it your working directory:
mkdir rtf-custom-provider
cd rtf-custom-provider
Create an empty YAML file for the custom provider definition:
touch my-provider.yaml
We will now step through creating a simple custom provider definition.
Adding required fields
A custom provider definition has three required fields: name, description, and command. The
sections below add each of these required fields and explain them in more detail.
name
Add the name field to the my-provider.yaml file:
name: env-generator
name is used to give each custom provider an identifiable title. It can be any valid string. The
value used for the name field has no impact on the execution of the custom provider. This makes it
easier to work with the custom provider programmatically.
description
Add the description field to the my-provider.yaml file:
name: env-generator
description: |
Generates an ENV_VARS.txt file with configuration for downstream scripts.
Output directory contains:
- ENV_VARS.txt (environment variables for setup scripts)
- base-config.txt (a base configuration file)
description is used to give more information about the custom provider for future users. It can be
any valid string. The value used for the description field has no impact on the execution of the
custom provider itself. This is a useful place to document what files the provider generates and how
they should be used.
command
The command is used to define what will be executed when the custom provider runs. The command is
responsible for generating output files in the $RTF_OUTPUT directory.
Add the command field to the my-provider.yaml file:
name: env-generator
description: |
Generates an ENV_VARS.txt file with configuration for downstream scripts.
Output directory contains:
- ENV_VARS.txt (environment variables for setup scripts)
- base-config.txt (a base configuration file)
command:
name: generate.sh
kind: relative_path
path: scripts/generate.sh
This references a script file that we will create in the custom provider commands section. Before we can run the custom provider, we need to create this script.
Custom provider commands
Before we can run the custom provider, we need to create the script referenced in the command
section. Create a scripts directory and the generate.sh file:
mkdir scripts
touch scripts/generate.sh
Add the following content to scripts/generate.sh:
#!/usr/bin/env bash
set -e
mkdir -p "$RTF_OUTPUT"
cat > "$RTF_OUTPUT/ENV_VARS.txt" << EOF
# Environment variables for project setup
# Generated by env-generator provider
export PROJECT_NAME="default-project"
export LOG_LEVEL="info"
EOF
echo "Generated environment config in $RTF_OUTPUT"
This script does the following:
- Creates the output directory using the
$RTF_OUTPUTenvironment variable, which is automatically set by rtf to the directory where output files should be written. All custom provider command scripts must write to this location. - Writes an
ENV_VARS.txtfile with environment variable exports that can be sourced by downstream scripts. This is not a required pattern for a custom provider but can be useful in many use cases which is why it is included in this guide. - Prints a message confirming the generation was successful.
The key difference between a command in a custom provider and one in a config file is that the command in a custom provider MUST write one or more files to RTF_OUTPUT. Commands in config files perform an action, for example, setting up an environment, whereas commands in a custom provider write files for config files to make use of.
Make the script executable:
chmod +x scripts/generate.sh
Your directory structure should now look like this:
ls -R
my-provider.yaml scripts
./scripts:
generate.sh
Checking the custom provider
Now, let’s check that the custom provider has been defined correctly:
rtf custom-provider template my-provider.yaml
This should result in the fully templated custom provider being printed to the terminal:
name: env-generator
description: |
Generates an ENV_VARS.txt file with configuration for downstream scripts.
Output directory contains:
- ENV_VARS.txt (environment variables for setup scripts)
- base-config.txt (a base configuration file)
variable_definitions: []
command:
name: generate.sh
kind: relative_path
path: scripts/generate.sh
args: []
env_vars: {}
file_providers: []
This highlights the optional fields for custom providers that have not yet been used:
variable_definitions, env_vars, and file_providers. These are discussed in the following
sections.
Running the custom provider
Before looking at the optional fields, let’s run the custom provider:
rtf custom-provider run my-provider.yaml
You should see output similar to this:
Generated environment config in /path/to/rtf-custom-provider/output/RTF_OUTPUT
The output directory contains the generated files. Let’s examine what was created:
cat output/RTF_OUTPUT/ENV_VARS.txt
Output:
# Environment variables for project setup
# Generated by env-generator provider
export PROJECT_NAME="default-project"
export LOG_LEVEL="info"
Remove the output directory before continuing:
rm -rf output/
Note rtf is deliberately configured to not overwrite an existing output directory. This is so you cannot accidentally overwrite output you intend to keep. The
--outputflag can be used withrtf custom-provider runto set a different output directory if you want to keep the existing output and run a new test.
Defining variables
The variable_definitions field is used to define parameters that the custom provider accepts. When
the custom provider is used in a test plan, these variables are passed as arguments. The
using a custom provider guide covers how to pass arguments to a custom
provider in detail.
For now, let’s add a variable to make the project name configurable. We are also going to update the
script to use this variable. The env_vars field is used to pass variable values to the command as
environment variables.
Update my-provider.yaml:
name: env-generator
description: |
Generates an ENV_VARS.txt file with configuration for downstream scripts.
Output directory contains:
- ENV_VARS.txt (environment variables for setup scripts)
- base-config.txt (a base configuration file)
# --- Add variable definitions ---
variable_definitions:
- name: project_name
description: "The name of the project"
# --------------------------------
command:
name: generate.sh
kind: relative_path
path: scripts/generate.sh
# --- Add env_vars to pass variables to the command ---
env_vars:
PROJECT_NAME: "{{ project_name }}"
# -----------------------------------------------------
Update scripts/generate.sh to use the environment variable:
#!/usr/bin/env bash
set -e
mkdir -p "$RTF_OUTPUT"
cat > "$RTF_OUTPUT/ENV_VARS.txt" << EOF
# Environment variables for project setup
# Generated by env-generator provider
export PROJECT_NAME="$PROJECT_NAME"
EOF
echo "Generated environment config in $RTF_OUTPUT"
Now run the custom provider with the --var flag to set the variable:
rtf custom-provider run my-provider.yaml --var project_name=my-app
Output:
Generated environment config in /path/to/rtf-custom-provider/output/RTF_OUTPUT
cat output/RTF_OUTPUT/ENV_VARS.txt
Output:
# Environment variables for project setup
# Generated by env-generator provider
export PROJECT_NAME="my-app"
The project_name variable is now configurable. Remove the output directory before continuing:
rm -rf output/
Adding a default value
Variables can have default values, like in config files. Let’s add a log_level variable with a
default value of "info".
Update my-provider.yaml:
name: env-generator
description: |
Generates an ENV_VARS.txt file with configuration for downstream scripts.
Output directory contains:
- ENV_VARS.txt (environment variables for setup scripts)
- base-config.txt (a base configuration file)
variable_definitions:
- name: project_name
description: "The name of the project"
# --- Add a variable with a default ---
- name: log_level
description: "Logging verbosity level"
default: "info"
# -------------------------------------
command:
name: generate.sh
kind: relative_path
path: scripts/generate.sh
env_vars:
PROJECT_NAME: "{{ project_name }}"
# --- Add LOG_LEVEL ---
LOG_LEVEL: "{{ log_level }}"
# ---------------------
Update scripts/generate.sh:
#!/usr/bin/env bash
set -e
mkdir -p "$RTF_OUTPUT"
cat > "$RTF_OUTPUT/ENV_VARS.txt" << EOF
# Environment variables for project setup
# Generated by env-generator provider
export PROJECT_NAME="$PROJECT_NAME"
export LOG_LEVEL="$LOG_LEVEL"
EOF
echo "Generated environment config in $RTF_OUTPUT"
Now run the custom provider without specifying log_level:
rtf custom-provider run my-provider.yaml --var project_name=my-app
Output:
Generated environment config in /path/to/rtf-custom-provider/output/RTF_OUTPUT
cat output/RTF_OUTPUT/ENV_VARS.txt
Output:
# Environment variables for project setup
# Generated by env-generator provider
export PROJECT_NAME="my-app"
export LOG_LEVEL="info"
The default value "info" is used. You can override it by passing --var log_level=debug.
Remove the output directory before continuing:
rm -rf output/
Using file providers
The file_providers field is used to make files available to the command script. Each file provider
creates a file and sets an environment variable containing the path to that file. This allows the
command script to read input files or copy template files to the output directory.
Let’s add a base configuration file that the command will copy to the output. Update
my-provider.yaml:
name: env-generator
description: |
Generates an ENV_VARS.txt file with configuration for downstream scripts.
Output directory contains:
- ENV_VARS.txt (environment variables for setup scripts)
- base-config.txt (a base configuration file)
variable_definitions:
- name: project_name
description: "The name of the project"
- name: log_level
description: "Logging verbosity level"
default: "info"
command:
name: generate.sh
kind: relative_path
path: scripts/generate.sh
# --- Add file providers ---
file_providers:
- name: base-config.txt
env_var: BASE_CONFIG
kind: inline
content: |
# Base configuration
# Project-specific values set via ENV_VARS.txt
# -------------------------
env_vars:
PROJECT_NAME: "{{ project_name }}"
LOG_LEVEL: "{{ log_level }}"
The file provider defines:
name: The filename used when the file is written to the providers directory.env_var: The environment variable that will contain the path to the file.kind: The type of file provider. Here we useinlineto define the content directly.content: The file content (forinlineproviders).
Update scripts/generate.sh to copy the base config to the output:
#!/usr/bin/env bash
set -e
mkdir -p "$RTF_OUTPUT"
cat > "$RTF_OUTPUT/ENV_VARS.txt" << EOF
# Environment variables for project setup
# Generated by env-generator provider
export PROJECT_NAME="$PROJECT_NAME"
export LOG_LEVEL="$LOG_LEVEL"
export BASE_CONFIG="$RTF_OUTPUT/base-config.txt"
EOF
# Copy the base config to output
cp "$BASE_CONFIG" "$RTF_OUTPUT/base-config.txt"
echo "Generated environment config in $RTF_OUTPUT"
Now run the custom provider:
rtf custom-provider run my-provider.yaml --var project_name=my-app
Output:
Generated environment config in /path/to/rtf-custom-provider/output/RTF_OUTPUT
cat output/RTF_OUTPUT/base-config.txt
Output:
# Base configuration
# Project-specific values set via ENV_VARS.txt
The base configuration file is now included in the output. Remove the output directory before continuing:
rm -rf output/
This completes the custom provider definition.
In this guide we have covered writing a simple custom provider definition. Next, we will guide you through how to use it in a test plan.
Next: Using a custom provider