diff --git a/roles/ipaclient/defaults/main.yml b/roles/ipaclient/defaults/main.yml
index 890f35fde53889f7534488182e8391e4bfc1c52f..892fac4258bbb01e59c2f84f2575d2a1a373c817 100644
--- a/roles/ipaclient/defaults/main.yml
+++ b/roles/ipaclient/defaults/main.yml
@@ -12,12 +12,18 @@ ipaclient_no_dns_lookup: no
 ipaclient_ssh_trust_dns: no
 ipaclient_no_ssh: no
 ipaclient_no_sshd: no
+ipaclient_no_sudo: no
 #ipaclient_no_dns_sshfp: no
 #ipaclient_force: no
 ipaclient_force_ntpd: no
 ipaclient_no_nisdomain: no
 ipaclient_configure_firefox: no
 ipahost_all_ip_addresses: no
+ipassd_fixed_primary: no
+ipassd_permit: no
+ipassd_enable_dns_updates: no
+ipassd_no_krb5_offline_passwords: no
+ipassd_preserve_sssd: no
 
 ### packages ###
 ipaclient_install_packages: yes
diff --git a/roles/ipaclient/library/ipaclient_setup_sssd.py b/roles/ipaclient/library/ipaclient_setup_sssd.py
index e486f3543b42b9d0a7a226076873549dfdbd199c..f4833562e3a9fc12b59738ce526d3cf8dee29315 100644
--- a/roles/ipaclient/library/ipaclient_setup_sssd.py
+++ b/roles/ipaclient/library/ipaclient_setup_sssd.py
@@ -30,10 +30,10 @@ ANSIBLE_METADATA = {
 
 DOCUMENTATION = '''
 ---
-module: ipaclient_setup_sssd
-short description: Configure sssd for IPA client
+module: ipaclient_setup_ssd
+short description: Setup sssd for IPA client
 description:
-  Configure sssd for IPA client
+  Setup sssd for IPA client
 options:
   servers:
     description: The FQDN of the IPA servers to connect to.
@@ -48,27 +48,33 @@ options:
   hostname:
     description: The hostname of the machine to join (FQDN).
     required: true
-  services:
-    description: The services that should be enabled in the ssd configuration.
-    required: true
-    type: list
-  krb5_offline_passwords:
-    description: Whether user passwords are stored when the server is offline.
+  on_master:
+    description: Whether the configuration is done on the master or not.
     required: false
     type: bool
     default: no
-  on_master:
-    description: Whether the configuration is done on the master or not.
+  no_ssh:
+    description: Do not configure OpenSSH client
     required: false
     type: bool
     default: no
-  primary:
-    description: Whether to use fixed server as primary IPA server.
+  no_sshd:
+    description: Do not configure OpenSSH server
     required: false
     type: bool
     default: no
-  preserve_sssd:
-    description: Preserve old SSSD configuration if possible.
+  no_sudo:
+    description: Do not configure SSSD as data source for sudo
+    required: false
+    type: bool
+    default: no
+  all_ip_addresses:
+    description: All routable IP addresses configured on any interface will be added to DNS.
+    required: false
+    type: bool
+    default: no
+  fixed_primary:
+    description: Whether to use fixed server as primary IPA server.
     required: false
     type: bool
     default: no
@@ -77,13 +83,18 @@ options:
     required: false
     type: bool
     default: no
-  dns_updates:
+  enable_dns_updates:
     description: Configures the machine to attempt dns updates when the ip address changes.
     required: false
     type: bool
     default: no
-  all_ip_addresses:
-    description: All routable IP addresses configured on any interface will be added to DNS.
+  preserve_sssd:
+    description: Preserve old SSSD configuration if possible.
+    required: false
+    type: bool
+    default: no
+  no_krb5_offline_passwords:
+    description: Whether user passwords are stored when the server is offline.
     required: false
     type: bool
     default: no
@@ -98,32 +109,15 @@ EXAMPLES = '''
     domain: example.com
     realm: EXAMPLE.COM
     hostname: client1.example.com
-    services: ["ssh", "sudo"]
-    cache_credentials: yes
-    krb5_offline_passwords: yes
+    no_krb5_offline_passwords: yes
 '''
 
 RETURN = '''
 '''
 
-import os
-import sys
-import tempfile
-import SSSDConfig
-
 from ansible.module_utils.basic import AnsibleModule
 from ansible.module_utils.ansible_ipa_client import *
 
-def sssd_enable_service(module, sssdconfig, service):
-    try:
-        sssdconfig.new_service(service)
-    except SSSDConfig.ServiceAlreadyExists:
-        pass
-    except SSSDConfig.ServiceNotRecognizedError:
-        module.fail_json(
-            msg="Unable to activate the %s service in SSSD config." % service)
-    sssdconfig.activate_service(service)
-
 def main():
     module = AnsibleModule(
         argument_spec = dict(
@@ -131,149 +125,54 @@ def main():
             domain=dict(required=True),
             realm=dict(required=True),
             hostname=dict(required=True),
-            services=dict(required=True, type='list'),
-            krb5_offline_passwords=dict(required=False, type='bool'),
             on_master=dict(required=False, type='bool'),
-            primary=dict(required=False, type='bool'),
-            preserve_sssd=dict(required=False, type='bool'),
-            permit=dict(required=False, type='bool'),
-            dns_updates=dict(required=False, type='bool'),
+            no_ssh=dict(required=False, type='bool'),
+            no_sshd=dict(required=False, type='bool'),
+            no_sudo=dict(required=False, type='bool'),
             all_ip_addresses=dict(required=False, type='bool'),
+
+            fixed_primary=dict(required=False, type='bool'),
+            permit=dict(required=False, type='bool'),
+            enable_dns_updates=dict(required=False, type='bool'),
+            preserve_sssd=dict(required=False, type='bool'),
+            no_krb5_offline_passwords=dict(required=False, type='bool'),
         ),
         supports_check_mode = True,
     )
+    #ansible_log = AnsibleModuleLog(module, logger)
+    #options.set_logger(ansible_log)
 
     module._ansible_debug = True
-    cli_servers = module.params.get('servers')
+    cli_server = module.params.get('servers')
     cli_domain = module.params.get('domain')
     cli_realm = module.params.get('realm')
-    client_hostname = module.params.get('hostname')
-    services = module.params.get('services')
-    krb5_offline_passwords = module.params.get('krb5_offline_passwords')
-    on_master = module.params.get('on_master')
-    primary = module.params.get('primary')
-    preserve_sssd = module.params.get('preserve_sssd')
-    permit = module.params.get('permit')
-    dns_updates = module.params.get('dns_updates')
-    all_ip_addresses = module.params.get('all_ip_addresses')
+    hostname = module.params.get('hostname')
+    options.on_master = module.params.get('on_master')
+
+    options.no_ssh = module.params.get('no_ssh')
+    options.conf_ssh = not options.no_ssh
+    options.no_sshd = module.params.get('no_sshd')
+    options.conf_sshd = not options.no_sshd
+    options.no_sudo = module.params.get('no_sudo')
+    options.conf_sudo = not options.no_sudo
+    options.all_ip_addresses = module.params.get('all_ip_addresses')
+
+    options.primary = module.params.get('fixed_primary')
+    options.permit = module.params.get('permit')
+    options.dns_updates = module.params.get('enable_dns_updates')
+    options.preserve_sssd = module.params.get('preserve_sssd')
+
+    options.no_krb5_offline_passwords = module.params.get(
+        'krb5_offline_passwords')
+    options.krb5_offline_passwords = not options.no_krb5_offline_passwords
 
     fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
-    client_domain = client_hostname[client_hostname.find(".")+1:]
-
-    try:
-        sssdconfig = SSSDConfig.SSSDConfig()
-        sssdconfig.import_config()
-    except Exception as e:
-        if os.path.exists(paths.SSSD_CONF) and preserve_sssd:
-            # SSSD config is in place but we are unable to read it
-            # In addition, we are instructed to preserve it
-            # This all means we can't use it and have to bail out
-            module.fail_json(
-                msg="SSSD config exists but cannot be parsed: %s" % str(e))
-
-        # SSSD configuration does not exist or we are not asked to preserve it,
-        # create new one
-        # We do make new SSSDConfig instance because IPAChangeConf-derived
-        # classes have no means to reset their state and ParseError exception
-        # could come due to parsing error from older version which cannot be
-        # upgraded anymore, leaving sssdconfig instance practically unusable
-        # Note that we already backed up sssd.conf before going into this
-        # routine
-        if isinstance(e, IOError):
-            pass
-        else:
-            # It was not IOError so it must have been parsing error
-            module.fail_json(msg="Unable to parse existing SSSD config.")
-
-        module.log("New SSSD config will be created")
-        sssdconfig = SSSDConfig.SSSDConfig()
-        sssdconfig.new_config()
-
-    try:
-        domain = sssdconfig.new_domain(cli_domain)
-    except SSSDConfig.DomainAlreadyExistsError:
-        module.log("Domain %s is already configured in existing SSSD "
-                   "config, creating a new one." % cli_domain)
-        sssdconfig = SSSDConfig.SSSDConfig()
-        sssdconfig.new_config()
-        domain = sssdconfig.new_domain(cli_domain)
-
-    if on_master:
-        sssd_enable_service(module, sssdconfig, 'ifp')
-
-    if (("ssh" in services and os.path.isfile(paths.SSH_CONFIG)) or
-        ("sshd" in services and os.path.isfile(paths.SSHD_CONFIG))):
-        sssd_enable_service(module, sssdconfig, 'ssh')
-
-    if "sudo" in services:
-        sssd_enable_service(module, sssdconfig, 'sudo')
-        configure_nsswitch_database(fstore, 'sudoers', ['sss'],
-                                    default_value=['files'])
-
-    domain.add_provider('ipa', 'id')
-
-    # add discovery domain if client domain different from server domain
-    # do not set this config in server mode (#3947)
-    if not on_master and cli_domain != client_domain:
-        domain.set_option('dns_discovery_domain', cli_domain)
-
-    if not on_master:
-        if primary:
-            domain.set_option('ipa_server', ', '.join(cli_servers))
-        else:
-            domain.set_option('ipa_server',
-                              '_srv_, %s' % ', '.join(cli_servers))
-    else:
-        domain.set_option('ipa_server_mode', 'True')
-        # the master should only use itself for Kerberos
-        domain.set_option('ipa_server', cli_servers[0])
-
-        # increase memcache timeout to 10 minutes when in server mode
-        try:
-            nss_service = sssdconfig.get_service('nss')
-        except SSSDConfig.NoServiceError:
-            nss_service = sssdconfig.new_service('nss')
-
-        nss_service.set_option('memcache_timeout', 600)
-        sssdconfig.save_service(nss_service)
-
-    domain.set_option('ipa_domain', cli_domain)
-    domain.set_option('ipa_hostname', client_hostname)
-    if cli_domain.lower() != cli_realm.lower():
-        domain.set_option('krb5_realm', cli_realm)
-
-    # Might need this if /bin/hostname doesn't return a FQDN
-    # domain.set_option('ipa_hostname', 'client.example.com')
-
-    domain.add_provider('ipa', 'auth')
-    domain.add_provider('ipa', 'chpass')
-    if not permit:
-        domain.add_provider('ipa', 'access')
-    else:
-        domain.add_provider('permit', 'access')
-
-    domain.set_option('cache_credentials', True)
-
-    # SSSD will need TLS for checking if ipaMigrationEnabled attribute is set
-    # Note that SSSD will force StartTLS because the channel is later used for
-    # authentication as well if password migration is enabled. Thus set
-    # the option unconditionally.
-    domain.set_option('ldap_tls_cacert', paths.IPA_CA_CRT)
-
-    if dns_updates:
-        domain.set_option('dyndns_update', True)
-        if all_ip_addresses:
-            domain.set_option('dyndns_iface', '*')
-        else:
-            iface = get_server_connection_interface(cli_servers[0])
-            domain.set_option('dyndns_iface', iface)
-    if krb5_offline_passwords:
-        domain.set_option('krb5_store_password_if_offline', True)
-
-    domain.set_active(True)
+    client_domain = hostname[hostname.find(".")+1:]
 
-    sssdconfig.save_domain(domain)
-    sssdconfig.write(paths.SSSD_CONF)
+    if configure_sssd_conf(fstore, cli_realm, cli_domain, cli_server,
+                           options, client_domain, hostname):
+        module.fail_json("configure_sssd_conf failed")
+    logger.info("Configured /etc/sssd/sssd.conf")
 
     module.exit_json(changed=True)
 
diff --git a/roles/ipaclient/tasks/install.yml b/roles/ipaclient/tasks/install.yml
index ba16a9a72b952568999077341d17b81ba09a1c29..a9a06702ee8e41204d2e853e46f61e1a4b4bf41d 100644
--- a/roles/ipaclient/tasks/install.yml
+++ b/roles/ipaclient/tasks/install.yml
@@ -216,13 +216,17 @@
       domain: "{{ result_ipaclient_test.domain }}"
       realm: "{{ result_ipaclient_test.realm }}"
       hostname: "{{ result_ipaclient_test.hostname }}"
-      services: ["ssh", "sudo"]
-      krb5_offline_passwords: yes
       on_master: "{{ ipaclient_on_master }}"
-      #primary: no
-      #permit: no
-      #dns_updates: no
-      #all_ip_addresses: no
+      no_ssh: "{{ ipaclient_no_ssh }}"
+      no_sshd: "{{ ipaclient_no_sshd }}"
+      no_sudo: "{{ ipaclient_no_sudo }}"
+      all_ip_addresses: "{{ ipahost_all_ip_addresses }}"
+
+      fixed_primary: "{{ ipassd_fixed_primary }}"
+      permit: "{{ ipassd_permit }}"
+      enable_dns_updates: "{{ ipassd_enable_dns_updates }}"
+      preserve_sssd: "{{ ipassd_preserve_sssd }}"
+      no_krb5_offline_passwords: "{{ ipassd_no_krb5_offline_passwords }}"
 
   - name: Install - Configure krb5 for IPA realm "{{ result_ipaclient_test.realm }} <= 4.4"
     include_role: