diff --git a/cmake/utils.cmake b/cmake/utils.cmake
index a0c305fa59ff4740f37b83353ec97059565c0de2..d021601c2e10d4fc686bd2f1cba0cd0566083862 100644
--- a/cmake/utils.cmake
+++ b/cmake/utils.cmake
@@ -69,6 +69,24 @@ function(lua_source varname filename symbolname)
     set(${varname} ${var} ${dstfile} PARENT_SCOPE)
 endfunction()
 
+# A helper function to unpack list with filenames and variable names
+# and compile *.lua source into *.lua.c sources using lua_source() function.
+# Function expects a list 'source_list' with pairs of paths to a Lua source file
+# and a symbol names that should be used in C source code for that file.
+function(lua_multi_source var_name source_list)
+    set(source_list ${source_list} ${ARGN})
+    list(LENGTH source_list len)
+    math(EXPR len "${len} - 1")
+    set(_sources)
+    foreach(filename_idx RANGE 0 ${len} 2)
+        list(GET source_list ${filename_idx} filename)
+        math(EXPR symbolname_idx "${filename_idx} + 1")
+        list(GET source_list ${symbolname_idx} symbolname)
+        lua_source(_sources ${filename} ${symbolname})
+    endforeach()
+    set(${var_name} ${${var_name}};${_sources} PARENT_SCOPE)
+endfunction()
+
 function(bin_source varname srcfile dstfile symbolname)
     set(var ${${varname}})
     set (srcfile "${CMAKE_CURRENT_SOURCE_DIR}/${srcfile}")
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index bfa2ba999c9bbcb8afdfb113fef6266e1d11e17d..1beaea0a26ee39286949504dda086066ace13d49 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -74,21 +74,7 @@ if (ENABLE_COMPRESS_MODULE)
     lua_source(lua_sources ${COMPRESS_MODULE_LUA_SOURCE} compress_lua)
 endif()
 if (ENABLE_ETCD_CLIENT)
-    lua_source(lua_sources ${ETCD_CLIENT_DIR}/etcd-client/client/auth_http.lua etcd_client_client_auth_http_lua)
-    lua_source(lua_sources ${ETCD_CLIENT_DIR}/etcd-client/client/http.lua etcd_client_client_http_lua)
-    lua_source(lua_sources ${ETCD_CLIENT_DIR}/etcd-client/client/jsstream.lua etcd_client_client_jsstream_lua)
-    lua_source(lua_sources ${ETCD_CLIENT_DIR}/etcd-client/client/pool.lua etcd_client_client_pool_lua)
-    lua_source(lua_sources ${ETCD_CLIENT_DIR}/etcd-client/error/etcd.lua etcd_client_error_etcd_lua)
-    lua_source(lua_sources ${ETCD_CLIENT_DIR}/etcd-client/error/http.lua etcd_client_error_http_lua)
-    lua_source(lua_sources ${ETCD_CLIENT_DIR}/etcd-client/grpc_json.lua etcd_client_grpc_json_lua)
-    lua_source(lua_sources ${ETCD_CLIENT_DIR}/etcd-client/init.lua etcd_client_init_lua)
-    lua_source(lua_sources ${ETCD_CLIENT_DIR}/etcd-client/math.lua etcd_client_math_lua)
-    lua_source(lua_sources ${ETCD_CLIENT_DIR}/etcd-client/protocol.lua etcd_client_protocol_lua)
-    lua_source(lua_sources ${ETCD_CLIENT_DIR}/etcd-client/subscribe/auto.lua etcd_client_subscribe_auto_lua)
-    lua_source(lua_sources ${ETCD_CLIENT_DIR}/etcd-client/subscribe/once.lua etcd_client_subscribe_once_lua)
-    lua_source(lua_sources ${ETCD_CLIENT_DIR}/etcd-client/txn.lua etcd_client_txn_lua)
-    lua_source(lua_sources ${ETCD_CLIENT_DIR}/etcd-client/utils.lua etcd_client_utils_lua)
-    lua_source(lua_sources ${ETCD_CLIENT_DIR}/etcd-client/version.lua etcd_client_version_lua)
+    lua_multi_source(lua_sources ${ETCD_CLIENT_LUA_SOURCES})
 endif()
 
 # 3rd party lua sources
@@ -306,6 +292,7 @@ add_library(server STATIC ${server_sources})
 add_dependencies(server build_bundled_libs)
 target_link_libraries(server core coll http_parser bit uri swim swim_udp
                       swim_ev crypto mpstream crc32 tzcode)
+target_include_directories(server PRIVATE ${EXTRA_SERVER_INCLUDE_DIRS})
 
 if(EMBED_LUAZLIB)
     target_link_libraries(server ${ZLIB_LIBRARIES})
diff --git a/src/box/lua/audit.h b/src/box/lua/audit.h
new file mode 100644
index 0000000000000000000000000000000000000000..460b8c4e9dbb88ec32413043bdf74dac5ea0db36
--- /dev/null
+++ b/src/box/lua/audit.h
@@ -0,0 +1,24 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2010-2023, Tarantool AUTHORS, please see AUTHORS file.
+ */
+#pragma once
+
+#include "trivia/config.h"
+
+#if defined(ENABLE_AUDIT_LOG)
+#include "lua/audit_impl.h"
+#else /* !defined(ENABLE_AUDIT_LOG) */
+
+#define AUDIT_BOX_LUA_MODULES
+
+struct lua_State;
+
+static inline void
+box_lua_audit_init(struct lua_State *L)
+{
+	(void)L;
+}
+
+#endif /* !defined(ENABLE_AUDIT_LOG) */
diff --git a/src/box/lua/flight_recorder.h b/src/box/lua/flight_recorder.h
new file mode 100644
index 0000000000000000000000000000000000000000..bc14afce6bc26d7eea1be45d1371830d08c1b0d5
--- /dev/null
+++ b/src/box/lua/flight_recorder.h
@@ -0,0 +1,24 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2010-2023, Tarantool AUTHORS, please see AUTHORS file.
+ */
+#pragma once
+
+#include "trivia/config.h"
+
+#if defined(ENABLE_FLIGHT_RECORDER)
+#include "lua/flightrec_impl.h"
+#else /* !defined(ENABLE_FLIGHT_RECORDER) */
+
+#define FLIGHT_RECORDER_BOX_LUA_MODULES
+
+struct lua_State;
+
+static inline void
+box_lua_flightrec_init(struct lua_State *L)
+{
+	(void)L;
+}
+
+#endif /* !defined(ENABLE_FLIGHT_RECORDER) */
diff --git a/src/box/lua/init.c b/src/box/lua/init.c
index df19ecdf69bd8f2e2c08a1fc39c526542a721568..b039454d7469fa7875d704adda8d381de9b9d26c 100644
--- a/src/box/lua/init.c
+++ b/src/box/lua/init.c
@@ -69,41 +69,17 @@
 #include "box/lua/merger.h"
 #include "box/lua/watcher.h"
 #include "box/lua/iproto.h"
+#include "box/lua/audit.h"
+#include "box/lua/flight_recorder.h"
+#include "box/lua/read_view.h"
+#include "box/lua/security.h"
+#include "box/lua/space_upgrade.h"
+#include "box/lua/wal_ext.h"
 
 #include "mpstream/mpstream.h"
 
 static uint32_t CTID_STRUCT_TXN_SAVEPOINT_PTR = 0;
 
-#if ENABLE_SPACE_UPGRADE
-void
-box_lua_space_upgrade_init(struct lua_State *L);
-#endif
-
-#if ENABLE_AUDIT_LOG
-void
-box_lua_audit_init(struct lua_State *L);
-#endif
-
-#if ENABLE_WAL_EXT
-void
-box_lua_wal_ext_init(struct lua_State *L);
-#endif
-
-#if ENABLE_READ_VIEW
-void
-box_lua_read_view_init(struct lua_State *L);
-#endif
-
-#ifdef ENABLE_SECURITY
-void
-box_lua_security_init(struct lua_State *L);
-#endif
-
-#if ENABLE_FLIGHT_RECORDER
-void
-box_lua_flightrec_init(struct lua_State *L);
-#endif
-
 extern char session_lua[],
 	tuple_lua[],
 	key_def_lua[],
@@ -112,21 +88,6 @@ extern char session_lua[],
 	xlog_lua[],
 #if ENABLE_FEEDBACK_DAEMON
 	feedback_daemon_lua[],
-#endif
-#if ENABLE_SPACE_UPGRADE
-	space_upgrade_lua[],
-#endif
-#if ENABLE_AUDIT_LOG
-	audit_lua[],
-#endif
-#if ENABLE_FLIGHT_RECORDER
-	flightrec_lua[],
-#endif
-#if ENABLE_READ_VIEW
-	read_view_lua[],
-#endif
-#if ENABLE_SECURITY
-	security_lua[],
 #endif
 	net_box_lua[],
 	upgrade_lua[],
@@ -204,25 +165,15 @@ static const char *lua_sources[] = {
 	 */
 	"box/feedback_daemon", NULL, feedback_daemon_lua,
 #endif
-#if ENABLE_SPACE_UPGRADE
 	/*
 	 * Must be loaded after schema_lua, because it redefines
 	 * box.schema.space.upgrade.
 	 */
-	"box/space_upgrade", NULL, space_upgrade_lua,
-#endif
-#if ENABLE_AUDIT_LOG
-	"box/audit", "audit", audit_lua,
-#endif
-#if ENABLE_FLIGHT_RECORDER
-	"box/flightrec", "flightrec", flightrec_lua,
-#endif
-#if ENABLE_READ_VIEW
-	"box/read_view", NULL, read_view_lua,
-#endif
-#if ENABLE_SECURITY
-	"box/security", NULL, security_lua,
-#endif
+	SPACE_UPGRADE_BOX_LUA_MODULES
+	AUDIT_BOX_LUA_MODULES
+	FLIGHT_RECORDER_BOX_LUA_MODULES
+	READ_VIEW_BOX_LUA_MODULES
+	SECURITY_BOX_LUA_MODULES
 	"box/xlog", "xlog", xlog_lua,
 	"box/upgrade", NULL, upgrade_lua,
 	"box/net_box", "net.box", net_box_lua,
@@ -702,24 +653,12 @@ box_lua_init(struct lua_State *L)
 	box_lua_sql_init(L);
 	box_lua_watcher_init(L);
 	box_lua_iproto_init(L);
-#ifdef ENABLE_SPACE_UPGRADE
 	box_lua_space_upgrade_init(L);
-#endif
-#ifdef ENABLE_AUDIT_LOG
 	box_lua_audit_init(L);
-#endif
-#ifdef ENABLE_WAL_EXT
 	box_lua_wal_ext_init(L);
-#endif
-#ifdef ENABLE_READ_VIEW
 	box_lua_read_view_init(L);
-#endif
-#ifdef ENABLE_SECURITY
 	box_lua_security_init(L);
-#endif
-#ifdef ENABLE_FLIGHT_RECORDER
 	box_lua_flightrec_init(L);
-#endif
 	luaopen_net_box(L);
 	lua_pop(L, 1);
 	tarantool_lua_console_init(L);
diff --git a/src/box/lua/read_view.h b/src/box/lua/read_view.h
new file mode 100644
index 0000000000000000000000000000000000000000..82b12c824149994c5922003250f141a84e59ebd4
--- /dev/null
+++ b/src/box/lua/read_view.h
@@ -0,0 +1,24 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2010-2023, Tarantool AUTHORS, please see AUTHORS file.
+ */
+#pragma once
+
+#include "trivia/config.h"
+
+#if defined(ENABLE_READ_VIEW)
+#include "lua/read_view_impl.h"
+#else /* !defined(ENABLE_READ_VIEW) */
+
+#define READ_VIEW_BOX_LUA_MODULES
+
+struct lua_State;
+
+static inline void
+box_lua_read_view_init(struct lua_State *L)
+{
+	(void)L;
+}
+
+#endif /* !defined(ENABLE_READ_VIEW) */
diff --git a/src/box/lua/security.h b/src/box/lua/security.h
new file mode 100644
index 0000000000000000000000000000000000000000..fedb869c360d7a76a08a60554bce3c8b0da1aba2
--- /dev/null
+++ b/src/box/lua/security.h
@@ -0,0 +1,24 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2010-2023, Tarantool AUTHORS, please see AUTHORS file.
+ */
+#pragma once
+
+#include "trivia/config.h"
+
+#if defined(ENABLE_SECURITY)
+#include "lua/security_impl.h"
+#else /* !defined(ENABLE_SECURITY) */
+
+#define SECURITY_BOX_LUA_MODULES
+
+struct lua_State;
+
+static inline void
+box_lua_security_init(struct lua_State *L)
+{
+	(void)L;
+}
+
+#endif /* !defined(ENABLE_SECURITY) */
diff --git a/src/box/lua/space_upgrade.h b/src/box/lua/space_upgrade.h
new file mode 100644
index 0000000000000000000000000000000000000000..6e0693739b04bb4c7e5a129354e9d1ecb5797756
--- /dev/null
+++ b/src/box/lua/space_upgrade.h
@@ -0,0 +1,24 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2010-2023, Tarantool AUTHORS, please see AUTHORS file.
+ */
+#pragma once
+
+#include "trivia/config.h"
+
+#if defined(ENABLE_SPACE_UPGRADE)
+#include "lua/space_upgrade_impl.h"
+#else /* !defined(ENABLE_SPACE_UPGRADE) */
+
+#define SPACE_UPGRADE_BOX_LUA_MODULES
+
+struct lua_State;
+
+static inline void
+box_lua_space_upgrade_init(struct lua_State *L)
+{
+	(void)L;
+}
+
+#endif /* !defined(ENABLE_SPACE_UPGRADE) */
diff --git a/src/box/lua/wal_ext.h b/src/box/lua/wal_ext.h
new file mode 100644
index 0000000000000000000000000000000000000000..62c285d0e65bc98c1421052fb77c3e9a4021261f
--- /dev/null
+++ b/src/box/lua/wal_ext.h
@@ -0,0 +1,22 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2010-2023, Tarantool AUTHORS, please see AUTHORS file.
+ */
+#pragma once
+
+#include "trivia/config.h"
+
+#if defined(ENABLE_WAL_EXT)
+#include "lua/wal_ext_impl.h"
+#else /* !defined(ENABLE_WAL_EXT) */
+
+struct lua_State;
+
+static inline void
+box_lua_wal_ext_init(struct lua_State *L)
+{
+	(void)L;
+}
+
+#endif /* !defined(ENABLE_WAL_EXT) */
diff --git a/src/lua/compress.h b/src/lua/compress.h
new file mode 100644
index 0000000000000000000000000000000000000000..ca3f4fed9a82b31b30cab5155540a628ffe0001b
--- /dev/null
+++ b/src/lua/compress.h
@@ -0,0 +1,24 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2010-2023, Tarantool AUTHORS, please see AUTHORS file.
+ */
+#pragma once
+
+#include "trivia/config.h"
+
+#if defined(ENABLE_COMPRESS_MODULE)
+#include "lua/compress_impl.h"
+#else /* !defined(ENABLE_COMPRESS_MODULE) */
+
+#define COMPRESS_LUA_MODULES
+
+struct lua_State;
+
+static inline void
+tarantool_lua_compress_init(struct lua_State *L)
+{
+	(void)L;
+}
+
+#endif /* !defined(ENABLE_COMPRESS_MODULE) */
diff --git a/src/lua/etcd_client.h b/src/lua/etcd_client.h
new file mode 100644
index 0000000000000000000000000000000000000000..aff094d4f8ba530251512abe57d0de07bed92f94
--- /dev/null
+++ b/src/lua/etcd_client.h
@@ -0,0 +1,16 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2010-2023, Tarantool AUTHORS, please see AUTHORS file.
+ */
+#pragma once
+
+#include "trivia/config.h"
+
+#if defined(ENABLE_ETCD_CLIENT)
+#include "lua/etcd_client_impl.h"
+#else /* !defined(ENABLE_ETCD_CLIENT) */
+
+#define ETCD_CLIENT_LUA_MODULES
+
+#endif /* !defined(ENABLE_ETCD_CLIENT) */
diff --git a/src/lua/init.c b/src/lua/init.c
index c2d5dd53ec06ba6ce6d8763fa653240cc9f99844..c9dc6a49ac935a95d0809edaa185748e82d84c3e 100644
--- a/src/lua/init.c
+++ b/src/lua/init.c
@@ -71,6 +71,8 @@
 #include "lua/builtin_modcache.h"
 #include "lua/tweaks.h"
 #include "lua/xml.h"
+#include "lua/etcd_client.h"
+#include "lua/compress.h"
 #include "digest.h"
 #include "errinj.h"
 
@@ -94,11 +96,6 @@ LUALIB_API int
 luaopen_zip(lua_State *L);
 #endif
 
-#if defined(ENABLE_COMPRESS_MODULE)
-void
-tarantool_lua_compress_init(lua_State *L);
-#endif
-
 #define MAX_MODNAME 64
 
 /**
@@ -175,9 +172,6 @@ extern char minifio_lua[],
 	print_lua[],
 	pairs_lua[],
 	luadebug_lua[]
-#if defined(ENABLE_COMPRESS_MODULE)
-	, compress_lua[]
-#endif
 #if defined(EMBED_LUAROCKS)
 	, luarocks_core_hardcoded_lua[],
 	luarocks_admin_cache_lua[],
@@ -271,23 +265,6 @@ extern char minifio_lua[],
 	luarocks_util_lua[],
 	luarocks_core_util_lua[]
 #endif /* defined(EMBED_LUAROCKS) */
-#if ENABLE_ETCD_CLIENT
-	, etcd_client_client_auth_http_lua[],
-	etcd_client_client_http_lua[],
-	etcd_client_client_jsstream_lua[],
-	etcd_client_client_pool_lua[],
-	etcd_client_error_etcd_lua[],
-	etcd_client_error_http_lua[],
-	etcd_client_grpc_json_lua[],
-	etcd_client_init_lua[],
-	etcd_client_math_lua[],
-	etcd_client_protocol_lua[],
-	etcd_client_subscribe_auto_lua[],
-	etcd_client_subscribe_once_lua[],
-	etcd_client_txn_lua[],
-	etcd_client_utils_lua[],
-	etcd_client_version_lua[]
-#endif
 ;
 
 static const char *lua_modules[] = {
@@ -324,9 +301,7 @@ static const char *lua_modules[] = {
 	"http.client", httpc_lua,
 	"iconv", iconv_lua,
 	"swim", swim_lua,
-#if defined(ENABLE_COMPRESS_MODULE)
-	"compress", compress_lua,
-#endif
+	COMPRESS_LUA_MODULES
 	/* jit.* library */
 	"jit.vmdef", jit_vmdef_lua,
 	"jit.bc", jit_bc_lua,
@@ -357,27 +332,7 @@ static const char *lua_modules[] = {
 	"internal.print", print_lua,
 	"internal.pairs", pairs_lua,
 	"luadebug", luadebug_lua,
-#if ENABLE_ETCD_CLIENT
-	/*
-	 * Module components order is important here: components that required
-	 * other modules must be loaded first.
-	 */
-	"etcd-client.version", etcd_client_version_lua,
-	"etcd-client.utils", etcd_client_utils_lua,
-	"etcd-client.math", etcd_client_math_lua,
-	"etcd-client.txn", etcd_client_txn_lua,
-	"etcd-client.grpc_json", etcd_client_grpc_json_lua,
-	"etcd-client.protocol", etcd_client_protocol_lua,
-	"etcd-client.subscribe.auto", etcd_client_subscribe_auto_lua,
-	"etcd-client.subscribe.once", etcd_client_subscribe_once_lua,
-	"etcd-client.error.etcd", etcd_client_error_etcd_lua,
-	"etcd-client.error.http", etcd_client_error_http_lua,
-	"etcd-client.client.pool", etcd_client_client_pool_lua,
-	"etcd-client.client.jsstream", etcd_client_client_jsstream_lua,
-	"etcd-client.client.http", etcd_client_client_http_lua,
-	"etcd-client.client.auth_http", etcd_client_client_auth_http_lua,
-	"etcd-client", etcd_client_init_lua,
-#endif
+	ETCD_CLIENT_LUA_MODULES
 	NULL
 };
 
@@ -942,9 +897,7 @@ tarantool_lua_init(const char *tarantool_bin, const char *script, int argc,
 	tarantool_lua_serializer_init(L);
 	tarantool_lua_swim_init(L);
 	tarantool_lua_decimal_init(L);
-#if defined(ENABLE_COMPRESS_MODULE)
 	tarantool_lua_compress_init(L);
-#endif
 #ifdef ENABLE_BACKTRACE
 	luaM_sysprof_set_backtracer(fiber_backtracer);
 #endif