diff --git a/src/main.rs b/src/main.rs
index bbea17e08ad210181c789423b81bf5b83565bb86..e38f354a5ead7ecdcb06dabf0314ab0684348c46 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -472,7 +472,7 @@ fn start_join(args: &args::Run, leader_address: String) {
     let cfg = tarantool::Cfg {
         listen: None,
         read_only: false,
-        // instance_uuid: resp.instance_uuid
+        instance_uuid: Some(resp.peer.instance_uuid.clone()),
         // replicaset_uuid: resp.replicaset_uuid
         replication: resp.box_replication.clone(),
         wal_dir: args.data_dir.clone(),
diff --git a/src/traft/mod.rs b/src/traft/mod.rs
index b1e03c7b73001380a039ee230698d7f2f987d947..cc38a84653f2198f04ef9015e07a28a62b15f601 100644
--- a/src/traft/mod.rs
+++ b/src/traft/mod.rs
@@ -11,6 +11,7 @@ use ::tarantool::tuple::AsTuple;
 use serde::de::DeserializeOwned;
 use serde::{Deserialize, Serialize};
 use std::convert::TryFrom;
+use uuid::Uuid;
 
 use protobuf::Message as _;
 use protobuf::ProtobufEnum as _;
@@ -69,7 +70,7 @@ pub struct Peer {
     pub voter: bool,
     pub instance_id: String,
     // pub replicaset_id: String,
-    // pub instance_uuid: String,
+    pub instance_uuid: String,
     // pub replicaset_uuid: String,
     /// `0` means it's not committed yet.
     pub commit_index: u64,
@@ -297,3 +298,16 @@ pub struct JoinResponse {
     // pub read_only: bool,
 }
 impl AsTuple for JoinResponse {}
+
+///////////////////////////////////////////////////////////////////////////////
+lazy_static::lazy_static! {
+    static ref NAMESPACE_INSTANCE_UUID: Uuid =
+        Uuid::new_v3(&Uuid::nil(), "INSTANCE_UUID".as_bytes());
+}
+
+/// Generate UUID for an instance from `instance_id` (String).
+/// Use Version-3 (MD5) UUID.
+pub fn instance_uuid(instance_id: &str) -> String {
+    let uuid = Uuid::new_v3(&NAMESPACE_INSTANCE_UUID, instance_id.as_bytes());
+    uuid.hyphenated().to_string()
+}
diff --git a/src/traft/storage.rs b/src/traft/storage.rs
index 88dd995d1689678258a8ba300d26935c8fa9fe94..7f2b8e58542efc9d64e6a25bf25ece62f3f40e4c 100644
--- a/src/traft/storage.rs
+++ b/src/traft/storage.rs
@@ -76,8 +76,8 @@ impl Storage {
                     {name = 'peer_address', type = 'string', is_nullable = false},
                     {name = 'voter', type = 'boolean', is_nullable = false},
                     {name = 'instance_id', type = 'string', is_nullable = false},
-                    -- {name = 'instance_uuid', type = 'string', is_nullable = false},
                     -- {name = 'replicaset_id', type = 'string', is_nullable = false},
+                    {name = 'instance_uuid', type = 'string', is_nullable = false},
                     -- {name = 'replicaset_uuid', type = 'string', is_nullable = false},
                     {name = 'commit_index', type = 'unsigned', is_nullable = false},
                 }
diff --git a/src/traft/topology.rs b/src/traft/topology.rs
index 49d545094afd47c81dbcae485f6f18500bfbf515..12df06d78e447407929db5e185a68d902b5f0aa6 100644
--- a/src/traft/topology.rs
+++ b/src/traft/topology.rs
@@ -1,5 +1,6 @@
 use std::collections::BTreeMap;
 
+use crate::traft::instance_uuid;
 use crate::traft::JoinRequest;
 use crate::traft::Peer;
 use crate::traft::RaftId;
@@ -62,6 +63,7 @@ impl Topology {
                 raft_id,
                 instance_id: req.instance_id.clone(),
                 commit_index: INVALID_INDEX,
+                instance_uuid: instance_uuid(&req.instance_id),
                 peer_address: req.advertise_address.clone(),
                 voter: req.voter,
             };
@@ -81,6 +83,7 @@ impl Topology {
 #[cfg(test)]
 mod tests {
     use super::Topology;
+    use crate::traft::instance_uuid;
     use crate::traft::JoinRequest;
     use crate::traft::Peer;
 
@@ -98,6 +101,7 @@ mod tests {
                     voter: $voter,
                     instance_id: $instance_id.into(),
                     commit_index: raft::INVALID_INDEX,
+                    instance_uuid: instance_uuid($instance_id),
                 }
             ),*]
         };