diff --git a/.bashrc b/.bashrc
index d7b5b466ecceafb4ae7c4ed07af99da0fb8d1b01..2144c5f409276c243618ae3f648200d630112f28 100644
--- a/.bashrc
+++ b/.bashrc
@@ -30,12 +30,13 @@ fi
 if [ -f /etc/bash_completion ]; then
     . /etc/bash_completion
 fi
-
 if [ -f /usr/local/bin/virtualenvwrapper.sh ]
 then
     . /usr/local/bin/virtualenvwrapper.sh
 fi
 
+. $HOME/.local/share/bash/molecule.bash-completion.sh
+
 export REPREPRO_BASE_DIR=$HOME/Documents/Shore/debian-repository
 export EDITOR=vim
 export GOPATH=$HOME/Documents/Golang
@@ -64,6 +65,7 @@ alias deconcat="perl -pe 's/\\\n/\n/g'"
 alias ggo='sudo GOPATH=/usr/share/go go'
 alias tag-version='git tag -f v"$(cat VERSION)"'
 alias ecr-login='eval $(aws ecr get-login)'
+alias hostlocal='docker run --rm --privileged --net=host gliderlabs/hostlocal'
 deduce-aws-region () {
     export AWS_DEFAULT_REGION="$(curl --silent \
         http://169.254.169.254/latest/dynamic/instance-identity/document \
diff --git a/.local/share/bash/molecule.bash-completion.sh b/.local/share/bash/molecule.bash-completion.sh
new file mode 100644
index 0000000000000000000000000000000000000000..654d8ce62a2fba4dc40218e075f59f49d84f143d
--- /dev/null
+++ b/.local/share/bash/molecule.bash-completion.sh
@@ -0,0 +1,167 @@
+#!/bin/bash
+
+# Credits:
+# https://blog.heckel.xyz/2015/03/24/bash-completion-with-sub-commands-and-dynamic-options/
+# https://raw.githubusercontent.com/syncany/syncany/develop/gradle/bash/syncany.bash-completion
+
+shopt -s progcomp
+
+_platforms(){
+  molecule status --porcelain --platforms | cut -d' ' -f1 2>/dev/null
+}
+
+_providers(){
+  molecule status --porcelain --providers | cut -d' ' -f1 2>/dev/null
+}
+
+_hosts(){
+  molecule status --porcelain --hosts | cut -d' ' -f1 2>/dev/null
+}
+
+_molecule(){
+  local cur prev firstword lastword complete_words complete_options
+  cur=${COMP_WORDS[COMP_CWORD]}
+	prev=${COMP_WORDS[COMP_CWORD-1]}
+	firstword=$(_get_firstword)
+
+  GLOBAL_COMMANDS="check create converge destroy idempotence init list login status test verify"
+  GLOBAL_OPTIONS="-h -v"
+  CHECK_OPTIONS=""
+  CREATE_OPTIONS="--debug --platform --provider --tags"
+  CONVERGE_OPTIONS="--debug --platform --provider --tags"
+  DESTROY_OPTIONS="--debug --platform --provider --tags"
+  IDEMPOTENCE_OPTIONS="--debug --platform --provider --tags"
+  INIT_OPTIONS="--docker"
+  LIST_OPTIONS="--debug -m"
+  LOGIN_OPTIONS=""
+  STATUS_OPTIONS="--debug --hosts --platforms --porcelain --providers"
+  TEST_OPTIONS="--debug --platform --provider --tags --sudo"
+  VERIFY_OPTIONS="--debug --platform --provider --tags --sudo"
+
+  # Un-comment this for debug purposes:
+  # echo -e "\nprev = $prev, cur = $cur, firstword = $firstword.\n"
+
+  case "${firstword}" in
+    create)
+      case "${prev}" in
+        --platform)
+          complete_words=$(_platforms)
+          ;;
+        --provider)
+          complete_words=$(_providers)
+          ;;
+        *)
+          complete_options="${CREATE_OPTIONS}"
+          ;;
+      esac
+      ;;
+    converge)
+      case "${prev}" in
+        --platform)
+          complete_words=$(_platforms)
+          ;;
+        --provider)
+          complete_words=$(_providers)
+          ;;
+        *)
+          complete_options="${CONVERGE_OPTIONS}"
+          ;;
+      esac
+      ;;
+    destroy)
+      case "${prev}" in
+        --platform)
+          complete_words=$(_platforms)
+          ;;
+        --provider)
+          complete_words=$(_providers)
+          ;;
+        *)
+          complete_options="${DESTROY_OPTIONS}"
+          ;;
+      esac
+      ;;
+    idempotence)
+      case "${prev}" in
+        --platform)
+          complete_words=$(_platforms)
+          ;;
+        --provider)
+          complete_words=$(_providers)
+          ;;
+        *)
+          complete_options="${IDEMPOTENCE_OPTIONS}"
+          ;;
+      esac
+      ;;
+    init)
+      complete_options="${INIT_OPTIONS}"
+      ;;
+    list)
+      complete_options="${LIST_OPTIONS}"
+      ;;
+    login)
+      complete_options="${LOGIN_OPTIONS}"
+      complete_words=$(_hosts)
+      ;;
+    status)
+      complete_options="${STATUS_OPTIONS}"
+      ;;
+    test)
+      case "${prev}" in
+        --platform)
+          complete_words=$(_platforms)
+          ;;
+        --provider)
+          complete_words=$(_providers)
+          ;;
+        *)
+          complete_options="${TEST_OPTIONS}"
+          ;;
+      esac
+      ;;
+    verify)
+      case "${prev}" in
+        --platform)
+          complete_words=$(_platforms)
+          ;;
+        --provider)
+          complete_words=$(_providers)
+          ;;
+        *)
+          complete_options="${VERIFY_OPTIONS}"
+          ;;
+      esac
+      ;;
+    *)
+  		complete_words="${GLOBAL_COMMANDS}"
+  		complete_options="${GLOBAL_OPTIONS}"
+  		;;
+  esac
+
+  # Either display words or options, depending on the user input
+	if [[ ${cur} == -* ]]; then
+		COMPREPLY=( $( compgen -W "${complete_options}" -- ${cur} ))
+	else
+		COMPREPLY=( $( compgen -W "${complete_words}" -- ${cur} ))
+	fi
+
+	return 0
+}
+
+# Determines the first non-option word of the command line. This is usually the command.
+_get_firstword() {
+	local firstword i
+
+	firstword=
+	for ((i = 1; i < ${#COMP_WORDS[@]}; ++i)); do
+		if [[ ${COMP_WORDS[i]} != -* ]]; then
+			firstword=${COMP_WORDS[i]}
+			break
+		fi
+	done
+
+	echo $firstword
+}
+
+complete -F _molecule molecule