diff --git a/ironic/conf/drac.py b/ironic/conf/drac.py
index 0b3b2bdc66..ebf402ce17 100644
--- a/ironic/conf/drac.py
+++ b/ironic/conf/drac.py
@@ -34,7 +34,12 @@ opts = [
                min=1,
                help=_('Maximum number of retries for '
                       'the configuration job to complete '
-                      'successfully.'))
+                      'successfully.')),
+    cfg.IntOpt('query_import_config_job_status_interval',
+               min=0,
+               default=60,
+               help=_('Number of seconds to wait between checking for '
+                      'completed import configuration task'))
 ]
 
 
diff --git a/ironic/drivers/modules/drac/management.py b/ironic/drivers/modules/drac/management.py
index f595bea3be..e069e086c4 100644
--- a/ironic/drivers/modules/drac/management.py
+++ b/ironic/drivers/modules/drac/management.py
@@ -20,8 +20,10 @@
 DRAC management interface
 """
 
+import json
 import time
 
+from futurist import periodics
 from ironic_lib import metrics_utils
 from oslo_log import log as logging
 from oslo_utils import importutils
@@ -29,15 +31,21 @@ from oslo_utils import importutils
 from ironic.common import boot_devices
 from ironic.common import exception
 from ironic.common.i18n import _
+from ironic.common import molds
+from ironic.common import states
 from ironic.conductor import task_manager
+from ironic.conductor import utils as manager_utils
 from ironic.conf import CONF
 from ironic.drivers import base
+from ironic.drivers.modules import deploy_utils
 from ironic.drivers.modules.drac import common as drac_common
 from ironic.drivers.modules.drac import job as drac_job
 from ironic.drivers.modules.redfish import management as redfish_management
+from ironic.drivers.modules.redfish import utils as redfish_utils
 
 
 drac_exceptions = importutils.try_import('dracclient.exceptions')
+sushy = importutils.try_import('sushy')
 
 LOG = logging.getLogger(__name__)
 
@@ -301,14 +309,333 @@ def set_boot_device(node, device, persistent=False):
 
 
 class DracRedfishManagement(redfish_management.RedfishManagement):
-    """iDRAC Redfish interface for management-related actions.
+    """iDRAC Redfish interface for management-related actions."""
 
-    Presently, this class entirely defers to its base class, a generic,
-    vendor-independent Redfish interface. Future resolution of Dell EMC-
-    specific incompatibilities and introduction of vendor value added
-    should be implemented by this class.
-    """
-    pass
+    EXPORT_CONFIGURATION_ARGSINFO = {
+        "export_configuration_location": {
+            "description": "URL of location to save the configuration to.",
+            "required": True,
+        }
+    }
+
+    IMPORT_CONFIGURATION_ARGSINFO = {
+        "import_configuration_location": {
+            "description": "URL of location to fetch desired configuration "
+                           "from.",
+            "required": True,
+        }
+    }
+
+    IMPORT_EXPORT_CONFIGURATION_ARGSINFO = {**EXPORT_CONFIGURATION_ARGSINFO,
+                                            **IMPORT_CONFIGURATION_ARGSINFO}
+
+    @base.deploy_step(priority=0, argsinfo=EXPORT_CONFIGURATION_ARGSINFO)
+    @base.clean_step(priority=0, argsinfo=EXPORT_CONFIGURATION_ARGSINFO)
+    def export_configuration(self, task, export_configuration_location):
+        """Export the configuration of the server.
+
+        Exports the configuration of the server against which the step is run
+        and stores it in specific format in indicated location.
+
+        Uses Dell's Server Configuration Profile (SCP) from `sushy-oem-idrac`
+        library to get ALL configuration for cloning.
+
+        :param task: A task from TaskManager.
+        :param export_configuration_location: URL of location to save the
+            configuration to.
+
+        :raises: MissingParameterValue if missing configuration name of a file
+            to save the configuration to
+        :raises: DracOperatationError when no managagers for Redfish system
+            found or configuration export from SCP failed
+        :raises: RedfishError when loading OEM extension failed
+        """
+        if not export_configuration_location:
+            raise exception.MissingParameterValue(
+                _('export_configuration_location missing'))
+
+        system = redfish_utils.get_system(task.node)
+        configuration = None
+
+        if not system.managers:
+            raise exception.DracOperationError(
+                error=(_("No managers found for %(node)s"),
+                       {'node': task.node.uuid}))
+
+        for manager in system.managers:
+
+            try:
+                manager_oem = manager.get_oem_extension('Dell')
+            except sushy.exceptions.OEMExtensionNotFoundError as e:
+                error_msg = (_("Search for Sushy OEM extension Python package "
+                               "'sushy-oem-idrac' failed for node %(node)s. "
+                               "Ensure it is installed. Error: %(error)s") %
+                             {'node': task.node.uuid, 'error': e})
+                LOG.error(error_msg)
+                raise exception.RedfishError(error=error_msg)
+
+            try:
+                configuration = manager_oem.export_system_configuration()
+                LOG.info("Exported %(node)s configuration via OEM",
+                         {'node': task.node.uuid})
+            except sushy.exceptions.SushyError as e:
+                LOG.debug("Sushy OEM extension Python package "
+                          "'sushy-oem-idrac' failed to export system "
+                          " configuration for node %(node)s. Will try next "
+                          "manager, if available. Error: %(error)s",
+                          {'system': system.uuid if system.uuid else
+                           system.identity,
+                           'manager': manager.uuid if manager.uuid else
+                           manager.identity,
+                           'node': task.node.uuid,
+                           'error': e})
+                continue
+            break
+
+        if configuration and configuration.status_code == 200:
+            configuration = {"oem": {"interface": "idrac-redfish",
+                                     "data": configuration.json()}}
+            molds.save_configuration(task,
+                                     export_configuration_location,
+                                     configuration)
+        else:
+            raise exception.DracOperationError(
+                error=(_("No configuration exported for node %(node)s"),
+                       {'node': task.node.uuid}))
+
+    @base.deploy_step(priority=0, argsinfo=IMPORT_CONFIGURATION_ARGSINFO)
+    @base.clean_step(priority=0, argsinfo=IMPORT_CONFIGURATION_ARGSINFO)
+    def import_configuration(self, task, import_configuration_location):
+        """Import and apply the configuration to the server.
+
+        Gets pre-created configuration from storage by given location and
+        imports that into given server. Uses Dell's Server Configuration
+        Profile (SCP).
+
+        :param task: A task from TaskManager.
+        :param import_configuration_location: URL of location to fetch desired
+            configuration from.
+
+        :raises: MissingParameterValue if missing configuration name of a file
+            to fetch the configuration from
+        """
+        if not import_configuration_location:
+            raise exception.MissingParameterValue(
+                _('import_configuration_location missing'))
+
+        configuration = molds.get_configuration(task,
+                                                import_configuration_location)
+        if not configuration:
+            raise exception.DracOperationError(
+                error=(_("No configuration found for node %(node)s by name "
+                         "%(configuration_name)s"),
+                       {'node': task.node.uuid,
+                        'configuration_name': import_configuration_location}))
+
+        interface = configuration["oem"]["interface"]
+        if interface != "idrac-redfish":
+            raise exception.DracOperationError(
+                error=(_("Invalid configuration for node %(node)s "
+                         "in %(configuration_name)s. Supports only "
+                         "idrac-redfish, but found %(interface)s"),
+                       {'node': task.node.uuid,
+                        'configuration_name': import_configuration_location,
+                        'interface': interface}))
+
+        system = redfish_utils.get_system(task.node)
+
+        if not system.managers:
+            raise exception.DracOperationError(
+                error=(_("No managers found for %(node)s"),
+                       {'node': task.node.uuid}))
+
+        for manager in system.managers:
+            try:
+                manager_oem = manager.get_oem_extension('Dell')
+            except sushy.exceptions.OEMExtensionNotFoundError as e:
+                error_msg = (_("Search for Sushy OEM extension Python package "
+                               "'sushy-oem-idrac' failed for node %(node)s. "
+                               "Ensure it is installed. Error: %(error)s") %
+                             {'node': task.node.uuid, 'error': e})
+                LOG.error(error_msg)
+                raise exception.RedfishError(error=error_msg)
+
+            try:
+                task_monitor = manager_oem.import_system_configuration(
+                    json.dumps(configuration["oem"]["data"]))
+
+                info = task.node.driver_internal_info
+                info['import_task_monitor_url'] = task_monitor.task_monitor_uri
+                task.node.driver_internal_info = info
+
+                deploy_utils.set_async_step_flags(
+                    task.node,
+                    reboot=True,
+                    skip_current_step=True,
+                    polling=True)
+                deploy_opts = deploy_utils.build_agent_options(task.node)
+                task.driver.boot.prepare_ramdisk(task, deploy_opts)
+                manager_utils.node_power_action(task, states.REBOOT)
+
+                return deploy_utils.get_async_step_return_state(task.node)
+            except sushy.exceptions.SushyError as e:
+                LOG.debug("Sushy OEM extension Python package "
+                          "'sushy-oem-idrac' failed to import system "
+                          " configuration for node %(node)s. Will try next "
+                          "manager, if available. Error: %(error)s",
+                          {'system': system.uuid if system.uuid else
+                           system.identity,
+                           'manager': manager.uuid if manager.uuid else
+                           manager.identity,
+                           'node': task.node.uuid,
+                           'error': e})
+                continue
+
+        raise exception.DracOperationError(
+            error=(_("Failed to import configuration for node %(node)s"),
+                   {'node': task.node.uuid}))
+
+    @base.clean_step(priority=0,
+                     argsinfo=IMPORT_EXPORT_CONFIGURATION_ARGSINFO)
+    @base.deploy_step(priority=0,
+                      argsinfo=IMPORT_EXPORT_CONFIGURATION_ARGSINFO)
+    def import_export_configuration(self, task, import_configuration_location,
+                                    export_configuration_location):
+        """Import and export configuration in one go.
+
+        Gets pre-created configuration from storage by given name and
+        imports that into given server. After that exports the configuration of
+        the server against which the step is run and stores it in specific
+        format in indicated storage as configured by Ironic.
+
+        :param import_configuration_location: URL of location to fetch desired
+            configuration from.
+        :param export_configuration_location: URL of location to save the
+            configuration to.
+        """
+        # Import is async operation, setting sub-step to store export config
+        # and indicate that it's being executed as part of composite step
+        info = task.node.driver_internal_info
+        info['export_configuration_location'] = export_configuration_location
+        task.node.driver_internal_info = info
+        task.node.save()
+
+        return self.import_configuration(task, import_configuration_location)
+        # Export executed as part of Import async periodic task status check
+
+    @METRICS.timer('DracRedfishManagement._query_import_configuration_status')
+    @periodics.periodic(
+        spacing=CONF.drac.query_import_config_job_status_interval,
+        enabled=CONF.drac.query_import_config_job_status_interval > 0)
+    def _query_import_configuration_status(self, manager, context):
+        """Period job to check import configuration task."""
+
+        filters = {'reserved': False, 'maintenance': False}
+        fields = ['driver_internal_info']
+        node_list = manager.iter_nodes(fields=fields, filters=filters)
+        for (node_uuid, driver, conductor_group,
+             driver_internal_info) in node_list:
+            try:
+                lock_purpose = 'checking async import configuration task'
+                with task_manager.acquire(context, node_uuid,
+                                          purpose=lock_purpose,
+                                          shared=True) as task:
+                    if not isinstance(task.driver.management,
+                                      DracRedfishManagement):
+                        continue
+                    task_monitor_url = driver_internal_info.get(
+                        'import_task_monitor_url')
+                    if not task_monitor_url:
+                        continue
+                    self._check_import_configuration_task(
+                        task, task_monitor_url)
+            except exception.NodeNotFound:
+                LOG.info('During _query_import_configuration_status, node '
+                         '%(node)s was not found and presumed deleted by '
+                         'another process.', {'node': node_uuid})
+            except exception.NodeLocked:
+                LOG.info('During _query_import_configuration_status, node '
+                         '%(node)s was already locked by another process. '
+                         'Skip.', {'node': node_uuid})
+
+    def _check_import_configuration_task(self, task, task_monitor_url):
+        """Checks progress of running import configuration task"""
+
+        node = task.node
+        task_monitor = redfish_utils.get_task_monitor(node, task_monitor_url)
+
+        if not task_monitor.is_processing:
+            import_task = task_monitor.get_task()
+
+            task.upgrade_lock()
+            info = node.driver_internal_info
+            info.pop('import_task_monitor_url', None)
+            node.driver_internal_info = info
+
+            if (import_task.task_state == sushy.TASK_STATE_COMPLETED
+                and import_task.task_status in
+                    [sushy.HEALTH_OK, sushy.HEALTH_WARNING]):
+                LOG.info('Configuration import %(task_monitor_url)s '
+                         'successful for node %(node)s',
+                         {'node': node.uuid,
+                          'task_monitor_url': task_monitor_url})
+
+                # If import executed as part of import_export_configuration
+                export_configuration_location =\
+                    info.get('export_configuration_location')
+                if export_configuration_location:
+                    # then do sync export configuration before finishing
+                    self._cleanup_export_substep(node)
+                    try:
+                        self.export_configuration(
+                            task, export_configuration_location)
+                    except (sushy.exceptions.SushyError,
+                            exception.IronicException) as e:
+                        error_msg = (_("Failed export configuration. %(exc)s" %
+                                       {'exc': e}))
+                        log_msg = ("Export configuration failed for node "
+                                   "%(node)s. %(error)s" %
+                                   {'node': task.node.uuid,
+                                    'error': error_msg})
+                        self._set_failed(task, log_msg, error_msg)
+                        return
+                self._set_success(task)
+            else:
+                # Select all messages, skipping OEM messages that don't have
+                # `message` field populated.
+                messages = [m.message for m in import_task.messages
+                            if m.message is not None]
+                error_msg = (_("Failed import configuration task: "
+                               "%(task_monitor_url)s. Message: '%(message)s'.")
+                             % {'task_monitor_url': task_monitor_url,
+                                'message': ', '.join(messages)})
+                log_msg = ("Import configuration task failed for node "
+                           "%(node)s. %(error)s" % {'node': task.node.uuid,
+                                                    'error': error_msg})
+                self._set_failed(task, log_msg, error_msg)
+            node.save()
+        else:
+            LOG.debug('Import configuration %(task_monitor_url)s in progress '
+                      'for node %(node)s',
+                      {'node': node.uuid,
+                       'task_monitor_url': task_monitor_url})
+
+    def _set_success(self, task):
+        if task.node.clean_step:
+            manager_utils.notify_conductor_resume_clean(task)
+        else:
+            manager_utils.notify_conductor_resume_deploy(task)
+
+    def _set_failed(self, task, log_msg, error_msg):
+        if task.node.clean_step:
+            manager_utils.cleaning_error_handler(task, log_msg, error_msg)
+        else:
+            manager_utils.deploying_error_handler(task, log_msg, error_msg)
+
+    def _cleanup_export_substep(self, node):
+        driver_internal_info = node.driver_internal_info
+        driver_internal_info.pop('export_configuration_location', None)
+        node.driver_internal_info = driver_internal_info
 
 
 class DracWSManManagement(base.ManagementInterface):
diff --git a/ironic/tests/unit/drivers/modules/drac/test_management.py b/ironic/tests/unit/drivers/modules/drac/test_management.py
index 27de5f7d53..227d5cd5f7 100644
--- a/ironic/tests/unit/drivers/modules/drac/test_management.py
+++ b/ironic/tests/unit/drivers/modules/drac/test_management.py
@@ -20,20 +20,26 @@
 Test class for DRAC management interface
 """
 
+import json
 from unittest import mock
 
 from oslo_utils import importutils
 
 import ironic.common.boot_devices
 from ironic.common import exception
+from ironic.common import molds
 from ironic.conductor import task_manager
+from ironic.conductor import utils as manager_utils
+from ironic.drivers.modules import deploy_utils
 from ironic.drivers.modules.drac import common as drac_common
 from ironic.drivers.modules.drac import job as drac_job
 from ironic.drivers.modules.drac import management as drac_mgmt
+from ironic.drivers.modules.redfish import utils as redfish_utils
 from ironic.tests.unit.drivers.modules.drac import utils as test_utils
 from ironic.tests.unit.objects import utils as obj_utils
 
 dracclient_exceptions = importutils.try_import('dracclient.exceptions')
+sushy = importutils.try_import('sushy')
 
 INFO_DICT = test_utils.INFO_DICT
 
@@ -822,3 +828,598 @@ class DracManagementTestCase(test_utils.BaseDracTest):
                 job_ids=['JID_CLEARALL_FORCE'])
 
             self.assertIsNone(return_value)
+
+
+class DracRedfishManagementTestCase(test_utils.BaseDracTest):
+
+    def setUp(self):
+        super(DracRedfishManagementTestCase, self).setUp()
+        self.node = obj_utils.create_test_node(self.context,
+                                               driver='idrac',
+                                               driver_info=INFO_DICT)
+        self.management = drac_mgmt.DracRedfishManagement()
+
+    def test_export_configuration_name_missing(self):
+        task = mock.Mock(node=self.node, context=self.context)
+        self.assertRaises(exception.MissingParameterValue,
+                          self.management.export_configuration, task, None)
+
+    @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+    def test_export_configuration_no_managers(self, mock_get_system):
+        task = mock.Mock(node=self.node, context=self.context)
+        fake_system = mock.Mock(managers=[])
+        mock_get_system.return_value = fake_system
+
+        self.assertRaises(exception.DracOperationError,
+                          self.management.export_configuration, task, 'edge')
+
+    @mock.patch.object(drac_mgmt, 'LOG', autospec=True)
+    @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+    def test_export_configuration_oem_not_found(self, mock_get_system,
+                                                mock_log):
+        task = mock.Mock(node=self.node, context=self.context)
+        fake_manager1 = mock.Mock()
+        fake_manager1.get_oem_extension.side_effect = (
+            sushy.exceptions.OEMExtensionNotFoundError)
+        fake_system = mock.Mock(managers=[fake_manager1])
+        mock_get_system.return_value = fake_system
+
+        self.assertRaises(exception.RedfishError,
+                          self.management.export_configuration, task, 'edge')
+        self.assertEqual(mock_log.error.call_count, 1)
+
+    @mock.patch.object(drac_mgmt, 'LOG', autospec=True)
+    @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+    def test_export_configuration_all_managers_fail(self, mock_get_system,
+                                                    mock_log):
+        task = mock.Mock(node=self.node, context=self.context)
+        fake_manager_oem1 = mock.Mock()
+        fake_manager_oem1.export_system_configuration.side_effect = (
+            sushy.exceptions.SushyError)
+        fake_manager1 = mock.Mock()
+        fake_manager1.get_oem_extension.return_value = fake_manager_oem1
+        fake_manager_oem2 = mock.Mock()
+        fake_manager_oem2.export_system_configuration.side_effect = (
+            sushy.exceptions.SushyError)
+        fake_manager2 = mock.Mock()
+        fake_manager2.get_oem_extension.return_value = fake_manager_oem2
+        fake_system = mock.Mock(managers=[fake_manager1, fake_manager2])
+        mock_get_system.return_value = fake_system
+
+        self.assertRaises(exception.DracOperationError,
+                          self.management.export_configuration,
+                          task, 'edge')
+        self.assertEqual(mock_log.debug.call_count, 2)
+
+    @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+    def test_export_configuration_export_failed(self, mock_get_system):
+        task = mock.Mock(node=self.node, context=self.context)
+        fake_manager_oem1 = mock.Mock()
+        fake_manager_oem1.export_system_configuration = mock.Mock()
+        fake_manager_oem1.export_system_configuration.status_code = 500
+        fake_manager1 = mock.Mock()
+        fake_manager1.get_oem_extension.return_value = fake_manager_oem1
+        fake_system = mock.Mock(managers=[fake_manager1])
+        mock_get_system.return_value = fake_system
+
+        self.assertRaises(exception.DracOperationError,
+                          self.management.export_configuration, task, 'edge')
+
+    @mock.patch.object(drac_mgmt, 'LOG', autospec=True)
+    @mock.patch.object(molds, 'save_configuration', autospec=True)
+    @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+    def test_export_configuration_success(self, mock_get_system,
+                                          mock_save_configuration,
+                                          mock_log):
+        task = mock.Mock(node=self.node, context=self.context)
+        fake_manager_oem1 = mock.Mock()
+        fake_manager_oem1.export_system_configuration.side_effect = (
+            sushy.exceptions.SushyError)
+        fake_manager1 = mock.Mock()
+        fake_manager1.get_oem_extension.return_value = fake_manager_oem1
+
+        configuration = mock.Mock(status_code=200)
+        configuration.json.return_value = (
+            json.loads('{"prop1":"value1", "prop2":2}'))
+        fake_manager_oem2 = mock.Mock()
+        fake_manager_oem2.export_system_configuration.return_value = (
+            configuration)
+        fake_manager2 = mock.Mock()
+        fake_manager2.get_oem_extension.return_value = fake_manager_oem2
+        fake_system = mock.Mock(managers=[fake_manager1, fake_manager2])
+        mock_get_system.return_value = fake_system
+        self.management.export_configuration(task, 'edge')
+
+        mock_save_configuration.assert_called_once_with(
+            task,
+            'edge',
+            {"oem": {"interface": "idrac-redfish",
+             "data": {"prop1": "value1", "prop2": 2}}})
+        self.assertEqual(mock_log.debug.call_count, 1)
+        self.assertEqual(mock_log.info.call_count, 1)
+
+    def test_import_configuration_name_missing(self):
+        task = mock.Mock(node=self.node, context=self.context)
+        self.assertRaises(exception.MissingParameterValue,
+                          self.management.import_configuration, task, None)
+
+    @mock.patch.object(molds, 'get_configuration', autospec=True)
+    def test_import_configuration_file_not_found(self, mock_get_configuration):
+        task = mock.Mock(node=self.node, context=self.context)
+        mock_get_configuration.return_value = None
+
+        self.assertRaises(exception.DracOperationError,
+                          self.management.import_configuration, task, 'edge')
+
+    @mock.patch.object(molds, 'get_configuration', autospec=True)
+    @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+    def test_import_configuration_no_managers(self, mock_get_system,
+                                              mock_get_configuration):
+        task = mock.Mock(node=self.node, context=self.context)
+        fake_system = mock.Mock(managers=[])
+        mock_get_configuration.return_value = json.loads(
+            '{"oem": {"interface": "idrac-redfish", '
+            '"data": {"prop1": "value1", "prop2": 2}}}')
+        mock_get_system.return_value = fake_system
+
+        self.assertRaises(exception.DracOperationError,
+                          self.management.import_configuration, task, 'edge')
+
+    @mock.patch.object(drac_mgmt, 'LOG', autospec=True)
+    @mock.patch.object(molds, 'get_configuration', autospec=True)
+    @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+    def test_import_configuration_oem_not_found(self, mock_get_system,
+                                                mock_get_configuration,
+                                                mock_log):
+        task = mock.Mock(node=self.node, context=self.context)
+        fake_manager1 = mock.Mock()
+        fake_manager1.get_oem_extension.side_effect = (
+            sushy.exceptions.OEMExtensionNotFoundError)
+        fake_system = mock.Mock(managers=[fake_manager1])
+        mock_get_system.return_value = fake_system
+        mock_get_configuration.return_value = json.loads(
+            '{"oem": {"interface": "idrac-redfish", '
+            '"data": {"prop1": "value1", "prop2": 2}}}')
+
+        self.assertRaises(exception.RedfishError,
+                          self.management.import_configuration, task, 'edge')
+        self.assertEqual(mock_log.error.call_count, 1)
+
+    @mock.patch.object(drac_mgmt, 'LOG', autospec=True)
+    @mock.patch.object(molds, 'get_configuration', autospec=True)
+    @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+    def test_import_configuration_all_managers_fail(self, mock_get_system,
+                                                    mock_get_configuration,
+                                                    mock_log):
+        task = mock.Mock(node=self.node, context=self.context)
+        fake_manager_oem1 = mock.Mock()
+        fake_manager_oem1.import_system_configuration.side_effect = (
+            sushy.exceptions.SushyError)
+        fake_manager1 = mock.Mock()
+        fake_manager1.get_oem_extension.return_value = fake_manager_oem1
+        fake_manager_oem2 = mock.Mock()
+        fake_manager_oem2.import_system_configuration.side_effect = (
+            sushy.exceptions.SushyError)
+        fake_manager2 = mock.Mock()
+        fake_manager2.get_oem_extension.return_value = fake_manager_oem2
+        fake_system = mock.Mock(managers=[fake_manager1, fake_manager2])
+        mock_get_system.return_value = fake_system
+        mock_get_configuration.return_value = json.loads(
+            '{"oem": {"interface": "idrac-redfish", '
+            '"data": {"prop1": "value1", "prop2": 2}}}')
+
+        self.assertRaises(exception.DracOperationError,
+                          self.management.import_configuration, task, 'edge')
+        self.assertEqual(mock_log.debug.call_count, 2)
+
+    @mock.patch.object(molds, 'get_configuration', autospec=True)
+    @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+    def test_import_configuration_incorrect_interface(self, mock_get_system,
+                                                      mock_get_configuration):
+        task = mock.Mock(node=self.node, context=self.context)
+        fake_manager_oem1 = mock.Mock()
+        fake_manager1 = mock.Mock()
+        fake_manager1.get_oem_extension.return_value = fake_manager_oem1
+        fake_system = mock.Mock(managers=[fake_manager1])
+        mock_get_system.return_value = fake_system
+        mock_get_configuration.return_value = json.loads(
+            '{"oem": {"interface": "idrac-wsman", '
+            '"data": {"prop1": "value1", "prop2": 2}}}')
+
+        self.assertRaises(exception.DracOperationError,
+                          self.management.import_configuration, task, 'edge')
+
+    @mock.patch.object(deploy_utils, 'get_async_step_return_state',
+                       autospec=True)
+    @mock.patch.object(deploy_utils, 'set_async_step_flags', autospec=True)
+    @mock.patch.object(deploy_utils, 'build_agent_options', autospec=True)
+    @mock.patch.object(manager_utils, 'node_power_action', autospec=True)
+    @mock.patch.object(drac_mgmt, 'LOG', autospec=True)
+    @mock.patch.object(molds, 'get_configuration', autospec=True)
+    @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+    def test_import_configuration_success(
+            self, mock_get_system, mock_get_configuration, mock_log,
+            mock_power, mock_build_agent_options,
+            mock_set_async_step_flags, mock_get_async_step_return_state):
+        deploy_opts = mock.Mock()
+        mock_build_agent_options.return_value = deploy_opts
+        step_result = mock.Mock()
+        mock_get_async_step_return_state.return_value = step_result
+        task = mock.Mock(node=self.node, context=self.context)
+        fake_manager_oem1 = mock.Mock()
+        fake_manager_oem1.import_system_configuration.side_effect = (
+            sushy.exceptions.SushyError)
+        fake_manager1 = mock.Mock()
+        fake_manager1.get_oem_extension.return_value = fake_manager_oem1
+        fake_manager_oem2 = mock.Mock()
+        fake_manager2 = mock.Mock()
+        fake_manager2.get_oem_extension.return_value = fake_manager_oem2
+        fake_system = mock.Mock(managers=[fake_manager1, fake_manager2])
+        mock_get_system.return_value = fake_system
+        mock_get_configuration.return_value = json.loads(
+            '{"oem": {"interface": "idrac-redfish", '
+            '"data": {"prop1": "value1", "prop2": 2}}}')
+
+        result = self.management.import_configuration(task, 'edge')
+
+        fake_manager_oem2.import_system_configuration.assert_called_once_with(
+            '{"prop1": "value1", "prop2": 2}')
+        self.assertEqual(mock_log.debug.call_count, 1)
+
+        mock_set_async_step_flags.assert_called_once_with(
+            task.node, reboot=True, skip_current_step=True, polling=True)
+        mock_build_agent_options.assert_called_once_with(task.node)
+        task.driver.boot.prepare_ramdisk.assert_called_once_with(
+            task, deploy_opts)
+        mock_get_async_step_return_state.assert_called_once_with(task.node)
+        self.assertEqual(step_result, result)
+
+    @mock.patch.object(drac_mgmt.DracRedfishManagement,
+                       'import_configuration', autospec=True)
+    def test_import_export_configuration_success(self, mock_import):
+        task = mock.Mock(node=self.node, context=self.context)
+
+        self.management.import_export_configuration(
+            task, 'https://server/edge_import', 'https://server/edge_export')
+
+        mock_import.assert_called_once_with(self.management, task,
+                                            'https://server/edge_import')
+        self.assertEqual(
+            'https://server/edge_export',
+            self.node.driver_internal_info.get(
+                'export_configuration_location'))
+
+    @mock.patch.object(task_manager, 'acquire', autospec=True)
+    def test__query_import_configuration_not_drac(self, mock_acquire):
+        driver_internal_info = {'import_task_monitor_url': '/TaskService/123'}
+        self.node.driver_internal_info = driver_internal_info
+        self.node.save()
+        mock_manager = mock.Mock()
+        node_list = [(self.node.uuid, 'not-idrac', '', driver_internal_info)]
+        mock_manager.iter_nodes.return_value = node_list
+        task = mock.Mock(node=self.node,
+                         driver=mock.Mock(management=mock.Mock()))
+        mock_acquire.return_value = mock.MagicMock(
+            __enter__=mock.MagicMock(return_value=task))
+        self.management._check_import_configuration_task = mock.Mock()
+
+        self.management._query_import_configuration_status(mock_manager,
+                                                           self.context)
+
+        self.management._check_import_configuration_task.assert_not_called()
+
+    @mock.patch.object(task_manager, 'acquire', autospec=True)
+    def test__query_import_configuration_status_no_task_monitor_url(
+            self, mock_acquire):
+        driver_internal_info = {'something': 'else'}
+        self.node.driver_internal_info = driver_internal_info
+        self.node.save()
+        mock_manager = mock.Mock()
+        node_list = [(self.node.uuid, 'idrac', '', driver_internal_info)]
+        mock_manager.iter_nodes.return_value = node_list
+        task = mock.Mock(node=self.node,
+                         driver=mock.Mock(management=self.management))
+        mock_acquire.return_value = mock.MagicMock(
+            __enter__=mock.MagicMock(return_value=task))
+        self.management._check_import_configuration_task = mock.Mock()
+
+        self.management._query_import_configuration_status(mock_manager,
+                                                           self.context)
+
+        self.management._check_import_configuration_task.assert_not_called()
+
+    @mock.patch.object(drac_mgmt.LOG, 'info', autospec=True)
+    @mock.patch.object(task_manager, 'acquire', autospec=True)
+    def test__query_import_configuration_status_node_notfound(
+            self, mock_acquire, mock_log):
+        driver_internal_info = {'import_task_monitor_url': '/TaskService/123'}
+        self.node.driver_internal_info = driver_internal_info
+        self.node.save()
+        mock_manager = mock.Mock()
+        node_list = [(self.node.uuid, 'idrac', '', driver_internal_info)]
+        mock_manager.iter_nodes.return_value = node_list
+        mock_acquire.side_effect = exception.NodeNotFound
+        task = mock.Mock(node=self.node,
+                         driver=mock.Mock(management=self.management))
+        mock_acquire.return_value = mock.MagicMock(
+            __enter__=mock.MagicMock(return_value=task))
+        self.management._check_import_configuration_task = mock.Mock()
+
+        self.management._query_import_configuration_status(mock_manager,
+                                                           self.context)
+
+        self.management._check_import_configuration_task.assert_not_called()
+        self.assertTrue(mock_log.called)
+
+    @mock.patch.object(drac_mgmt.LOG, 'info', autospec=True)
+    @mock.patch.object(task_manager, 'acquire', autospec=True)
+    def test__query_import_configuration_status_node_locked(
+            self, mock_acquire, mock_log):
+        driver_internal_info = {'import_task_monitor_url': '/TaskService/123'}
+        self.node.driver_internal_info = driver_internal_info
+        self.node.save()
+        mock_manager = mock.Mock()
+        node_list = [(self.node.uuid, 'idrac', '', driver_internal_info)]
+        mock_manager.iter_nodes.return_value = node_list
+        mock_acquire.side_effect = exception.NodeLocked
+        task = mock.Mock(node=self.node,
+                         driver=mock.Mock(management=self.management))
+        mock_acquire.return_value = mock.MagicMock(
+            __enter__=mock.MagicMock(return_value=task))
+        self.management._check_import_configuration_task = mock.Mock()
+
+        self.management._query_import_configuration_status(mock_manager,
+                                                           self.context)
+
+        self.management._check_import_configuration_task.assert_not_called()
+        self.assertTrue(mock_log.called)
+
+    @mock.patch.object(task_manager, 'acquire', autospec=True)
+    def test__query_import_configuration_status(self, mock_acquire):
+        driver_internal_info = {'import_task_monitor_url': '/TaskService/123'}
+        self.node.driver_internal_info = driver_internal_info
+        self.node.save()
+        mock_manager = mock.Mock()
+        node_list = [(self.node.uuid, 'idrac', '', driver_internal_info)]
+        mock_manager.iter_nodes.return_value = node_list
+        task = mock.Mock(node=self.node,
+                         driver=mock.Mock(management=self.management))
+        mock_acquire.return_value = mock.MagicMock(
+            __enter__=mock.MagicMock(return_value=task))
+        self.management._check_import_configuration_task = mock.Mock()
+
+        self.management._query_import_configuration_status(mock_manager,
+                                                           self.context)
+
+        (self.management
+            ._check_import_configuration_task
+            .assert_called_once_with(task, '/TaskService/123'))
+
+    @mock.patch.object(drac_mgmt.LOG, 'debug', autospec=True)
+    @mock.patch.object(redfish_utils, 'get_task_monitor', autospec=True)
+    def test__check_import_configuration_task_still_processing(
+            self, mock_get_task_monitor, mock_log):
+        driver_internal_info = {'import_task_monitor_url': '/TaskService/123'}
+        self.node.driver_internal_info = driver_internal_info
+        self.node.save()
+
+        mock_task_monitor = mock.Mock()
+        mock_task_monitor.is_processing = True
+        mock_get_task_monitor.return_value = mock_task_monitor
+
+        self.management._set_success = mock.Mock()
+        self.management._set_failed = mock.Mock()
+
+        with task_manager.acquire(self.context, self.node.uuid,
+                                  shared=False) as task:
+            self.management._check_import_configuration_task(
+                task, '/TaskService/123')
+
+            self.management._set_success.assert_not_called()
+            self.management._set_failed.assert_not_called()
+            self.assertTrue(mock_log.called)
+            self.assertEqual(
+                '/TaskService/123',
+                task.node.driver_internal_info.get('import_task_monitor_url'))
+
+    @mock.patch.object(redfish_utils, 'get_task_monitor', autospec=True)
+    def test__check_import_configuration_task_failed(
+            self, mock_get_task_monitor):
+        driver_internal_info = {'import_task_monitor_url': '/TaskService/123'}
+        self.node.driver_internal_info = driver_internal_info
+        self.node.save()
+
+        mock_message = mock.Mock()
+        mock_message.message = 'Firmware upgrade failed'
+        mock_import_task = mock.Mock()
+        mock_import_task.task_state = sushy.TASK_STATE_COMPLETED
+        mock_import_task.task_status = 'Failed'
+        mock_import_task.messages = [mock_message]
+        mock_task_monitor = mock.Mock()
+        mock_task_monitor.is_processing = False
+        mock_task_monitor.get_task.return_value = mock_import_task
+        mock_get_task_monitor.return_value = mock_task_monitor
+
+        self.management._set_success = mock.Mock()
+        self.management._set_failed = mock.Mock()
+
+        with task_manager.acquire(self.context, self.node.uuid,
+                                  shared=False) as task:
+            self.management._check_import_configuration_task(
+                task, '/TaskService/123')
+
+            self.management._set_failed.assert_called_once_with(
+                task, mock.ANY,
+                "Failed import configuration task: /TaskService/123. Message: "
+                "'Firmware upgrade failed'.")
+            self.management._set_success.assert_not_called()
+            self.assertIsNone(
+                task.node.driver_internal_info.get('import_task_monitor_url'))
+
+    @mock.patch.object(redfish_utils, 'get_task_monitor', autospec=True)
+    def test__check_import_configuration_task(self, mock_get_task_monitor):
+        driver_internal_info = {'import_task_monitor_url': '/TaskService/123'}
+        self.node.driver_internal_info = driver_internal_info
+        self.node.save()
+
+        mock_message = mock.Mock()
+        mock_message.message = 'Configuration import done'
+        mock_import_task = mock.Mock()
+        mock_import_task.task_state = sushy.TASK_STATE_COMPLETED
+        mock_import_task.task_status = sushy.HEALTH_OK
+        mock_import_task.messages = [mock_message]
+        mock_task_monitor = mock.Mock()
+        mock_task_monitor.is_processing = False
+        mock_task_monitor.get_task.return_value = mock_import_task
+        mock_get_task_monitor.return_value = mock_task_monitor
+
+        self.management._set_success = mock.Mock()
+        self.management._set_failed = mock.Mock()
+
+        with task_manager.acquire(self.context, self.node.uuid,
+                                  shared=False) as task:
+            self.management._check_import_configuration_task(
+                task, '/TaskService/123')
+
+            self.management._set_success.assert_called_once_with(task)
+            self.management._set_failed.assert_not_called()
+            self.assertIsNone(
+                task.node.driver_internal_info.get('import_task_monitor_url'))
+
+    @mock.patch.object(redfish_utils, 'get_task_monitor', autospec=True)
+    def test__check_import_configuration_task_with_export_failed(
+            self, mock_get_task_monitor):
+        driver_internal_info = {
+            'import_task_monitor_url': '/TaskService/123',
+            'export_configuration_location': 'https://server/export1'}
+        self.node.driver_internal_info = driver_internal_info
+        self.node.save()
+
+        mock_message = mock.Mock()
+        mock_message.message = 'Configuration import done'
+        mock_import_task = mock.Mock()
+        mock_import_task.task_state = sushy.TASK_STATE_COMPLETED
+        mock_import_task.task_status = sushy.HEALTH_OK
+        mock_import_task.messages = [mock_message]
+        mock_task_monitor = mock.Mock()
+        mock_task_monitor.is_processing = False
+        mock_task_monitor.get_task.return_value = mock_import_task
+        mock_get_task_monitor.return_value = mock_task_monitor
+
+        self.management._set_success = mock.Mock()
+        self.management._set_failed = mock.Mock()
+        mock_export = mock.Mock()
+        mock_export.side_effect = exception.IronicException
+        self.management.export_configuration = mock_export
+
+        with task_manager.acquire(self.context, self.node.uuid,
+                                  shared=False) as task:
+            self.management._check_import_configuration_task(
+                task, '/TaskService/123')
+
+            self.management.export_configuration.assert_called_once_with(
+                task, 'https://server/export1')
+            self.management._set_success.assert_not_called()
+            self.assertIsNone(
+                task.node.driver_internal_info.get('import_task_monitor_url'))
+            self.assertIsNone(
+                task.node.driver_internal_info.get(
+                    'export_configuration_location'))
+            self.management._set_failed.assert_called_with(
+                task, mock.ANY,
+                'Failed export configuration. An unknown exception occurred.')
+
+    @mock.patch.object(redfish_utils, 'get_task_monitor', autospec=True)
+    def test__check_import_configuration_task_with_export(
+            self, mock_get_task_monitor):
+        driver_internal_info = {
+            'import_task_monitor_url': '/TaskService/123',
+            'export_configuration_location': 'https://server/export1'}
+        self.node.driver_internal_info = driver_internal_info
+        self.node.save()
+
+        mock_message = mock.Mock()
+        mock_message.message = 'Configuration import done'
+        mock_import_task = mock.Mock()
+        mock_import_task.task_state = sushy.TASK_STATE_COMPLETED
+        mock_import_task.task_status = sushy.HEALTH_OK
+        mock_import_task.messages = [mock_message]
+        mock_task_monitor = mock.Mock()
+        mock_task_monitor.is_processing = False
+        mock_task_monitor.get_task.return_value = mock_import_task
+        mock_get_task_monitor.return_value = mock_task_monitor
+
+        self.management._set_success = mock.Mock()
+        self.management._set_failed = mock.Mock()
+        self.management.export_configuration = mock.Mock()
+
+        with task_manager.acquire(self.context, self.node.uuid,
+                                  shared=False) as task:
+            self.management._check_import_configuration_task(
+                task, '/TaskService/123')
+
+            self.management.export_configuration.assert_called_once_with(
+                task, 'https://server/export1')
+            self.management._set_success.assert_called_once_with(task)
+            self.assertIsNone(
+                task.node.driver_internal_info.get('import_task_monitor_url'))
+            self.assertIsNone(
+                task.node.driver_internal_info.get(
+                    'export_configuration_location'))
+            self.management._set_failed.assert_not_called()
+
+    @mock.patch.object(manager_utils, 'notify_conductor_resume_deploy',
+                       autospec=True)
+    @mock.patch.object(manager_utils, 'notify_conductor_resume_clean',
+                       autospec=True)
+    def test__set_success_clean(self, mock_notify_clean, mock_notify_deploy):
+        self.node.clean_step = {'test': 'value'}
+        self.node.save()
+        with task_manager.acquire(self.context, self.node.uuid,
+                                  shared=False) as task:
+            self.management._set_success(task)
+
+            mock_notify_clean.assert_called_once_with(task)
+
+    @mock.patch.object(manager_utils, 'notify_conductor_resume_deploy',
+                       autospec=True)
+    @mock.patch.object(manager_utils, 'notify_conductor_resume_clean',
+                       autospec=True)
+    def test__set_success_deploy(self, mock_notify_clean, mock_notify_deploy):
+        self.node.clean_step = None
+        self.node.save()
+        with task_manager.acquire(self.context, self.node.uuid,
+                                  shared=False) as task:
+            self.management._set_success(task)
+
+            mock_notify_deploy.assert_called_once_with(task)
+
+    @mock.patch.object(manager_utils, 'deploying_error_handler',
+                       autospec=True)
+    @mock.patch.object(manager_utils, 'cleaning_error_handler',
+                       autospec=True)
+    def test__set_failed_clean(self, mock_clean_handler, mock_deploy_handler):
+        self.node.clean_step = {'test': 'value'}
+        self.node.save()
+
+        with task_manager.acquire(self.context, self.node.uuid,
+                                  shared=False) as task:
+            self.management._set_failed(task, 'error', 'log message')
+
+            mock_clean_handler.assert_called_once_with(
+                task, 'error', 'log message')
+
+    @mock.patch.object(manager_utils, 'deploying_error_handler',
+                       autospec=True)
+    @mock.patch.object(manager_utils, 'cleaning_error_handler',
+                       autospec=True)
+    def test__set_failed_deploy(self, mock_clean_handler, mock_deploy_handler):
+        self.node.clean_step = None
+        self.node.save()
+
+        with task_manager.acquire(self.context, self.node.uuid,
+                                  shared=False) as task:
+            self.management._set_failed(task, 'error', 'log message')
+
+            mock_deploy_handler.assert_called_once_with(
+                task, 'error', 'log message')
diff --git a/releasenotes/notes/add-config-mold-steps-idrac-1773d81953209964.yaml b/releasenotes/notes/add-config-mold-steps-idrac-1773d81953209964.yaml
new file mode 100644
index 0000000000..00295acefa
--- /dev/null
+++ b/releasenotes/notes/add-config-mold-steps-idrac-1773d81953209964.yaml
@@ -0,0 +1,8 @@
+---
+features:
+  - |
+    Adds ``import_configuration``, ``export_configuration`` and
+    ``import_export_configuration`` steps to ``idrac-redfish`` management
+    interface. These steps allow to use configuration from another system as
+    template and replicate that configuration to other, similarly capable,
+    systems. Currently, this feature is experimental.