For every star on GitHub, we'll donate $2 to clean up our waterways. Star us now!
Meltano is responsible for managing the configuration of all of a project’s plugins. It knows what settings are supported by each plugin, and how and when different types of plugins expect to be fed that configuration.
Since this also goes for extractors and loaders, you do not need to manually craft the
config.json
files expected by Singer taps and targets,
because Meltano will generate them on the fly whenever an extractor or loader is used through meltano elt
or meltano invoke
.
If the plugin you’d like to use and configure is supported out of the box (that is, it shows up when you run meltano discover
), Meltano already knows what settings it supports.
If you’re adding a custom plugin, on the other hand, you will be asked to provide the names of the supported configuration options yourself.
You can use meltano config <plugin> list
to list all available settings for a plugin with their names, environment variables, and current values. meltano config <plugin>
will print the current configuration in JSON format.
If supported by the plugin type, its configuration can be tested using meltano config <plugin> test
.
Meltano itself can be configured as well. To learn more, refer to the Settings Reference.
To determine the values of settings, Meltano will look in 4 main places (and one optional one), with each taking precedence over the next:
meltano elt
runtime, your project’s .env
file, a scheduled pipeline’s env
dictionary, or any other method.
meltano config <plugin> list
to list the available variable names, which typically have the format <PLUGIN_NAME>_<SETTING_NAME>
.meltano.yml
project file, under the plugin’s config
key.
$VAR
(as a single word) or ${VAR}
(inside a word).meltano.yml
.meltano config <plugin> set
or the UI when the project is deployed as read-only.
value
s set in the plugin’s settings
metadata.
discovery.yml
manifest.meltano.yml
project file.meltano config <plugin> list
will list the default values.Configuration that is not environment-specific or sensitive should be stored in meltano.yml
and checked into version
control. Sensitive values like passwords and tokens are most appropriately stored in the environment, .env
, or the system database.
meltano config <plugin> set
will automatically store configuration in meltano.yml
or .env
as appropriate.
Starting with Meltano 2.0
, you can override the properties of discoverable plugins, such as their capabilities
and settings_group_validation
, and extend their default settings
:
plugins:
extractors:
- name: tap-example
variant: meltanolabs
capabilities: # This will override the capabilities declared in the lockfile
- state
- discover
- catalog
settings: # These will be appended to the settings declared in the lockfile
- name: my-new-setting
kind: object
value:
key: value
All overrides replace the values stored in the lockfile, except for settings
, which extend the base definitions. If there is a collision on name, then the setting is taken from the override definition in meltano.yml
and used at runtime, while the token setting definition in the lockfile is discarded.
When you run an executable on your system, environment variables can be used to pass along arbitrary key-value data to the new process.
Meltano reads settings from environment variables when you run the meltano
command,
and populates them when it evaluates plugin configuration
and invokes plugin executables.
Meltano also supports specifying environment variables under the env:
keys of meltano.yml
, a Meltano Environment, or on the Plugin.
In addition to the terminal environment and the .env
file, Meltano supports the specification of environment variables at the following configuration levels:
env:
# root level env
MY_ENV_VAR: top_level_env_var
plugins:
extractors:
- name: tap-google-analytics
variant: meltano
env:
# root level plugin env
MY_ENV_VAR: plugin_level_env_var
loaders:
- name: target-postgres
variant: transferwise
pip_url: pipelinewise-target-postgres
environments:
- name: dev
env:
# environment level env
MY_ENV_VAR: environment_level_env_var
config:
plugins:
extractors:
- name: tap-google-analytics
variant: meltano
env:
# environment level plugin env
MY_ENV_VAR: environment_level_plugin_env_var
schedules:
- name: daily-google-analytics-load
interval: '@daily'
extractor: tap-google-analytics
loader: target-postgres
transform: skip
start_date: 2022-08-24 00:00:00
env:
SCHEDULE_SPECIFIC_ENV_VAR: schedule_specific_value
Environment levels within meltano.yml
resolve in order of precedence (within a plugins context):
- environment level plugin env # highest
- environment level env
- root level plugin env
- root level env
- schedule level env
- .env file
- terminal env # lowest
We are considering adding support for the env
key to jobs as well as updating the precedence order when we do.
We'd love to hear your thoughts in the GitHub issue about this possible change!
This allows you to override environment variables per plugin and per environment, as needed for your use case.
Environment variable values within a given layer of your meltano.yml
can inherit values from other layers.
For example, if your terminal environment has the environment variable TERMINAL_ENVIRONMENT_VARIABLE
set to the value 1
and you then add the following to your meltano.yml
environments:
- name: dev
env:
INHERITED: ${TERMINAL_ENVIRONMENT_VARIABLE}2
then the environment variable INHERITED
would be expanded to have the value of 12
in your dev
environment.
Environment variables are inherited across layers in the following order, where environment variable values at each level are expanded using values from the layers above it.
- terminal env and .env
- root-level env in meltano.yml
- active environment env
- root-level plugin-level env
- active environment-level plugin-level env
The following example illustrates how values are expanded:
env:
# Level 2: top-level `env:`
# Inherits from terminal context
LEVEL_NUM: "2" # '2'
STACKED: "${STACKED}2" # '12'
plugins:
extractors:
- name: tap-foobar
env:
# Level 4: plugin-level `env:`
# Inherits from a environment-level `env:` if an environment is active
# Inherits directly from top-level `env:` if no environment is active
LEVEL_NUM: "4" # '4'
STACKED: "${STACKED}4" # '1234'
environments:
- name: prod
env:
# Level 3: environment-level `env:`
# Inherits from top-level `env:`
LEVEL_NUM: "3" # '3'
STACKED: "${STACKED}3" # '123'
config:
plugins:
extractors:
- name: tap-foobar
env:
# Level 5: environment-level plugin `env:`
# Inherits from (global) plugin-level `env:`
LEVEL_NUM: "5" # '5'
STACKED: "${STACKED}5" # '12345'
Note that the resolution and inheritance behavior of environment variables set via env
keys in your meltano.yml
differ from the resolution and inheritance behavior of config
or settings
keys.
Because settings and environment variable behavior can become complex when set in multiple places, the meltano invoke
command provides a --print-var
option which allows you to easily inspect what value is being supplied for a given environment variable within your plugin’s invocation environment at runtime.
pip_url
#
In addition to affecting the environment variables at runtime, and the config
/settings
values, environment variables can be expanded within the value of a plugin’s pip_url
. The environment variable inheritance shown above applies to environment variables expanded within the value of pip_url
.
This can be useful for using a different pip_url
for different environments (e.g. to change which git branch of a plugin repository is used):
pip_url: "git+https://github.com/MeltanoLabs/tap-github.git@${TAP_GITHUB_GIT_REV}"
Another use for this is to supply credentials for a private Python package index:
pip_url: "https://${NEXUS_USERNAME}:${NEXUS_PASSWORD}@nexus.example.com/simple"
As mentioned under Configuration layers, Meltano will look at the environment variables it was executed with
and those specified in your project’s .env
file
to determine the values of its own settings and those of its plugins.
Any setting can be configured by specifying an environment variable named <PLUGIN_NAME>_<SETTING_NAME>
, with characters other than alphanumeric (A-Z
, 0-9
) and underscores (_
) replaced with underscores, e.g. TAP_GITLAB_API_URL
for extractor tap-gitlab
’s api_url
setting:
export <PLUGIN_NAME>_<SETTING_NAME>=<value>
# For example:
export TAP_GITLAB_API_URL=https://gitlab.example.com
Plugins can also specify alternative variables (aliases for their settings, to match existing usage or variables expected by plugin executables. You can use meltano config <plugin> list
to list all available settings for a plugin along with their variables, in order of precedence.
Since environment variable values are always strings, Meltano will cast values to the appropriate type before passing them on to the plugin.
To verify that any environment variables you’ve set will be picked up by Meltano as you intended, you can test them with meltano config <plugin>
before running meltano elt
or meltano invoke
.
To learn how to use environment variables to specify pipeline-specific configuration, refer to the Data Integration (EL) guide.
Aliases allow for configuration values to be set via one of multiple keys.
Environment variable aliases are listed next to the canonical names for the variable in the output of the meltano config <plugin> list
command.
They can be defined via the aliases
key in a custom plugin’s settings
configuration.
For example, the following defines a my_custom_username
setting with aliases custom_tap_username
and username
:
# meltano.yml
---
plugins:
extractors:
- name: my-custom-tap
namespace: my_custom_tap
pip_url: git+https://github.com/my-organization/my-custom-tap.git
executable: my-custom-tap
capabilities:
- discover
- catalog
settings:
- name: password
kind: password
- name: my_custom_tap_username
aliases: [custom_tap_username, username]
Within a given configuration layer, a setting can be set via only a single name, whether that name is its canonical name or one of its aliases.
So given the custom extractor defined above, the my_custom_tap_username
setting could be set via the MY_CUSTOM_TAP_MY_CUSTOM_TAP_USERNAME
environment variable or either the MY_CUSTOM_TAP_CUSTOM_TAP_USERNAME
or MY_CUSTOM_TAP_USERNAME
variables.
But if more than one of these variables is set in the terminal environment, then an exception will be raised–even if all the relevant environment variables have the same value.
The configuration setting could also be set via the meltano config set
by setting either the canonical name or any of its aliases. Again using the custom extractor defined above as an example, the my_custom_tap_username
could be set by any of the following commands:
# The canonical name
meltano config my-custom-tap set my_custom_tap_username some_value
# Alias 1
meltano config my-custom-tap set custom_tap_username some_value
# Alias 2
meltano config my-custom-tap set username some_value
To see what name or alias a setting’s value is being derived from, you can run meltano config <plugin-name> list
:
$ export MY_CUSTOM_TAP_USERNAME=some_username
$ meltano config my-custom-tap list
2022-06-22T10:00:00Z [info ] Environment 'dev' is active
password [env: MY_CUSTOM_TAP_PASSWORD] current value: 'some_very_secure_password' (from the MY_CUSTOM_TAP_PASSWORD variable in `.env`)
my_custom_tap_username [env: MY_CUSTOM_TAP_MY_CUSTOM_TAP_USERNAME, MY_CUSTOM_TAP_CUSTOM_TAP_USERNAME, MY_CUSTOM_TAP_USERNAME] current value: 'some_username' (from the MY_CUSTOM_TAP_USERNAME variable in the environment)
If a setting’s value is being set via multiple environment variables, the resulting error message will list the environment variables where it is being set:
$ export MY_CUSTOM_TAP_USERNAME=some_username
$ export MY_CUSTOM_TAP_CUSTOM_TAP_USERNAME=some_username
$ meltano config my-custom-tap
Setting value set via multiple environment variables: ['MY_CUSTOM_TAP_CUSTOM_TAP_USERNAME', 'MY_CUSTOM_TAP_USERNAME']
If the values for the multiple environment variables differ, the error message will also list what the values are:
$ export MY_CUSTOM_TAP_USERNAME=some_username
$ export MY_CUSTOM_TAP_CUSTOM_TAP_USERNAME=some_other_username
$ meltano config my-custom-tap
Conflicting values for setting found in: ['MY_CUSTOM_TAP_CUSTOM_TAP_USERNAME', 'MY_CUSTOM_TAP_USERNAME']
Inside the values of settings in your meltano.yml
project file, environment variables can be referenced to dynamically adapt a plugin’s configuration to the environment it is run in, specific properties of your project, or the plugins it is run with inside a meltano run
pipeline.
The following variables can be referenced from any setting:
.env
fileMELTANO_PROJECT_ROOT
: Absolute path to the current project directory, e.g. /home/meltano-projects/demo-project
Additionally, the following variables can be referenced from plugin settings (as opposed to Meltano settings):
MELTANO_<SETTING_NAME>
: Variables describing Meltano’s current configuration, discoverable using meltano config --format=env meltano
MELTANO_<PLUGIN_TYPE>_NAME
: The plugin’s name
, e.g. MELTANO_EXTRACTOR_NAME
as tap-gitlab
for extractor tap-gitlab
MELTANO_<PLUGIN_TYPE>_NAMESPACE
: The plugin’s namespace
, e.g. MELTANO_EXTRACTOR_NAMESPACE
as tap_gitlab
for extractor tap-gitlab
When running a meltano elt
pipeline, additional pipeline environment variables
are available to loaders and transformers that describe the extractor and loader they are run with.
When a plugin is invoked outside the context of a pipeline, these variables will be unset and any references to them will expand to empty strings.
Inside the values of plugin extras, additional variables describing the plugin’s current configuration are available,
as discoverable using meltano config --format=env <plugin>
.
Generic MELTANO_<PLUGIN_TYPE_VERB>_<SETTING_NAME>
variables can be used when the plugin name isn’t known, e.g. MELTANO_LOAD_SCHEMA
for a loader’s schema
setting.
Inside the plugin config
objects in your meltano.yml
project file,
these variables can be referenced using standard variable expansion syntax, i.e. $VAR
(as a single word) or ${VAR}
(inside a word):
extractors:
- name: tap-example
config:
simple_setting: $MELTANO_EXTRACTOR_NAME
multiple_words: $MELTANO_EXTRACTOR_NAMESPACE foo
part_of_a_path: $MELTANO_PROJECT_ROOT/example.txt
inside_a_word: ${MELTANO_EXTRACTOR_NAMESPACE}_foo
When Meltano invokes a plugin’s executable as part of meltano elt
or meltano invoke
, it populates the environment with the same variables that can be referenced from settings, as well as those describing the plugin’s current configuration (including extras), as discoverable using meltano config --format=env <plugin>
.
These can then be accessed from inside the plugin using the mechanism provided by the standard library, e.g. Python’s os.environ
.
Within a Meltano environment environment variables can be specified using the env
key:
environments:
- name: dev
env:
AN_ENVIRONMENT_VARIABLE: dev
Any plugins run in that Meltano environment will then have the provided environment variables populated into the plugin’s environment.
Every plugin in your project has its own configuration, but you can use plugin inheritance to define multiple plugins that use the same package but still have their own configuration:
plugins:
extractors:
- name: tap-google-analytics
variant: meltano
config:
key_file_location: client_secrets.json
start_date: "2020-10-01T00:00:00Z"
- name: tap-ga--view-foo
inherit_from: tap-google-analytics
config:
# `key_file_location` and `start_date` are inherited
view_id: 123456
- name: tap-ga--view-bar
inherit_from: tap-google-analytics
config:
# `key_file_location` is inherited
start_date: "2020-12-01T00:00:00Z" # `start_date` is overridden
view_id: 789012
In this example, tap-ga--view-foo
and tap-ga--view-bar
are separate plugins that
inherit their base plugin description (describing the package)
and configuration (where not overridden) from tap-google-analytics
,
which itself shadows the
discoverable plugin with the same name.
If there is no need for the different plugins to inherit any common configuration, they can directly inherit from the discoverable plugin instead, without an intermediary plugin:
plugins:
extractors:
- name: tap-postgres--billing
inherit_from: tap-postgres
config:
host: one.postgres.example.com
user: billing_user
dbname: billing_db
- name: tap-postgres--events
inherit_from: tap-postgres
config:
host: two.postgres.example.com
user: events_user
dbname: events_db
To configure tap-postgres
’s password
setting, you would typically set the TAP_POSTGRES_PASSWORD
environment variable,
but that will not work here as it would not be clear which plugin the password was intended for.
Instead, as meltano config <name> list
would tell you,
both plugins get their own unique environment variables with prefixes derived from their names:
TAP_POSTGRES__BILLING_PASSWORD
and TAP_POSTGRES__EVENTS_PASSWORD
.
To learn how to add an inheriting plugin to your project, refer to the Plugin Management guide.
Meltano keeps track of the settings a plugin supports using settings
metadata, and will list them all when you run meltano config <plugin> list
.
If you’ve added a discoverable plugin to your project, this metadata will already be known to Meltano. If we’re dealing with a custom plugin instead, you will have been asked to provide the names of the supported configuration options yourself.
If a plugin supports a setting that is not yet known to Meltano (because it may have been added after the settings
metadata was specified, for example),
you do not need to modify the settings
metadata to be able to use it.
Instead, you can define a custom setting by adding the setting name (key) to your plugin’s config
object in your meltano.yml
project file with the desired value (or simply null
), by manually editing the file or using meltano config <plugin> set <key> <value>
:
meltano config tap-example set custom_setting value
extractors:
- name: tap-example
config:
known_setting: value
custom_setting: value
As long as the custom setting exists in meltano.yml
, it will behave and can be interacted with just like any regular (known) setting. It will show up in meltano config <plugin> list
and meltano config <plugin>
, and the value that will be passed on to the plugin can be overridden using an environment variable:
export TAP_EXAMPLE_CUSTOM_SETTING=overridden_value
Plugin extras are additional configuration options specific to the type of plugin (e.g. all extractors) that are handled by Meltano instead of the plugin itself.
Meltano currently knows these extras for these plugin types:
The values of these extras are stored in your meltano.yml
project file among the plugin’s other properties, outside of the config
object:
extractors:
- name: tap-example
config:
# Configuration goes here!
example_setting: value
# Extras go here!
example_extra: value
These extras can be thought of and interacted with as a special kind of setting,
and environment variables and
meltano config
can be used to manage them:
How to use: Plugin extras.
The configuration of a plugin can be tested using meltano config <plugin> test
.
Configuration testing is only supported for extractor plugins currently.