diff --git a/.ansible-lint b/.ansible-lint
new file mode 100644
index 0000000..fd30108
--- /dev/null
+++ b/.ansible-lint
@@ -0,0 +1,8 @@
+skip_list:
+  - experimental  # all rules tagged as experimental
+  - no-changed-when  # Commands should not change things if nothing needs doing
+
+warn_list:
+  - literal-compare  # Don't compare to literal True/False
+  - unnamed-task  # All tasks should be named
+  - var-spacing  # Variables should have spaces before and after:  {{ var_name }}
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 0ed5424..2db8bdd 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -25,9 +25,11 @@ repos:
         types: [file, yaml]
         entry: yamllint --strict -f parsable
   - repo: https://github.com/ansible/ansible-lint
-    rev: v4.1.1a2
+    rev: v4.3.5
     hooks:
       - id: ansible-lint
+        additional_dependencies:
+          - 'ansible<2.10'
         files: \.(yaml|yml)$
         entry: >-
           ansible-lint --force-color -v -x "ANSIBLE0006,ANSIBLE0007,ANSIBLE0010,ANSIBLE0012,ANSIBLE0013,ANSIBLE0016"
diff --git a/tox.ini b/tox.ini
index db9b764..567b4d3 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,4 +1,5 @@
 [tox]
+basepython = python3
 minversion = 2.0
 # add docs to the list of environments once we actually have docs to generate
 envlist = py36,pep8,molecule,linters
@@ -31,7 +32,7 @@ commands = molecule test --all
 [testenv:ansible-lint]
 deps = {[testenv:linters]deps}
 commands =
-  ansible-lint {toxinidir}/tripleo_ipa
+  ansible-lint -c .ansible-lint {toxinidir}/tripleo_ipa
 
 [testenv:yamllint]
 deps = {[testenv:linters]deps}
@@ -39,7 +40,12 @@ commands =
   yamllint -c {toxinidir}/tripleo_ipa/.yamllint {toxinidir}/tripleo_ipa
 
 [testenv:linters]
+setenv =
+  ANSIBLE_FILTER_PLUGINS={toxinidir}/tripleo_ipa/ansible_plugins/filter
+  ANSIBLE_LIBRARY={toxinidir}/tripleo_ipa/roles.galaxy/config_template/library:{toxinidir}/tripleo_ipa/ansible_plugins/modules
+  ANSIBLE_ROLES_PATH={toxinidir}/tripleo_ipa/roles.galaxy:{toxinidir}/tripleo_ipa/roles
 deps =
+   -r {toxinidir}/ansible-requirements.txt
    -r {toxinidir}/test-requirements.txt
 commands =
   {[testenv:ansible-lint]commands}
diff --git a/tripleo_ipa/molecule/default/Dockerfile b/tripleo_ipa/molecule/default/Dockerfile
index 86294ca..43b9cc7 100644
--- a/tripleo_ipa/molecule/default/Dockerfile
+++ b/tripleo_ipa/molecule/default/Dockerfile
@@ -22,7 +22,7 @@ FROM {{ item.image }}
 {% endif %}
 
 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 python*-dnf bash {{ item.pkg_extras | default('') }} && dnf clean all; \
+    elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install sudo python*-devel python*-dnf bash {{ item.pkg_extras | default('') }} && dnf clean all; \
     elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl python-setuptools bash {{ item.pkg_extras | default('') }} && 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 {{ item.pkg_extras | default('') }} && zypper clean -a; \
     elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates {{ item.pkg_extras | default('') }}; \
diff --git a/tripleo_ipa/molecule/default/molecule.yml b/tripleo_ipa/molecule/default/molecule.yml
index a77ae8f..0909b45 100644
--- a/tripleo_ipa/molecule/default/molecule.yml
+++ b/tripleo_ipa/molecule/default/molecule.yml
@@ -5,9 +5,11 @@ driver:
 log: true
 
 platforms:
-  - name: centos7
+  - name: centos8
     hostname: test-0.example.test
-    image: centos:7
+    image: centos/centos:centos8
+    registry:
+      url: quay.io
     security_opts:
       - seccomp=unconfined
     command: /sbin/init
@@ -16,10 +18,9 @@ platforms:
       - /tmp
     volumes:
       - /sys/fs/cgroup:/sys/fs/cgroup:ro
+      - /etc/pki/rpm-gpg:/etc/pki/rpm-gpg
     dockerfile: Dockerfile
     network_mode: host
-    easy_install:
-      - pip
     environment: &env
       http_proxy: "{{ lookup('env', 'http_proxy') }}"
       https_proxy: "{{ lookup('env', 'https_proxy') }}"
@@ -32,6 +33,12 @@ provisioner:
     ANSIBLE_ROLES_PATH: "${ANSIBLE_ROLES_PATH:-/usr/share/ansible/roles}:${HOME}/zuul-jobs/roles"
     ANSIBLE_LIBRARY: "${ANSIBLE_LIBRARY:-/usr/share/ansible/plugins/modules}"
     ANSIBLE_FILTER_PLUGINS: "${ANSIBLE_FILTER_PLUGINS:-/usr/share/ansible/plugins/filter}"
+  inventory:
+    hosts:
+      all:
+        hosts:
+          centos8:
+            ansible_python_interpreter: /usr/bin/python3
 
 scenario:
   test_sequence:
diff --git a/tripleo_ipa/molecule/default/prepare.yml b/tripleo_ipa/molecule/default/prepare.yml
index 8cac5b3..fa4ee35 100644
--- a/tripleo_ipa/molecule/default/prepare.yml
+++ b/tripleo_ipa/molecule/default/prepare.yml
@@ -61,7 +61,7 @@
         -h ipa.{{ domain }}
         --read-only --tmpfs /run --tmpfs /tmp
         -v /sys/fs/cgroup:/sys/fs/cgroup:ro
-        -v /tmp/ipa-data:/data:Z freeipa/freeipa-server:fedora-28 exit-on-finished
+        -v /tmp/ipa-data:/data:Z freeipa/freeipa-server:fedora-28 no-exit
         -U -r {{ domain | upper }} --setup-dns --no-reverse --no-ntp
         --forwarder={{ unbound_primary_nameserver_v4 | default('1.1.1.1') }}
         --forwarder={{ unbound_secondary_nameserver_v4 | default('8.8.8.8') }} &
@@ -72,3 +72,22 @@
         search_regex: "(INFO The ipa-server-install command was successful|ERROR The ipa-server-install command failed)"
         timeout: 900
       become: true
+
+    - name: Wait for FreeIPA LDAP port to open
+      wait_for:
+        host=172.18.0.22
+        port=389
+        delay=1
+        timeout=300
+      ignore_errors: true
+
+    - name: Check the status of ipactl to make sure all services are started
+      command: "docker exec freeipa-server-container ipactl status"
+      retries: 10
+      delay: 3
+      register: result
+      until: result.rc == 0
+
+    - name: Print ipactl status
+      debug:
+        msg: "{{result.stdout}}"
diff --git a/tripleo_ipa/molecule/deregister/Dockerfile b/tripleo_ipa/molecule/deregister/Dockerfile
index b91d113..9bf1e52 100644
--- a/tripleo_ipa/molecule/deregister/Dockerfile
+++ b/tripleo_ipa/molecule/deregister/Dockerfile
@@ -22,7 +22,7 @@ FROM {{ item.image }}
 {% endif %}
 
 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 python*-dnf bash {{ item.pkg_extras | default('') }} && dnf clean all; \
+    elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install sudo python*-devel python*-dnf bash {{ item.pkg_extras | default('') }} && dnf clean all; \
     elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl python-setuptools bash {{ item.pkg_extras | default('') }} && 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 {{ item.pkg_extras | default('') }} && zypper clean -a; \
     elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates {{ item.pkg_extras | default('') }}; \
diff --git a/tripleo_ipa/molecule/deregister/converge.yml b/tripleo_ipa/molecule/deregister/converge.yml
index d0b3fe3..5a3bb7d 100644
--- a/tripleo_ipa/molecule/deregister/converge.yml
+++ b/tripleo_ipa/molecule/deregister/converge.yml
@@ -274,5 +274,5 @@
     - include_role:
         name: tripleo_ipa_cleanup
       vars:
-        tripleo_ipa_hosts_to_delete: [ 'test-1.example.test' ]
+        tripleo_ipa_hosts_to_delete: ['test-1.example.test']
         tripleo_ipa_keytab: "/etc/novajoin/krb5.keytab"
diff --git a/tripleo_ipa/molecule/deregister/molecule.yml b/tripleo_ipa/molecule/deregister/molecule.yml
index a77ae8f..0909b45 100644
--- a/tripleo_ipa/molecule/deregister/molecule.yml
+++ b/tripleo_ipa/molecule/deregister/molecule.yml
@@ -5,9 +5,11 @@ driver:
 log: true
 
 platforms:
-  - name: centos7
+  - name: centos8
     hostname: test-0.example.test
-    image: centos:7
+    image: centos/centos:centos8
+    registry:
+      url: quay.io
     security_opts:
       - seccomp=unconfined
     command: /sbin/init
@@ -16,10 +18,9 @@ platforms:
       - /tmp
     volumes:
       - /sys/fs/cgroup:/sys/fs/cgroup:ro
+      - /etc/pki/rpm-gpg:/etc/pki/rpm-gpg
     dockerfile: Dockerfile
     network_mode: host
-    easy_install:
-      - pip
     environment: &env
       http_proxy: "{{ lookup('env', 'http_proxy') }}"
       https_proxy: "{{ lookup('env', 'https_proxy') }}"
@@ -32,6 +33,12 @@ provisioner:
     ANSIBLE_ROLES_PATH: "${ANSIBLE_ROLES_PATH:-/usr/share/ansible/roles}:${HOME}/zuul-jobs/roles"
     ANSIBLE_LIBRARY: "${ANSIBLE_LIBRARY:-/usr/share/ansible/plugins/modules}"
     ANSIBLE_FILTER_PLUGINS: "${ANSIBLE_FILTER_PLUGINS:-/usr/share/ansible/plugins/filter}"
+  inventory:
+    hosts:
+      all:
+        hosts:
+          centos8:
+            ansible_python_interpreter: /usr/bin/python3
 
 scenario:
   test_sequence:
diff --git a/tripleo_ipa/playbooks/undercloud-ipa-install.yaml b/tripleo_ipa/playbooks/undercloud-ipa-install.yaml
index d6b09bf..40076a4 100644
--- a/tripleo_ipa/playbooks/undercloud-ipa-install.yaml
+++ b/tripleo_ipa/playbooks/undercloud-ipa-install.yaml
@@ -73,7 +73,7 @@
         ipaadmin_password: "{{ ipa_server_password }}"
         ansible_user: "{{ undercloud_ansible_user }}"
         ansible_ssh_extra_args: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
-      no_log: True
+      no_log: true
 
     - name: Add host to ipaservers group
       add_host:
@@ -110,7 +110,7 @@
         stdin: "{{ ipa_server_password }}"
       register: kinit
       changed_when: kinit.rc == 0
-      no_log: True
+      no_log: true
 
     - name: setup the undercloud and get keytab
       include_role:
diff --git a/tripleo_ipa/tests/test.yml b/tripleo_ipa/tests/test.yml
index 6e3f673..df5fc40 100644
--- a/tripleo_ipa/tests/test.yml
+++ b/tripleo_ipa/tests/test.yml
@@ -2,4 +2,4 @@
 - hosts: localhost
   remote_user: root
   roles:
-    - tripleo_ipa
\ No newline at end of file
+    - tripleo_ipa
diff --git a/zuul.d/playbooks/pre.yml b/zuul.d/playbooks/pre.yml
index 8741271..861187f 100644
--- a/zuul.d/playbooks/pre.yml
+++ b/zuul.d/playbooks/pre.yml
@@ -15,6 +15,12 @@
       include_role:
         name: ensure-pip
 
+    - name: Ensure a recent version of pip is installed in virtualenv
+      pip:
+        name: "pip>=19.1.1"
+        virtualenv: "{{ ansible_user_dir }}/test-python"
+        virtualenv_command: "{{ ensure_pip_virtualenv_command }}"
+
     - name: Setup test-python
       pip:
         requirements: "{{ tripleo_ipa_project_path }}/molecule-requirements.txt"