diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000000000000000000000000000000000000..7160f9652030db9e1572b97ac84dfad54ef0719c
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,23 @@
+# EditorConfig is awesome: https://EditorConfig.org
+
+# top-most EditorConfig file
+root = true
+
+# Unix-style newlines with a newline ending every file
+[*]
+charset = utf-8
+end_of_line = LF
+insert_final_newline = true
+trim_trailing_whitespace = true
+indent_style = space
+indent_size = 4
+max_line_length = 120
+
+[*.{yml,yaml}]
+indent_size = 2
+
+[*.md]
+max_line_length = 140
+
+[COMMIT_EDITMSG]
+max_line_length = 0
diff --git a/.gitignore b/.gitignore
index ddacf424a16e464143e51e2c2351365f8d1337a1..1eae7f0a044c72935664b18a7dad19daef319ec1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,8 @@
 .idea/
 virtualenv/
 venv/
-molecule/default/.molecule/
-molecule/default/.pytest_cache/
-molecule/default/pytestdebug.log
-__pycache__
+__pycache__/
+molecule/*/.molecule/
+molecule/*/.pytest_cache/
+molecule/*/pytestdebug.log
+.tox/
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f409d9901fcb82129ae86b3d91479a5855f6baa9..bba1f866a30fe2894eafb6f2f4cc9e4c97b2a03c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -19,8 +19,6 @@ stage-tests:
   tags:
     - privileged-runner
   script:
-    - apk add --update python py-pip python-dev gcc libc-dev libffi-dev openssl-dev linux-headers make
-    - pip install --upgrade pip
-    - pip install -r requirements.txt
-    - pip install -r requirements-tests.txt
-    - molecule test
+    - apk add --update python3 py-pip python3-dev gcc libc-dev libffi-dev openssl-dev linux-headers make git
+    - pip install tox
+    - tox
diff --git a/README.md b/README.md
index b71b9bd3653b7d73c683a22eebde001f8b044b4a..1553ca85f948397603f978f6b2cb8a19331b8eb8 100644
--- a/README.md
+++ b/README.md
@@ -89,13 +89,15 @@ bind_zones:
 
 Tests
 -----
-Role successfully tested with [Molecule](https://molecule.readthedocs.io/). To run these tests, init a new [Virtualenv](https://virtualenv.pypa.io/) (I usually use the name `venv` for the virtualenv... yes, naming is not my best skill), install requirements and run tests inside:
+Role successfully tested with [Molecule](https://molecule.readthedocs.io/) in:
+
+- [Debian 10 (Buster)](https://www.debian.org/releases/buster/)
+- [Debian 9 (Stretch)](https://www.debian.org/releases/stretch/)
+
+To run these tests, just use the [tox](https://tox.readthedocs.io/en/latest/) command:
 
 ```bash
-$ virtualenv --python=python3 venv
-$ source venv/bin/activate
-(venv) $ pip3 install -r requirements-tests.txt
-(venv) $ molecule test
+$ tox
 ```
 
 
diff --git a/meta/main.yml b/meta/main.yml
index da14ebd9e2e62888649b4a1a1f6992d265944e59..de5509d0982b373c5fdddde43333fb06b688ef65 100644
--- a/meta/main.yml
+++ b/meta/main.yml
@@ -13,7 +13,8 @@ galaxy_info:
   platforms:
     - name: Debian
       versions:
-        - all
+        - buster
+        - stretch
 
   galaxy_tags:
     - bhean
diff --git a/molecule/default/Dockerfile.j2 b/molecule/default/Dockerfile.j2
index 9f689d9e15f0fb865cb4389ca3f782976ce8fbc2..0a605536a263ce5f94e9971128d9ea0267312d5f 100644
--- a/molecule/default/Dockerfile.j2
+++ b/molecule/default/Dockerfile.j2
@@ -6,8 +6,9 @@ FROM {{ item.registry.url }}/{{ item.image }}
 FROM {{ item.image }}
 {% endif %}
 
-RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get upgrade -y && apt-get install -y python sudo bash ca-certificates && apt-get clean; \
+RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates && apt-get clean; \
     elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python2-dnf bash && dnf clean all; \
-    elif [ $(command -v yum) ]; then yum makecache fast && yum update -y && yum install -y python sudo yum-plugin-ovl bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
-    elif [ $(command -v zypper) ]; then zypper refresh && zypper update -y && zypper install -y python sudo bash python-xml && zypper clean -a; \
-    elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; fi
+    elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
+    elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml && zypper clean -a; \
+    elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \
+    elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates && xbps-remove -O; fi
diff --git a/molecule/default/create.yml b/molecule/default/create.yml
deleted file mode 100644
index ac90767ff601e764a2dedfe08b099390024e2d83..0000000000000000000000000000000000000000
--- a/molecule/default/create.yml
+++ /dev/null
@@ -1,71 +0,0 @@
----
-- name: Create
-  hosts: localhost
-  connection: local
-  gather_facts: false
-  no_log: "{{ not lookup('env', 'MOLECULE_DEBUG') | bool }}"
-  vars:
-    molecule_file: "{{ lookup('env', 'MOLECULE_FILE') }}"
-    molecule_ephemeral_directory: "{{ lookup('env', 'MOLECULE_EPHEMERAL_DIRECTORY') }}"
-    molecule_scenario_directory: "{{ lookup('env', 'MOLECULE_SCENARIO_DIRECTORY') }}"
-    molecule_yml: "{{ lookup('file', molecule_file) | molecule_from_yaml }}"
-  tasks:
-    - name: Create Dockerfiles from image names
-      template:
-        src: "{{ molecule_scenario_directory }}/Dockerfile.j2"
-        dest: "{{ molecule_ephemeral_directory }}/Dockerfile_{{ item.image | regex_replace('[^a-zA-Z0-9_]', '_') }}"
-      with_items: "{{ molecule_yml.platforms }}"
-      register: platforms
-
-    - name: Discover local Docker images
-      docker_image_facts:
-        name: "molecule_local/{{ item.item.name }}"
-      with_items: "{{ platforms.results }}"
-      register: docker_images
-
-    - name: Build an Ansible compatible image
-      docker_image:
-        path: "{{ molecule_ephemeral_directory }}"
-        name: "molecule_local/{{ item.item.image }}"
-        dockerfile: "{{ item.item.dockerfile | default(item.invocation.module_args.dest) }}"
-        force: "{{ item.item.force | default(true) }}"
-      with_items: "{{ platforms.results }}"
-      when: platforms.changed or docker_images.results |
-       map(attribute='images') | select('equalto', []) | list | count >= 0
-
-    - name: Create docker network(s)
-      docker_network:
-        name: "{{ item }}"
-        state: present
-      with_items: "{{ molecule_yml.platforms | molecule_get_docker_networks }}"
-
-    - name: Create molecule instance(s)
-      docker_container:
-        name: "{{ item.name }}"
-        hostname: "{{ item.name }}"
-        image: "molecule_local/{{ item.image }}"
-        state: started
-        recreate: false
-        log_driver: json-file
-        command: "{{ item.command | default('bash -c \"while true; do sleep 10000; done\"') }}"
-        privileged: "{{ item.privileged | default(omit) }}"
-        volumes: "{{ item.volumes | default(omit) }}"
-        capabilities: "{{ item.capabilities | default(omit) }}"
-        exposed_ports: "{{ item.exposed_ports | default(omit) }}"
-        published_ports: "{{ item.published_ports | default(omit) }}"
-        ulimits: "{{ item.ulimits | default(omit) }}"
-        network_mode: "{{ item.network_mode | default(omit) }}"
-        networks: "{{ item.networks | default(omit) }}"
-        dns_servers: "{{ item.dns_servers | default(omit) }}"
-      register: server
-      with_items: "{{ molecule_yml.platforms }}"
-      async: 7200
-      poll: 0
-
-    - name: Wait for instance(s) creation to complete
-      async_status:
-        jid: "{{ item.ansible_job_id }}"
-      register: docker_jobs
-      until: docker_jobs.finished
-      retries: 300
-      with_items: "{{ server.results }}"
diff --git a/molecule/default/destroy.yml b/molecule/default/destroy.yml
deleted file mode 100644
index ec4da497e315324c358449fac4e9f53e10938e26..0000000000000000000000000000000000000000
--- a/molecule/default/destroy.yml
+++ /dev/null
@@ -1,33 +0,0 @@
----
-- name: Destroy
-  hosts: localhost
-  connection: local
-  gather_facts: false
-  no_log: "{{ not lookup('env', 'MOLECULE_DEBUG') | bool }}"
-  vars:
-    molecule_file: "{{ lookup('env', 'MOLECULE_FILE') }}"
-    molecule_yml: "{{ lookup('file', molecule_file) | molecule_from_yaml }}"
-  tasks:
-    - name: Destroy molecule instance(s)
-      docker_container:
-        name: "{{ item.name }}"
-        state: absent
-        force_kill: "{{ item.force_kill | default(true) }}"
-      register: server
-      with_items: "{{ molecule_yml.platforms }}"
-      async: 7200
-      poll: 0
-
-    - name: Wait for instance(s) deletion to complete
-      async_status:
-        jid: "{{ item.ansible_job_id }}"
-      register: docker_jobs
-      until: docker_jobs.finished
-      retries: 300
-      with_items: "{{ server.results }}"
-
-    - name: Delete docker network(s)
-      docker_network:
-        name: "{{ item }}"
-        state: absent
-      with_items: "{{ molecule_yml.platforms | molecule_get_docker_networks }}"
diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml
index 26d5628e73315a9efe83723b793c66d2aef18367..f854eeff7d6867bf49fc75d1c9bbc2a73d1e3550 100644
--- a/molecule/default/molecule.yml
+++ b/molecule/default/molecule.yml
@@ -50,11 +50,14 @@ driver:
   name: docker
 
 platforms:
+  # Debian 10 (BUSTER)
+  - name: molecule_bind_debian_10
+    image: debian:buster-slim
+    privileged: True
   # Debian 9 (STRETCH)
-  - name: molecule_debian9
-    image: debian:9-slim
+  - name: molecule_bind_debian_9
+    image: debian:stretch-slim
     privileged: True
-    network_mode: host
 
 provisioner:
   name: ansible
diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml
index d3ab79c5c506e5525f992931204e86321ee12d2f..771d8c4c530ac2eabea44770e6ce0f57af3c02c8 100644
--- a/molecule/default/prepare.yml
+++ b/molecule/default/prepare.yml
@@ -3,12 +3,13 @@
   hosts: all
   gather_facts: false
   tasks:
-    - name: Installing packages for TestInfra
+    - name: "Installing needed packages for tests"
       become: yes
       package:
-        name: "{{ item }}"
+        name: [
+          'host',
+          'coreutils',
+          'net-tools',
+        ]
         state: present
         update_cache: yes
-      with_items:
-        - host
-        - coreutils
diff --git a/molecule/default/tests/test_dns.py b/molecule/default/tests/test_dns.py
index dfae51c59d9ba9af8eb5cef16802c0980c85776c..47136bc40cf2589234516c4a3e13e7c7b03f81d9 100644
--- a/molecule/default/tests/test_dns.py
+++ b/molecule/default/tests/test_dns.py
@@ -12,7 +12,7 @@ def test_daemon_is_running_and_enabled(host):
 
 def test_resolve_hostname_from_localzone(host):
     command = host.run("host test.example.com 127.0.0.1 | tail -1")
-    assert command.stdout == 'test.example.com has address 91.69.69.69'
+    assert command.stdout.strip() == 'test.example.com has address 91.69.69.69'
 
 
 def test_resolve_hostname_forwarded(host):
diff --git a/requirements-tests.txt b/requirements-tests.txt
index ea7c2703f0be2f332789817ecf856ea0336fd46f..617e9274e09c0d07061ce82c58a7ef3b2cab961c 100644
--- a/requirements-tests.txt
+++ b/requirements-tests.txt
@@ -1,2 +1,4 @@
-molecule>=2.11
-docker-py>=1
+molecule~=2.10
+docker-py~=1.0
+pytest~=5.0
+testinfra~=3.0
diff --git a/requirements.txt b/requirements.txt
index c8ab69178f16359359e66311f2a39e717382d62c..5fda8b28e3b80c3cd44bb5be9564d431d7a29848 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1 +1,2 @@
-ansible>=2.6
+ansible~=2.7
+tox~=3.13
diff --git a/tox.ini b/tox.ini
new file mode 100644
index 0000000000000000000000000000000000000000..b73e19e61989cf775c2869457772b2ce4528e463
--- /dev/null
+++ b/tox.ini
@@ -0,0 +1,15 @@
+# tox (https://tox.readthedocs.io/) is a tool for running tests
+# in multiple virtualenvs. This configuration file will run the
+# test suite on all supported python versions. To use it, "pip install tox"
+# and then run "tox" from this directory.
+
+[tox]
+minversion = 3.13
+envlist = py3
+skipsdist=True
+
+[testenv]
+deps = -rrequirements-tests.txt
+
+commands =
+	molecule test