diff --git a/src/args.rs b/src/args.rs
index 82d79b79b7ba9383dda2910e30be23ae06175d9d..3b65305443e59d7e9c4535d4a6f0abc81cb6c514 100644
--- a/src/args.rs
+++ b/src/args.rs
@@ -7,9 +7,9 @@ use tarantool::log::SayLevel;
 use tarantool::tlua;
 use thiserror::Error;
 
+use crate::failure_domain::FailureDomain;
 use crate::instance::InstanceId;
 use crate::replicaset::ReplicasetId;
-use crate::traft::FailureDomain;
 use crate::util::Uppercase;
 
 #[derive(Debug, Parser)]
diff --git a/src/failure_domain.rs b/src/failure_domain.rs
new file mode 100644
index 0000000000000000000000000000000000000000..85e9dfb645fbbd2ea8b2cdac9bb90859f88cc527
--- /dev/null
+++ b/src/failure_domain.rs
@@ -0,0 +1,85 @@
+use crate::stringify_debug;
+use crate::util::Uppercase;
+use std::collections::HashMap;
+
+////////////////////////////////////////////////////////////////////////////////
+/// Failure domains of a given instance.
+#[derive(Default, PartialEq, Eq, Clone, serde::Deserialize, serde::Serialize)]
+pub struct FailureDomain {
+    #[serde(flatten)]
+    data: HashMap<Uppercase, Uppercase>,
+}
+
+impl FailureDomain {
+    pub fn contains_name(&self, name: &Uppercase) -> bool {
+        self.data.contains_key(name)
+    }
+
+    pub fn names(&self) -> std::collections::hash_map::Keys<Uppercase, Uppercase> {
+        self.data.keys()
+    }
+
+    /// Empty `FailureDomain` doesn't intersect with any other `FailureDomain`
+    /// even with another empty one.
+    pub fn intersects(&self, other: &Self) -> bool {
+        for (name, value) in &self.data {
+            match other.data.get(name) {
+                Some(other_value) if value == other_value => {
+                    return true;
+                }
+                _ => {}
+            }
+        }
+        false
+    }
+}
+
+impl std::fmt::Display for FailureDomain {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.write_str("{")?;
+        let mut iter = self.data.iter();
+        if let Some((k, v)) = iter.next() {
+            write!(f, "{k}: {v}")?;
+            for (k, v) in iter {
+                write!(f, ", {k}: {v}")?;
+            }
+        }
+        f.write_str("}")?;
+        Ok(())
+    }
+}
+
+impl std::fmt::Debug for FailureDomain {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        let mut ds = f.debug_struct(stringify_debug!(FailureDomain));
+        for (name, value) in &self.data {
+            ds.field(name, &**value);
+        }
+        ds.finish()
+    }
+}
+
+impl<I, K, V> From<I> for FailureDomain
+where
+    I: IntoIterator<Item = (K, V)>,
+    Uppercase: From<K>,
+    Uppercase: From<V>,
+{
+    fn from(data: I) -> Self {
+        Self {
+            data: data
+                .into_iter()
+                .map(|(k, v)| (Uppercase::from(k), Uppercase::from(v)))
+                .collect(),
+        }
+    }
+}
+
+impl<'a> IntoIterator for &'a FailureDomain {
+    type IntoIter = <&'a HashMap<Uppercase, Uppercase> as IntoIterator>::IntoIter;
+    type Item = <&'a HashMap<Uppercase, Uppercase> as IntoIterator>::Item;
+
+    fn into_iter(self) -> Self::IntoIter {
+        self.data.iter()
+    }
+}
diff --git a/src/instance.rs b/src/instance.rs
index 898b489d854caf8ee697d6cebe35aa8983f82f0c..911211d7685d7ae00df269cbb5580ade88776bcb 100644
--- a/src/instance.rs
+++ b/src/instance.rs
@@ -1,6 +1,6 @@
+use super::failure_domain::FailureDomain;
 use super::replicaset::ReplicasetId;
 use crate::has_grades;
-use crate::traft::FailureDomain;
 use crate::traft::RaftId;
 use crate::util::Transition;
 use ::serde::{Deserialize, Serialize};
diff --git a/src/main.rs b/src/main.rs
index 05a0baf3d36fa5be0e2a7497dd76baa11d287417..ddad33dafe5af4e10a985cb40efeca9c598cb904 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -35,6 +35,7 @@ use traft::error::Error;
 mod app;
 mod args;
 mod discovery;
+mod failure_domain;
 mod governor;
 mod instance;
 mod ipc;
diff --git a/src/storage.rs b/src/storage.rs
index 719921b1832f689fcf5022fd4f31933ac07bf108..cd9a5513ca91cc28e66fde6cf0a3cc72a413911e 100644
--- a/src/storage.rs
+++ b/src/storage.rs
@@ -2,6 +2,7 @@ use ::tarantool::index::{Index, IndexIterator, IteratorType};
 use ::tarantool::space::{FieldType, Space};
 use ::tarantool::tuple::{DecodeOwned, ToTupleBuffer, Tuple};
 
+use crate::failure_domain as fd;
 use crate::instance::{self, grade, Instance};
 use crate::replicaset::{Replicaset, ReplicasetId};
 use crate::traft;
@@ -523,7 +524,7 @@ define_instance_fields! {
     ReplicasetUuid : String               = ("replicaset_uuid", FieldType::String)
     CurrentGrade   : grade::CurrentGrade  = ("current_grade",   FieldType::Array)
     TargetGrade    : grade::TargetGrade   = ("target_grade",    FieldType::Array)
-    FailureDomain  : traft::FailureDomain = ("failure_domain",  FieldType::Map)
+    FailureDomain  : fd::FailureDomain    = ("failure_domain",  FieldType::Map)
 }
 
 impl tarantool::tuple::TupleIndex for InstanceField {
@@ -764,13 +765,14 @@ inventory::submit!(crate::InnerTest {
     body: || {
         use crate::instance::grade::{CurrentGradeVariant as CGV, TargetGradeVariant as TGV};
         use crate::instance::InstanceId;
+        use crate::failure_domain::FailureDomain;
 
         let storage_instances = Instances::new().unwrap();
         let space_instances = storage_instances.space.clone();
         let storage_peer_addresses = PeerAddresses::new().unwrap();
         let space_peer_addresses = storage_peer_addresses.space.clone();
 
-        let faildom = crate::traft::FailureDomain::from([("a", "b")]);
+        let faildom = FailureDomain::from([("a", "b")]);
 
         for instance in vec![
             // r1
diff --git a/src/traft/mod.rs b/src/traft/mod.rs
index 344a9b5bc1284f56935db074861b5022067725be..aaddea5b84fa8ea1bff93d0bfb0a64fba9d6d9b9 100644
--- a/src/traft/mod.rs
+++ b/src/traft/mod.rs
@@ -12,13 +12,11 @@ pub mod topology;
 
 use crate::instance::Instance;
 use crate::stringify_debug;
-use crate::util::Uppercase;
 use ::raft::prelude as raft;
 use ::tarantool::tuple::Encode;
 use op::Op;
 use serde::de::DeserializeOwned;
 use serde::{Deserialize, Serialize};
-use std::collections::HashMap;
 use std::convert::TryFrom;
 use std::fmt::Debug;
 use std::result::Result as StdResult;
@@ -395,88 +393,6 @@ pub fn replicaset_uuid(replicaset_id: &str) -> String {
     uuid.hyphenated().to_string()
 }
 
-////////////////////////////////////////////////////////////////////////////////
-/// Failure domains of a given instance.
-#[derive(Default, PartialEq, Eq, Clone, serde::Deserialize, serde::Serialize)]
-pub struct FailureDomain {
-    #[serde(flatten)]
-    data: HashMap<Uppercase, Uppercase>,
-}
-
-impl FailureDomain {
-    pub fn contains_name(&self, name: &Uppercase) -> bool {
-        self.data.contains_key(name)
-    }
-
-    pub fn names(&self) -> std::collections::hash_map::Keys<Uppercase, Uppercase> {
-        self.data.keys()
-    }
-
-    /// Empty `FailureDomain` doesn't intersect with any other `FailureDomain`
-    /// even with another empty one.
-    pub fn intersects(&self, other: &Self) -> bool {
-        for (name, value) in &self.data {
-            match other.data.get(name) {
-                Some(other_value) if value == other_value => {
-                    return true;
-                }
-                _ => {}
-            }
-        }
-        false
-    }
-}
-
-impl std::fmt::Display for FailureDomain {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.write_str("{")?;
-        let mut iter = self.data.iter();
-        if let Some((k, v)) = iter.next() {
-            write!(f, "{k}: {v}")?;
-            for (k, v) in iter {
-                write!(f, ", {k}: {v}")?;
-            }
-        }
-        f.write_str("}")?;
-        Ok(())
-    }
-}
-
-impl std::fmt::Debug for FailureDomain {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        let mut ds = f.debug_struct(stringify_debug!(FailureDomain));
-        for (name, value) in &self.data {
-            ds.field(name, &**value);
-        }
-        ds.finish()
-    }
-}
-
-impl<I, K, V> From<I> for FailureDomain
-where
-    I: IntoIterator<Item = (K, V)>,
-    Uppercase: From<K>,
-    Uppercase: From<V>,
-{
-    fn from(data: I) -> Self {
-        Self {
-            data: data
-                .into_iter()
-                .map(|(k, v)| (Uppercase::from(k), Uppercase::from(v)))
-                .collect(),
-        }
-    }
-}
-
-impl<'a> IntoIterator for &'a FailureDomain {
-    type IntoIter = <&'a HashMap<Uppercase, Uppercase> as IntoIterator>::IntoIter;
-    type Item = <&'a HashMap<Uppercase, Uppercase> as IntoIterator>::Item;
-
-    fn into_iter(self) -> Self::IntoIter {
-        self.data.iter()
-    }
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 /// Migration
 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
diff --git a/src/traft/rpc/join.rs b/src/traft/rpc/join.rs
index 19c6f26a8ccf7a594bff8d86554f79241a6c7adf..f8b90cbf3bf0cc2bd12d37b0b2b95b26c926c202 100644
--- a/src/traft/rpc/join.rs
+++ b/src/traft/rpc/join.rs
@@ -1,7 +1,8 @@
+use crate::failure_domain::FailureDomain;
 use crate::instance::{Instance, InstanceId};
 use crate::replicaset::ReplicasetId;
 use crate::storage::ToEntryIter as _;
-use crate::traft::{error::Error, node, Address, FailureDomain, PeerAddress, Result};
+use crate::traft::{error::Error, node, Address, PeerAddress, Result};
 
 #[derive(Clone, Debug, ::serde::Serialize, ::serde::Deserialize)]
 pub struct OkResponse {
diff --git a/src/traft/rpc/update_instance.rs b/src/traft/rpc/update_instance.rs
index fa66be7d16a0915f088184115b18ab1c137fa0f8..ee09a204daf5e4dc46aab0470a0fe6b2b565c117 100644
--- a/src/traft/rpc/update_instance.rs
+++ b/src/traft/rpc/update_instance.rs
@@ -1,7 +1,7 @@
+use crate::failure_domain::FailureDomain;
 use crate::instance::grade::{CurrentGrade, TargetGradeVariant};
 use crate::instance::InstanceId;
 use crate::tlog;
-use crate::traft::FailureDomain;
 use crate::traft::Result;
 use crate::traft::{error::Error, node};
 
diff --git a/src/traft/topology.rs b/src/traft/topology.rs
index a5a5b284dc4af1c310ab822d75b3699bc98c3f08..198a7719d8fb08674db4ea3f3ff87d21c1b3aa37 100644
--- a/src/traft/topology.rs
+++ b/src/traft/topology.rs
@@ -1,5 +1,6 @@
 use std::collections::{BTreeMap, HashMap, HashSet};
 
+use crate::failure_domain::FailureDomain;
 use crate::has_grades;
 use crate::instance::grade::{
     CurrentGrade, CurrentGradeVariant, Grade, TargetGrade, TargetGradeVariant,
@@ -10,7 +11,6 @@ use crate::rpc::update_instance;
 use crate::traft::instance_uuid;
 use crate::traft::replicaset_uuid;
 use crate::traft::Address;
-use crate::traft::FailureDomain;
 use crate::traft::RaftId;
 use crate::util::Uppercase;
 
@@ -243,10 +243,10 @@ mod tests {
 
     use super::Topology;
 
+    use crate::failure_domain::FailureDomain;
     use crate::instance::grade::{CurrentGrade, Grade, TargetGrade, TargetGradeVariant};
     use crate::traft::instance_uuid;
     use crate::traft::replicaset_uuid;
-    use crate::traft::FailureDomain;
     use crate::traft::Instance;
     use crate::traft::rpc::update_instance;
     use pretty_assertions::assert_eq;