diff --git a/README-vault.md b/README-vault.md
index 61f684147030b6918bc48505a65823c37b4862c3..c7ae6916cc56926d3ca600592d57cab7f67a1009 100644
--- a/README-vault.md
+++ b/README-vault.md
@@ -144,8 +144,7 @@ Example playbook to retrieve vault data from a symmetric vault:
       name: symvault
       username: admin
       password: SomeVAULTpassword
-      retrieve: true
-      action: member
+      state: retrieved
 ```
 
 Example playbook to make sure vault data is absent in a symmetric vault:
@@ -180,6 +179,9 @@ Example playbook to make sure vault is absent:
       name: symvault
       username: admin
       state: absent
+    register: result
+  - debug:
+      msg: "{{ result.data }}"
 ```
 
 Variables
@@ -199,7 +201,7 @@ Variable | Description | Required
 `public_key ` \| `vault_public_key` \| `ipavaultpublickey` | Base64 encoded vault public key. | no
 `public_key_file` \| `vault_public_key_file` | Path to file with public key. | no
 `private_key `\| `vault_private_key` | Base64 encoded vault private key. Used only to retrieve data. | no
-`private_key_file` \| `vault_private_key_file` | Path to file with private key. | no
+`private_key_file` \| `vault_private_key_file` | Path to file with private key. Used only to retrieve data. | no
 `salt` \| `vault_salt` \| `ipavaultsalt` | Vault salt. | no
 `vault_type` \| `ipavaulttype` | Vault types are based on security level. It can be one of `standard`, `symmetric` or `asymmetric`, default: `symmetric` | no
 `user` \| `username` | Any user can own one or more user vaults. | no
@@ -211,9 +213,21 @@ Variable | Description | Required
 `data` \|`vault_data` \| `ipavaultdata` | Data to be stored in the vault. | no
 `in` \| `datafile_in` | Path to file with data to be stored in the vault. | no
 `out` \| `datafile_out` | Path to file to store data retrieved from the vault. | no
-`retrieve` | If set to True, retrieve data stored in the vault. (bool) | no
 `action` | Work on vault or member level. It can be on of `member` or `vault` and defaults to `vault`. | no
-`state` | The state to ensure. It can be one of `present` or `absent`, default: `present`. | no
+`state` | The state to ensure. It can be one of `present`, `absent` or `retrieved`, default: `present`. | no
+
+
+Return Values
+=============
+
+ipavault
+--------
+
+There is only a return value if `state` is `retrieved`.
+
+Variable | Description | Returned When
+-------- | ----------- | -------------
+`data` | The data stored in the vault. | If `state` is `retrieved`.
 
 
 Notes
diff --git a/playbooks/vault/retrive-data-asymmetric-vault.yml b/playbooks/vault/retrive-data-asymmetric-vault.yml
index 420acc78f206d444e3b0d07d438608f8befe6c87..5f67c593b1aedad864752b50cbc30dde4b95ed98 100644
--- a/playbooks/vault/retrive-data-asymmetric-vault.yml
+++ b/playbooks/vault/retrive-data-asymmetric-vault.yml
@@ -1,19 +1,17 @@
 ---
 - name: Tests
   hosts: ipaserver
-  become: true
-  gather_facts: True
+  become: no
+  gather_facts: no
 
   tasks:
     - name: Retrieve data from assymetric vault with a private key file.
       ipavault:
         ipaadmin_password: SomeADMINpassword
-        name: symvault
-        username: admin
+        name: asymvault
+        username: user01
         private_key_file: private.pem
-        retrieve: True
+        state: retrieved
       register: result
     - debug:
        msg: "Data: {{ result.data }}"
-    - debug:
-       msg: "Decoded Data: {{ result.data | b64decode }}"
diff --git a/playbooks/vault/retrive-data-symmetric-vault.yml b/playbooks/vault/retrive-data-symmetric-vault.yml
index 0ac1337291e91f9661b17f2e9c05a8d5a3cc3898..163f8b9544b3c0ec85575513309dffa70e991fbb 100644
--- a/playbooks/vault/retrive-data-symmetric-vault.yml
+++ b/playbooks/vault/retrive-data-symmetric-vault.yml
@@ -1,8 +1,8 @@
 ---
 - name: Tests
   hosts: ipaserver
-  become: true
-  gather_facts: True
+  become: no
+  gather_facts: no
 
   tasks:
     - name: Retrieve data from symmetric vault.
@@ -11,8 +11,7 @@
         name: symvault
         username: admin
         password: SomeVAULTpassword
-        retrieve: yes
-        action: member
+        state: retrieved
       register: result
     - debug:
         msg: "{{ result.data | b64decode }}"
diff --git a/plugins/modules/ipavault.py b/plugins/modules/ipavault.py
index dc59d4bedd00b54505b69200a57e3bec845627fd..ad5dd413285188a0ae4d298c0be246eb8f00dbe0 100644
--- a/plugins/modules/ipavault.py
+++ b/plugins/modules/ipavault.py
@@ -74,7 +74,7 @@ options:
     description: file with password to be used on symmetric vault.
     required: false
     type: string
-    aliases: ["ipavaultpassword", "vault_password"]
+    aliases: ["vault_password_file"]
   salt:
     description: Vault salt.
     required: false
@@ -99,16 +99,24 @@ options:
     description: Vault is shared.
     required: false
     type: boolean
+  users:
+    description: Users that are member of the vault.
+    required: false
+    type: list
+  groups:
+    description: Groups that are member of the vault.
+    required: false
+    type: list
   owners:
-    description: Users that are owners of the container.
+    description: Users that are owners of the vault.
     required: false
     type: list
-  users:
-    description: Users that are member of the container.
+  ownergroups:
+    description: Groups that are owners of the vault.
     required: false
     type: list
-  groups:
-    description: Groups that are member of the container.
+  ownerservices:
+    description: Services that are owners of the vault.
     required: false
     type: list
   services:
@@ -130,10 +138,6 @@ options:
     required: false
     type: string
     aliases: ["datafile_out"]
-  retrieve:
-    description: If set to True, retrieve data stored in the vault.
-    required: false
-    type: bool
   action:
     description: Work on vault or member level.
     default: vault
@@ -141,7 +145,7 @@ options:
   state:
     description: State to ensure
     default: present
-    choices: ["present", "absent"]
+    choices: ["present", "absent", "retrieved"]
 author:
     - Rafael Jeffman
 """
@@ -228,8 +232,7 @@ EXAMPLES = """
     name: symvault
     username: admin
     password: SomeVAULTpassword
-    retrieve: yes
-    action: member
+    state: retrieved
   register: result
 - debug:
     msg: "{{ result.data | b64decode }}"
@@ -266,14 +269,13 @@ EXAMPLES = """
       More data archived.
     action: member
 
-# Retrive data archived in an asymmetric vault
+# Retrive data archived in an asymmetric vault, using a private key file.
 - ipavault:
     ipaadmin_password: SomeADMINpassword
     name: asymvault
     username: admin
-    retrieve: yes
-    private_key:
-
+    private_key_file: private.pem
+    state: retrieved
 
 # Ensure asymmetric vault is absent.
 - ipavault:
@@ -285,10 +287,14 @@ EXAMPLES = """
 """
 
 RETURN = """
+user:
+  description: The vault data.
+  returned: If state is retrieved.
+  type: string
 """
 
 import os
-from base64 import b64encode, b64decode
+from base64 import b64decode
 from ansible.module_utils.basic import AnsibleModule
 from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
     temp_kdestroy, valid_creds, api_connect, api_command, \
@@ -355,18 +361,21 @@ def gen_member_args(args, users, groups, services):
         if arg in _args:
             del _args[arg]
 
-    if users is not None:
-        _args['user'] = users
-    if groups is not None:
-        _args['group'] = groups
-    if services is not None:
-        _args['services'] = services
+    if any([users, groups, services]):
+        if users is not None:
+            _args['user'] = users
+        if groups is not None:
+            _args['group'] = groups
+        if services is not None:
+            _args['services'] = services
 
-    return _args
+        return _args
+
+    return None
 
 
 def data_storage_args(args, data, password, password_file, private_key,
-                      private_key_file, retrieve, datafile_in, datafile_out):
+                      private_key_file, datafile_in, datafile_out):
     _args = {}
 
     if 'username' in args:
@@ -407,51 +416,38 @@ def check_parameters(module, state, action, description, username, service,
                      shared, users, groups, services, owners, ownergroups,
                      ownerservices, vault_type, salt, password, password_file,
                      public_key, public_key_file, private_key,
-                     private_key_file, retrieve, vault_data, datafile_in,
-                     datafile_out):
+                     private_key_file, vault_data, datafile_in, datafile_out):
     invalid = []
     if state == "present":
-        if salt is not None:
-            if vault_type is not None and vault_type != "symmetric":
-                module.fail_json(
-                    msg="Attribute `salt` can only be used with `symmetric` "
-                        "vaults.")
-            if not any([password, password_file]):
-                module.fail_json(
-                    msg="Value of `salt` can only modified by providing "
-                        "vault password.")
-        if action == "member":
-            invalid = ['description']
+        invalid = ['private_key', 'private_key_file', 'datafile_out']
 
-        if not retrieve:
-            if datafile_out is not None:
-                module.fail_json(
-                    msg="Retrieve must be enabled to use datafile_out.")
-
-            if any([private_key, private_key_file]):
-                module.fail_json(
-                    msg="Attributes private_key and private_key_file can only "
-                        "be used when retrieving data from asymmetric vaults.")
-        else:
-            check = ['description', 'salt', 'datafile_in', 'users', 'groups',
-                     'owners', 'ownergroups', 'public_key', 'public_key_file',
-                     'vault_data']
-
-            for arg in check:
-                if vars()[arg] is not None:
-                    module.fail_json(
-                        msg="`%s` cannot be used with `retrieve`." % arg)
+        if action == "member":
+            invalid.extend(['description'])
 
     elif state == "absent":
         invalid = ['description', 'salt', 'vault_type', 'private_key',
-                   'private_key_file', 'retrieve', 'datafile_in',
-                   'datafile_out', 'vault_data']
+                   'private_key_file', 'datafile_in', 'datafile_out',
+                   'vault_data']
 
         if action == "vault":
             invalid.extend(['users', 'groups', 'services', 'owners',
                             'ownergroups', 'ownerservices', 'password',
                             'password_file', 'public_key', 'public_key_file'])
 
+    elif state == "retrieved":
+        invalid = ['description', 'salt', 'datafile_in', 'users', 'groups',
+                   'owners', 'ownergroups', 'public_key', 'public_key_file',
+                   'vault_data']
+        if action == 'member':
+            module.fail_json(
+                msg="State `retrieved` do not support action `member`.")
+
+    for arg in invalid:
+        if vars()[arg] is not None:
+            module.fail_json(
+                msg="Argument '%s' can not be used with state '%s', "
+                    "action '%s'" % (arg, state, action))
+
     for arg in invalid:
         if vars()[arg] is not None:
             module.fail_json(
@@ -459,30 +455,30 @@ def check_parameters(module, state, action, description, username, service,
                     "action '%s'" % (arg, state, action))
 
 
-def check_encryption_params(module, state, vault_type, salt, password,
-                            password_file, public_key, public_key_file,
-                            private_key, private_key_file, retrieve,
+def check_encryption_params(module, state, action, vault_type, salt,
+                            password, password_file, public_key,
+                            public_key_file, private_key, private_key_file,
                             vault_data, datafile_in, datafile_out, res_find):
     vault_type_invalid = []
-    if state == "present":
-        if vault_type == "standard":
-            vault_type_invalid = ['public_key', 'public_key_file', 'password',
-                                  'password_file', 'salt']
-
-        if vault_type is None or vault_type == "symmetric":
-            vault_type_invalid = ['public_key', 'public_key_file',
-                                  'private_key', 'private_key_file']
-            if not any([password, password_file]):
-                module.fail_json(
-                    msg="Symmetric vault requires password or password_file "
-                        "to store data.")
-
-        if vault_type == "asymmetric":
-            vault_type_invalid = ['password', 'password_file']
-            if not any([public_key, public_key_file]) and res_find is None:
-                module.fail_json(
-                    msg="Assymmetric vault requires public_key "
-                        "or public_key_file to store data.")
+    if vault_type == "standard":
+        vault_type_invalid = ['public_key', 'public_key_file', 'password',
+                              'password_file', 'salt']
+
+    if vault_type is None or vault_type == "symmetric":
+        vault_type_invalid = ['public_key', 'public_key_file',
+                              'private_key', 'private_key_file']
+
+        if password is None and password_file is None and action != 'member':
+            module.fail_json(
+                msg="Symmetric vault requires password or password_file "
+                    "to store data or change `salt`.")
+
+    if vault_type == "asymmetric":
+        vault_type_invalid = ['password', 'password_file']
+        if not any([public_key, public_key_file]) and res_find is None:
+            module.fail_json(
+                msg="Assymmetric vault requires public_key "
+                    "or public_key_file to store data.")
 
     for param in vault_type_invalid:
         if vars()[param] is not None:
@@ -516,7 +512,6 @@ def main():
             vault_private_key_file=dict(type="str", required=False,
                                         default=None,
                                         aliases=['private_key_file']),
-            retrieve=dict(type="bool", required=False, default=None),
             vault_salt=dict(type="str", required=False, default=None,
                             aliases=['ipavaultsalt', 'salt']),
             username=dict(type="str", required=False, default=None,
@@ -546,7 +541,7 @@ def main():
             action=dict(type="str", default="vault",
                         choices=["vault", "data", "member"]),
             state=dict(type="str", default="present",
-                       choices=["present", "absent"]),
+                       choices=["present", "absent", "retrieved"]),
         ),
         supports_check_mode=True,
         mutually_exclusive=[['username', 'service', 'shared'],
@@ -593,8 +588,6 @@ def main():
     datafile_in = module_params_get(ansible_module, "datafile_in")
     datafile_out = module_params_get(ansible_module, "datafile_out")
 
-    retrieve = module_params_get(ansible_module, "retrieve")
-
     action = module_params_get(ansible_module, "action")
     state = module_params_get(ansible_module, "state")
 
@@ -609,6 +602,11 @@ def main():
         if len(names) < 1:
             ansible_module.fail_json(msg="No name given.")
 
+    elif state == "retrieved":
+        if len(names) != 1:
+            ansible_module.fail_json(
+                msg="Only one vault can be retrieved at a time.")
+
     else:
         ansible_module.fail_json(msg="Invalid state '%s'" % state)
 
@@ -616,8 +614,7 @@ def main():
                      service, shared, users, groups, services, owners,
                      ownergroups, ownerservices, vault_type, salt, password,
                      password_file, public_key, public_key_file, private_key,
-                     private_key_file, retrieve, vault_data, datafile_in,
-                     datafile_out)
+                     private_key_file, vault_data, datafile_in, datafile_out)
     # Init
 
     changed = False
@@ -656,15 +653,14 @@ def main():
                 else:
                     args['ipavaulttype'] = vault_type = "symmetric"
 
-            # verify data encription args
-            check_encryption_params(ansible_module, state, vault_type, salt,
-                                    password, password_file, public_key,
-                                    public_key_file, private_key,
-                                    private_key_file, retrieve, vault_data,
-                                    datafile_in, datafile_out, res_find)
-
             # Create command
             if state == "present":
+                # verify data encription args
+                check_encryption_params(
+                    ansible_module, state, action, vault_type, salt, password,
+                    password_file, public_key, public_key_file, private_key,
+                    private_key_file, vault_data, datafile_in, datafile_out,
+                    res_find)
 
                 # Found the vault
                 if action == "vault":
@@ -710,25 +706,36 @@ def main():
                     # Add users and groups
                     user_add_args = gen_member_args(args, user_add,
                                                     group_add, service_add)
-                    commands.append([name, 'vault_add_member', user_add_args])
+                    if user_add_args is not None:
+                        commands.append(
+                            [name, 'vault_add_member', user_add_args])
 
                     # Remove users and groups
                     user_del_args = gen_member_args(args, user_del,
                                                     group_del, service_del)
-                    commands.append(
-                        [name, 'vault_remove_member', user_del_args])
+                    if user_del_args is not None:
+                        commands.append(
+                            [name, 'vault_remove_member', user_del_args])
 
                     # Add owner users and groups
                     owner_add_args = gen_member_args(
                         args, owner_add, ownergroups_add, ownerservice_add)
-                    commands.append(
-                        [name, 'vault_add_owner', owner_add_args])
+                    if owner_add_args is not None:
+                        # ansible_module.warn("OWNER ADD: %s" % owner_add_args)
+                        commands.append(
+                            [name, 'vault_add_owner', owner_add_args])
 
                     # Remove owner users and groups
                     owner_del_args = gen_member_args(
                         args, owner_del, ownergroups_del, ownerservice_del)
-                    commands.append(
-                        [name, 'vault_remove_owner', owner_del_args])
+                    if owner_del_args is not None:
+                        # ansible_module.warn("OWNER DEL: %s" % owner_del_args)
+                        commands.append(
+                            [name, 'vault_remove_owner', owner_del_args])
+
+                    if vault_type == 'symmetric' \
+                       and 'ipavaultsalt' not in args:
+                        args['ipavaultsalt'] = os.urandom(32)
 
                     if vault_type == 'symmetric' \
                        and 'ipavaultsalt' not in args:
@@ -746,15 +753,32 @@ def main():
                         commands.append([name, 'vault_add_owner', owner_args])
 
                 pwdargs = data_storage_args(
-                    args, vault_data, password, password_file,
-                    private_key, private_key_file, retrieve, datafile_in,
-                    datafile_out)
+                    args, vault_data, password, password_file, private_key,
+                    private_key_file, datafile_in, datafile_out)
                 if any([vault_data, datafile_in]):
                     commands.append([name, "vault_archive", pwdargs])
-                if retrieve:
-                    if 'data' in pwdargs:
-                        del pwdargs['data']
-                    commands.append([name, "vault_retrieve", pwdargs])
+
+            elif state == "retrieved":
+                if res_find is None:
+                    ansible_module.fail_json(
+                        msg="Vault `%s` not found to retrieve data." % name)
+
+                vault_type = res_find['cn']
+
+                # verify data encription args
+                check_encryption_params(
+                    ansible_module, state, action, vault_type, salt, password,
+                    password_file, public_key, public_key_file, private_key,
+                    private_key_file, vault_data, datafile_in, datafile_out,
+                    res_find)
+
+                pwdargs = data_storage_args(
+                    args, vault_data, password, password_file, private_key,
+                    private_key_file, datafile_in, datafile_out)
+                if 'data' in pwdargs:
+                    del pwdargs['data']
+
+                commands.append([name, "vault_retrieve", pwdargs])
 
             elif state == "absent":
                 if 'ipavaulttype' in args:
@@ -782,21 +806,30 @@ def main():
                         msg="Invalid action '%s' for state '%s'" %
                         (action, state))
             else:
-                ansible_module.fail_json(msg="Unkown state '%s'" % state)
+                ansible_module.fail_json(msg="Unknown state '%s'" % state)
 
         # Execute commands
 
         errors = []
         for name, command, args in commands:
             try:
+                # ansible_module.warn("RUN: %s %s %s" % (command, name, args))
                 result = api_command(ansible_module, command, name, args)
 
                 if command == 'vault_archive':
                     changed = 'Archived data into' in result['summary']
                 elif command == 'vault_retrieve':
-                    exit_args['data'] = b64encode(result['result']['data'])
+                    if 'result' not in result:
+                        raise Exception("No result obtained.")
+                    if 'data' in result['result']:
+                        exit_args['data'] = result['result']['data']
+                    elif 'vault_data' in result['result']:
+                        exit_args['data'] = result['result']['vault_data']
+                    else:
+                        raise Exception("No data retrieved.")
                     changed = False
                 else:
+                    # ansible_module.warn("RESULT: %s" % (result))
                     if "completed" in result:
                         if result["completed"] > 0:
                             changed = True
diff --git a/tests/vault/env_cleanup.yml b/tests/vault/env_cleanup.yml
new file mode 100644
index 0000000000000000000000000000000000000000..081a9d96460e24db37d45d8ff535ef4006d7040a
--- /dev/null
+++ b/tests/vault/env_cleanup.yml
@@ -0,0 +1,64 @@
+# Tasks executed to clean up test environment for Vault module.
+
+  - name: Ensure user vaults are absent
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name:
+      - stdvault
+      - symvault
+      - asymvault
+      username: "{{username}}"
+      state: absent
+    loop:
+      - admin
+      - user01
+    loop_control:
+      loop_var: username
+
+  - name: Ensure shared vaults are absent
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name:
+      - sharedvault
+      - svcvault
+      state: absent
+
+  - name: Ensure test users do not exist.
+    ipauser:
+      ipaadmin_password: SomeADMINpassword
+      name:
+      - user01
+      - user02
+      - user03
+      state: absent
+
+  - name: Ensure test groups do not exist.
+    ipagroup:
+      ipaadmin_password: SomeADMINpassword
+      name: vaultgroup
+      state: absent
+
+  - name: Remove password file from target host.
+    file:
+      path: "{{ ansible_env.HOME }}/password.txt"
+      state: absent
+
+  - name: Remove public key file from target host.
+    file:
+      path: "{{ ansible_env.HOME }}/public.pem"
+      state: absent
+
+  - name: Remove private key file from target host.
+    file:
+      path: "{{ ansible_env.HOME }}/private.pem"
+      state: absent
+
+  - name: Remove output data file from target host.
+    file:
+      path: "{{ ansible_env.HOME }}/data.txt"
+      state: absent
+
+  - name: Remove input data file from target host.
+    file:
+      path: "{{ ansible_env.HOME }}/in.txt"
+      state: absent
diff --git a/tests/vault/env_setup.yml b/tests/vault/env_setup.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a8437b86053c1bec6e204ac64e60b58451c0b0d2
--- /dev/null
+++ b/tests/vault/env_setup.yml
@@ -0,0 +1,55 @@
+# Tasks executed to ensure a sane environment to test IPA Vault module.
+
+  - name: Create private key file.
+    shell:
+      cmd: openssl genrsa -out private.pem 2048
+    delegate_to: localhost
+    become: no
+
+  - name: Create public key file.
+    shell:
+      cmd: openssl rsa -in private.pem -outform PEM -pubout -out public.pem
+    delegate_to: localhost
+    become: no
+
+  - name: Ensure environment is clean.
+    import_tasks: env_cleanup.yml
+
+  - name: Copy password file to target host.
+    copy:
+      src: "{{ playbook_dir }}/password.txt"
+      dest: "{{ ansible_env.HOME }}/password.txt"
+
+  - name: Copy public key file to target host.
+    copy:
+      src: "{{ playbook_dir }}/public.pem"
+      dest: "{{ ansible_env.HOME }}/public.pem"
+
+  - name: Copy private key file to target host.
+    copy:
+      src: "{{ playbook_dir }}/private.pem"
+      dest: "{{ ansible_env.HOME }}/private.pem"
+
+  - name: Copy input data file to target host.
+    copy:
+      src: "{{ playbook_dir }}/in.txt"
+      dest: "{{ ansible_env.HOME }}/in.txt"
+
+  - name: Ensure vaultgroup exists.
+    ipagroup:
+      ipaadmin_password: SomeADMINpassword
+      name: vaultgroup
+
+  - name: Ensure testing users exist.
+    ipauser:
+      ipaadmin_password: SomeADMINpassword
+      users:
+      - name: user01
+        first: First
+        last: Start
+      - name: user02
+        first: Second
+        last: Middle
+      - name: user03
+        first: Third
+        last: Last
diff --git a/tests/vault/private.pem b/tests/vault/private.pem
deleted file mode 100644
index 0ac895b9252a4293d19fe59f7ac4764745188609..0000000000000000000000000000000000000000
--- a/tests/vault/private.pem
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEArM5/f6dd/YIm/a9eoGVTW8jobEgrf9PXRA3aHsA7kJo6fB18
-HD4+RVUwx/lqlkPYbUi9bXV/rJAkUwAEDOnJeqXESZ+gVCVmigRzmKWK2ad9agmY
-SiqyyNxFIJvZAo0dG4CAWjYK27tLg4Ih6oGsZIDG+WVES5W89K+L0bwVjq4tshhe
-DMO57unvmIKEmaBE0ewPfvkdZh5k8Gts9H4fh0fGk5tbIYa0bhwMUpL+WHOm6nbd
-+n7BbaVc820TgZDO/rSYtnuXaIc6Wx0U9LXZkUmk3apMnzknNaTqguAQdTn79G8P
-qrGqmyWd/E1cH2b5jzIxiGo8psL5sxWVY7WJdwIDAQABAoIBAA6e9iit14UAgx4J
-vX7is9fbOtcWkB+jo94NMfxSFXgZpIMl139oQMqK97KjxsHqAaDVe7mMLH5EP96J
-7M3O5g4rgl0cVWtpMrDQyZsLvqDFzBWxtCHqVPAruumUZhsSJ3lROQro8ag/w5bf
-5tC5ogVq4+rsB4hBphgp1jGrsUM+E8O7DXXFH68F8WgBi725WvcjnbI9irkb0Gcq
-1bCPJwN3fA1i2VWiRwVYWbNTWnDoNM9ZdYYxK0kuUkD+QtreycWPf9V49lvUi1Vp
-FVNmBUDvGK3K1MwbgXRwOXhacY7Ptjkdvaeb2Qcu5RjTkruGhzUYsOP3p/cw+wKV
-vzQqceECgYEA5Wz7V2SlRa2r//z+ETQkJfENJ0KDnCb0pMClCQh3jTNPA6DbhiMk
-FTkcoNbqcpTiVSlvhh6TKscSgqYQUjQ/OqyG7SkjKVjQ72j5beQLxiLTtUyj1OmP
-Xh9cWJXx8iQ+45cPon+kMOAIiTwiB3mmFRfQjIGve1DPUo9J+NZ4XdECgYEAwNKg
-OdGYxxKtCrXVz1mdg6PDlV8qh7nxxZbPch+aMIQl1+oTCgSiw8oOYEd8g0HOdV6t
-1G+IWhvPxiiWy3/AE0QhgoKk2GUsSjWSMLcJbaUzDoEHFjTLjecRlqdzo7qxRXqB
-meN4L5WJYKnLC482K7hvufS+uo5fB5qwPmt13McCgYAe4TVPRP+tyjttYCr+O8tl
-w/UmRKCcQu4Iwtkzxwz4V2CaN2t0uYQgyygcSfESbRGtrr8RCUp7poHKTfnCZr/f
-8NrUTwYpiYfNwY5ZCSnAiG2AaIlgnfMrEwOF9OC028YPMgTrtUxvO6hKeGqIIQqG
-qkbqsoXhDjZpgVnOgWeAEQKBgGuiZ0w/IqAlXbC31fUb2iBMfvXXnJ8M/dfFGmFj
-IKfqbFF9WUljUxQlqya1YNzIFB5STohiBeP+2FmN+Lb5xdc7VdVLZgdhWnrGMqe8
-1Kd+6uQyxCjyKZo5nQjSymtf4GqfOs8TOdieCYSK40u9koiPONa9tuXeaU+OWslN
-JQqrAoGBAJ3MKOvsnQzuZVP2vz0ZqLwIE3XjRiFGveVpizq4hwOVeuNsV08JvA0t
-pueNIy9klPScFc9OUdiZWkEX09BwJkVIrOHotuSB8AStO5UAntNnuyWLJEFC4Uq4
-GpB8lbj9jkxSKaU7X3Gac23K9JL8euLh7E7rPuZRYa6mYN4nbKqu
------END RSA PRIVATE KEY-----
diff --git a/tests/vault/public.pem b/tests/vault/public.pem
deleted file mode 100644
index d8a9f71bf194a0ce9ca48ca54d7cb9e8477e2434..0000000000000000000000000000000000000000
--- a/tests/vault/public.pem
+++ /dev/null
@@ -1,9 +0,0 @@
------BEGIN PUBLIC KEY-----
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArM5/f6dd/YIm/a9eoGVT
-W8jobEgrf9PXRA3aHsA7kJo6fB18HD4+RVUwx/lqlkPYbUi9bXV/rJAkUwAEDOnJ
-eqXESZ+gVCVmigRzmKWK2ad9agmYSiqyyNxFIJvZAo0dG4CAWjYK27tLg4Ih6oGs
-ZIDG+WVES5W89K+L0bwVjq4tshheDMO57unvmIKEmaBE0ewPfvkdZh5k8Gts9H4f
-h0fGk5tbIYa0bhwMUpL+WHOm6nbd+n7BbaVc820TgZDO/rSYtnuXaIc6Wx0U9LXZ
-kUmk3apMnzknNaTqguAQdTn79G8PqrGqmyWd/E1cH2b5jzIxiGo8psL5sxWVY7WJ
-dwIDAQAB
------END PUBLIC KEY-----
diff --git a/tests/vault/tasks_vault_members.yml b/tests/vault/tasks_vault_members.yml
new file mode 100644
index 0000000000000000000000000000000000000000..12332ff1897c2a21318e0fc69d0c67faef86ab76
--- /dev/null
+++ b/tests/vault/tasks_vault_members.yml
@@ -0,0 +1,318 @@
+---
+# Tasks to test member management for Vault module.
+  - name: Setup testing environment.
+    import_tasks: env_setup.yml
+
+  - name: Ensure vault is present
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      vault_type: "{{vault.vault_type}}"
+    register: result
+    failed_when: not result.changed
+    when: vault.vault_type == 'standard'
+
+  - name: Ensure vault is present
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      vault_password: SomeVAULTpassword
+      vault_type: "{{vault.vault_type}}"
+    register: result
+    failed_when: not result.changed
+    when: vault.vault_type == 'symmetric'
+
+  - name: Ensure vault is present
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      vault_type: "{{vault.vault_type}}"
+      public_key: "{{lookup('file', 'private.pem') | b64encode}}"
+    register: result
+    failed_when: not result.changed
+    when: vault.vault_type == 'asymmetric'
+
+  - name: Ensure vault member user is present.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      action: member
+      users:
+      - user02
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure vault member user is present, again.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      action: member
+      users:
+      - user02
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure more vault member users are present.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      action: member
+      users:
+      - admin
+      - user02
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure vault member user is still present.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      action: member
+      users:
+      - user02
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure vault users are absent.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      action: member
+      users:
+      - admin
+      - user02
+      state: absent
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure vault users are absent, again.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      action: member
+      users:
+      - admin
+      - user02
+      state: absent
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure vault user is absent, once more.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      action: member
+      users:
+      - admin
+      state: absent
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure vault member group is present.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      action: member
+      groups: vaultgroup
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure vault member group is present, again.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      action: member
+      groups: vaultgroup
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure vault member group is absent.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      action: member
+      groups: vaultgroup
+      state: absent
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure vault member group is absent, again.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      action: member
+      groups: vaultgroup
+      state: absent
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure vault member service is present.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      action: member
+      services: "HTTP/{{ groups.ipaserver[0] }}"
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure vault member service is present, again.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      action: member
+      services: "HTTP/{{ groups.ipaserver[0] }}"
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure vault member service is absent.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      action: member
+      services: "HTTP/{{ groups.ipaserver[0] }}"
+      state: absent
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure vault member service is absent, again.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      action: member
+      services: "HTTP/{{ groups.ipaserver[0] }}"
+      state: absent
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure user03 is an owner of vault.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      owners: user03
+      action: member
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure user03 is an owner of vault, again.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      owners: user03
+      action: member
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure user03 is not owner of vault.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      owners: user03
+      state: absent
+      action: member
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure user03 is not owner of vault, again.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      owners: user03
+      state: absent
+      action: member
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure vaultgroup is an ownergroup of vault.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      ownergroups: vaultgroup
+      action: member
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure vaultgroup is an ownergroup of vault, again.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      ownergroups: vaultgroup
+      action: member
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure vaultgroup is not ownergroup of vault.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      ownergroups: vaultgroup
+      state: absent
+      action: member
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure vaultgroup is not ownergroup of vault, again.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      ownergroups: vaultgroup
+      state: absent
+      action: member
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure service is an owner of vault.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      ownerservices: "HTTP/{{ groups.ipaserver[0] }}"
+      action: member
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure service is an owner of vault, again.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      ownerservices: "HTTP/{{ groups.ipaserver[0] }}"
+      action: member
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure service is not owner of vault.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      ownerservices: "HTTP/{{ groups.ipaserver[0] }}"
+      state: absent
+      action: member
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure service is not owner of vault, again.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      ownerservices: "HTTP/{{ groups.ipaserver[0] }}"
+      state: absent
+      action: member
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure {{vault.vault_type}} vault is absent
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      state: absent
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure {{vault.vault_type}} vault is absent, again
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: "{{vault.name}}"
+      state: absent
+    register: result
+    failed_when: result.changed
+
+  - name: Cleanup testing environment.
+    import_tasks: env_cleanup.yml
diff --git a/tests/vault/test_vault.yml b/tests/vault/test_vault.yml
deleted file mode 100644
index c0af27007f1a211573f729af8aff50cf243a95a0..0000000000000000000000000000000000000000
--- a/tests/vault/test_vault.yml
+++ /dev/null
@@ -1,929 +0,0 @@
----
-
-- name: Test vault
-  hosts: ipaserver
-  become: true
-  # Need to gather facts for ansible_env.
-  gather_facts: true
-
-  tasks:
-
-  - name: Copy password file to target host.
-    copy:
-      src: "{{ playbook_dir }}/password.txt"
-      dest: "{{ ansible_env.HOME }}/password.txt"
-
-  - name: Copy public key file to target host.
-    copy:
-      src: "{{ playbook_dir }}/public.pem"
-      dest: "{{ ansible_env.HOME }}/public.pem"
-
-  - name: Copy private key file to target host.
-    copy:
-      src: "{{ playbook_dir }}/private.pem"
-      dest: "{{ ansible_env.HOME }}/private.pem"
-
-  - name: Copy input data file to target host.
-    copy:
-      src: "{{ playbook_dir }}/in.txt"
-      dest: "{{ ansible_env.HOME }}/in.txt"
-
-  - name: Ensure user vaults are absent
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name:
-      - stdvault
-      - symvault
-      - asymvault
-      username: user01
-      state: absent
-
-  - name: Ensure test users do not exist.
-    ipauser:
-      ipaadmin_password: SomeADMINpassword
-      name:
-      - user01
-      - user02
-      - user03
-      state: absent
-
-  - name: Ensure test groups do not exist.
-    ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      name: vaultgroup
-      state: absent
-
-  - name: Ensure vaultgroup exists.
-    ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      name: vaultgroup
-
-  - name: Ensure user01 exists.
-    ipauser:
-      ipaadmin_password: SomeADMINpassword
-      name: user01
-      first: First
-      last: Start
-
-  - name: Ensure user02 exists.
-    ipauser:
-      ipaadmin_password: SomeADMINpassword
-      name: user02
-      first: Second
-      last: Middle
-
-  - name: Ensure user03 exists.
-    ipauser:
-      ipaadmin_password: SomeADMINpassword
-      name: user03
-      first: Third
-      last: Last
-
-  - name: Ensure shared vaults are absent
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: sharedvault
-      shared: True
-      state: absent
-
-  - name: Ensure standard vault is absent
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      state: absent
-
-  - name: Ensure service vault is absent
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: svcvault
-      service: "HTTP/{{ groups.ipaserver[0] }}"
-      state: absent
-
-  # tests
-  - name: Ensure standard vault is present
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      vault_type: standard
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure standard vault is present, again
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      vault_type: standard
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure standard vault is absent
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      vault_type: standard
-      state: absent
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure standard vault is absent, again
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      vault_type: standard
-      state: absent
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure symmetric vault is present
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: symvault
-      username: user01
-      vault_password: SomeVAULTpassword
-      vault_type: symmetric
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure symmetric vault is present, again
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: symvault
-      username: user01
-      vault_password: SomeVAULTpassword
-      vault_type: symmetric
-    register: result
-    failed_when: result.changed
-
-  - name: Archive data to symmetric vault
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: symvault
-      username: user01
-      vault_password: SomeVAULTpassword
-      vault_data: Hello World.
-    register: result
-    failed_when: not result.changed
-
-  - name: Archive data with non-ASCII characters to symmetric vault
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: symvault
-      username: user01
-      vault_password: SomeVAULTpassword
-      vault_data: The world of π is half rounded.
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure symmetric vault is absent
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: symvault
-      username: user01
-      state: absent
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure symmetric vault is absent, again
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: symvault
-      username: user01
-      state: absent
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure symmetric vault is present
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: symvault
-      username: user01
-      vault_password: SomeVAULTpassword
-      vault_type: symmetric
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure symmetric vault is present, with a different password
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: symvault
-      username: user01
-      vault_password: SomeOtherVAULTpassword
-      vault_type: symmetric
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure symmetric vault is absent
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: symvault
-      username: user01
-      state: absent
-    register: result
-    failed_when: not result.changed
-
-
-  - name: Ensure symmetric vault is present, with password from file.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: symvault
-      username: user01
-      vault_password_file: "{{ ansible_env.HOME }}/password.txt"
-      vault_type: symmetric
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure symmetric vault is present, with password from file, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: symvault
-      username: user01
-      vault_password_file: password.txt
-      vault_type: symmetric
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure asymmetric vault is present, with public key file.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: asymvault
-      username: admin
-      description: An asymmetric private vault.
-      public_key_file: "{{ ansible_env.HOME }}/public.pem"
-      vault_type: asymmetric
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure asymmetric vault is present, with public key file, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: asymvault
-      username: admin
-      description: An asymmetric private vault.
-      public_key_file: "{{ ansible_env.HOME }}/public.pem"
-      vault_type: asymmetric
-    register: result
-    failed_when: result.changed
-
-  - name: Archive data in asymmetric vault.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: asymvault
-      username: admin
-      vault_data: Hello World.
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure asymmetric vault is absent.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: asymvault
-      username: admin
-      state: absent
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure asymmetric vault is absent, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: asymvault
-      username: admin
-      state: absent
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure asymmetric vault is present.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: asymvault
-      username: user01
-      description: An asymmetric private vault.
-      vault_public_key:
-        LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFyTTUvZjZkZC9ZSW0vYTllb0dWVApXOGpvYkVncmY5UFhSQTNhSHNBN2tKbzZmQjE4SEQ0K1JWVXd4L2xxbGtQWWJVaTliWFYvckpBa1V3QUVET25KCmVxWEVTWitnVkNWbWlnUnptS1dLMmFkOWFnbVlTaXF5eU54RklKdlpBbzBkRzRDQVdqWUsyN3RMZzRJaDZvR3MKWklERytXVkVTNVc4OUsrTDBid1ZqcTR0c2hoZURNTzU3dW52bUlLRW1hQkUwZXdQZnZrZFpoNWs4R3RzOUg0ZgpoMGZHazV0YklZYTBiaHdNVXBMK1dIT202bmJkK243QmJhVmM4MjBUZ1pETy9yU1l0bnVYYUljNld4MFU5TFhaCmtVbWszYXBNbnprbk5hVHFndUFRZFRuNzlHOFBxckdxbXlXZC9FMWNIMmI1anpJeGlHbzhwc0w1c3hXVlk3V0oKZHdJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==
-      vault_type: asymmetric
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure asymmetric vault is present, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: asymvault
-      username: user01
-      description: An asymmetric private vault.
-      vault_public_key:
-        LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFyTTUvZjZkZC9ZSW0vYTllb0dWVApXOGpvYkVncmY5UFhSQTNhSHNBN2tKbzZmQjE4SEQ0K1JWVXd4L2xxbGtQWWJVaTliWFYvckpBa1V3QUVET25KCmVxWEVTWitnVkNWbWlnUnptS1dLMmFkOWFnbVlTaXF5eU54RklKdlpBbzBkRzRDQVdqWUsyN3RMZzRJaDZvR3MKWklERytXVkVTNVc4OUsrTDBid1ZqcTR0c2hoZURNTzU3dW52bUlLRW1hQkUwZXdQZnZrZFpoNWs4R3RzOUg0ZgpoMGZHazV0YklZYTBiaHdNVXBMK1dIT202bmJkK243QmJhVmM4MjBUZ1pETy9yU1l0bnVYYUljNld4MFU5TFhaCmtVbWszYXBNbnprbk5hVHFndUFRZFRuNzlHOFBxckdxbXlXZC9FMWNIMmI1anpJeGlHbzhwc0w1c3hXVlk3V0oKZHdJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==
-      vault_type: asymmetric
-    register: result
-    failed_when: result.changed
-
-  - name: Archive data in asymmetric vault.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: asymvault
-      username: user01
-      vault_data: Hello World.
-    register: result
-    failed_when: not result.changed
-
-  - name: Retrieve data from asymmetric vault.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: asymvault
-      username: user01
-      vault_type: asymmetric
-      retrieve: true
-      private_key:
-        LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBck01L2Y2ZGQvWUltL2E5ZW9HVlRXOGpvYkVncmY5UFhSQTNhSHNBN2tKbzZmQjE4CkhENCtSVlV3eC9scWxrUFliVWk5YlhWL3JKQWtVd0FFRE9uSmVxWEVTWitnVkNWbWlnUnptS1dLMmFkOWFnbVkKU2lxeXlOeEZJSnZaQW8wZEc0Q0FXallLMjd0TGc0SWg2b0dzWklERytXVkVTNVc4OUsrTDBid1ZqcTR0c2hoZQpETU81N3Vudm1JS0VtYUJFMGV3UGZ2a2RaaDVrOEd0czlINGZoMGZHazV0YklZYTBiaHdNVXBMK1dIT202bmJkCituN0JiYVZjODIwVGdaRE8vclNZdG51WGFJYzZXeDBVOUxYWmtVbWszYXBNbnprbk5hVHFndUFRZFRuNzlHOFAKcXJHcW15V2QvRTFjSDJiNWp6SXhpR284cHNMNXN4V1ZZN1dKZHdJREFRQUJBb0lCQUE2ZTlpaXQxNFVBZ3g0Sgp2WDdpczlmYk90Y1drQitqbzk0Tk1meFNGWGdacElNbDEzOW9RTXFLOTdLanhzSHFBYURWZTdtTUxINUVQOTZKCjdNM081ZzRyZ2wwY1ZXdHBNckRReVpzTHZxREZ6Qld4dENIcVZQQXJ1dW1VWmhzU0ozbFJPUXJvOGFnL3c1YmYKNXRDNW9nVnE0K3JzQjRoQnBoZ3Axakdyc1VNK0U4TzdEWFhGSDY4RjhXZ0JpNzI1V3Zjam5iSTlpcmtiMEdjcQoxYkNQSndOM2ZBMWkyVldpUndWWVdiTlRXbkRvTk05WmRZWXhLMGt1VWtEK1F0cmV5Y1dQZjlWNDlsdlVpMVZwCkZWTm1CVUR2R0szSzFNd2JnWFJ3T1hoYWNZN1B0amtkdmFlYjJRY3U1UmpUa3J1R2h6VVlzT1AzcC9jdyt3S1YKdnpRcWNlRUNnWUVBNVd6N1YyU2xSYTJyLy96K0VUUWtKZkVOSjBLRG5DYjBwTUNsQ1FoM2pUTlBBNkRiaGlNawpGVGtjb05icWNwVGlWU2x2aGg2VEtzY1NncVlRVWpRL09xeUc3U2tqS1ZqUTcyajViZVFMeGlMVHRVeWoxT21QClhoOWNXSlh4OGlRKzQ1Y1BvbitrTU9BSWlUd2lCM21tRlJmUWpJR3ZlMURQVW85SitOWjRYZEVDZ1lFQXdOS2cKT2RHWXh4S3RDclhWejFtZGc2UERsVjhxaDdueHhaYlBjaCthTUlRbDErb1RDZ1NpdzhvT1lFZDhnMEhPZFY2dAoxRytJV2h2UHhpaVd5My9BRTBRaGdvS2syR1VzU2pXU01MY0piYVV6RG9FSEZqVExqZWNSbHFkem83cXhSWHFCCm1lTjRMNVdKWUtuTEM0ODJLN2h2dWZTK3VvNWZCNXF3UG10MTNNY0NnWUFlNFRWUFJQK3R5anR0WUNyK084dGwKdy9VbVJLQ2NRdTRJd3Rrenh3ejRWMkNhTjJ0MHVZUWd5eWdjU2ZFU2JSR3RycjhSQ1VwN3BvSEtUZm5DWnIvZgo4TnJVVHdZcGlZZk53WTVaQ1NuQWlHMkFhSWxnbmZNckV3T0Y5T0MwMjhZUE1nVHJ0VXh2TzZoS2VHcUlJUXFHCnFrYnFzb1hoRGpacGdWbk9nV2VBRVFLQmdHdWlaMHcvSXFBbFhiQzMxZlViMmlCTWZ2WFhuSjhNL2RmRkdtRmoKSUtmcWJGRjlXVWxqVXhRbHF5YTFZTnpJRkI1U1RvaGlCZVArMkZtTitMYjV4ZGM3VmRWTFpnZGhXbnJHTXFlOAoxS2QrNnVReXhDanlLWm81blFqU3ltdGY0R3FmT3M4VE9kaWVDWVNLNDB1OWtvaVBPTmE5dHVYZWFVK09Xc2xOCkpRcXJBb0dCQUozTUtPdnNuUXp1WlZQMnZ6MFpxTHdJRTNYalJpRkd2ZVZwaXpxNGh3T1ZldU5zVjA4SnZBMHQKcHVlTkl5OWtsUFNjRmM5T1VkaVpXa0VYMDlCd0prVklyT0hvdHVTQjhBU3RPNVVBbnRObnV5V0xKRUZDNFVxNApHcEI4bGJqOWpreFNLYVU3WDNHYWMyM0s5Skw4ZXVMaDdFN3JQdVpSWWE2bVlONG5iS3F1Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
-    register: result
-    failed_when: result.data | b64decode != 'Hello World.' or result.changed
-
-  - name: Retrieve data from asymmetric vault, with private key file.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: asymvault
-      username: user01
-      vault_type: asymmetric
-      retrieve: true
-      private_key_file: "{{ ansible_env.HOME }}/private.pem"
-    register: result
-    failed_when: result.data | b64decode != 'Hello World.' or result.changed
-
-  - name: Ensure asymmetric vault is absent.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: asymvault
-      username: user01
-      state: absent
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure asymmetric vault is absent, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: asymvault
-      username: user01
-      state: absent
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure standard vault is present.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      vault_type: standard
-      username: user01
-      description: A standard private vault.
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure standard vault is present, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      vault_type: standard
-      description: A standard private vault.
-    register: result
-    failed_when: result.changed
-
-  - name: Archive data in standard vault.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      vault_data: Hello World.
-    register: result
-    failed_when: not result.changed
-
-  - name: Retrieve data from standard vault.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      retrieve: yes
-      out: "{{ ansible_env.HOME }}/data.txt"
-    register: result
-    failed_when: result.changed
-
-  - name: Verify retrieved data.
-    slurp:
-      src: "{{ ansible_env.HOME }}/data.txt"
-    register: slurpfile
-    failed_when: slurpfile['content'] | b64decode != 'Hello World.'
-
-  - name: Archive data in standard vault.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      in: "{{ ansible_env.HOME }}/in.txt"
-    register: result
-    failed_when: not result.changed
-
-  - name: Retrieve data from standard vault.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      vault_type: standard
-      retrieve: true
-    register: result
-    failed_when: result.data | b64decode != 'Another World.' or result.changed
-
-  - name: Ensure standard vault member user is present.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      action: member
-      users:
-      - user02
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure standard vault member user is present, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      action: member
-      users:
-      - user02
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure more vault member users are present.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      action: member
-      users:
-      - user01
-      - user02
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure vault member user is still present.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      action: member
-      users:
-      - user02
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure vault users are absent.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      action: member
-      users:
-      - user01
-      - user02
-      state: absent
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure vault users are absent, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      action: member
-      users:
-      - user01
-      - user02
-      state: absent
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure vault user is absent, once more.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      action: member
-      users:
-      - user01
-      state: absent
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure vault member group is present.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      action: member
-      groups: vaultgroup
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure vault member group is present, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      action: member
-      groups: vaultgroup
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure vault member group is absent.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      action: member
-      groups: vaultgroup
-      state: absent
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure vault member group is absent, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      action: member
-      groups: vaultgroup
-      state: absent
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure vault member service is present.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      action: member
-      services: "HTTP/{{ groups.ipaserver[0] }}"
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure vault member service is present, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      action: member
-      services: "HTTP/{{ groups.ipaserver[0] }}"
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure vault member service is absent.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      action: member
-      services: "HTTP/{{ groups.ipaserver[0] }}"
-      state: absent
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure vault member service is absent, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      action: member
-      services: "HTTP/{{ groups.ipaserver[0] }}"
-      state: absent
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure vault is absent.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      state: absent
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure vault is absent, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      state: absent
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure shared vault is present.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: sharedvault
-      shared: True
-      ipavaultpassword: SomeVAULTpassword
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure shared vault is absent.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: sharedvault
-      shared: True
-      state: absent
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure service vault is present.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: svcvault
-      ipavaultpassword: SomeVAULTpassword
-      service: "HTTP/{{ groups.ipaserver[0] }}"
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure service vault is absent.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: svcvault
-      service: "HTTP/{{ groups.ipaserver[0] }}"
-      state: absent
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure vault is present, with members.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      vault_type: standard
-      users:
-      - user02
-      - user03
-      groups:
-      - vaultgroup
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure vault is present, with members, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      vault_type: standard
-      users:
-      - user02
-      - user03
-      groups:
-      - vaultgroup
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure user02 is not a member of vault stdvault.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      users: user02
-      state: absent
-      action: member
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure user02 is not a member of vault stdvault, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      users: user02
-      state: absent
-      action: member
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure user02 is a member of vault stdvault.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      users: user02
-      action: member
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure user02 is a member of vault stdvault, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      users: user03
-      action: member
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure user03 owns vault stdvault.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      owners: user03
-      action: member
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure user03 owns vault stdvault, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      owners: user03
-      action: member
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure user03 is not owner of stdvault.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      owners: user03
-      state: absent
-      action: member
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure user03 is not owner of stdvault, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      owners: user03
-      state: absent
-      action: member
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure vaultgroup is owner of stdvault.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      ownergroups: vaultgroup
-      action: member
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure vaultgroup is owner of stdvault, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      ownergroups: vaultgroup
-      action: member
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure vaultgroup is not owner of stdvault.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      ownergroups: vaultgroup
-      state: absent
-      action: member
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure vaultgroup is not owner of stdvault, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      ownergroups: vaultgroup
-      state: absent
-      action: member
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure vault is owned by HTTP service.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      ownerservices: "HTTP/{{ groups.ipaserver[0] }}"
-      action: member
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure vault is owned by HTTP service, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      ownerservices: "HTTP/{{ groups.ipaserver[0] }}"
-      action: member
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure vault is not owned by HTTP service.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      ownerservices: "HTTP/{{ groups.ipaserver[0] }}"
-      state: absent
-      action: member
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure vault is not owned by HTTP service, again.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      ownerservices: "HTTP/{{ groups.ipaserver[0] }}"
-      state: absent
-      action: member
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure vault is absent.
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: stdvault
-      username: user01
-      state: absent
-
-  # cleaup
-  - name: Ensure user01 vaults are absent
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name:
-      - stdvault
-      - symvault
-      - asymvault
-      username: user01
-      state: absent
-
-  - name: Ensure test vaults are absent
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name:
-      - stdvault
-      - symvault
-      - asymvault
-      username: admin
-      state: absent
-
-  - name: Ensure shared vaults are absent
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: sharedvault
-      shared: True
-      state: absent
-
-  - name: Ensure service vaults are absent
-    ipavault:
-      ipaadmin_password: SomeADMINpassword
-      name: svcvault
-      service: "HTTP/{{ groups.ipaserver[0] }}"
-      state: absent
-
-  - name: Ensure test users do not exist.
-    ipauser:
-      ipaadmin_password: SomeADMINpassword
-      name:
-      - user01
-      - user02
-      - user03
-      state: absent
-
-  - name: Ensure test groups do not exist.
-    ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      name: vaultgroup
-      state: absent
-
-  - name: Remove password file from target host.
-    file:
-      path: "{{ ansible_env.HOME }}/password.txt"
-      state: absent
-
-  - name: Remove public key file from target host.
-    file:
-      path: "{{ ansible_env.HOME }}/public.pem"
-      state: absent
-
-  - name: Remove private key file from target host.
-    file:
-      path: "{{ ansible_env.HOME }}/private.pem"
-      state: absent
-
-  - name: Remove output data file from target host.
-    file:
-      path: "{{ ansible_env.HOME }}/data.txt"
-      state: absent
-
-  - name: Remove input data file from target host.
-    file:
-      path: "{{ ansible_env.HOME }}/in.txt"
-      state: absent
diff --git a/tests/vault/test_vault_asymmetric.yml b/tests/vault/test_vault_asymmetric.yml
new file mode 100644
index 0000000000000000000000000000000000000000..1a1d3dcab5ca1d6248c27ace0d8a928c015733aa
--- /dev/null
+++ b/tests/vault/test_vault_asymmetric.yml
@@ -0,0 +1,192 @@
+---
+- name: Test vault
+  hosts: ipaserver
+  become: true
+  # Need to gather facts for ansible_env.
+  gather_facts: true
+
+  tasks:
+  - name: Setup testing environment.
+    import_tasks: env_setup.yml
+
+  - name: Ensure asymmetric vault is present
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: asymvault
+      vault_type: asymmetric
+      public_key: "{{ lookup('file', 'public.pem') | b64encode }}"
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure asymmetric vault is present, again
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: asymvault
+      vault_type: asymmetric
+      public_key: "{{ lookup('file', 'public.pem') | b64encode }}"
+    register: result
+    failed_when: result.changed
+
+  - name: Archive data to asymmetric vault
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: asymvault
+      data: Hello World.
+    register: result
+    failed_when: not result.changed
+
+  - name: Retrieve data from asymmetric vault.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: asymvault
+      private_key: "{{ lookup('file', 'private.pem') | b64encode }}"
+      state: retrieved
+    register: result
+    failed_when: result.data != 'Hello World.' or result.changed
+
+  - name: Retrieve data from asymmetric vault into file {{ ansible_env.HOME }}/data.txt.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: asymvault
+      out: "{{ ansible_env.HOME }}/data.txt"
+      private_key: "{{ lookup('file', 'private.pem') | b64encode }}"
+      state: retrieved
+    register: result
+    failed_when: result.changed
+
+  - name: Verify retrieved data.
+    slurp:
+      src: "{{ ansible_env.HOME }}/data.txt"
+    register: slurpfile
+    failed_when: slurpfile['content'] | b64decode != 'Hello World.'
+
+  - name: Archive data with non-ASCII characters to asymmetric vault
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: asymvault
+      data: The world of π is half rounded.
+    register: result
+    failed_when: not result.changed
+
+  - name: Retrieve data from asymmetric vault.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: asymvault
+      private_key: "{{ lookup('file', 'private.pem') | b64encode }}"
+      state: retrieved
+    register: result
+    failed_when: result.data != 'The world of π is half rounded.' or result.changed
+
+  - name: Archive data in asymmetric vault, from file.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: asymvault
+      vault_type: asymmetric
+      in: "{{ ansible_env.HOME }}/in.txt"
+    register: result
+    failed_when: not result.changed
+
+  - name: Retrieve data from asymmetric vault.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: asymvault
+      private_key: "{{ lookup('file', 'private.pem') | b64encode }}"
+      state: retrieved
+    register: result
+    failed_when: result.data != 'Another World.' or result.changed
+
+  - name: Archive data with single character to asymmetric vault
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: asymvault
+      data: c
+    register: result
+    failed_when: not result.changed
+
+  - name: Retrieve data from asymmetric vault.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: asymvault
+      private_key: "{{ lookup('file', 'private.pem') | b64encode }}"
+      state: retrieved
+    register: result
+    failed_when: result.data != 'c' or result.changed
+
+  - name: Ensure asymmetric vault is absent
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: asymvault
+      state: absent
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure asymmetric vault is absent, again
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: asymvault
+      state: absent
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure asymmetric vault is present, with public key from file.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: asymvault
+      public_key_file: "{{ ansible_env.HOME }}/public.pem"
+      vault_type: asymmetric
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure asymmetric vault is present, with password from file, again.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: asymvault
+      public_key_file: "{{ ansible_env.HOME }}/public.pem"
+      vault_type: asymmetric
+    register: result
+    failed_when: result.changed
+
+  - name: Archive data to asymmetric vault
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: asymvault
+      data: Hello World.
+    register: result
+    failed_when: not result.changed
+
+  - name: Retrieve data from asymmetric vault.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: asymvault
+      private_key: "{{ lookup('file', 'private.pem') | b64encode }}"
+      state: retrieved
+    register: result
+    failed_when: result.data != 'Hello World.' or result.changed
+
+  - name: Retrieve data from asymmetric vault, with password file.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: asymvault
+      private_key_file: "{{ ansible_env.HOME }}/private.pem"
+      state: retrieved
+    register: result
+    failed_when: result.data != 'Hello World.' or result.changed
+
+  - name: Ensure asymmetric vault is absent
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: asymvault
+      state: absent
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure asymmetric vault is absent, again
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: asymvault
+      state: absent
+    register: result
+    failed_when: result.changed
+
+  - name: Cleanup testing environment.
+    import_tasks: env_setup.yml
diff --git a/tests/vault/test_vault_members.yml b/tests/vault/test_vault_members.yml
new file mode 100644
index 0000000000000000000000000000000000000000..219236aef176b86732f3a501b17172e0e5415da5
--- /dev/null
+++ b/tests/vault/test_vault_members.yml
@@ -0,0 +1,20 @@
+---
+- name: Test vault
+  hosts: ipaserver
+  become: true
+  # Need to gather facts for ansible_env.
+  gather_facts: true
+
+  tasks:
+  - name: Test vault module member operations.
+    include_tasks:
+      file: tasks_vault_members.yml
+      apply:
+        tags:
+          - "{{ vault.vault_type }}"
+    loop_control:
+        loop_var: vault
+    loop:
+      - { name: "stdvault", vault_type: "standard" }
+      - { name: "symvault", vault_type: "symmetric" }
+      - { name: "asymvault", vault_type: "asymmetric" }
diff --git a/tests/vault/test_vault_standard.yml b/tests/vault/test_vault_standard.yml
new file mode 100644
index 0000000000000000000000000000000000000000..5e0da98e647c9eda079a40cae7098bae137795e1
--- /dev/null
+++ b/tests/vault/test_vault_standard.yml
@@ -0,0 +1,125 @@
+---
+- name: Test vault
+  hosts: ipaserver
+  become: true
+  # Need to gather facts for ansible_env.
+  gather_facts: true
+
+  tasks:
+  - name: Setup testing environment.
+    import_tasks: env_setup.yml
+
+  - name: Ensure standard vault is present
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: stdvault
+      vault_type: standard
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure standard vault is present, again
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: stdvault
+      vault_type: standard
+    register: result
+    failed_when: result.changed
+
+  - name: Archive data to standard vault
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: stdvault
+      vault_data: Hello World.
+    register: result
+    failed_when: not result.changed
+
+  - name: Retrieve data from standard vault.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: stdvault
+      state: retrieved
+    register: result
+    failed_when: result.data != 'Hello World.' or result.changed
+
+  - name: Retrieve data from standard vault into file {{ ansible_env.HOME }}/data.txt.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: stdvault
+      out: "{{ ansible_env.HOME }}/data.txt"
+      state: retrieved
+    register: result
+    failed_when: result.changed
+
+  - name: Verify retrieved data.
+    slurp:
+      src: "{{ ansible_env.HOME }}/data.txt"
+    register: slurpfile
+    failed_when: slurpfile['content'] | b64decode != 'Hello World.'
+
+  - name: Archive data with non-ASCII characters to standard vault
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: stdvault
+      vault_data: The world of π is half rounded.
+    register: result
+    failed_when: not result.changed
+
+  - name: Retrieve data from standard vault.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: stdvault
+      state: retrieved
+    register: result
+    failed_when: result.data != 'The world of π is half rounded.' or result.changed
+
+  - name: Archive data in standard vault, from file.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: stdvault
+      vault_type: standard
+      in: "{{ ansible_env.HOME }}/in.txt"
+    register: result
+    failed_when: not result.changed
+
+  - name: Retrieve data from standard vault.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: stdvault
+      state: retrieved
+    register: result
+    failed_when: result.data != 'Another World.' or result.changed
+
+  - name: Archive data with single character to standard vault
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: stdvault
+      vault_data: c
+    register: result
+    failed_when: not result.changed
+
+  - name: Retrieve data from standard vault.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: stdvault
+      state: retrieved
+    register: result
+    failed_when: result.data != 'c' or result.changed
+
+  - name: Ensure standard vault is absent
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: stdvault
+      state: absent
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure standard vault is absent, again
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: stdvault
+      state: absent
+    register: result
+    failed_when: result.changed
+
+  - name: Cleanup testing environment.
+    import_tasks: env_setup.yml
diff --git a/tests/vault/test_vault_symmetric.yml b/tests/vault/test_vault_symmetric.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c9429f4f6d3264c25296003c3f93d16c2d3ab686
--- /dev/null
+++ b/tests/vault/test_vault_symmetric.yml
@@ -0,0 +1,198 @@
+---
+- name: Test vault
+  hosts: ipaserver
+  become: true
+  # Need to gather facts for ansible_env.
+  gather_facts: true
+
+  tasks:
+  - name: Setup testing environment.
+    import_tasks: env_setup.yml
+
+  - name: Ensure symmetric vault is present
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: symvault
+      vault_type: symmetric
+      password: SomeVAULTpassword
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure symmetric vault is present, again
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: symvault
+      vault_type: symmetric
+      password: SomeVAULTpassword
+    register: result
+    failed_when: result.changed
+
+  - name: Archive data to symmetric vault
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: symvault
+      vault_data: Hello World.
+      password: SomeVAULTpassword
+    register: result
+    failed_when: not result.changed
+
+  - name: Retrieve data from symmetric vault.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: symvault
+      password: SomeVAULTpassword
+      state: retrieved
+    register: result
+    failed_when: result.data != 'Hello World.' or result.changed
+
+  - name: Retrieve data from symmetric vault into file {{ ansible_env.HOME }}/data.txt.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: symvault
+      password: SomeVAULTpassword
+      out: "{{ ansible_env.HOME }}/data.txt"
+      state: retrieved
+    register: result
+    failed_when: result.changed
+
+  - name: Verify retrieved data.
+    slurp:
+      src: "{{ ansible_env.HOME }}/data.txt"
+    register: slurpfile
+    failed_when: slurpfile['content'] | b64decode != 'Hello World.'
+
+  - name: Archive data with non-ASCII characters to symmetric vault
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: symvault
+      password: SomeVAULTpassword
+      vault_data: The world of π is half rounded.
+    register: result
+    failed_when: not result.changed
+
+  - name: Retrieve data from symmetric vault.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: symvault
+      password: SomeVAULTpassword
+      state: retrieved
+    register: result
+    failed_when: result.data != 'The world of π is half rounded.' or result.changed
+
+  - name: Archive data in symmetric vault, from file.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: symvault
+      in: "{{ ansible_env.HOME }}/in.txt"
+      password: SomeVAULTpassword
+    register: result
+    failed_when: not result.changed
+
+  - name: Retrieve data from symmetric vault.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: symvault
+      password: SomeVAULTpassword
+      state: retrieved
+    register: result
+    failed_when: result.data != 'Another World.' or result.changed
+
+  - name: Archive data with single character to symmetric vault
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: symvault
+      password: SomeVAULTpassword
+      vault_data: c
+    register: result
+    failed_when: not result.changed
+
+  - name: Retrieve data from symmetric vault.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: symvault
+      password: SomeVAULTpassword
+      state: retrieved
+    register: result
+    failed_when: result.data != 'c' or result.changed
+
+  - name: Ensure symmetric vault is absent
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: symvault
+      state: absent
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure symmetric vault is absent, again
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: symvault
+      state: absent
+    register: result
+    failed_when: result.changed
+
+  - name: Ensure symmetric vault is present, with password from file.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: symvault
+      username: user01
+      password_file: "{{ ansible_env.HOME }}/password.txt"
+      vault_type: symmetric
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure symmetric vault is present, with password from file, again.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: symvault
+      username: user01
+      password_file: "{{ ansible_env.HOME }}/password.txt"
+      vault_type: symmetric
+    register: result
+    failed_when: result.changed
+
+  - name: Archive data to symmetric vault
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: symvault
+      vault_data: Hello World.
+      password: SomeVAULTpassword
+    register: result
+    failed_when: not result.changed
+
+  - name: Retrieve data from symmetric vault.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: symvault
+      password: SomeVAULTpassword
+      state: retrieved
+    register: result
+    failed_when: result.data != 'Hello World.' or result.changed
+
+  - name: Retrieve data from symmetric vault, with password file.
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: symvault
+      password_file: "{{ ansible_env.HOME }}/password.txt"
+      state: retrieved
+    register: result
+    failed_when: result.data != 'Hello World.' or result.changed
+
+  - name: Ensure symmetric vault is absent
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: symvault
+      state: absent
+    register: result
+    failed_when: not result.changed
+
+  - name: Ensure symmetric vault is absent, again
+    ipavault:
+      ipaadmin_password: SomeADMINpassword
+      name: symvault
+      state: absent
+    register: result
+    failed_when: result.changed
+
+  - name: Cleanup testing environment.
+    import_tasks: env_cleanup.yml