diff --git a/.github/workflows/ansible-test.yml b/.github/workflows/ansible-test.yml
index 24929098d13759346c3e76b1dde937c8ff18c73f..1aecc615001b2de30759742b7c7eeeb119621fb2 100644
--- a/.github/workflows/ansible-test.yml
+++ b/.github/workflows/ansible-test.yml
@@ -8,7 +8,7 @@ jobs:
     name: Verify ansible-test sanity
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v3.1.0
+      - uses: actions/checkout@v4.1.1
         with:
           fetch-depth: 0
       - name: Run ansible-test
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index c5f1719ba0fd324dc172e980ce484e13955f2bf1..f509046c7268244b6a062c9412ed2113047f38dc 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -8,10 +8,10 @@ jobs:
     name: Check Ansible Documentation with ansible-core 2.13.
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v3.1.0
+      - uses: actions/checkout@v4.1.1
         with:
-          fetch-depth: 0
-      - uses: actions/setup-python@v4.3.0
+          fetch-depth: 1
+      - uses: actions/setup-python@v5.1.0
         with:
           python-version: '3.x'
       - name: Install Ansible 2.13
@@ -25,10 +25,10 @@ jobs:
     name: Check Ansible Documentation with ansible-core 2.14.
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v3.1.0
+      - uses: actions/checkout@v4.1.1
         with:
-          fetch-depth: 0
-      - uses: actions/setup-python@v4.3.0
+          fetch-depth: 1
+      - uses: actions/setup-python@v5.1.0
         with:
           python-version: '3.x'
       - name: Install Ansible 2.14
@@ -42,10 +42,10 @@ jobs:
     name: Check Ansible Documentation with ansible-core 2.15.
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v3.1.0
+      - uses: actions/checkout@v4.1.1
         with:
-          fetch-depth: 0
-      - uses: actions/setup-python@v4.3.0
+          fetch-depth: 1
+      - uses: actions/setup-python@v5.1.0
         with:
           python-version: '3.x'
       - name: Install Ansible 2.15
@@ -59,10 +59,10 @@ jobs:
     name: Check Ansible Documentation with latest Ansible version.
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v3.1.0
+      - uses: actions/checkout@v4.1.1
         with:
-          fetch-depth: 0
-      - uses: actions/setup-python@v4.3.0
+          fetch-depth: 1
+      - uses: actions/setup-python@v5.1.0
         with:
           python-version: '3.x'
       - name: Install Ansible-latest
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 849d9a1d532645a93933ef426ab8f5a869a10357..cec6196cd2596c7028c1c66c3a1f4986339c1d86 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -8,15 +8,15 @@ jobs:
     name: Verify ansible-lint
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v3.1.0
+      - uses: actions/checkout@v4.1.1
         with:
           fetch-depth: 0
-      - uses: actions/setup-python@v4.3.0
+      - uses: actions/setup-python@v5.1.0
         with:
           python-version: "3.x"
       - name: Run ansible-lint
         run: |
-          pip install "ansible-core>=2.16,<2.17" 'ansible-lint>=6.22'
+          pip install "ansible-core>=2.16,<2.17" 'ansible-lint==6.22'
           utils/build-galaxy-release.sh -ki
           cd .galaxy-build
           ansible-lint --profile production --exclude tests/integration/ --exclude tests/unit/ --parseable --nocolor
@@ -25,10 +25,10 @@ jobs:
     name: Verify yamllint
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v3.1.0
+      - uses: actions/checkout@v4.1.1
         with:
-          fetch-depth: 0
-      - uses: actions/setup-python@v4.3.0
+          fetch-depth: 1
+      - uses: actions/setup-python@v5.1.0
         with:
           python-version: "3.x"
       - name: Run yaml-lint
@@ -38,10 +38,10 @@ jobs:
     name: Verify pydocstyle
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v3.1.0
+      - uses: actions/checkout@v4.1.1
         with:
-          fetch-depth: 0
-      - uses: actions/setup-python@v4.3.0
+          fetch-depth: 1
+      - uses: actions/setup-python@v5.1.0
         with:
           python-version: "3.x"
       - name: Run pydocstyle
@@ -53,10 +53,10 @@ jobs:
     name: Verify flake8
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v3.1.0
+      - uses: actions/checkout@v4.1.1
         with:
-          fetch-depth: 0
-      - uses: actions/setup-python@v4.3.0
+          fetch-depth: 1
+      - uses: actions/setup-python@v5.1.0
         with:
           python-version: "3.x"
       - name: Run flake8
@@ -68,10 +68,10 @@ jobs:
     name: Verify pylint
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v3.1.0
+      - uses: actions/checkout@v4.1.1
         with:
-          fetch-depth: 0
-      - uses: actions/setup-python@v4.3.0
+          fetch-depth: 1
+      - uses: actions/setup-python@v5.1.0
         with:
           python-version: "3.x"
       - name: Run pylint
@@ -83,8 +83,8 @@ jobs:
     name: Shellcheck
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v3.1.0
+      - uses: actions/checkout@v4.1.1
         with:
-          fetch-depth: 0
+          fetch-depth: 1
       - name: Run ShellCheck
         uses: ludeeus/action-shellcheck@master
diff --git a/.github/workflows/readme.yml b/.github/workflows/readme.yml
index edea5b9fe1514dc60d8f3f86496b16a435ce5406..5f821f6722293c43c71d7931ed734433281b44b2 100644
--- a/.github/workflows/readme.yml
+++ b/.github/workflows/readme.yml
@@ -8,9 +8,9 @@ jobs:
     name: Verify readme
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v3.1.0
+      - uses: actions/checkout@v4.1.1
         with:
-          fetch-depth: 0
+          fetch-depth: 1
       - name: Run readme test
         run: |
           error=0
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 323b56ea45a0a4fa43ca46333f50bd9174104e4c..82bfbcd71f9c656615d61a576c1553e5876354c6 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,7 +1,7 @@
 ---
 repos:
 - repo: https://github.com/ansible/ansible-lint.git
-  rev: v6.22.0
+  rev: v24.5.0
   hooks:
   - id: ansible-lint
     always_run: false
@@ -21,20 +21,20 @@ repos:
           --parseable
           --nocolor
 - repo: https://github.com/adrienverge/yamllint.git
-  rev: v1.32.0
+  rev: v1.35.1
   hooks:
   - id: yamllint
     files: \.(yaml|yml)$
 - repo: https://github.com/pycqa/flake8
-  rev: 6.0.0
+  rev: 7.0.0
   hooks:
   - id: flake8
 - repo: https://github.com/pycqa/pydocstyle
-  rev: 6.0.0
+  rev: 6.3.0
   hooks:
   - id: pydocstyle
 - repo: https://github.com/pycqa/pylint
-  rev: v3.0.2
+  rev: v3.2.2
   hooks:
   - id: pylint
     args:
diff --git a/plugins/module_utils/ansible_freeipa_module.py b/plugins/module_utils/ansible_freeipa_module.py
index 6938f0db11e9acb0eaf0afd97f68e0d823a7e207..2f0ebff6ef9e4555dd10561b2ef1f43487d4b2d6 100644
--- a/plugins/module_utils/ansible_freeipa_module.py
+++ b/plugins/module_utils/ansible_freeipa_module.py
@@ -499,7 +499,10 @@ def module_params_get(module, name, allow_empty_list_item=False):
     # Ansible issue https://github.com/ansible/ansible/issues/77108
     if isinstance(value, list):
         for val in value:
-            if isinstance(val, (str, unicode)) and not val:
+            if (
+                isinstance(val, (str, unicode))  # pylint: disable=W0012,E0606
+                and not val
+            ):
                 if not allow_empty_list_item:
                     module.fail_json(
                         msg="Parameter '%s' contains an empty string" %
diff --git a/plugins/modules/ipaautomember.py b/plugins/modules/ipaautomember.py
index 027140100e1293bb85dd6178fc7e1436175cf3d7..eb5dec19ca7a9f7ebbeb6a6be805c7581708ab73 100644
--- a/plugins/modules/ipaautomember.py
+++ b/plugins/modules/ipaautomember.py
@@ -450,6 +450,10 @@ def main():
         commands = []
 
         for name in names:
+            _type = None
+            inclusive_add, inclusive_del = [], []
+            exclusive_add, exclusive_del = [], []
+
             # Make sure automember rule exists
             res_find = find_automember(ansible_module, name, automember_type)
 
@@ -495,16 +499,12 @@ def main():
                             transform_conditions(inclusive),
                             res_find.get("automemberinclusiveregex", [])
                         )
-                    else:
-                        inclusive_add, inclusive_del = [], []
 
                     if exclusive is not None:
                         exclusive_add, exclusive_del = gen_add_del_lists(
                             transform_conditions(exclusive),
                             res_find.get("automemberexclusiveregex", [])
                         )
-                    else:
-                        exclusive_add, exclusive_del = [], []
 
                 elif action == "member":
                     if res_find is None:
@@ -512,9 +512,7 @@ def main():
                             msg="No automember '%s'" % name)
 
                     inclusive_add = transform_conditions(inclusive or [])
-                    inclusive_del = []
                     exclusive_add = transform_conditions(exclusive or [])
-                    exclusive_del = []
 
                 for _inclusive in inclusive_add:
                     key, regex = _inclusive.split("=", 1)
diff --git a/plugins/modules/ipadnsforwardzone.py b/plugins/modules/ipadnsforwardzone.py
index 93a31f5ec0eb70e247868f3eb381cffd1f7a520d..1397934eef5761f967d602b4b255f21ee8fd4f40 100644
--- a/plugins/modules/ipadnsforwardzone.py
+++ b/plugins/modules/ipadnsforwardzone.py
@@ -250,6 +250,8 @@ def main():
         operation = "add"
 
     invalid = []
+    wants_enable = False
+
     if state in ["enabled", "disabled"]:
         if action == "member":
             ansible_module.fail_json(
diff --git a/plugins/modules/ipadnsrecord.py b/plugins/modules/ipadnsrecord.py
index f027791c8aeac917a12c65ceda8ef4ae96020eae..c8559c49eb1b328dd032630948ce88a13977b45e 100644
--- a/plugins/modules/ipadnsrecord.py
+++ b/plugins/modules/ipadnsrecord.py
@@ -1605,6 +1605,8 @@ def main():
 
             res_find = find_dnsrecord(ansible_module, zone_name, name)
 
+            cmds = []
+
             if state == 'present':
                 cmds = define_commands_for_present_state(
                     ansible_module, zone_name, entry, res_find)
diff --git a/plugins/modules/ipagroup.py b/plugins/modules/ipagroup.py
index 425be7810f03a7bdfaab8494e68d1f01d306e42a..09e90e09312bd09b582fbfece0c4b64e0a8054f8 100644
--- a/plugins/modules/ipagroup.py
+++ b/plugins/modules/ipagroup.py
@@ -663,7 +663,11 @@ def main():
 
                 check_parameters(ansible_module, state, action)
 
-            elif isinstance(group_name, (str, unicode)):
+            elif (
+                isinstance(
+                    group_name, (str, unicode)  # pylint: disable=W0012,E0606
+                )
+            ):
                 name = group_name
             else:
                 ansible_module.fail_json(msg="Group '%s' is not valid" %
diff --git a/plugins/modules/ipahost.py b/plugins/modules/ipahost.py
index 3e6c3327e6221333aa10af4db188dac1c6c7b8b0..6600d81d09bfae47defc69c87545221a0f846551 100644
--- a/plugins/modules/ipahost.py
+++ b/plugins/modules/ipahost.py
@@ -988,7 +988,9 @@ def main():
                     sshpubkey = [str(normalize_sshpubkey(key)) for
                                  key in sshpubkey]
 
-            elif isinstance(host, (str, unicode)):
+            elif (
+                isinstance(host, (str, unicode))  # pylint: disable=W0012,E0606
+            ):
                 name = host
             else:
                 ansible_module.fail_json(msg="Host '%s' is not valid" %
diff --git a/plugins/modules/iparole.py b/plugins/modules/iparole.py
index 2e876268026e9ae11e8a6eda293cc166cd4bd504..ba77db9ac66a0d27b07285f1d788176e3b81ef2d 100644
--- a/plugins/modules/iparole.py
+++ b/plugins/modules/iparole.py
@@ -293,7 +293,7 @@ def result_get_value_lowercase(res_find, key, default=None):
     if existing is not None:
         if isinstance(existing, (list, tuple)):
             existing = [to_text(item).lower() for item in existing]
-        if isinstance(existing, (str, unicode)):
+        if isinstance(existing, (str, unicode)):  # pylint: disable=W0012,E0606
             existing = existing.lower()
     else:
         existing = default
diff --git a/plugins/modules/ipaservice.py b/plugins/modules/ipaservice.py
index c6719a9872eb05a59c2716a42612b419ca398244..6a2e5eb7ad18b36cf59a258c3ce9950fceb58766 100644
--- a/plugins/modules/ipaservice.py
+++ b/plugins/modules/ipaservice.py
@@ -693,7 +693,11 @@ def main():
 
                 delete_continue = service.get("delete_continue")
 
-            elif isinstance(service, (str, unicode)):
+            elif (
+                isinstance(
+                    service, (str, unicode)  # pylint: disable=W0012,E0606
+                )
+            ):
                 name = service
             else:
                 ansible_module.fail_json(msg="Service '%s' is not valid" %
diff --git a/plugins/modules/ipauser.py b/plugins/modules/ipauser.py
index 73693667052d224655768fe8dddcb331861c8c19..36372c4adeb2bfeb8e2e6fbc33792eedf68b5709 100644
--- a/plugins/modules/ipauser.py
+++ b/plugins/modules/ipauser.py
@@ -1382,7 +1382,11 @@ def main():
 
                 email = extend_emails(email, default_email_domain)
 
-            elif isinstance(user, (str, unicode)):
+            elif (
+                isinstance(
+                    user, (str, unicode)  # pylint: disable=W0012,E0606
+                )
+            ):
                 name = user
             else:
                 ansible_module.fail_json(msg="User '%s' is not valid" %
diff --git a/requirements-dev.txt b/requirements-dev.txt
index 5df0f4335a6bcee4a7f89cba25ed7f1b8f320853..08e3366214b64501c73864714af15f89fc92060d 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -1,10 +1,10 @@
 -r requirements-tests.txt
 ipdb==0.13.4
 pre-commit==2.20.0
-flake8==6.0.0
+flake8==7.0.0
 flake8-bugbear
-pylint==2.17.2
+pylint>=3.2
 wrapt==1.14.1
 pydocstyle==6.3.0
-yamllint==1.32.0
-ansible-lint >= 6.22
+yamllint==1.35.1
+ansible-lint>=24.5.0
diff --git a/roles/ipareplica/library/ipareplica_add_to_ipaservers.py b/roles/ipareplica/library/ipareplica_add_to_ipaservers.py
index 66c1615b1768eb3eef7379f48b82aa618e1e1a42..4056f705dd8e0f9e234bebfe6402c7b8fd1cf25a 100644
--- a/roles/ipareplica/library/ipareplica_add_to_ipaservers.py
+++ b/roles/ipareplica/library/ipareplica_add_to_ipaservers.py
@@ -139,7 +139,7 @@ def main():
         conn.connect(ccache=installer._ccache)
         remote_api.Command['hostgroup_add_member'](
             u'ipaservers',
-            host=[unicode(api.env.host)],
+            host=[unicode(api.env.host)],  # pylint: disable=W0012,E0606
         )
     finally:
         if conn.isconnected():
diff --git a/roles/ipareplica/library/ipareplica_prepare.py b/roles/ipareplica/library/ipareplica_prepare.py
index 962432407259695bca239fb4e1bcc65bc3a0d734..63f1dcbdc97a74f1319d73dcfac045e351d82cff 100644
--- a/roles/ipareplica/library/ipareplica_prepare.py
+++ b/roles/ipareplica/library/ipareplica_prepare.py
@@ -658,7 +658,7 @@ def main():
         # Check authorization
         result = remote_api.Command['hostgroup_find'](
             cn=u'ipaservers',
-            host=[unicode(api.env.host)]
+            host=[unicode(api.env.host)]  # pylint: disable=W0012,E0606
         )['result']
         add_to_ipaservers = not result