diff --git a/tests/ca-less/certificates/pkinit/extensions.conf b/tests/ca-less/certificates/pkinit/extensions.conf
new file mode 100644
index 0000000000000000000000000000000000000000..cbff73bef1ed6cf35caf01ec8347627155983b27
--- /dev/null
+++ b/tests/ca-less/certificates/pkinit/extensions.conf
@@ -0,0 +1,20 @@
+[kdc_cert]
+basicConstraints=CA:FALSE
+keyUsage=nonRepudiation,digitalSignature,keyEncipherment,keyAgreement
+extendedKeyUsage=1.3.6.1.5.2.3.5
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+issuerAltName=issuer:copy
+subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:kdc_princ_name
+
+[kdc_princ_name]
+realm=EXP:0,GeneralString:${ENV::REALM}
+principal_name=EXP:1,SEQUENCE:kdc_principal_seq
+
+[kdc_principal_seq]
+name_type=EXP:0,INTEGER:1
+name_string=EXP:1,SEQUENCE:kdc_principals
+
+[kdc_principals]
+princ1=GeneralString:krbtgt
+princ2=GeneralString:${ENV::REALM}
diff --git a/tests/ca-less/clean_up_certificates.yml b/tests/ca-less/clean_up_certificates.yml
new file mode 100644
index 0000000000000000000000000000000000000000..ea8a4e8ee714efbe9dd95f792eb92d11964c6eda
--- /dev/null
+++ b/tests/ca-less/clean_up_certificates.yml
@@ -0,0 +1,15 @@
+---
+- name: Clean up certificates
+  hosts: localhost
+  gather_facts: false
+
+  tasks:
+  - name: Run generate-certificates.sh
+    command: >
+      /bin/bash
+      generate-certificates.sh delete "{{ item }}"
+    args:
+      chdir: "{{ playbook_dir }}"
+    with_items:
+      - "{{ groups.ipaserver[0] }}"
+      - "{{ groups.ipareplicas[0] }}"
\ No newline at end of file
diff --git a/tests/ca-less/generate-certificates.sh b/tests/ca-less/generate-certificates.sh
new file mode 100755
index 0000000000000000000000000000000000000000..59b12cdf6b943ebdf01813ba3c7f66e7fd44bf59
--- /dev/null
+++ b/tests/ca-less/generate-certificates.sh
@@ -0,0 +1,153 @@
+#!/usr/bin/env bash
+
+ROOT_CA_DIR="certificates/root-ca"
+DIRSRV_CERTS_DIR="certificates/dirsrv"
+HTTPD_CERTS_DIR="certificates/httpd"
+PKINIT_CERTS_DIR="certificates/pkinit"
+PKCS12_PASSWORD="SomePKCS12password"
+
+# generate_ipa_pkcs12_certificate \
+#    $cert_name $ipa_fqdn $certs_dir $root_ca_cert $root_ca_private_key extensions_file extensions_name
+function generate_ipa_pkcs12_certificate {
+
+    cert_name=$1
+    ipa_fqdn=$2
+    certs_dir=$3
+    root_ca_cert=$4
+    root_ca_private_key=$5
+    extensions_file=$6
+    extensions_name=$7
+
+    # Generate CSR and private key
+    openssl req -new -newkey rsa:4096 -nodes \
+        -subj "/C=US/ST=Test/L=Testing/O=Default/CN=${ipa_fqdn}" \
+        -keyout ${certs_dir}/private.key \
+        -out ${certs_dir}/request.csr
+
+    # Sign CSR to generate PEM certificate
+    if [ -z "${extensions_file}" ]; then
+        openssl x509 -req -days 365 -sha256 \
+            -CAcreateserial \
+            -CA ${root_ca_cert} \
+            -CAkey ${root_ca_private_key} \
+            -in ${certs_dir}/request.csr \
+            -out ${certs_dir}/cert.pem
+    else
+        openssl x509 -req -days 365 -sha256 \
+            -CAcreateserial \
+            -CA ${ROOT_CA_DIR}/cert.pem \
+            -CAkey ${ROOT_CA_DIR}/private.key \
+            -extfile ${extensions_file} \
+            -extensions ${extensions_name} \
+            -in ${certs_dir}/request.csr \
+            -out ${certs_dir}/cert.pem
+    fi
+
+    # Convert certificate to PKCS12 format
+    openssl pkcs12 -export \
+        -name ${cert_name} \
+        -certfile ${root_ca_cert} \
+        -in ${certs_dir}/cert.pem \
+        -inkey ${certs_dir}/private.key \
+        -passout "pass:${PKCS12_PASSWORD}" \
+        -out ${certs_dir}/cert.p12
+}
+
+# generate_ipa_pkcs12_certificates $ipa_fqdn $ipa_domain
+function generate_ipa_pkcs12_certificates {
+
+    host=$1
+    if [ -z "$host" ]; then
+        echo "ERROR: ipa-host-fqdn is not set"
+        echo
+        echo "usage: $0 create ipa-host-fqdn domain"
+        exit 0;
+    fi
+
+    domain=$2
+    if [ -z "$domain" ]; then
+        echo "ERROR: domain is not set"
+        echo
+        echo "usage: $0 create ipa-host-fqdn domain"
+        exit 0;
+    fi
+
+    # Generate certificates folder structure
+    mkdir -p ${ROOT_CA_DIR}
+    mkdir -p ${DIRSRV_CERTS_DIR}/$host
+    mkdir -p ${HTTPD_CERTS_DIR}/$host
+    mkdir -p ${PKINIT_CERTS_DIR}/$host
+
+    # Generate root CA
+    if [ ! -f "${ROOT_CA_DIR}/private.key" ]; then
+        openssl genrsa \
+                -out ${ROOT_CA_DIR}/private.key 4096
+
+        openssl req -new -x509 -sha256 -nodes -days 3650 \
+                -subj "/C=US/ST=Test/L=Testing/O=Default" \
+                -key ${ROOT_CA_DIR}/private.key \
+                -out ${ROOT_CA_DIR}/cert.pem
+    fi
+
+    # Generate a certificate for the Directory Server
+    if [ ! -f "${DIRSRV_CERTS_DIR}/$host/cert.pem" ]; then
+        generate_ipa_pkcs12_certificate \
+            "dirsrv-cert" \
+            $host \
+            "${DIRSRV_CERTS_DIR}/$host" \
+            "${ROOT_CA_DIR}/cert.pem" \
+            "${ROOT_CA_DIR}/private.key"
+    fi
+
+    # Generate a certificate for the Apache server
+    if [ ! -f "${HTTPD_CERTS_DIR}/$host/cert.pem" ]; then
+        generate_ipa_pkcs12_certificate \
+            "httpd-cert" \
+            $host \
+            "${HTTPD_CERTS_DIR}/$host" \
+            "${ROOT_CA_DIR}/cert.pem" \
+            "${ROOT_CA_DIR}/private.key"
+    fi
+
+    # Generate a certificate for the KDC PKINIT
+    if [ ! -f "${PKINIT_CERTS_DIR}/$host/cert.pem" ]; then
+        export REALM=${domain^^}
+
+        generate_ipa_pkcs12_certificate \
+            "pkinit-cert" \
+            $host \
+            "${PKINIT_CERTS_DIR}/$host" \
+            "${ROOT_CA_DIR}/cert.pem" \
+            "${ROOT_CA_DIR}/private.key" \
+            "${PKINIT_CERTS_DIR}/extensions.conf" \
+            "kdc_cert"
+    fi
+}
+
+# delete_ipa_pkcs12_certificates $ipa_fqdn
+function delete_ipa_pkcs12_certificates {
+
+    host=$1
+    if [ -z "$host" ]; then
+        echo "ERROR: ipa-host-fqdn is not set"
+        echo
+        echo "usage: $0 delete ipa-host-fqdn"
+        exit 0;
+    fi
+
+    rm -f certificates/*/$host/*
+    rm -f ${ROOT_CA_DIR}/*
+}
+
+# Entrypoint
+case "$1" in
+  create)
+    generate_ipa_pkcs12_certificates $2 $3
+    ;;
+  delete)
+    delete_ipa_pkcs12_certificates $2
+    ;;
+  *)
+    echo $"Usage: $0 {create|delete}"
+    ;;
+esac
\ No newline at end of file
diff --git a/tests/ca-less/install_replica_without_ca.yml b/tests/ca-less/install_replica_without_ca.yml
new file mode 100644
index 0000000000000000000000000000000000000000..40493a6e2110340466e49381390e3e1b1c8025bc
--- /dev/null
+++ b/tests/ca-less/install_replica_without_ca.yml
@@ -0,0 +1,74 @@
+---
+- name: Generate certificates
+  hosts: localhost
+  gather_facts: false
+
+  tasks:
+  - name: Run generate-certificates.sh
+    command: >
+      /bin/bash
+      generate-certificates.sh create
+      "{{ groups.ipareplicas[0] }}"
+      "{{ ipareplica_domain | default(groups.ipareplicas[0].split('.')[1:] | join ('.')) }}"
+    args:
+      chdir: "{{ playbook_dir }}"
+
+- name: Test ipareplicas installation without CA
+  hosts: ipareplicas
+  become: true
+
+  vars:
+    # Root CA certificate
+    ipareplica_ca_cert_files:
+      - /root/ca-less-test/ca.crt
+    # Directory server certificates
+    ipareplica_dirsrv_cert_name: dirsrv-cert
+    ipareplica_dirsrv_cert_files:
+      - /root/ca-less-test/dirsrv.p12
+    ipareplica_dirsrv_pin: SomePKCS12password
+    # Apache certificates
+    ipareplica_http_cert_name: httpd-cert
+    ipareplica_http_cert_files:
+      - /root/ca-less-test/httpd.p12
+    ipareplica_http_pin: SomePKCS12password
+    # PKINIT configuration
+    ipareplica_no_pkinit: no
+    ipareplica_pkinit_cert_name: pkinit-cert
+    ipareplica_pkinit_cert_files:
+      - /root/ca-less-test/pkinit.p12
+    ipareplica_pkinit_pin: SomePKCS12password
+
+  pre_tasks:
+    - name: Remove "/root/ca-less-test"
+      file:
+        path: "/root/ca-less-test"
+        state: absent
+
+    - name: Generate "/root/ca-less-test"
+      file:
+        path: "/root/ca-less-test"
+        state: directory
+
+    - name: Copy CA certificate
+      copy:
+        src: "{{ playbook_dir }}/certificates/root-ca/cert.pem"
+        dest: "/root/ca-less-test/ca.crt"
+        owner: root
+        group: root
+        mode: "0644"
+
+    - name: Copy p12 certificates
+      copy:
+        src: "{{ playbook_dir }}/certificates/{{ item }}/{{ groups.ipareplicas[0] }}/cert.p12"
+        dest: "/root/ca-less-test/{{ item }}.p12"
+        owner: root
+        group: root
+        mode: "0644"
+      with_items:
+        - dirsrv
+        - httpd
+        - pkinit
+
+  roles:
+    - role: ipareplica
+      state: present
diff --git a/tests/ca-less/install_server_without_ca.yml b/tests/ca-less/install_server_without_ca.yml
new file mode 100644
index 0000000000000000000000000000000000000000..ecb609c4fd17593e0352a5b2c37c28465266e394
--- /dev/null
+++ b/tests/ca-less/install_server_without_ca.yml
@@ -0,0 +1,74 @@
+---
+- name: Generate certificates
+  hosts: localhost
+  gather_facts: false
+
+  tasks:
+  - name: Run generate-certificates.sh
+    command: >
+      /bin/bash
+      generate-certificates.sh create
+      "{{ groups.ipaserver[0] }}"
+      "{{ ipaserver_domain | default(groups.ipaserver[0].split('.')[1:] | join ('.')) }}"
+    args:
+      chdir: "{{ playbook_dir }}"
+
+- name: Test ipaserver installation without CA
+  hosts: ipaserver
+  become: true
+
+  vars:
+    # Root CA certificate
+    ipaserver_ca_cert_files:
+      - /root/ca-less-test/ca.crt
+    # Directory server certificates
+    ipaserver_dirsrv_cert_name: dirsrv-cert
+    ipaserver_dirsrv_cert_files:
+      - /root/ca-less-test/dirsrv.p12
+    ipaserver_dirsrv_pin: SomePKCS12password
+    # Apache certificates
+    ipaserver_http_cert_name: httpd-cert
+    ipaserver_http_cert_files:
+      - /root/ca-less-test/httpd.p12
+    ipaserver_http_pin: SomePKCS12password
+    # PKINIT configuration
+    ipaserver_no_pkinit: no
+    ipaserver_pkinit_cert_name: pkinit-cert
+    ipaserver_pkinit_cert_files:
+      - /root/ca-less-test/pkinit.p12
+    ipaserver_pkinit_pin: SomePKCS12password
+
+  pre_tasks:
+    - name: Remove "/root/ca-less-test"
+      file:
+        path: "/root/ca-less-test"
+        state: absent
+
+    - name: Generate "/root/ca-less-test"
+      file:
+        path: "/root/ca-less-test"
+        state: directory
+
+    - name: Copy CA certificate
+      copy:
+        src: "{{ playbook_dir }}/certificates/root-ca/cert.pem"
+        dest: "/root/ca-less-test/ca.crt"
+        owner: root
+        group: root
+        mode: "0644"
+
+    - name: Copy p12 certificates
+      copy:
+        src: "{{ playbook_dir }}/certificates/{{ item }}/{{ groups.ipaserver[0] }}/cert.p12"
+        dest: "/root/ca-less-test/{{ item }}.p12"
+        owner: root
+        group: root
+        mode: "0644"
+      with_items:
+        - dirsrv
+        - httpd
+        - pkinit
+
+  roles:
+    - role: ipaserver
+      state: present
diff --git a/tests/ca-less/inventory b/tests/ca-less/inventory
new file mode 100644
index 0000000000000000000000000000000000000000..ec5da4ef66fe5601863f805f0fbf32bea9c6b999
--- /dev/null
+++ b/tests/ca-less/inventory
@@ -0,0 +1,17 @@
+[ipaserver]
+ipaserver.test.local
+
+[ipaserver:vars]
+ipaserver_domain=test.local
+ipaserver_realm=TEST.LOCAL
+ipaadmin_password=SomeADMINpassword
+ipadm_password=SomeDMpassword
+
+[ipareplicas]
+ipareplica.test.local
+
+[ipareplicas:vars]
+ipareplica_domain=test.local
+ipareplica_realm=TEST.LOCAL
+ipaadmin_password=SomeADMINpassword
+ipadm_password=SomeDMpassword
\ No newline at end of file