diff --git a/cinder/volume/drivers/rbd.py b/cinder/volume/drivers/rbd.py
index 46e66990263..5d0f1f8c8db 100644
--- a/cinder/volume/drivers/rbd.py
+++ b/cinder/volume/drivers/rbd.py
@@ -102,7 +102,7 @@ RBD_OPTS = [
                 help='Set to True for driver to report total capacity as a '
                      'dynamic value -used + current free- and to False to '
                      'report a static value -quota max bytes if defined and '
-                     'global size of cluster if not-.'),
+                     'global size of cluster if not.'),
     cfg.BoolOpt('rbd_exclusive_cinder_pool', default=False,
                 help="Set to True if the pool is used exclusively by Cinder. "
                      "On exclusive use driver won't query images' provisioned "
diff --git a/doc/ext/driver_opts.py b/doc/ext/driver_opts.py
new file mode 100644
index 00000000000..4e6f0c6470c
--- /dev/null
+++ b/doc/ext/driver_opts.py
@@ -0,0 +1,127 @@
+# Copyright (c) 2018 Huawei Technologies Co., Ltd.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+"""Sphinx extension to be able to extract driver config options from code."""
+
+import importlib
+
+from docutils import nodes
+from docutils.parsers import rst
+from docutils.parsers.rst import directives
+from docutils import statemachine as sm
+from oslo_config import cfg
+
+
+class ConfigTableDirective(rst.Directive):
+    """Directive to extract config options into docs output."""
+
+    option_spec = {
+        'table-title': directives.unchanged,
+        'config-target': directives.unchanged,
+    }
+
+    has_content = True
+
+    def _doc_module(self, module):
+        """Extract config options from module."""
+        options = []
+        try:
+            mod = importlib.import_module(module)
+            for prop in dir(mod):
+                thing = getattr(mod, prop)
+                if isinstance(thing, cfg.Opt):
+                    # An individual config option
+                    options.append(thing)
+                elif (isinstance(thing, list) and len(thing) > 0 and
+                        isinstance(thing[0], cfg.Opt)):
+                    # A list of config opts
+                    options.extend(thing)
+        except Exception as e:
+            self.error('Unable to import {}: {}'.format(module, e))
+
+        return options
+
+    def _get_default(self, opt):
+        """Tries to pick the best text to use as the default."""
+        if hasattr(opt, 'sample_default') and opt.sample_default:
+            return opt.sample_default
+
+        if type(opt.default) == list:
+            return ', '.join(str(item) for item in opt.default)
+
+        result = str(opt.default)
+        if not result:
+            result = '<>'
+        return result
+
+    def run(self):
+        """Load and find config options to document."""
+        modules = [c.strip() for c in self.content if c.strip()]
+
+        if not modules:
+            raise self.error('No modules provided to document.')
+
+        env = self.state.document.settings.env
+        app = env.app
+
+        result = sm.ViewList()
+        source = '<{}>'.format(__name__)
+
+        target = self.options.get('config-target', '')
+        title = self.options.get(
+            'table-title',
+            'Description of {} configuration options'.format(target))
+
+        result.append('.. _{}:'.format(title.replace(' ', '-')), source)
+        result.append('', source)
+        result.append('.. list-table:: {}'.format(title), source)
+        result.append('   :header-rows: 1', source)
+        result.append('   :class: config-ref-table', source)
+        result.append('', source)
+        result.append('   * - Configuration option = Default value', source)
+        result.append('     - Description', source)
+
+        options = []
+        for module in modules:
+            retval = self._doc_module(module)
+            if retval:
+                options.extend(retval)
+            else:
+                app.info('[config-table] No options found in {}'.format(
+                         module))
+
+        # Get options sorted alphabetically but with deprecated options last
+        list.sort(options, key=lambda opt: opt.name)
+        list.sort(options, key=lambda opt: opt.deprecated_for_removal)
+
+        for opt in options:
+            result.append(
+                '   * - ``{}`` = ``{}``'.format(
+                    opt.name, self._get_default(opt)),
+                source)
+            result.append(
+                '     - ({}) {}{}'.format(
+                    opt.type, opt.help,
+                    ' **DEPRECATED**' if opt.deprecated_for_removal else ''),
+                source)
+
+        node = nodes.section()
+        node.document = self.state.document
+        self.state.nested_parse(result, 0, node)
+        return node.children
+
+
+def setup(app):
+    app.add_directive('config-table', ConfigTableDirective)
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 2ca4914d3f4..2a5ed8c6f5c 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -58,6 +58,7 @@ extensions = ['sphinx.ext.coverage',
               'stevedore.sphinxext',
               'oslo_config.sphinxconfiggen',
               'ext.cinder_driverlist',
+              'ext.driver_opts',
               'oslo_policy.sphinxext',
               'oslo_policy.sphinxpolicygen',
               'sphinxcontrib.apidoc',
diff --git a/doc/source/configuration/block-storage/drivers/ceph-rbd-volume-driver.rst b/doc/source/configuration/block-storage/drivers/ceph-rbd-volume-driver.rst
index 45e78cef328..78c564b9ab9 100644
--- a/doc/source/configuration/block-storage/drivers/ceph-rbd-volume-driver.rst
+++ b/doc/source/configuration/block-storage/drivers/ceph-rbd-volume-driver.rst
@@ -87,4 +87,7 @@ Driver options
 The following table contains the configuration options supported by the
 Ceph RADOS Block Device driver.
 
-.. include:: ../../tables/cinder-storage_ceph.inc
+.. config-table::
+   :config-target: Ceph storage
+
+   cinder.volume.drivers.rbd
diff --git a/doc/source/configuration/block-storage/drivers/lvm-volume-driver.rst b/doc/source/configuration/block-storage/drivers/lvm-volume-driver.rst
index 50b8285ba5e..10fb618b73a 100644
--- a/doc/source/configuration/block-storage/drivers/lvm-volume-driver.rst
+++ b/doc/source/configuration/block-storage/drivers/lvm-volume-driver.rst
@@ -22,7 +22,10 @@ Use the following options to configure for the iSER transport:
    volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
    iscsi_protocol = iser
 
-.. include:: ../../tables/cinder-lvm.inc
+.. config-table::
+   :config-target: LVM
+
+   cinder.volume.drivers.lvm
 
 .. caution::
 
diff --git a/doc/source/configuration/block-storage/drivers/nfs-volume-driver.rst b/doc/source/configuration/block-storage/drivers/nfs-volume-driver.rst
index daac4f76400..a792c1c822d 100644
--- a/doc/source/configuration/block-storage/drivers/nfs-volume-driver.rst
+++ b/doc/source/configuration/block-storage/drivers/nfs-volume-driver.rst
@@ -33,7 +33,12 @@ in the ``cinder.conf`` configuration file:
 
 The following table contains the options supported by the NFS driver.
 
-.. include:: ../../tables/cinder-storage_nfs.inc
+.. _cinder-storage_nfs:
+
+.. config-table::
+   :config-target: NFS storage
+
+   cinder.volume.drivers.nfs
 
 .. note::
 
diff --git a/doc/source/configuration/tables/cinder-lvm.inc b/doc/source/configuration/tables/cinder-lvm.inc
deleted file mode 100644
index 9415631a028..00000000000
--- a/doc/source/configuration/tables/cinder-lvm.inc
+++ /dev/null
@@ -1,32 +0,0 @@
-..
-    Warning: Do not edit this file. It is automatically generated from the
-    software project's code and your changes will be overwritten.
-
-    The tool to generate this file lives in openstack-doc-tools repository.
-
-    Please make any changes needed in the code, then run the
-    autogenerate-config-doc tool from the openstack-doc-tools repository, or
-    ask for help on the documentation mailing list, IRC channel or meeting.
-
-.. _cinder-lvm:
-
-.. list-table:: Description of LVM configuration options
-   :header-rows: 1
-   :class: config-ref-table
-
-   * - Configuration option = Default value
-     - Description
-   * - **[DEFAULT]**
-     -
-   * - ``lvm_conf_file`` = ``/etc/cinder/lvm.conf``
-     - (String) LVM conf file to use for the LVM driver in Cinder; this setting is ignored if the specified file does not exist (You can also specify 'None' to not use a conf file even if one exists).
-   * - ``lvm_max_over_subscription_ratio`` = ``1.0``
-     - (Floating point) max_over_subscription_ratio setting for the LVM driver. If set, this takes precedence over the general max_over_subscription_ratio option. If None, the general option is used.
-   * - ``lvm_mirrors`` = ``0``
-     - (Integer) If >0, create LVs with multiple mirrors. Note that this requires lvm_mirrors + 2 PVs with available space
-   * - ``lvm_suppress_fd_warnings`` = ``False``
-     - (Boolean) Suppress leaked file descriptor warnings in LVM commands.
-   * - ``lvm_type`` = ``auto``
-     - (String) Type of LVM volumes to deploy; (default, thin, or auto). Auto defaults to thin if thin is supported.
-   * - ``volume_group`` = ``cinder-volumes``
-     - (String) Name for the VG that will contain exported volumes
diff --git a/doc/source/configuration/tables/cinder-storage_ceph.inc b/doc/source/configuration/tables/cinder-storage_ceph.inc
deleted file mode 100644
index 15529cbce18..00000000000
--- a/doc/source/configuration/tables/cinder-storage_ceph.inc
+++ /dev/null
@@ -1,44 +0,0 @@
-..
-    Warning: Do not edit this file. It is automatically generated from the
-    software project's code and your changes will be overwritten.
-
-    The tool to generate this file lives in openstack-doc-tools repository.
-
-    Please make any changes needed in the code, then run the
-    autogenerate-config-doc tool from the openstack-doc-tools repository, or
-    ask for help on the documentation mailing list, IRC channel or meeting.
-
-.. _cinder-storage_ceph:
-
-.. list-table:: Description of Ceph storage configuration options
-   :header-rows: 1
-   :class: config-ref-table
-
-   * - Configuration option = Default value
-     - Description
-   * - **[DEFAULT]**
-     -
-   * - ``rados_connect_timeout`` = ``-1``
-     - (Integer) Timeout value (in seconds) used when connecting to ceph cluster. If value < 0, no timeout is set and default librados value is used.
-   * - ``rados_connection_interval`` = ``5``
-     - (Integer) Interval value (in seconds) between connection retries to ceph cluster.
-   * - ``rados_connection_retries`` = ``3``
-     - (Integer) Number of retries if connection to ceph cluster failed.
-   * - ``rbd_ceph_conf`` =
-     - (String) Path to the ceph configuration file
-   * - ``rbd_cluster_name`` = ``ceph``
-     - (String) The name of ceph cluster
-   * - ``rbd_flatten_volume_from_snapshot`` = ``False``
-     - (Boolean) Flatten volumes created from snapshots to remove dependency from volume to snapshot
-   * - ``rbd_max_clone_depth`` = ``5``
-     - (Integer) Maximum number of nested volume clones that are taken before a flatten occurs. Set to 0 to disable cloning.
-   * - ``rbd_pool`` = ``rbd``
-     - (String) The RADOS pool where rbd volumes are stored
-   * - ``rbd_secret_uuid`` = ``None``
-     - (String) The libvirt uuid of the secret for the rbd_user volumes
-   * - ``rbd_store_chunk_size`` = ``4``
-     - (Integer) Volumes will be chunked into objects of this size (in megabytes).
-   * - ``rbd_user`` = ``None``
-     - (String) The RADOS client name for accessing rbd volumes - only set when using cephx authentication
-   * - ``replication_connect_timeout`` = ``5``
-     - (Integer) Timeout value (in seconds) used when connecting to ceph cluster to do a demotion/promotion of volumes. If value < 0, no timeout is set and default librados value is used.
diff --git a/doc/source/configuration/tables/cinder-storage_nfs.inc b/doc/source/configuration/tables/cinder-storage_nfs.inc
deleted file mode 100644
index 4f9597a67ed..00000000000
--- a/doc/source/configuration/tables/cinder-storage_nfs.inc
+++ /dev/null
@@ -1,34 +0,0 @@
-..
-    Warning: Do not edit this file. It is automatically generated from the
-    software project's code and your changes will be overwritten.
-
-    The tool to generate this file lives in openstack-doc-tools repository.
-
-    Please make any changes needed in the code, then run the
-    autogenerate-config-doc tool from the openstack-doc-tools repository, or
-    ask for help on the documentation mailing list, IRC channel or meeting.
-
-.. _cinder-storage_nfs:
-
-.. list-table:: Description of NFS storage configuration options
-   :header-rows: 1
-   :class: config-ref-table
-
-   * - Configuration option = Default value
-     - Description
-   * - **[DEFAULT]**
-     -
-   * - ``nfs_mount_attempts`` = ``3``
-     - (Integer) The number of attempts to mount NFS shares before raising an error. At least one attempt will be made to mount an NFS share, regardless of the value specified.
-   * - ``nfs_mount_options`` = ``None``
-     - (String) Mount options passed to the NFS client. See section of the NFS man page for details.
-   * - ``nfs_mount_point_base`` = ``$state_path/mnt``
-     - (String) Base dir containing mount points for NFS shares.
-   * - ``nfs_qcow2_volumes`` = ``False``
-     - (Boolean) Create volumes as QCOW2 files rather than raw files.
-   * - ``nfs_shares_config`` = ``/etc/cinder/nfs_shares``
-     - (String) File with the list of available NFS shares.
-   * - ``nfs_snapshot_support`` = ``False``
-     - (Boolean) Enable support for snapshots on the NFS driver. Platforms using libvirt <1.2.7 will encounter issues with this feature.
-   * - ``nfs_sparsed_volumes`` = ``True``
-     - (Boolean) Create volumes as sparsed files which take no space. If set to False volume is created as regular file. In such case volume creation takes a lot of time.