diff --git a/lib/etcd3 b/lib/etcd3
new file mode 100644
index 0000000000..fa60a392c9
--- /dev/null
+++ b/lib/etcd3
@@ -0,0 +1,126 @@
+#!/bin/bash
+#
+# lib/etcd3
+#
+# Functions to control the installation and configuration of etcd 3.x
+# that provides a key-value store (and possibly other functions).
+
+# Dependencies:
+#
+# - ``functions`` file
+
+# ``stack.sh`` calls the entry points in this order:
+#
+# - start_etcd3
+# - stop_etcd3
+# - cleanup_etcd3
+
+# Save trace setting
+_XTRACE_ETCD3=$(set +o | grep xtrace)
+set +o xtrace
+
+
+# Defaults
+# --------
+
+# Set up default values for etcd
+ETCD_DOWNLOAD_URL=${ETCD_DOWNLOAD_URL:-https://github.com/coreos/etcd/releases/download}
+ETCD_VERSION=${ETCD_VERSION:-v3.1.7}
+ETCD_DATA_DIR="$DEST/data/etcd"
+ETCD_SYSTEMD_SERVICE="devstack@etcd.service"
+ETCD_BIN_DIR="$DEST/bin"
+
+if is_ubuntu ; then
+    UBUNTU_RELEASE_BASE_NUM=`lsb_release -r | awk '{print $2}' | cut -d '.' -f 1`
+fi
+
+# start_etcd3() - Starts to run the etcd process
+function start_etcd3 {
+    _install_etcd
+
+    local cmd="$ETCD_BIN_DIR/etcd"
+    cmd+=" --name $HOSTNAME --data-dir $ETCD_DATA_DIR"
+    cmd+=" --initial-cluster-state new --initial-cluster-token etcd-cluster-01"
+    cmd+=" --initial-cluster $HOSTNAME=http://$SERVICE_HOST:2380"
+    cmd+=" --initial-advertise-peer-urls http://$SERVICE_HOST:2380"
+    cmd+=" --advertise-client-urls http://$SERVICE_HOST:2379"
+    cmd+=" --listen-peer-urls http://0.0.0.0:2380 "
+    cmd+=" --listen-client-urls http://$SERVICE_HOST:2379"
+
+    local unitfile="$SYSTEMD_DIR/$ETCD_SYSTEMD_SERVICE"
+    write_user_unit_file $ETCD_SYSTEMD_SERVICE "$cmd" "" "root"
+
+    iniset -sudo $unitfile "Unit" "After" "network.target"
+    iniset -sudo $unitfile "Service" "Type" "notify"
+    iniset -sudo $unitfile "Service" "Restart" "on-failure"
+    iniset -sudo $unitfile "Service" "LimitNOFILE" "65536"
+
+    $SYSTEMCTL daemon-reload
+    $SYSTEMCTL enable $ETCD_SYSTEMD_SERVICE
+    $SYSTEMCTL start $ETCD_SYSTEMD_SERVICE
+}
+
+# stop_etcd3() stops the etcd3 process
+function stop_etcd3 {
+    $SYSTEMCTL stop $ETCD_SYSTEMD_SERVICE
+}
+
+function cleanup_etcd {
+    $SYSTEMCTL disable $ETCD_SYSTEMD_SERVICE
+
+    local unitfile="$SYSTEMD_DIR/$ETCD_SYSTEMD_SERVICE"
+    sudo rm -f $unitfile
+
+    $SYSTEMCTL daemon-reload
+
+    sudo rm -rf $ETCD_DATA_DIR
+}
+
+function _install_etcd {
+    echo "Installing etcd"
+
+    # Make sure etcd3 downloads the correct architecture
+    if is_arch "x86_64"; then
+        ETCD_ARCH="amd64"
+    elif is_arch "aarch64"; then
+        ETCD_ARCH="arm64"
+    elif is_arch "ppc64le"; then
+        ETCD_ARCH="ppc64le"
+    else
+        exit_distro_not_supported "invalid hardware type - $ETCD_ARCH"
+    fi
+
+    # Install the libraries needed. Note: tooz for example does not have a hard dependency on these libraries
+    pip_install etcd3
+    pip_install etcd3gw
+
+    # Create the necessary directories
+    sudo mkdir -p $ETCD_BIN_DIR
+    sudo mkdir -p $ETCD_DATA_DIR
+
+    # Download and cache the etcd tgz for subsequent use
+    if [ ! -f "$DEST/etcd/etcd-$ETCD_VERSION-linux-$ETCD_ARCH/etcd" ]; then
+        mkdir -p $DEST/etcd
+        ETCD_DOWNLOAD_FILE=etcd-$ETCD_VERSION-linux-$ETCD_ARCH.tar.gz
+        wget $ETCD_DOWNLOAD_URL/$ETCD_VERSION/$ETCD_DOWNLOAD_FILE -O $DEST/etcd/$ETCD_DOWNLOAD_FILE
+        wget $ETCD_DOWNLOAD_URL/$ETCD_VERSION/$ETCD_DOWNLOAD_FILE.asc -O $DEST/etcd/$ETCD_DOWNLOAD_FILE.asc
+
+        # use gpg to verify the artifact, use a backup key server in case the first one is down for some reason
+        gpg --keyserver hkps.pool.sks-keyservers.net --recv-key FC8A365E || gpg --keyserver pgpkeys.mit.edu --recv-key FC8A365E
+        gpg --verify $DEST/etcd/$ETCD_DOWNLOAD_FILE.asc $DEST/etcd/$ETCD_DOWNLOAD_FILE
+
+        tar xzvf $DEST/etcd/$ETCD_DOWNLOAD_FILE -C $DEST/etcd
+        sudo cp $DEST/etcd/etcd-$ETCD_VERSION-linux-$ETCD_ARCH/etcd $ETCD_BIN_DIR/etcd
+    fi
+    if [ ! -f "$ETCD_BIN_DIR/etcd" ]; then
+        sudo cp $DEST/etcd/etcd-$ETCD_VERSION-linux-$ETCD_ARCH/etcd $ETCD_BIN_DIR/etcd
+    fi
+}
+
+# Restore xtrace
+$_XTRACE_ETCD3
+
+# Tell emacs to use shell-script-mode
+## Local variables:
+## mode: shell-script
+## End:
diff --git a/stack.sh b/stack.sh
index e83eaea326..ecf068a4a9 100755
--- a/stack.sh
+++ b/stack.sh
@@ -574,6 +574,7 @@ source $TOP_DIR/lib/neutron
 source $TOP_DIR/lib/ldap
 source $TOP_DIR/lib/dstat
 source $TOP_DIR/lib/dlm
+source $TOP_DIR/lib/etcd3
 source $TOP_DIR/lib/os_brick
 
 # Extras Source
@@ -1043,6 +1044,11 @@ fi
 # A better kind of sysstat, with the top process per time slice
 start_dstat
 
+# Etcd
+# -----
+
+# etcd is a distributed key value store that provides a reliable way to store data across a cluster of machines
+start_etcd3
 
 # Keystone
 # --------
diff --git a/stackrc b/stackrc
index 41ff268bbe..9203f8b5b9 100644
--- a/stackrc
+++ b/stackrc
@@ -65,7 +65,7 @@ if ! isset ENABLED_SERVICES ; then
     # Dashboard
     ENABLED_SERVICES+=,horizon
     # Additional services
-    ENABLED_SERVICES+=,rabbit,tempest,mysql,dstat
+    ENABLED_SERVICES+=,rabbit,tempest,mysql,etcd3,dstat
 fi
 
 # Global toggle for enabling services under mod_wsgi. If this is set to
diff --git a/unstack.sh b/unstack.sh
index 485fed7f80..a9826f5a97 100755
--- a/unstack.sh
+++ b/unstack.sh
@@ -69,6 +69,7 @@ source $TOP_DIR/lib/swift
 source $TOP_DIR/lib/neutron
 source $TOP_DIR/lib/ldap
 source $TOP_DIR/lib/dstat
+source $TOP_DIR/lib/etcd3
 source $TOP_DIR/lib/dlm
 
 # Extras Source
@@ -162,6 +163,11 @@ if is_service_enabled neutron; then
     cleanup_neutron
 fi
 
+if is_service_enabled etcd3; then
+    stop_etcd3
+    cleanup_etcd3
+fi
+
 if is_service_enabled dstat; then
     stop_dstat
 fi