diff --git a/roles/ipaserver/README.md b/roles/ipaserver/README.md
index 130be07c7b34f3bdcc837564cc85199690e5dcae..b5dd9e625f638685b7071f0aadb8a1befbe7cf86 100644
--- a/roles/ipaserver/README.md
+++ b/roles/ipaserver/README.md
@@ -168,6 +168,22 @@ Server installation step 2: Copy `<ipaserver hostname>-chain.crt` to the IPA ser
 
 The files can also be copied automatically: Set `ipaserver_copy_csr_to_controller` to true in the server installation step 1 and set `ipaserver_external_cert_files_from_controller` to point to the `chain.crt` file in the server installation step 2.
 
+Since version 4.10, FreeIPA supports creating certificates using random serial numbers. Random serial numbers is a global and permanent setting, that can only be activated while deploying the first server of the domain. Replicas will inherit this setting automatically. An example of an inventory file to deploy a server with random serial numbers enabled is:
+
+```ini
+[ipaserver]
+ipaserver.example.com
+
+[ipaserver:vars]
+ipaserver_domain=example.com
+ipaserver_realm=EXAMPLE.COM
+ipaadmin_password=MySecretPassword123
+ipadm_password=MySecretPassword234
+ipaserver_random_serial_number=true
+```
+
+By setting the variable in the inventory file, the same ipaserver deployment playbook, shown before, can be used.
+
 
 Example inventory file to remove a server from the domain:
 
@@ -263,6 +279,7 @@ Variable | Description | Required
 `ipaserver_no_ui_redirect` | Do not automatically redirect to the Web UI. (bool) | no
 `ipaserver_dirsrv_config_file` | The path to LDIF file that will be used to modify configuration of dse.ldif during installation. (string) | no
 `ipaserver_pki_config_override` | Path to ini file with config overrides. This is only usable with recent FreeIPA versions. (string) | no
+`ipaserver_random_serial_numbers` | Enable use of random serial numbers for certificates. Requires FreeIPA version 4.10 or later. (boolean) | no
 
 SSL certificate Variables
 -------------------------
diff --git a/roles/ipaserver/defaults/main.yml b/roles/ipaserver/defaults/main.yml
index 5af85c2d4473a387991fc02d673651e8b4a91f78..0acecc574fb8e7190633b4254c0598fe93bccfcf 100644
--- a/roles/ipaserver/defaults/main.yml
+++ b/roles/ipaserver/defaults/main.yml
@@ -11,6 +11,7 @@ ipaserver_no_hbac_allow: no
 ipaserver_no_pkinit: no
 ipaserver_no_ui_redirect: no
 ipaserver_mem_check: yes
+ipaserver_random_serial_numbers: true
 ### ssl certificate ###
 ### client ###
 ipaclient_mkhomedir: no
diff --git a/roles/ipaserver/library/ipaserver_test.py b/roles/ipaserver/library/ipaserver_test.py
index cf5b7c8f0f7f3eb3ee56bda383ae162ef41cefd2..45f65a2be1b4bec3eae8d76ff7f13615e05e79d3 100644
--- a/roles/ipaserver/library/ipaserver_test.py
+++ b/roles/ipaserver/library/ipaserver_test.py
@@ -208,6 +208,10 @@ options:
     description: The installer ca_subject setting
     type: str
     required: no
+  random_serial_numbers:
+    description: The installer random_serial_numbers setting
+    type: bool
+    required: no
   allow_zone_overlap:
     description: Create DNS zone even if it already exists
     type: bool
@@ -304,7 +308,7 @@ from ansible.module_utils.ansible_ipa_server import (
     check_dirsrv, ScriptError, get_fqdn, verify_fqdn, BadHostError,
     validate_domain_name, load_pkcs12, IPA_PYTHON_VERSION,
     encode_certificate, check_available_memory, getargspec, adtrustinstance,
-    get_min_idstart
+    get_min_idstart, SerialNumber
 )
 from ansible.module_utils import six
 
@@ -369,6 +373,8 @@ def main():
                                      elements='str', default=None),
             subject_base=dict(required=False, type='str'),
             ca_subject=dict(required=False, type='str'),
+            random_serial_numbers=dict(required=False, type='bool',
+                                       default=False),
             # ca_signing_algorithm
             # dns
             allow_zone_overlap=dict(required=False, type='bool',
@@ -456,6 +462,8 @@ def main():
         'external_cert_files')
     options.subject_base = ansible_module.params.get('subject_base')
     options.ca_subject = ansible_module.params.get('ca_subject')
+    options._random_serial_numbers = ansible_module.params.get(
+        'random_serial_numbers')
     # ca_signing_algorithm
     # dns
     options.allow_zone_overlap = ansible_module.params.get(
@@ -513,6 +521,12 @@ def main():
                 ansible_module.fail_json(
                     msg="pki_config_override: %s" % str(e))
 
+    # Check if Random Serial Numbers v3 is available
+    if options._random_serial_numbers and SerialNumber is None:
+        ansible_module.fail_json(
+            msg="Random Serial Numbers is not supported for this IPA version"
+        )
+
     # default values ########################################################
 
     # idstart and idmax
@@ -1147,42 +1161,45 @@ def main():
         pkinit_pkcs12_info = ("/etc/ipa/.tmp_pkcs12_pkinit", pkinit_pin)
         pkinit_ca_cert = encode_certificate(pkinit_ca_cert)
 
-    ansible_module.exit_json(changed=False,
-                             ipa_python_version=IPA_PYTHON_VERSION,
-                             # basic
-                             domain=options.domain_name,
-                             realm=realm_name,
-                             hostname=host_name,
-                             _hostname_overridden=bool(options.host_name),
-                             no_host_dns=options.no_host_dns,
-                             # server
-                             setup_adtrust=options.setup_adtrust,
-                             setup_kra=options.setup_kra,
-                             setup_ca=options.setup_ca,
-                             idstart=options.idstart,
-                             idmax=options.idmax,
-                             no_pkinit=options.no_pkinit,
-                             # ssl certificate
-                             _dirsrv_pkcs12_info=dirsrv_pkcs12_info,
-                             _dirsrv_ca_cert=dirsrv_ca_cert,
-                             _http_pkcs12_info=http_pkcs12_info,
-                             _http_ca_cert=http_ca_cert,
-                             _pkinit_pkcs12_info=pkinit_pkcs12_info,
-                             _pkinit_ca_cert=pkinit_ca_cert,
-                             # certificate system
-                             external_ca=options.external_ca,
-                             external_ca_type=options.external_ca_type,
-                             external_ca_profile=options.external_ca_profile,
-                             # ad trust
-                             rid_base=options.rid_base,
-                             secondary_rid_base=options.secondary_rid_base,
-                             # client
-                             ntp_servers=options.ntp_servers,
-                             ntp_pool=options.ntp_pool,
-                             # additional
-                             _installation_cleanup=_installation_cleanup,
-                             domainlevel=options.domainlevel,
-                             sid_generation_always=sid_generation_always)
+    ansible_module.exit_json(
+        changed=False,
+        ipa_python_version=IPA_PYTHON_VERSION,
+        # basic
+        domain=options.domain_name,
+        realm=realm_name,
+        hostname=host_name,
+        _hostname_overridden=bool(options.host_name),
+        no_host_dns=options.no_host_dns,
+        # server
+        setup_adtrust=options.setup_adtrust,
+        setup_kra=options.setup_kra,
+        setup_ca=options.setup_ca,
+        idstart=options.idstart,
+        idmax=options.idmax,
+        no_pkinit=options.no_pkinit,
+        # ssl certificate
+        _dirsrv_pkcs12_info=dirsrv_pkcs12_info,
+        _dirsrv_ca_cert=dirsrv_ca_cert,
+        _http_pkcs12_info=http_pkcs12_info,
+        _http_ca_cert=http_ca_cert,
+        _pkinit_pkcs12_info=pkinit_pkcs12_info,
+        _pkinit_ca_cert=pkinit_ca_cert,
+        # certificate system
+        external_ca=options.external_ca,
+        external_ca_type=options.external_ca_type,
+        external_ca_profile=options.external_ca_profile,
+        # ad trust
+        rid_base=options.rid_base,
+        secondary_rid_base=options.secondary_rid_base,
+        # client
+        ntp_servers=options.ntp_servers,
+        ntp_pool=options.ntp_pool,
+        # additional
+        _installation_cleanup=_installation_cleanup,
+        domainlevel=options.domainlevel,
+        sid_generation_always=sid_generation_always,
+        random_serial_numbers=options._random_serial_numbers,
+    )
 
 
 if __name__ == '__main__':
diff --git a/roles/ipaserver/module_utils/ansible_ipa_server.py b/roles/ipaserver/module_utils/ansible_ipa_server.py
index 6dec4bc210b1a2497f3c5accefae6cf3210d477e..80e2042cc5a894db3c1d5507ecaf028f18b99090 100644
--- a/roles/ipaserver/module_utils/ansible_ipa_server.py
+++ b/roles/ipaserver/module_utils/ansible_ipa_server.py
@@ -44,7 +44,7 @@ __all__ = ["IPAChangeConf", "certmonger", "sysrestore", "root_logger",
            "check_available_memory", "getargspec", "get_min_idstart",
            "paths", "api", "ipautil", "adtrust_imported", "NUM_VERSION",
            "time_service", "kra_imported", "dsinstance", "IPA_PYTHON_VERSION",
-           "NUM_VERSION"]
+           "NUM_VERSION", "SerialNumber"]
 
 import sys
 import logging
@@ -203,6 +203,13 @@ try:
         except ImportError:
             get_min_idstart = None
 
+        # SerialNumber is defined in versions 4.10 and later and is
+        # used by Random Serian Number v3.
+        try:
+            from ipalib.parameters import SerialNumber
+        except ImportError:
+            SerialNumber = None
+
     else:
         # IPA version < 4.5
 
diff --git a/roles/ipaserver/tasks/install.yml b/roles/ipaserver/tasks/install.yml
index 50b4876f729dc6f430982939f30aca3140aca7fb..9c55c30d71a0d9e17852e93233754c2c4de1540a 100644
--- a/roles/ipaserver/tasks/install.yml
+++ b/roles/ipaserver/tasks/install.yml
@@ -108,6 +108,7 @@
     external_cert_files: "{{ ipaserver_external_cert_files | default(omit) }}"
     subject_base: "{{ ipaserver_subject_base | default(omit) }}"
     ca_subject: "{{ ipaserver_ca_subject | default(omit) }}"
+    random_serial_numbers: "{{ ipaserver_random_serial_numbers | default(omit) }}"
     # ca_signing_algorithm
     ### dns ###
     allow_zone_overlap: "{{ ipaserver_allow_zone_overlap }}"
@@ -199,7 +200,7 @@
       ### additional ###
       setup_ca: "{{ result_ipaserver_test.setup_ca }}"
       sid_generation_always: "{{ result_ipaserver_test.sid_generation_always }}"
-      random_serial_numbers: no
+      random_serial_numbers: "{{ result_ipaserver_test.random_serial_numbers }}"
       _hostname_overridden: "{{ result_ipaserver_test._hostname_overridden }}"
     register: result_ipaserver_prepare