diff --git a/README-group.md b/README-group.md
index c3477f72eae2ad31106605f0f2c4381f619cfed0..529553c544ceb689d90dc125b3e29d6a84a5d492 100644
--- a/README-group.md
+++ b/README-group.md
@@ -130,6 +130,45 @@ And ensure the presence of the groups with this example playbook:
       groups: "{{ groups }}"
 ```
 
+Example playbook to rename a group:
+
+```yaml
+---
+- name: Playbook to rename a single group
+  hosts: ipaserver
+  become: false
+  gather_facts: false
+
+  tasks:
+  - name: Rename group appops to webops
+    ipagroup:
+      ipaadmin_password: SomeADMINpassword
+      name: appops
+      rename: webops
+      state: renamed
+```
+
+Several groups can also be renamed with a single task, as in the example playbook:
+
+```yaml
+---
+- name: Playbook to rename multiple groups
+  hosts: ipaserver
+  become: false
+  gather_facts: false
+
+  tasks:
+  - name Rename group1 to newgroup1 and group2 to newgroup2
+    ipagroup:
+      ipaadmin_password: SomeADMINpassword
+      groups:
+      - name: group1
+        rename: newgroup1
+      - name: group2
+        rename: newgroup2
+      state: renamed
+```
+
 Example playbook to add users to a group:
 
 ```yaml
@@ -262,11 +301,13 @@ Variable | Description | Required
 `membermanager_group` | List of member manager groups assigned to this group. Only usable with IPA versions 4.8.4 and up. | no
 `externalmember` \| `ipaexternalmember`  \| `external_member`| List of members of a trusted domain in DOM\\name or name@domain form. | no
 `idoverrideuser` | List of user ID overrides to manage. Only usable with IPA versions 4.8.7 and up.| no
+`rename` \| `new_name` | Rename the user object to the new name string. Only usable with `state: renamed`. | no
 `action` | Work on group or member level. It can be on of `member` or `group` and defaults to `group`. | no
-`state` | The state to ensure. It can be one of `present` or `absent`, default: `present`. | yes
+`state` | The state to ensure. It can be one of `present`, `absent` or `renamed`, default: `present`. | yes
 
 
 Authors
 =======
 
-Thomas Woerner
+- Thomas Woerner
+- Rafael Jeffman
diff --git a/plugins/modules/ipagroup.py b/plugins/modules/ipagroup.py
index b80061663c68f87c444aed07b7892894d01328d4..70d85cb8334e37811a3f7ea33cf6793ed909c6c8 100644
--- a/plugins/modules/ipagroup.py
+++ b/plugins/modules/ipagroup.py
@@ -123,6 +123,11 @@ options:
         required: false
         type: list
         elements: str
+      rename:
+        description: Rename the group object
+        required: false
+        type: str
+        aliases: ["new_name"]
   description:
     description: The group description
     type: str
@@ -198,11 +203,16 @@ options:
     type: str
     default: group
     choices: ["member", "group"]
+  rename:
+    description: Rename the group object
+    required: false
+    type: str
+    aliases: ["new_name"]
   state:
     description: State to ensure
     type: str
     default: present
-    choices: ["present", "absent"]
+    choices: ["present", "absent", "renamed"]
 author:
   - Thomas Woerner (@t-woerner)
 """
@@ -267,6 +277,13 @@ EXAMPLES = """
       group:
         - group2
 
+# Rename a group
+- ipagroup:
+    ipaadmin_password: SomeADMINpassword
+    name: oldname
+    rename: newestname
+    state: renamed
+
 # Create a non-POSIX group
 - ipagroup:
     ipaadmin_password: SomeADMINpassword
@@ -380,18 +397,20 @@ def gen_member_args(user, group, service, externalmember, idoverrideuser):
 
 
 def check_parameters(module, state, action):
-    invalid = []
-    if state == "present":
+    invalid = ["description", "gid", "posix", "nonposix", "external",
+               "nomembers"]
+    if action == "group":
+        if state == "present":
+            invalid = []
+        elif state == "absent":
+            invalid.extend(["user", "group", "service", "externalmember"])
+    if state == "renamed":
         if action == "member":
-            invalid = ["description", "gid", "posix", "nonposix", "external",
-                       "nomembers"]
-
+            module.fail_json(
+                msg="Action member can not be used with state: renamed.")
+        invalid.extend(["user", "group", "service", "externalmember"])
     else:
-        invalid = ["description", "gid", "posix", "nonposix", "external",
-                   "nomembers"]
-        if action == "group":
-            invalid.extend(["user", "group", "service", "externalmember"])
-
+        invalid.append("rename")
     module.params_fail_used_invalid(invalid, state, action)
 
 
@@ -448,7 +467,9 @@ def main():
                             aliases=[
                                 "ipaexternalmember",
                                 "external_member"
-                            ])
+                            ]),
+        rename=dict(type="str", required=False, default=None,
+                    aliases=["new_name"]),
     )
     ansible_module = IPAAnsibleModule(
         argument_spec=dict(
@@ -470,7 +491,7 @@ def main():
             action=dict(type="str", default="group",
                         choices=["member", "group"]),
             state=dict(type="str", default="present",
-                       choices=["present", "absent"]),
+                       choices=["present", "absent", "renamed"]),
 
             # Add group specific parameters for simple use case
             **group_spec
@@ -506,8 +527,10 @@ def main():
     membermanager_user = ansible_module.params_get("membermanager_user")
     membermanager_group = ansible_module.params_get("membermanager_group")
     externalmember = ansible_module.params_get("externalmember")
+    # rename
+    rename = ansible_module.params_get("rename")
+    # state and action
     action = ansible_module.params_get("action")
-    # state
     state = ansible_module.params_get("state")
 
     # Check parameters
@@ -516,10 +539,11 @@ def main():
        (groups is None or len(groups) < 1):
         ansible_module.fail_json(msg="At least one name or groups is required")
 
-    if state == "present":
+    if state in ["present", "renamed"]:
         if names is not None and len(names) != 1:
+            what = "renamed" if state == "renamed" else "added"
             ansible_module.fail_json(
-                msg="Only one group can be added at a time using 'name'.")
+                msg="Only one group can be %s at a time using 'name'." % what)
 
     check_parameters(ansible_module, state, action)
 
@@ -633,6 +657,7 @@ def main():
                 membermanager_group = group_name.get("membermanager_group")
                 externalmember = group_name.get("externalmember")
                 nomembers = group_name.get("nomembers")
+                rename = group_name.get("rename")
 
                 check_parameters(ansible_module, state, action)
 
@@ -794,6 +819,11 @@ def main():
                         membermanager_group,
                         res_find.get("membermanager_group")
                     )
+            elif state == "renamed":
+                if res_find is None:
+                    ansible_module.fail_json(msg="No group '%s'" % name)
+                elif rename != name:
+                    commands.append([name, 'group_mod', {"rename": rename}])
             else:
                 ansible_module.fail_json(msg="Unkown state '%s'" % state)
 
diff --git a/tests/group/test_group.yml b/tests/group/test_group.yml
index 4a26400753afee6abac0625c87a25f55ca11dd30..8cb76946d23393a406ec9e65958026b186c346d9 100644
--- a/tests/group/test_group.yml
+++ b/tests/group/test_group.yml
@@ -3,6 +3,13 @@
   hosts: "{{ ipa_test_host | default('ipaserver') }}"
   become: true
   gather_facts: true
+  module_defaults:
+    ipauser:
+      ipaadmin_password: SomeADMINpassword
+      ipaapi_context: "{{ ipa_context | default(omit) }}"
+    ipagroup:
+      ipaadmin_password: SomeADMINpassword
+      ipaapi_context: "{{ ipa_context | default(omit) }}"
 
   tasks:
   # setup
@@ -19,24 +26,18 @@
 
   - name: Ensure users user1, user2 and user3 are absent
     ipauser:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: user1,user2,user3
       state: absent
 
   - name: Ensure group group3, group2 and group1 are absent
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
-      name: group3,group2,group1
+      name: groupren,group3,group2,group1
       state: absent
 
   # CREATE TEST ITEMS
 
   - name: Ensure users user1..user3 are present
     ipauser:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       users:
       - name: user1
         first: user1
@@ -54,56 +55,74 @@
 
   - name: Ensure group1 is present
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group1
     register: result
     failed_when: not result.changed or result.failed
 
   - name: Ensure group1 is present again
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group1
     register: result
     failed_when: result.changed or result.failed
 
+  - name: Rename group1 to groupren
+    ipagroup:
+      name: group1
+      rename: groupren
+      state: renamed
+    register: result
+    failed_when: not result.changed or result.failed
+
+  - name: Rename group1 to groupren
+    ipagroup:
+      name: group1
+      rename: groupren
+      state: renamed
+    register: result
+    failed_when: not result.failed or "No group 'group1'" not in result.msg
+
+  - name: Rename group groupren to groupren
+    ipagroup:
+      name: groupren
+      rename: groupren
+      state: renamed
+    register: result
+    failed_when: result.changed or result.failed
+
+  - name: Rename group groupren back to group1
+    ipagroup:
+      name: groupren
+      rename: group1
+      state: renamed
+    register: result
+    failed_when: not result.changed or result.failed
+
   - name: Ensure group2 is present
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group2
     register: result
     failed_when: not result.changed or result.failed
 
   - name: Ensure group2 is present again
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group2
     register: result
     failed_when: result.changed or result.failed
 
   - name: Ensure group3 is present
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group3
     register: result
     failed_when: not result.changed or result.failed
 
   - name: Ensure group3 is present again
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group3
     register: result
     failed_when: result.changed or result.failed
 
   - name: Ensure groups group2 and group3 are present in group group1
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group1
       group:
       - group2
@@ -114,8 +133,6 @@
 
   - name: Ensure groups group2 and group3 are present in group group1 again
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group1
       group:
       - group2
@@ -126,8 +143,6 @@
 
   - name: Ensure group3 ia present in group group1
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group1
       group:
       - group3
@@ -143,8 +158,6 @@
 
     - name: Ensure service "{{ 'HTTP/' + fqdn_at_domain }}" is present in group group1
       ipagroup:
-        ipaadmin_password: SomeADMINpassword
-        ipaapi_context: "{{ ipa_context | default(omit) }}"
         name: group1
         service:
         - "{{ 'HTTP/' + fqdn_at_domain }}"
@@ -154,8 +167,6 @@
 
     - name: Ensure service "{{ 'HTTP/' + fqdn_at_domain }}" is present in group group1, again
       ipagroup:
-        ipaadmin_password: SomeADMINpassword
-        ipaapi_context: "{{ ipa_context | default(omit) }}"
         name: group1
         service:
         - "{{ 'HTTP/' + fqdn_at_domain }}"
@@ -165,8 +176,6 @@
 
     - name: Ensure service "{{ 'ldap/' + fqdn_at_domain }}" is present in group group1
       ipagroup:
-        ipaadmin_password: SomeADMINpassword
-        ipaapi_context: "{{ ipa_context | default(omit) }}"
         name: group1
         service:
         - "{{ 'ldap/' + fqdn_at_domain }}"
@@ -176,8 +185,6 @@
 
     - name: Ensure service "{{ 'ldap/' + fqdn_at_domain }}" is present in group group1, again
       ipagroup:
-        ipaadmin_password: SomeADMINpassword
-        ipaapi_context: "{{ ipa_context | default(omit) }}"
         name: group1
         service:
         - "{{ 'ldap/' + fqdn_at_domain }}"
@@ -187,8 +194,6 @@
 
     - name: Ensure service "{{ 'HTTP/' + fqdn_at_domain }}" is absent in group group1
       ipagroup:
-        ipaadmin_password: SomeADMINpassword
-        ipaapi_context: "{{ ipa_context | default(omit) }}"
         name: group1
         service:
         - "{{ 'HTTP/' + fqdn_at_domain }}"
@@ -199,8 +204,6 @@
 
     - name: Ensure service "{{ 'HTTP/' + fqdn_at_domain }}" is absent in group group1, again
       ipagroup:
-        ipaadmin_password: SomeADMINpassword
-        ipaapi_context: "{{ ipa_context | default(omit) }}"
         name: group1
         service:
         - "{{ 'HTTP/' + fqdn_at_domain }}"
@@ -211,8 +214,6 @@
 
     - name: Ensure service "{{ 'ldap/' + fqdn_at_domain }}" is absent in group group1
       ipagroup:
-        ipaadmin_password: SomeADMINpassword
-        ipaapi_context: "{{ ipa_context | default(omit) }}"
         name: group1
         service:
         - "{{ 'ldap/' + fqdn_at_domain }}"
@@ -223,8 +224,6 @@
 
     - name: Ensure service "{{ 'ldap/' + fqdn_at_domain }}" is absent in group group1, again
       ipagroup:
-        ipaadmin_password: SomeADMINpassword
-        ipaapi_context: "{{ ipa_context | default(omit) }}"
         name: group1
         service:
         - "{{ 'ldap/' + fqdn_at_domain }}"
@@ -235,8 +234,6 @@
 
     - name: Ensure services are present in group group1
       ipagroup:
-        ipaadmin_password: SomeADMINpassword
-        ipaapi_context: "{{ ipa_context | default(omit) }}"
         name: group1
         service:
         - "{{ 'HTTP/' + fqdn_at_domain }}"
@@ -247,8 +244,6 @@
 
     - name: Ensure services are present in group group1, again
       ipagroup:
-        ipaadmin_password: SomeADMINpassword
-        ipaapi_context: "{{ ipa_context | default(omit) }}"
         name: group1
         service:
         - "{{ 'http/' + fqdn_at_domain }}"
@@ -259,8 +254,6 @@
 
     - name: Ensure services are absent in group group1
       ipagroup:
-        ipaadmin_password: SomeADMINpassword
-        ipaapi_context: "{{ ipa_context | default(omit) }}"
         name: group1
         service:
         - "{{ 'HTTP/' + fqdn_at_domain }}"
@@ -272,8 +265,6 @@
 
     - name: Ensure services are absent in group group1, again
       ipagroup:
-        ipaadmin_password: SomeADMINpassword
-        ipaapi_context: "{{ ipa_context | default(omit) }}"
         name: group1
         service:
         - "{{ 'HTTP/' + fqdn_at_domain }}"
@@ -287,8 +278,6 @@
 
   - name: Ensure users user1, user2 and user3 are present in group group1
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group1
       user:
       - user1
@@ -300,8 +289,6 @@
 
   - name: Ensure users user1, user2 and user3 are present in group group1 again
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group1
       user:
       - user1
@@ -312,8 +299,6 @@
     failed_when: result.changed or result.failed
 
   #- ipagroup:
-  #    ipaadmin_password: SomeADMINpassword
-  #    ipaapi_context: "{{ ipa_context | default(omit) }}"
   #    name: group1
   #    user:
   #    - user7
@@ -321,8 +306,6 @@
 
   - name: Ensure user user7 is absent in group group1
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group1
       user:
       - user7
@@ -333,8 +316,6 @@
 
   - name: Ensure group group4 is absent
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group4
       state: absent
     register: result
@@ -342,8 +323,6 @@
 
   - name: Ensure groups group3, group2, and group1 are absent
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group3,group2,group1
       state: absent
     register: result
@@ -351,16 +330,12 @@
 
   - name: Ensure group group1 is present
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group1
     register: result
     failed_when: not result.changed or result.failed
 
   - name: Ensure users user1, user2 are present in group group1
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group1
       user:
       - user1
@@ -371,8 +346,6 @@
 
   - name: Ensure users user1, user2 and user3 are present in group group1
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group1
       user:
       - user1
@@ -384,8 +357,6 @@
 
   - name: Ensure users user1, user2 are present in group group1, again
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group1
       user:
       - user1
@@ -396,8 +367,6 @@
 
   - name: Ensure users user1, user2 and user3 are present in group group1, again
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group1
       user:
       - user1
@@ -409,8 +378,6 @@
 
   - name: Ensure group group1 is absent
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group1
       state: absent
     register: result
@@ -418,8 +385,6 @@
 
   - name: Ensure group group1 with users user1, user2 is present
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group1
       user:
       - user1
@@ -429,8 +394,6 @@
 
   - name: Ensure group group1 with users user1, user2 and user3 is present
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group1
       user:
       - user1
@@ -441,8 +404,6 @@
 
   - name: Ensure group group1 with users user1, user2 and user3 is present, again
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group1
       user:
       - user1
@@ -454,8 +415,6 @@
 
   - name: Ensure only users user1, user2 are present in group group1
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group1
       user:
       - user1
@@ -467,8 +426,6 @@
 
   - name: Ensure group group3, group2 and group1 are absent
     ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: group3,group2,group1
       state: absent
     register: result
@@ -476,8 +433,6 @@
 
   - name: Ensure users user1, user2 and user3 are absent
     ipauser:
-      ipaadmin_password: SomeADMINpassword
-      ipaapi_context: "{{ ipa_context | default(omit) }}"
       name: user1,user2,user3
       state: absent
     register: result
diff --git a/tests/group/test_groups.yml b/tests/group/test_groups.yml
index 648b35b87878de36ff00abcf281012172de94ccc..2e0d3a8c7f3e7353e2e1de8d6c95363f5e7b6c2c 100644
--- a/tests/group/test_groups.yml
+++ b/tests/group/test_groups.yml
@@ -19,7 +19,7 @@
   - name: Remove test groups
     ipagroup:
       ipaadmin_password: SomeADMINpassword
-      name: group1,group2,group3,group4,group5,group6,group7,group8,group9,group10
+      name: group1,group2,group3,group4,group5,group6,group7,group8,group9,group10,newgroup1,newgroup2
       state: absent
 
   - name: Remove test users
@@ -130,10 +130,53 @@
     register: result
     failed_when: result.changed or not result.failed or "Only one group can be added at a time using 'name'." not in result.msg
 
+  - name: Ensure group1 and group2 exist
+    ipagroup:
+      ipaadmin_password: SomeADMINpassword
+      groups:
+        - name: group1
+        - name: group2
+
+  - name: Rename group1 and group2 to newgroup1 and newgroup2, respectively
+    ipagroup:
+      ipaadmin_password: SomeADMINpassword
+      groups:
+        - name: group1
+          rename: newgroup1
+        - name: group2
+          rename: newgroup2
+      state: renamed
+    register: result
+    failed_when: not result.changed or result.failed
+
+  - name: Rename newgroup1 and newgroup2 to the same name
+    ipagroup:
+      ipaadmin_password: SomeADMINpassword
+      groups:
+        - name: newgroup1
+          rename: newgroup1
+        - name: newgroup2
+          rename: newgroup2
+      state: renamed
+    register: result
+    failed_when: result.changed or result.failed
+
+  - name: Rename newgroup1 and newgroup2 back to group1 and group2, respectively
+    ipagroup:
+      ipaadmin_password: SomeADMINpassword
+      groups:
+        - name: newgroup1
+          rename: group1
+        - name: newgroup2
+          rename: group2
+      state: renamed
+    register: result
+    failed_when: not result.changed or result.failed
+
   - name: Remove test groups
     ipagroup:
       ipaadmin_password: SomeADMINpassword
-      name: group1,group2,group3,group4,group5,group6,group7,group8,group9,group10
+      name: group1,group2,group3,group4,group5,group6,group7,group8,group9,group10,newgroup1,newgroup2
       state: absent
 
   - name: Remove test users