diff --git a/README-group.md b/README-group.md
index 4ffdb291786b3cfaa7b9ee0d5a936ba1698f6f97..e807fdbdedfb25b75993c52bbfd8a8ad80f24539 100644
--- a/README-group.md
+++ b/README-group.md
@@ -137,6 +137,7 @@ Variable | Description | Required
 `name` \| `cn` | The list of group name strings. | no
 `description` | The group description string. | no
 `gid` \| `gidnumber` | The GID integer. | no
+`posix` | Create a non-POSIX group or change a non-POSIX to a posix group. (bool) | no
 `nonposix` | Create as a non-POSIX group. (bool) | no
 `external` | Allow adding external non-IPA members from trusted domains. (bool) | no
 `nomembers` | Suppress processing of membership attributes. (bool) | no
diff --git a/plugins/modules/ipagroup.py b/plugins/modules/ipagroup.py
index 903c256d33478878d6ce44bccbfcb8a9482d9053..dd342ee4420996400959b83af373edea94f4ccf2 100644
--- a/plugins/modules/ipagroup.py
+++ b/plugins/modules/ipagroup.py
@@ -57,6 +57,11 @@ options:
     description: Allow adding external non-IPA members from trusted domains
     required: false
     type: bool
+  posix:
+    description:
+      Create a non-POSIX group or change a non-POSIX to a posix group.
+    required: false
+    type: bool
   nomembers:
     description: Suppress processing of membership attributes
     required: false
@@ -140,10 +145,23 @@ EXAMPLES = """
     - sysops
     - appops
 
-# Remove goups sysops, appops and ops
+
+# Create a non-POSIX group
+- ipagroup:
+    ipaadmin_password: SomeADMINpassword
+    name: nongroup
+    nonposix: yes
+
+# Turn a non-POSIX group into a POSIX group.
 - ipagroup:
     ipaadmin_password: SomeADMINpassword
-    name: sysops,appops,ops
+    name: nonposix
+    posix: yes
+
+# Remove goups sysops, appops, ops and nongroup
+- ipagroup:
+    ipaadmin_password: SomeADMINpassword
+    name: sysops,appops,ops, nongroup
     state: absent
 """
 
@@ -173,16 +191,12 @@ def find_group(module, name):
         return None
 
 
-def gen_args(description, gid, nonposix, external, nomembers):
+def gen_args(description, gid, nomembers):
     _args = {}
     if description is not None:
         _args["description"] = description
     if gid is not None:
         _args["gidnumber"] = gid
-    if nonposix is not None:
-        _args["nonposix"] = nonposix
-    if external is not None:
-        _args["external"] = external
     if nomembers is not None:
         _args["nomembers"] = nomembers
 
@@ -201,6 +215,41 @@ def gen_member_args(user, group, service):
     return _args
 
 
+def check_objectclass_args(module, res_find, nonposix, posix, external):
+    if res_find and 'posixgroup' in res_find['objectclass']:
+        if (
+            (posix is not None and posix is False)
+            or nonposix
+            or external
+        ):
+            module.fail_json(
+                msg="Cannot change `POSIX` status of a group "
+                    "to `non-POSIX` or `external`.")
+    # Can't change an existing external group
+    if res_find and 'ipaexternalgroup' in res_find['objectclass']:
+        if (
+            posix
+            or (nonposix is not None and nonposix is False)
+            or (external is not None and external is False)
+        ):
+            module.fail_json(
+                msg="Cannot change `external` status of group "
+                    "to `POSIX` or `non-external`.")
+
+
+def should_modify_group(module, res_find, args, nonposix, posix, external):
+    if not compare_args_ipa(module, args, res_find):
+        return True
+    if any([posix, nonposix]):
+        set_posix = posix or (nonposix is not None and not nonposix)
+        if set_posix and 'posixgroup' not in res_find['objectclass']:
+            return True
+    if 'ipaexternalgroup' not in res_find['objectclass'] and external:
+        if 'posixgroup' not in res_find['objectclass']:
+            return True
+    return False
+
+
 def main():
     ansible_module = AnsibleModule(
         argument_spec=dict(
@@ -215,6 +264,7 @@ def main():
             gid=dict(type="int", aliases=["gidnumber"], default=None),
             nonposix=dict(required=False, type='bool', default=None),
             external=dict(required=False, type='bool', default=None),
+            posix=dict(required=False, type='bool', default=None),
             nomembers=dict(required=False, type='bool', default=None),
             user=dict(required=False, type='list', default=None),
             group=dict(required=False, type='list', default=None),
@@ -228,6 +278,7 @@ def main():
             state=dict(type="str", default="present",
                        choices=["present", "absent"]),
         ),
+        mutually_exclusive=[['posix', 'nonposix']],
         supports_check_mode=True,
     )
 
@@ -248,6 +299,7 @@ def main():
     gid = module_params_get(ansible_module, "gid")
     nonposix = module_params_get(ansible_module, "nonposix")
     external = module_params_get(ansible_module, "external")
+    posix = module_params_get(ansible_module, "posix")
     nomembers = module_params_get(ansible_module, "nomembers")
     user = module_params_get(ansible_module, "user")
     group = module_params_get(ansible_module, "group")
@@ -267,7 +319,7 @@ def main():
             ansible_module.fail_json(
                 msg="Only one group can be added at a time.")
         if action == "member":
-            invalid = ["description", "gid", "nonposix", "external",
+            invalid = ["description", "gid", "posix", "nonposix", "external",
                        "nomembers"]
             for x in invalid:
                 if vars()[x] is not None:
@@ -279,7 +331,8 @@ def main():
         if len(names) < 1:
             ansible_module.fail_json(
                 msg="No name given.")
-        invalid = ["description", "gid", "nonposix", "external", "nomembers"]
+        invalid = ["description", "gid", "posix", "nonposix", "external",
+                   "nomembers"]
         if action == "group":
             invalid.extend(["user", "group", "service"])
         for x in invalid:
@@ -322,9 +375,12 @@ def main():
 
             # Create command
             if state == "present":
+                # Can't change an existing posix group
+                check_objectclass_args(ansible_module, res_find, nonposix,
+                                       posix, external)
+
                 # Generate args
-                args = gen_args(description, gid, nonposix, external,
-                                nomembers)
+                args = gen_args(description, gid, nomembers)
 
                 if action == "group":
                     # Found the group
@@ -332,10 +388,21 @@ def main():
                         # For all settings is args, check if there are
                         # different settings in the find result.
                         # If yes: modify
-                        if not compare_args_ipa(ansible_module, args,
-                                                res_find):
+                        if should_modify_group(ansible_module, res_find, args,
+                                               nonposix, posix, external):
+                            if (
+                                posix
+                                or (nonposix is not None and not nonposix)
+                            ):
+                                args['posix'] = True
+                            if external:
+                                args['external'] = True
                             commands.append([name, "group_mod", args])
                     else:
+                        if nonposix or (posix is not None and not posix):
+                            args['nonposix'] = True
+                        if external:
+                            args['external'] = True
                         commands.append([name, "group_add", args])
                         # Set res_find to empty dict for next step
                         res_find = {}
diff --git a/tests/group/test_group_external_nonposix.yml b/tests/group/test_group_external_nonposix.yml
new file mode 100644
index 0000000000000000000000000000000000000000..55c924084d1d1cac57f644c0f1fea2f232bf0310
--- /dev/null
+++ b/tests/group/test_group_external_nonposix.yml
@@ -0,0 +1,133 @@
+---
+- name: Test group
+  hosts: ipaserver
+  become: yes
+  gather_facts: yes
+
+  tasks:
+    - name: Remove testing groups.
+      ipagroup:
+        ipaadmin_password: SomeADMINpassword
+        name:
+        - extgroup
+        - nonposixgroup
+        - posixgroup
+        state: absent
+
+    - name: Add nonposix group.
+      ipagroup:
+        ipaadmin_password: SomeADMINpassword
+        name: extgroup
+        nonposix: yes
+      register: result
+      failed_when: result.failed or not result.changed
+
+    - name: Add nonposix group, again.
+      ipagroup:
+        ipaadmin_password: SomeADMINpassword
+        name: extgroup
+        nonposix: yes
+      register: result
+      failed_when: result.failed or result.changed
+
+    - name: Set group to be external
+      ipagroup:
+        ipaadmin_password: SomeADMINpassword
+        name: extgroup
+        external: yes
+      register: result
+      failed_when: result.failed or not result.changed
+
+    - name: Set group to be external, again.
+      ipagroup:
+        ipaadmin_password: SomeADMINpassword
+        name: extgroup
+        external: yes
+      register: result
+      failed_when: result.failed or result.changed
+
+    - name: Set external group to be non-external.
+      ipagroup:
+        ipaadmin_password: SomeADMINpassword
+        name: extgroup
+        external: no
+      register: result
+      failed_when: not result.failed or "Cannot change `external` status of group" not in result.msg
+
+    - name: Set external group to be posix.
+      ipagroup:
+        ipaadmin_password: SomeADMINpassword
+        name: extgroup
+        posix: yes
+      register: result
+      failed_when: not result.failed or "Cannot change `external` status of group" not in result.msg
+
+    - name: Add nonposix group.
+      ipagroup:
+        ipaadmin_password: SomeADMINpassword
+        name: posixgroup
+        nonposix: yes
+      register: result
+      failed_when: result.failed or not result.changed
+
+    - name: Set group to be posix
+      ipagroup:
+        ipaadmin_password: SomeADMINpassword
+        name: posixgroup
+        posix: yes
+      register: result
+      failed_when: result.failed or not result.changed
+
+    - name: Set group to be posix, again.
+      ipagroup:
+        ipaadmin_password: SomeADMINpassword
+        name: posixgroup
+        posix: yes
+      register: result
+      failed_when: result.failed or result.changed
+
+    - name: Set posix group to be external.
+      ipagroup:
+        ipaadmin_password: SomeADMINpassword
+        name: posixgroup
+        external: yes
+      register: result
+      failed_when: not result.failed or "Cannot change `POSIX` status of a group" not in result.msg
+
+    - name: Set posix group to be non-POSIX.
+      ipagroup:
+        ipaadmin_password: SomeADMINpassword
+        name: posixgroup
+        posix: no
+      register: result
+      failed_when: not result.failed or "Cannot change `POSIX` status of a group" not in result.msg
+
+    - name: Set posix group to be non-POSIX.
+      ipagroup:
+        ipaadmin_password: SomeADMINpassword
+        name: posixgroup
+        nonposix: yes
+      register: result
+      failed_when: not result.failed or "Cannot change `POSIX` status of a group" not in result.msg
+
+    - name: Add nonposix group.
+      ipagroup:
+        ipaadmin_password: SomeADMINpassword
+        name: nonposixgroup
+        posix: no
+      register: result
+      failed_when: result.failed or not result.changed
+
+    - name: Add nonposix group, again.
+      ipagroup:
+        ipaadmin_password: SomeADMINpassword
+        name: nonposixgroup
+        nonposix: yes
+      register: result
+      failed_when: result.failed or result.changed
+
+    - name: Remove testing groups.
+      ipagroup:
+        ipaadmin_password: SomeADMINpassword
+        name: extgroup,nonposixgroup,posixgroup
+        state: absent