diff --git a/doc/code_snippets/snippets/centralized_config/README.md b/doc/code_snippets/snippets/centralized_config/README.md
new file mode 100644
index 0000000000..1fc5023364
--- /dev/null
+++ b/doc/code_snippets/snippets/centralized_config/README.md
@@ -0,0 +1,3 @@
+# Centralized configuration storages
+
+Sample applications demonstrating how to store configuration data in one place using Tarantool or etcd-based storage. Learn more at [Centralized configuration storages](https://www.tarantool.io/en/doc/latest/concepts/configuration/configuration_etcd/).
diff --git a/doc/code_snippets/snippets/centralized_config/etcd_config_storage.sh b/doc/code_snippets/snippets/centralized_config/etcd_config_storage.sh
new file mode 100644
index 0000000000..ca7128952e
--- /dev/null
+++ b/doc/code_snippets/snippets/centralized_config/etcd_config_storage.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+# 1. Remove the 'default.etcd' directory to reset etcd to initial state.
+# 2. Start etcd by executing the 'etcd' command.
+# 3. Execute this script to enable authentication.
+etcdctl user add root:topsecret
+etcdctl role add myapp_config_manager
+etcdctl role grant-permission myapp_config_manager --prefix=true readwrite /myapp/
+etcdctl user add sampleuser:123456
+etcdctl user grant-role sampleuser myapp_config_manager
+etcdctl auth enable
diff --git a/doc/code_snippets/snippets/centralized_config/instances.enabled/config_etcd/README.md b/doc/code_snippets/snippets/centralized_config/instances.enabled/config_etcd/README.md
new file mode 100644
index 0000000000..a422a4f5c0
--- /dev/null
+++ b/doc/code_snippets/snippets/centralized_config/instances.enabled/config_etcd/README.md
@@ -0,0 +1,13 @@
+# etcd configuration storage
+
+A sample application demonstrating how to obtain a cluster's configuration from the etcd-based configuration storage.
+
+## Running
+
+Before running this sample, start etcd and enable authentication by executing [etcd_config_storage.sh](../../etcd_config_storage.sh).
+
+To start all instances, execute the following command in the [centralized_config](../../../centralized_config) directory:
+
+```console
+$ tt start config_etcd
+```
diff --git a/doc/code_snippets/snippets/centralized_config/instances.enabled/config_etcd/config.yaml b/doc/code_snippets/snippets/centralized_config/instances.enabled/config_etcd/config.yaml
new file mode 100644
index 0000000000..893c369bff
--- /dev/null
+++ b/doc/code_snippets/snippets/centralized_config/instances.enabled/config_etcd/config.yaml
@@ -0,0 +1,10 @@
+config:
+ etcd:
+ endpoints:
+ - http://localhost:2379
+ prefix: /myapp
+ username: sampleuser
+ password: '123456'
+ http:
+ request:
+ timeout: 3
diff --git a/doc/code_snippets/snippets/config/instances.enabled/etcd/instances.yml b/doc/code_snippets/snippets/centralized_config/instances.enabled/config_etcd/instances.yml
similarity index 100%
rename from doc/code_snippets/snippets/config/instances.enabled/etcd/instances.yml
rename to doc/code_snippets/snippets/centralized_config/instances.enabled/config_etcd/instances.yml
diff --git a/doc/code_snippets/snippets/centralized_config/instances.enabled/config_storage/README.md b/doc/code_snippets/snippets/centralized_config/instances.enabled/config_storage/README.md
new file mode 100644
index 0000000000..4079cea76d
--- /dev/null
+++ b/doc/code_snippets/snippets/centralized_config/instances.enabled/config_storage/README.md
@@ -0,0 +1,13 @@
+# Tarantool configuration storage
+
+A sample application demonstrating how to obtain a cluster's configuration from the Tarantool-based configuration storage.
+
+## Running
+
+Before running this sample, start a Tarantool-based configuration storage: [tarantool_config_storage](../tarantool_config_storage).
+
+To start all instances, execute the following command in the [centralized_config](../../../centralized_config) directory:
+
+```console
+$ tt start config_storage
+```
diff --git a/doc/code_snippets/snippets/centralized_config/instances.enabled/config_storage/config.yaml b/doc/code_snippets/snippets/centralized_config/instances.enabled/config_storage/config.yaml
new file mode 100644
index 0000000000..9aaffa024b
--- /dev/null
+++ b/doc/code_snippets/snippets/centralized_config/instances.enabled/config_storage/config.yaml
@@ -0,0 +1,19 @@
+config:
+ storage:
+ endpoints:
+ - uri: '127.0.0.1:4401'
+ login: sampleuser
+ password: '123456'
+ - uri: '127.0.0.1:4402'
+ login: sampleuser
+ password: '123456'
+ - uri: '127.0.0.1:4403'
+ login: sampleuser
+ password: '123456'
+ prefix: /myapp
+ timeout: 3
+ reconnect_after: 5
+
+# Watch key changes
+app:
+ file: 'myapp.lua'
diff --git a/doc/code_snippets/snippets/config/instances.enabled/etcd_full/instances.yml b/doc/code_snippets/snippets/centralized_config/instances.enabled/config_storage/instances.yml
similarity index 100%
rename from doc/code_snippets/snippets/config/instances.enabled/etcd_full/instances.yml
rename to doc/code_snippets/snippets/centralized_config/instances.enabled/config_storage/instances.yml
diff --git a/doc/code_snippets/snippets/centralized_config/instances.enabled/config_storage/myapp.lua b/doc/code_snippets/snippets/centralized_config/instances.enabled/config_storage/myapp.lua
new file mode 100644
index 0000000000..040d407963
--- /dev/null
+++ b/doc/code_snippets/snippets/centralized_config/instances.enabled/config_storage/myapp.lua
@@ -0,0 +1,6 @@
+net_box = require('net.box')
+local conn = net_box.connect('127.0.0.1:4401')
+local log = require('log')
+conn:watch('config.storage:/myapp/config/all', function(key, value)
+ log.info("Configuration stored by the '/myapp/config/all' key is changed")
+end)
diff --git a/doc/code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/README.md b/doc/code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/README.md
new file mode 100644
index 0000000000..2fecb3681c
--- /dev/null
+++ b/doc/code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/README.md
@@ -0,0 +1,11 @@
+# Setting up Tarantool configuration storage
+
+A sample application demonstrating how to set up Tarantool configuration storage.
+
+## Running
+
+To start all instances of the configuration storage, execute the following command in the [centralized_config](../../../centralized_config) directory:
+
+```console
+$ tt start tarantool_config_storage
+```
diff --git a/doc/code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/config.yaml b/doc/code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/config.yaml
new file mode 100644
index 0000000000..4ec249c420
--- /dev/null
+++ b/doc/code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/config.yaml
@@ -0,0 +1,49 @@
+credentials:
+ users:
+ sampleuser:
+ password: '123456'
+ privileges:
+ - permissions: [ read, write ]
+ spaces: [ config_storage, config_storage_meta ]
+ - permissions: [ execute ]
+ universe: true
+ replicator:
+ password: 'topsecret'
+ roles: [ replication ]
+
+iproto:
+ advertise:
+ peer:
+ login: replicator
+
+replication:
+ failover: election
+
+database:
+ use_mvcc_engine: true
+
+groups:
+ group001:
+ replicasets:
+ replicaset001:
+ roles: [ config.storage ]
+ roles_cfg:
+ config.storage:
+ status_check_interval: 3
+ instances:
+ instance001:
+ iproto:
+ listen:
+ - uri: '127.0.0.1:4401'
+ instance002:
+ iproto:
+ listen:
+ - uri: '127.0.0.1:4402'
+ instance003:
+ iproto:
+ listen:
+ - uri: '127.0.0.1:4403'
+
+# Interact with config storage
+app:
+ file: 'myapp.lua'
diff --git a/doc/code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/instances.yml b/doc/code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/instances.yml
new file mode 100644
index 0000000000..6c765b2e67
--- /dev/null
+++ b/doc/code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/instances.yml
@@ -0,0 +1,3 @@
+instance001:
+instance002:
+instance003:
\ No newline at end of file
diff --git a/doc/code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/myapp.lua b/doc/code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/myapp.lua
new file mode 100644
index 0000000000..7df22d09a4
--- /dev/null
+++ b/doc/code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/myapp.lua
@@ -0,0 +1,37 @@
+function put_config()
+ local fio = require('fio')
+ local cluster_config_handle = fio.open('../../source.yaml')
+ local cluster_config = cluster_config_handle:read()
+ local response = config.storage.put('/myapp/config/all', cluster_config)
+ cluster_config_handle:close()
+ return response
+end
+
+function get_config_by_path()
+ local response = config.storage.get('/myapp/config/all')
+ return response
+end
+
+function get_config_by_prefix()
+ local response = config.storage.get('/myapp/')
+ return response
+end
+
+function make_txn_request()
+ local response = config.storage.txn({
+ predicates = { { 'value', '==', 'v0', '/myapp/config/all' } },
+ on_success = { { 'put', '/myapp/config/all', 'v1' } },
+ on_failure = { { 'get', '/myapp/config/all' } }
+ })
+ return response
+end
+
+function delete_config()
+ local response = config.storage.delete('/myapp/config/all')
+ return response
+end
+
+function delete_all_configs()
+ local response = config.storage.delete('/')
+ return response
+end
diff --git a/doc/code_snippets/snippets/centralized_config/source.yaml b/doc/code_snippets/snippets/centralized_config/source.yaml
new file mode 100644
index 0000000000..24385b2265
--- /dev/null
+++ b/doc/code_snippets/snippets/centralized_config/source.yaml
@@ -0,0 +1,34 @@
+# A sample cluster config used to demonstrate a centralized configuration storage.
+# Learn more: https://www.tarantool.io/en/doc/latest/concepts/configuration/configuration_etcd.
+credentials:
+ users:
+ replicator:
+ password: 'topsecret'
+ roles: [replication]
+
+iproto:
+ advertise:
+ peer:
+ login: replicator
+
+replication:
+ failover: manual
+
+groups:
+ group001:
+ replicasets:
+ replicaset001:
+ leader: instance001
+ instances:
+ instance001:
+ iproto:
+ listen:
+ - uri: '127.0.0.1:3301'
+ instance002:
+ iproto:
+ listen:
+ - uri: '127.0.0.1:3302'
+ instance003:
+ iproto:
+ listen:
+ - uri: '127.0.0.1:3303'
diff --git a/doc/code_snippets/snippets/centralized_config/tt.yaml b/doc/code_snippets/snippets/centralized_config/tt.yaml
new file mode 100644
index 0000000000..e9cf7000cf
--- /dev/null
+++ b/doc/code_snippets/snippets/centralized_config/tt.yaml
@@ -0,0 +1,54 @@
+modules:
+ # Directory where the external modules are stored.
+ directory: modules
+
+env:
+ # Restart instance on failure.
+ restart_on_failure: false
+
+ # Directory that stores binary files.
+ bin_dir: bin
+
+ # Directory that stores Tarantool header files.
+ inc_dir: include
+
+ # Path to directory that stores all applications.
+ # The directory can also contain symbolic links to applications.
+ instances_enabled: instances.enabled
+
+ # Tarantoolctl artifacts layout compatibility: if set to true tt will not create application
+ # sub-directories for control socket, pid files, log files, etc.. Data files (wal, vinyl,
+ # snap) and multi-instance applications are not affected by this option.
+ tarantoolctl_layout: false
+
+app:
+ # Directory that stores various instance runtime
+ # artifacts like console socket, PID file, etc.
+ run_dir: var/run
+
+ # Directory that stores log files.
+ log_dir: var/log
+
+ # Directory where write-ahead log (.xlog) files are stored.
+ wal_dir: var/lib
+
+ # Directory where memtx stores snapshot (.snap) files.
+ memtx_dir: var/lib
+
+ # Directory where vinyl files or subdirectories will be stored.
+ vinyl_dir: var/lib
+
+# Path to file with credentials for downloading Tarantool Enterprise Edition.
+# credential_path: /path/to/file
+ee:
+ credential_path:
+
+templates:
+ # The path to templates search directory.
+ - path: templates
+
+repo:
+ # Directory where local rocks files could be found.
+ rocks:
+ # Directory that stores installation files.
+ distfiles: distfiles
diff --git a/doc/code_snippets/snippets/config/instances.enabled/etcd/config.yaml b/doc/code_snippets/snippets/config/instances.enabled/etcd/config.yaml
deleted file mode 100644
index 1ed4162614..0000000000
--- a/doc/code_snippets/snippets/config/instances.enabled/etcd/config.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-config:
- etcd:
- endpoints:
- - http://localhost:2379
- prefix: /example
\ No newline at end of file
diff --git a/doc/code_snippets/snippets/config/instances.enabled/etcd_full/config.yaml b/doc/code_snippets/snippets/config/instances.enabled/etcd_full/config.yaml
deleted file mode 100644
index c4bf368d42..0000000000
--- a/doc/code_snippets/snippets/config/instances.enabled/etcd_full/config.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-config:
- etcd:
- endpoints:
- - http://localhost:2379
- prefix: /example
- username: testuser
- password: foobar
- ssl:
- ca_file: ca.crt
- http:
- request:
- timeout: 3
\ No newline at end of file
diff --git a/doc/concepts/configuration.rst b/doc/concepts/configuration.rst
index e709c66ec2..229ab31dd3 100644
--- a/doc/concepts/configuration.rst
+++ b/doc/concepts/configuration.rst
@@ -327,25 +327,29 @@ Below are a few examples that show how to set environment variables of different
.. _configuration_etcd_overview:
-Configuration in etcd
-~~~~~~~~~~~~~~~~~~~~~
+Centralized configuration
+~~~~~~~~~~~~~~~~~~~~~~~~~
.. include:: /concepts/configuration/configuration_etcd.rst
- :start-after: ee_note_etcd_start
- :end-before: ee_note_etcd_end
+ :start-after: ee_note_centralized_config_start
+ :end-before: ee_note_centralized_config_end
+
-Tarantool enables you to store configuration data in one reliable place using `etcd `_.
+Tarantool enables you to store configuration data in one reliable place, for example, a Tarantool or etcd-based configuration storage.
To achieve this, you need to:
-1. Provide a local YAML configuration with an etcd endpoint address and key prefix in the ``config`` section:
+1. Set up a centralized configuration storage.
+
+2. Publish a cluster's configuration to the storage.
- .. literalinclude:: /code_snippets/snippets/config/instances.enabled/etcd/config.yaml
+3. Configure a connection to the storage by providing a local YAML configuration with an endpoint address and key prefix in the ``config`` section:
+
+ .. literalinclude:: /code_snippets/snippets/centralized_config/instances.enabled/config_etcd/config.yaml
:language: yaml
+ :end-at: prefix: /myapp
:dedent:
-2. Publish a cluster's configuration to an etcd server.
-
-Learn more from the following guide: :ref:`Storing configuration in etcd `.
+Learn more from the following guide: :ref:`configuration_etcd`.
.. _configuration_precedence:
@@ -357,7 +361,7 @@ Tarantool configuration options are applied from multiple sources with the follo
- `TT_*` :ref:`environment variables `.
- Configuration from a :ref:`local YAML file `.
-- :ref:`Centralized configuration ` stored in etcd.
+- :ref:`Centralized configuration `.
- `TT_*_DEFAULT` :ref:`environment variables `.
If the same option is defined in two or more locations, the option with the highest precedence is applied.
diff --git a/doc/concepts/configuration/configuration_etcd.rst b/doc/concepts/configuration/configuration_etcd.rst
index 2afc2217ba..a949e4cead 100644
--- a/doc/concepts/configuration/configuration_etcd.rst
+++ b/doc/concepts/configuration/configuration_etcd.rst
@@ -1,94 +1,226 @@
.. _configuration_etcd:
-Storing configuration in etcd
-=============================
+Centralized configuration storages
+==================================
-.. ee_note_etcd_start
+.. ee_note_centralized_config_start
.. admonition:: Enterprise Edition
:class: fact
- Storing configuration in etcd is supported by the `Enterprise Edition `_ only.
+ Centralized configuration storages are supported by the `Enterprise Edition `_ only.
-.. ee_note_etcd_end
+.. ee_note_centralized_config_end
-Tarantool enables you to store configuration data in one place using `etcd `_.
-To achieve this, you need to define how to access etcd and publish a cluster's :ref:`YAML configuration ` to an etcd server.
+**Examples on GitHub**: `centralized_config `_
+Tarantool enables you to store configuration data in one place using Tarantool or etcd-based storage.
+With a :ref:`local YAML configuration `, you need to make sure that all cluster instances use identical configuration files:
+
+.. image:: tarantool_config_local.png
+ :align: left
+ :width: 500
+ :alt: Local configuration file
+
+Using a centralized configuration storage, all instances get actual configuration from one place:
+
+.. image:: tarantool_config_centralized.png
+ :align: left
+ :width: 500
+ :alt: Centralized configuration storage
+
+This topic describes how to set up a configuration storage, publish a cluster configuration to this storage, and use this configuration for all cluster instances.
+
+
+
+.. _centralized_configuration_storage_set_up:
+
+Setting up a configuration storage
+----------------------------------
+
+.. _centralized_configuration_storage_set_up_tarantool:
+
+Tarantool-based storage
+~~~~~~~~~~~~~~~~~~~~~~~
+
+A Tarantool configuration storage is a replica set that stores configuration data in :ref:`synchronous ` spaces.
+To make a replica set act as a configuration storage, use the built-in ``config.storage`` role.
-.. _etcd_local_configuration:
-Local etcd configuration
-------------------------
+.. _centralized_configuration_storage_tarantool_configure:
-To store a cluster's configuration in etcd, you need to provide etcd connection settings in a local configuration file.
-These settings are used to :ref:`publish ` a cluster's configuration and :ref:`show ` it.
+Configuring a storage
+*********************
-Connection options for etcd should be specified in the ``config.etcd`` section of the configuration file.
-At least, the following options should be specified:
+To :ref:`configure ` a Tarantool-based storage, follow the steps below:
-.. literalinclude:: /code_snippets/snippets/config/instances.enabled/etcd/config.yaml
+1. Define a replica set topology and specify the following options at the replica set level:
+
+ * Enable the ``config.storage`` role.
+ * Optionally, provide the role configuration using ``roles_cfg``. In the example below, the ``status_check_interval`` option is configured to determine the interval (in seconds) of status checks.
+
+ .. literalinclude:: /code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/config.yaml
+ :language: yaml
+ :start-at: groups:
+ :end-at: 127.0.0.1:4403
+ :dedent:
+
+2. :ref:`Create a user ` and grant them the following privileges:
+
+ * The ``read`` and ``write`` permissions to the ``config_storage`` and ``config_storage_meta`` spaces used to store configuration data.
+ * The ``execute`` permission to ``universe`` to allow interacting with the storage using the tt utility.
+
+ .. literalinclude:: /code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/config.yaml
+ :language: yaml
+ :start-at: credentials:
+ :end-before: replicator:
+ :dedent:
+
+3. Set the :ref:`replication.failover ` option to ``election`` to enable automated failover:
+
+ .. literalinclude:: /code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/config.yaml
+ :language: yaml
+ :start-at: replication:
+ :end-at: failover: election
+ :dedent:
+
+4. Enable the :ref:`MVCC transaction mode ` to provide linearizability of read operations:
+
+ .. literalinclude:: /code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/config.yaml
+ :language: yaml
+ :start-at: database:
+ :end-at: use_mvcc_engine
+ :dedent:
+
+The resulting ``config.yaml`` file might look as follows:
+
+.. literalinclude:: /code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/config.yaml
:language: yaml
+ :end-before: Interact with config storage
:dedent:
-- :ref:`config.etcd.endpoints ` specifies the list of etcd endpoints.
-- :ref:`config.etcd.prefix ` sets a key prefix used to search a configuration. Tarantool searches keys by the following path: ``/config/*``. Note that ```` should start with a slash (``/``).
+You can find the full example here: `tarantool_config_storage `_.
-You can also provide additional etcd connection options.
-In the example below, the following options are configured in addition to an endpoint and key prefix:
-.. literalinclude:: /code_snippets/snippets/config/instances.enabled/etcd_full/config.yaml
- :language: yaml
+.. _centralized_configuration_storage_tarantool_start:
+
+Starting a storage
+******************
+
+To start instances of the configured storage, use the :ref:`tt start ` command, for example:
+
+.. code-block:: console
+
+ $ tt start tarantool_config_storage
+
+Learn more from the :ref:`Starting and stopping instances ` section.
+
+
+
+.. _centralized_configuration_storage_tarantool_interact:
+
+Interacting with the storage
+****************************
+
+The :ref:`config module ` provides the API for interacting with the configuration storage.
+For example, you can get the configuration stored by the specified path using the ``config.storage.get`` function:
+
+.. literalinclude:: /code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/myapp.lua
+ :language: lua
+ :start-after: get_config_by_path
+ :end-at: get('/myapp/config/all')
+ :dedent:
+
+To get all configurations stored by the specified prefix (ending with ``/``), pass it to ``config.storage.get``:
+
+.. literalinclude:: /code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/myapp.lua
+ :language: lua
+ :start-after: get_config_by_prefix
+ :end-at: get('/myapp/')
+ :dedent:
+
+Learn more from the :ref:`config_storage_api_reference` section.
+
+
+.. _centralized_configuration_storage_tarantool_watch_changes:
+
+Watching key changes
+********************
+
+The :ref:`net.box module ` provides the ability to watch path or prefix changes to monitor configuration updates.
+In the example below, :ref:`conn:watch ` is used to watch on updates of the ``myapp/config/all`` path:
+
+.. literalinclude:: /code_snippets/snippets/centralized_config/instances.enabled/config_storage/myapp.lua
+ :language: lua
+ :dedent:
+
+You can find the full example here: `config_storage `_.
+
+
+
+.. _centralized_configuration_storage_set_up_etcd:
+
+etcd-based storage
+~~~~~~~~~~~~~~~~~~
+
+To learn how to set up a etcd-based configuration storage, consult the `etcd documentation `__.
+
+The example script below demonstrates how create a user that has read and write access to configurations stored by the ``/myapp/`` prefix:
+
+.. literalinclude:: /code_snippets/snippets/centralized_config/etcd_config_storage.sh
+ :language: bash
+ :start-at: user add root:topsecret
+ :end-at: auth enable
:dedent:
-- :ref:`config.etcd.username ` and :ref:`config.etcd.password ` specify credentials used for authentication.
-- :ref:`config.etcd.ssl.ca_file ` specifies a path to a trusted certificate authorities (CA) file.
-- :ref:`config.etcd.http.request.timeout ` configures a request timeout for an etcd server.
+The credentials of this user should be specified when :ref:`configuring a connection ` to the etcd cluster.
-You can find all the available configuration options in the :ref:`etcd ` section.
-.. _etcd_publishing_configuration:
+.. _centralized_configuration_storage_publish_config:
-Publishing a cluster's configuration to etcd
---------------------------------------------
+Publishing a cluster's configuration
+------------------------------------
-.. _etcd_publishing_configuration_tt:
+.. _centralized_configuration_storage_publish_config_tt:
Publishing configuration using the tt utility
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The tt utility provides the :ref:`tt cluster ` command for managing a cluster's configuration.
-The ``tt cluster publish`` command can be used to publish a cluster's configuration to etcd.
+The tt utility provides the :ref:`tt cluster ` command for managing centralized cluster configurations.
+The ``tt cluster publish`` command can be used to publish a cluster's configuration to both Tarantool and etcd-based configuration storages.
-The example below shows how a :ref:`layout ` of the application called ``app`` might look:
+The example below shows how a tt environment and a :ref:`layout ` of the application called ``myapp`` might look:
.. code-block:: none
├── tt.yaml
+ ├── source.yaml
└── instances.enabled
- └── app
+ └── myapp
├── config.yaml
- ├── cluster.yaml
└── instances.yml
-* ``config.yaml`` contains a :ref:`local configuration ` used to connect to etcd.
-* ``cluster.yaml`` contains a cluster's configuration to be published.
-* ``instances.yml`` specifies :ref:`instances ` to run in the current environment. ``tt cluster publish`` ignores the configured instances.
+* ``tt.yaml``: a tt configuration file.
+* ``source.yaml`` contains a cluster's configuration to be published.
+* ``config.yaml`` contains a :ref:`local configuration ` used to connect to the centralized storage.
+* ``instances.yml`` specifies :ref:`instances ` to run in the current environment.
+ The configured instances are used by tt when :ref:`starting a cluster `.
+ ``tt cluster publish`` ignores this configuration file.
-To publish a cluster's configuration (``cluster.yaml``) to an etcd server, execute ``tt cluster publish`` as follows:
+To publish a cluster's configuration (``source.yaml``) to a centralized storage, execute ``tt cluster publish`` as follows:
.. code-block:: console
- $ tt cluster publish "http://localhost:2379/example" instances.enabled/app/cluster.yaml
+ $ tt cluster publish "http://localhost:2379/myapp" source.yaml
.. NOTE::
- You can see a cluster's configuration using the :ref:`tt cluster show ` command.
+ You can see a cluster's configuration using the ``tt cluster show`` command.
-.. _etcd_publishing_configuration_etcdctl:
+.. _centralized_configuration_storage_publish_config_etcdctl:
Publishing configuration using etcdctl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -97,7 +229,7 @@ To publish a cluster's configuration using the ``etcdctl`` utility, use the ``pu
.. code-block:: console
- $ etcdctl put /example/config/all < cluster.yaml
+ $ etcdctl put /myapp/config/all < source.yaml
.. NOTE::
@@ -106,21 +238,79 @@ To publish a cluster's configuration using the ``etcdctl`` utility, use the ``pu
+
+.. _centralized_configuration_storage_connect:
+
+Connecting to a configuration storage
+-------------------------------------
+
+To use a centralized cluster's configuration, you need to provide connection settings in a local configuration file.
+
+
+.. _centralized_configuration_storage_connect_tarantool:
+
+Connecting to a Tarantool-based storage
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Connection options for a Tarantool-based storage should be specified in the :ref:`config.storage ` section of the configuration file.
+In the example below, the following options are specified:
+
+.. literalinclude:: /code_snippets/snippets/centralized_config/instances.enabled/config_storage/config.yaml
+ :language: yaml
+ :end-before: Watch key changes
+ :dedent:
+
+- ``endpoints`` specifies the list of endpoints used to access a configuration storage.
+- ``prefix`` sets a key prefix used to search a configuration. Tarantool searches keys by the following path: ``/config/*``. Note that ```` should start with a slash (``/``).
+- ``timeout`` specifies the interval (in seconds) to perform the status check of a configuration storage.
+- ``reconnect_after`` specifies how much time to wait (in seconds) before reconnecting to a configuration storage.
+
+You can find the full example here: `config_storage `_.
+
+
+
+.. _etcd_local_configuration:
+
+Connecting to a etcd-based storage
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Connection options for etcd should be specified in the :ref:`config.etcd ` section of the configuration file.
+In the example below, the following options are specified:
+
+.. literalinclude:: /code_snippets/snippets/centralized_config/instances.enabled/config_etcd/config.yaml
+ :language: yaml
+ :dedent:
+
+- ``endpoints`` specifies the list of etcd endpoints.
+- ``prefix`` sets a key prefix used to search a configuration. Tarantool searches keys by the following path: ``/config/*``. Note that ```` should start with a slash (``/``).
+- ``username`` and ``password`` specify credentials used for authentication.
+- ``http.request.timeout`` configures a request timeout for an etcd server.
+
+You can find the full example here: `config_etcd `_.
+
+
+
+
.. _etcd_starting_instances:
-Starting Tarantool instances
-----------------------------
+Starting a cluster
+------------------
The :ref:`tt ` utility is the recommended way to start Tarantool instances.
You can learn how to do this from the :ref:`Starting and stopping instances ` section.
You can also use the ``tarantool`` command to :ref:`start a Tarantool instance `.
-In this case, you can eliminate creating a :ref:`local etcd configuration ` and provide etcd connection settings using the ``TT_CONFIG_ETCD_ENDPOINTS`` and ``TT_CONFIG_ETCD_PREFIX`` :ref:`environment variables `.
+In this case, you can eliminate creating a :ref:`local configuration ` and provide connection settings using the following :ref:`environment variables `:
+
+* Tarantool-based storage: ``TT_CONFIG_STORAGE_ENDPOINTS`` and ``TT_CONFIG_STORAGE_PREFIX``.
+* etcd-based storage: ``TT_CONFIG_ETCD_ENDPOINTS`` and ``TT_CONFIG_ETCD_PREFIX``.
+
+The example below shows how to provide etcd connection settings and start cluster instances using the ``tarantool`` command:
.. code-block:: console
$ export TT_CONFIG_ETCD_ENDPOINTS=http://localhost:2379
- $ export TT_CONFIG_ETCD_PREFIX=/example
+ $ export TT_CONFIG_ETCD_PREFIX=/myapp
$ tarantool --name instance001
$ tarantool --name instance002
@@ -134,7 +324,7 @@ In this case, you can eliminate creating a :ref:`local etcd configuration ` for changes in a cluster's configuration and reloads a changed configuration automatically.
+By default, Tarantool watches keys with the :ref:`specified prefix ` for changes in a cluster's configuration and reloads a changed configuration automatically.
If necessary, you can set the :ref:`config.reload ` option to ``manual`` to turn off configuration reloading:
.. code-block:: yaml
@@ -149,29 +339,3 @@ In this case, you can reload a configuration in an :ref:`admin console `
* :ref:`config.context.* `
* :ref:`config.etcd.* `
+* :ref:`config.storage.* `
.. _configuration_reference_config_reload:
@@ -462,10 +463,10 @@ config.etcd.*
~~~~~~~~~~~~~
.. include:: /concepts/configuration/configuration_etcd.rst
- :start-after: ee_note_etcd_start
- :end-before: ee_note_etcd_end
+ :start-after: ee_note_centralized_config_start
+ :end-before: ee_note_centralized_config_end
-This section describes options related to :ref:`storing configuration in etcd `.
+This section describes options related to providing connection settings to a :ref:`centralized etcd-based storage `.
* :ref:`config.etcd.endpoints `
* :ref:`config.etcd.prefix `
@@ -489,7 +490,7 @@ This section describes options related to :ref:`storing configuration in etcd `.
+ See also: :ref:`etcd_local_configuration`.
|
| Type: array
@@ -507,7 +508,7 @@ This section describes options related to :ref:`storing configuration in etcd /config/*``.
Note that ```` should start with a slash (``/``).
- See also: :ref:`Local etcd configuration `.
+ See also: :ref:`etcd_local_configuration`.
|
| Type: string
@@ -522,6 +523,8 @@ This section describes options related to :ref:`storing configuration in etcd `.
+
+* :ref:`config.storage.endpoints `
+* :ref:`config.storage.prefix `
+* :ref:`config.storage.reconnect_after `
+* :ref:`config.storage.timeout `
+
+
+.. _config_storage_endpoints:
+
+.. confval:: config.storage.endpoints
+
+ **Since:** :doc:`3.0.0 `.
+
+ An array of endpoints used to access a configuration storage.
+ Each endpoint can include the following fields:
+
+ * ``uri``: a URI of the configuration storage's instance.
+ * ``login``: a username used to connect to the instance.
+ * ``password``: a password used for authentication.
+ * ``params``: SSL parameters required for :ref:`encrypted connections ` (:ref:`.params.* `).
+
+ See also: :ref:`centralized_configuration_storage_connect_tarantool`.
+
+ |
+ | Type: array
+ | Default: nil
+ | Environment variable: TT_CONFIG_STORAGE_ENDPOINTS
+
+
+.. _config_storage_prefix:
+
+.. confval:: config.storage.prefix
+
+ **Since:** :doc:`3.0.0 `.
+
+ A key prefix used to search a configuration in a centralized configuration storage.
+ Tarantool searches keys by the following path: ``/config/*``.
+ Note that ```` should start with a slash (``/``).
+
+ See also: :ref:`centralized_configuration_storage_connect_tarantool`.
+
+ |
+ | Type: string
+ | Default: nil
+ | Environment variable: TT_CONFIG_STORAGE_PREFIX
+
+
+.. _config_storage_reconnect_after:
+
+.. confval:: config.storage.reconnect_after
+
+ **Since:** :doc:`3.0.0 `.
+
+ A number of seconds to wait before reconnecting to a configuration storage.
+
+ |
+ | Type: number
+ | Default: 3
+ | Environment variable: TT_CONFIG_STORAGE_RECONNECT_AFTER
+
+
+.. _config_storage_timeout:
+
+.. confval:: config.storage.timeout
+
+ **Since:** :doc:`3.0.0 `.
+
+ The interval (in seconds) to perform the status check of a configuration storage.
+
+ See also: :ref:`centralized_configuration_storage_connect_tarantool`.
+
+ |
+ | Type: number
+ | Default: 3
+ | Environment variable: TT_CONFIG_STORAGE_TIMEOUT
+
+
+
.. _configuration_reference_credentials:
@@ -2167,6 +2262,45 @@ The ``replication`` section defines configuration parameters related to :ref:`re
| Environment variable: TT_REPLICATION_TIMEOUT
+.. _configuration_reference_roles_options:
+
+roles
+-----
+
+This section describes configuration parameters related to roles.
+
+.. NOTE::
+
+ Configuration parameters related to roles can be defined in any :ref:`scope `.
+
+- :ref:`roles `
+- :ref:`roles_cfg `
+
+
+.. _configuration_reference_roles:
+
+.. confval:: roles
+
+ **Since:** :doc:`3.0.0 `.
+
+ |
+ | Type: array
+ | Default: nil
+ | Environment variable: TT_ROLES
+
+
+.. _configuration_reference_roles_cfg:
+
+.. confval:: roles_cfg
+
+ **Since:** :doc:`3.0.0 `.
+
+ |
+ | Type: map
+ | Default: nil
+ | Environment variable: TT_ROLES_CFG
+
+
.. _configuration_reference_security:
diff --git a/doc/reference/reference_lua/config.rst b/doc/reference/reference_lua/config.rst
index 9ddacc11df..402fae4d29 100644
--- a/doc/reference/reference_lua/config.rst
+++ b/doc/reference/reference_lua/config.rst
@@ -5,4 +5,385 @@ Module config
**Since:** :doc:`3.0.0 `
-.. TODO: https://github.com/tarantool/doc/issues/3662
+The ``config`` module provides the ability to work with an instance's configuration.
+For example, you can determine whether the current instance is up and running without errors after applying the :ref:`cluster's configuration `.
+
+By using the ``config.storage`` :ref:`role `, you can set up a Tarantool-based :ref:`centralized configuration storage ` and interact with this storage using the ``config`` module API.
+
+
+.. _config_module_loading:
+
+Loading config
+--------------
+
+To load the ``config`` module, use the ``require()`` directive:
+
+.. code-block:: lua
+
+ local config = require('config')
+
+Then, you can access its :ref:`API `:
+
+.. code-block:: lua
+
+ config:reload()
+
+
+.. _config_module_api_reference:
+
+API Reference
+-------------
+
+.. container:: table
+
+ .. rst-class:: left-align-column-1
+ .. rst-class:: left-align-column-2
+
+ .. list-table::
+ :widths: 35 65
+
+ * - **config API**
+ -
+
+ * - :ref:`config:get() `
+ - Get a configuration applied to the current instance
+
+ * - :ref:`config:info() `
+ - Get the current instance's state in regard to configuration
+
+ * - :ref:`config:reload() `
+ - Reload the current instance's configuration
+
+ * - **config.storage API**
+ -
+
+ * - :ref:`config.storage.put() `
+ - Put a value by the specified path
+
+ * - :ref:`config.storage.get() `
+ - Get a value stored by the specified path
+
+ * - :ref:`config.storage.delete() `
+ - Delete a value stored by the specified path
+
+ * - :ref:`config.storage.info() `
+ - Get information about an instance's connection state
+
+ * - :ref:`config.storage.txn() `
+ - Make an atomic request
+
+
+
+.. _config_api_reference:
+
+config API
+~~~~~~~~~~
+
+.. class:: config
+
+ .. _config_api_reference_get:
+
+ .. method:: get([param])
+
+ Get a configuration applied to the current instance.
+ Optionally, you can pass a configuration option name to get its value.
+
+ :param string param: a configuration option name
+ :return: an instance configuration
+
+ **Examples:**
+
+ The example below shows how to get the full instance configuration:
+
+ .. code-block:: console
+
+ app:instance001> require('config'):get()
+ ---
+ - fiber:
+ io_collect_interval: null
+ too_long_threshold: 0.5
+ top:
+ enabled: false
+ # other configuration values
+ # ...
+
+ This example shows how to get an ``iproto.listen`` option value:
+
+ .. code-block:: console
+
+ app:instance001> require('config'):get('iproto.listen')
+ ---
+ - - uri: 127.0.0.1:3301
+ ...
+
+ ``config.get()`` can also be used in :ref:`application code ` to get the value of a custom configuration option.
+
+
+ .. _config_api_reference_info:
+
+ .. method:: info()
+
+ Get the current instance's state in regard to configuration.
+
+ :return: a table containing an instance's state
+
+ The returned state includes the following sections:
+
+ - ``status`` -- one of the following statuses:
+
+ * ``ready`` -- the instance is running successfully without any warnings
+ * ``check_warnings`` -- the instance is running with warnings
+ * ``check_errors`` -- the configuration cannot be applied due to configuration errors
+
+ - ``meta`` -- additional configuration information
+
+ - ``alerts`` -- warnings or errors raised on an attempt to apply the configuration
+
+ **Examples:**
+
+ Below are a few examples demonstrating how the ``info()`` output might look:
+
+ * In the example below, an instance's state is ``ready`` and no warnings are shown:
+
+ .. code-block:: console
+
+ app:instance001> require('config'):info()
+ ---
+ - status: ready
+ meta: []
+ alerts: []
+ ...
+
+ * In the example below, the instance's state is ``check_warnings``.
+ The ``alerts`` section informs that privileges to the ``books`` space for ``sampleuser`` cannot be granted because the ``books`` space has not created yet:
+
+ .. code-block:: console
+
+ app:instance001> require('config'):info()
+ ---
+ - status: check_warnings
+ meta: []
+ alerts:
+ - type: warn
+ message: box.schema.user.grant("sampleuser", "read,write", "space", "books") has
+ failed because either the object has not been created yet, or the privilege
+ write has failed (separate alert reported)
+ timestamp: 2024-02-27T15:07:41.815785+0300
+ ...
+
+ This warning is cleared when the ``books`` space is created.
+
+ * In the example below, the instance's state is ``check_errors``.
+ The ``alerts`` section informs that the ``log.level`` configuration option has an incorrect value:
+
+ .. code-block:: console
+
+ app:instance001> require('config'):info()
+ ---
+ - status: check_errors
+ meta: []
+ alerts:
+ - type: error
+ message: '[cluster_config] log.level: Got 8, but only the following values are
+ allowed: 0, fatal, 1, syserror, 2, error, 3, crit, 4, warn, 5, info, 6, verbose,
+ 7, debug'
+ timestamp: 2024-02-29T12:55:54.366810+0300
+ ...
+
+ * In this example, an instance's state includes information about a :ref:`centralized storage ` the instance takes a configuration from:
+
+ .. code-block:: console
+
+ app:instance001> require('config'):info()
+ ---
+ - status: ready
+ meta:
+ storage:
+ revision: 8
+ mod_revision:
+ /myapp/config/all: 8
+ alerts: []
+ ...
+
+
+ .. _config_api_reference_reload:
+
+ .. method:: reload()
+
+ Reload the current instance's configuration.
+ Below are a few use cases when this function can be used:
+
+ - A configuration option value specific to this instance is changed in a cluster's configuration.
+ - A new instance is :ref:`added to a replica set `.
+ - A centralized configuration with turned-off configuration reloading is updated. Learn more at :ref:`etcd_reloading_configuration`.
+
+
+.. _config_storage_api_reference:
+
+config.storage API
+~~~~~~~~~~~~~~~~~~
+
+The ``config.storage`` API allows you to interact with a Tarantool-based :ref:`centralized configuration storage `.
+
+.. module:: config.storage
+
+.. _config_storage_api_reference_put:
+
+.. function:: put(path, value)
+
+ Put a value by the specified path.
+
+ :param string path: a path to put the value by
+ :param string value: a value to put
+
+ :return: a table containing the following fields:
+
+ * ``revision``: a revision after performing the operation
+
+ :rtype: table
+
+ **Example:**
+
+ The example below shows how to read a configuration stored in the ``source.yaml`` file using the :ref:`fio module ` API and put this configuration by the ``/myapp/config/all`` path:
+
+ .. literalinclude:: /code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/myapp.lua
+ :language: lua
+ :start-after: function put_config
+ :end-at: cluster_config_handle:close()
+ :dedent:
+
+
+.. _config_storage_api_reference_get:
+
+.. function:: get(path)
+
+ Get a value stored by the specified path or prefix.
+
+ :param string path: a path or prefix to get a value by; prefixes end with ``/``
+
+ :return: a table containing the following fields:
+
+ * ``data``: a table containing the information about the value:
+
+ * ``path``: a path
+ * ``mod_revision``: a last revision at which this value was modified
+ * ``value:``: a value
+
+ * ``revision``: a revision after performing the operation
+
+ :rtype: table
+
+ **Examples:**
+
+ The example below shows how to get a configuration stored by the ``/myapp/config/all`` path:
+
+ .. literalinclude:: /code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/myapp.lua
+ :language: lua
+ :start-after: get_config_by_path
+ :end-at: get('/myapp/config/all')
+ :dedent:
+
+ This example shows how to get all configurations stored by the ``/myapp/`` prefix:
+
+ .. literalinclude:: /code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/myapp.lua
+ :language: lua
+ :start-after: get_config_by_prefix
+ :end-at: get('/myapp/')
+ :dedent:
+
+.. _config_storage_api_reference_delete:
+
+.. function:: delete(path)
+
+ Delete a value stored by the specified path or prefix.
+
+ :param string path: a path or prefix to delete the value by; prefixes end with ``/``
+
+ :return: a table containing the following fields:
+
+ * ``data``: a table containing the information about the value:
+
+ * ``path``: a path
+ * ``mod_revision``: a last revision at which this value was modified
+ * ``value:``: a value
+
+ * ``revision``: a revision after performing the operation
+
+ :rtype: table
+
+ **Examples:**
+
+ The example below shows how to delete a configuration stored by the ``/myapp/config/all`` path:
+
+ .. literalinclude:: /code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/myapp.lua
+ :language: lua
+ :start-after: delete_config
+ :end-at: delete('/myapp/config/all')
+ :dedent:
+
+ In this example, all configuration are deleted:
+
+ .. literalinclude:: /code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/myapp.lua
+ :language: lua
+ :start-after: delete_all_configs
+ :end-at: delete('/')
+ :dedent:
+
+
+.. _config_storage_api_reference_info:
+
+.. function:: info()
+
+ Get information about an instance's connection state.
+
+ :return: a table containing the following fields:
+
+ * ``status``: a connection status, which can be one of the following:
+
+ * ``connected``: if any instance from the quorum is available to the current instance
+ * ``disconnected``: if the current instance doesn't have a connection with the quorum
+
+ :rtype: table
+
+
+.. _config_storage_api_reference_txn:
+
+.. function:: txn(request)
+
+ Make an atomic request.
+
+ :param table request: a table containing the following optional fields:
+
+ * ``predicates``: a list of predicates to check. Each predicate is a list that contains:
+
+ .. code-block:: none
+
+ {target, operator, value[, path]}
+
+ * ``target`` -- one of the following string values: ``revision``, ``mod_revision``, ``value``, ``count``
+ * ``operator`` -- a string value: ``eq``, ``ne``, ``gt``, ``lt``, ``ge``, ``le`` or its symbolic equivalent, for example, ``==``, ``!=``, ``>``
+ * ``value`` -- an unsigned or string value to compare
+ * ``path`` (optional) -- a string value: can be a path with the ``mod_revision`` and ``value`` target or a path/prefix with the ``count`` target
+
+ * ``on_success``: a list with operations to execute if all predicates in the list evaluate to ``true``
+
+ * ``on_failure``: a list with operations to execute if any of a predicate evaluates to ``false``
+
+ :return: a table containing the following fields:
+
+ * ``data``: a table containing response data:
+
+ * ``responses``: the list of responses for all operations
+ * ``is_success``: a boolean value indicating whether the predicate is evaluated to ``true``
+
+ * ``revision``: a revision after performing the operation
+
+ :rtype: table
+
+ **Example:**
+
+ .. literalinclude:: /code_snippets/snippets/centralized_config/instances.enabled/tarantool_config_storage/myapp.lua
+ :language: lua
+ :start-at: config.storage.txn
+ :end-at: })
+ :dedent:
diff --git a/doc/reference/tooling/tt_cli/cluster.rst b/doc/reference/tooling/tt_cli/cluster.rst
index ad1b94718e..f879404097 100644
--- a/doc/reference/tooling/tt_cli/cluster.rst
+++ b/doc/reference/tooling/tt_cli/cluster.rst
@@ -1,4 +1,4 @@
-.. _tt-cluster2:
+.. _tt-cluster:
Managing cluster configurations
===============================
diff --git a/doc/release/3.0.0.rst b/doc/release/3.0.0.rst
index 0a346837dd..d2cdf038a6 100644
--- a/doc/release/3.0.0.rst
+++ b/doc/release/3.0.0.rst
@@ -65,15 +65,16 @@ Centralized configuration (EE)
Tarantool Enterprise Edition enables you to store configuration data in one reliable place, for example, an :ref:`etcd ` cluster. To achieve this, you need to configure connection options in the ``config.etcd`` section of the configuration file, for example:
-.. literalinclude:: /code_snippets/snippets/config/instances.enabled/etcd/config.yaml
+.. literalinclude:: /code_snippets/snippets/centralized_config/instances.enabled/config_etcd/config.yaml
:language: yaml
+ :end-at: password: '123456'
:dedent:
Using the configuration above, a Tarantool instance searches for a cluster configuration by the following path:
.. code-block:: none
- http://localhost:2379/example/config/*
+ http://localhost:2379/myapp/config/*