← Back to team overview

cloud-init-dev team mailing list archive

[Merge] ~wesley-wiedenmeier/cloud-init:module-docs into cloud-init:master

 

Wesley Wiedenmeier has proposed merging ~wesley-wiedenmeier/cloud-init:module-docs into cloud-init:master.

Requested reviews:
  cloud init development team (cloud-init-dev)

For more details, see:
https://code.launchpad.net/~wesley-wiedenmeier/cloud-init/+git/cloud-init/+merge/305292

Added per-module documentation for cloud-init with a standard format.
This should be a good improvement in documentation from what is available at:
  https://cloudinit.readthedocs.io/en/latest/topics/modules.html
-- 
Your team cloud init development team is requested to review the proposed merge of ~wesley-wiedenmeier/cloud-init:module-docs into cloud-init:master.
diff --git a/cloudinit/config/cc_apt_configure.py b/cloudinit/config/cc_apt_configure.py
index fa9505a..6145fcd 100644
--- a/cloudinit/config/cc_apt_configure.py
+++ b/cloudinit/config/cc_apt_configure.py
@@ -18,6 +18,213 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Apt Configure
+-------------
+**Summary:** configure apt
+
+This module handles both configuration of apt options and adding source lists.
+There are configuration options such as ``apt_get_wrapper`` and
+``apt_get_command`` that control how cloud-init invokes apt-get.
+These configuration options are handled on a per-distro basis, so consult
+documentation for cloud-init's distro support for instructions on using
+these config options.
+
+.. note::
+    To ensure that apt configuration is valid yaml, any strings containing
+    special characters, especially ``:`` should be quoted.
+
+.. note::
+    For more information about apt configuration, see the
+    ``Additional apt configuration`` example.
+
+**Preserve sources.list:**
+
+By default, cloud-init will generate a new sources list in
+``/etc/apt/sources.list.d`` based on any changes specified in cloud config.
+To disable this behavior and preserve the sources list from the pristine image,
+set ``preserve_sources_list`` to ``true``.
+
+.. note::
+    The ``preserve_sources_list`` option overrides all other config keys that
+    would alter ``sources.list`` or ``sources.list.d``, **except** for
+    additional sources to be added to ``sources.list.d``.
+
+**Disable source suites:**
+
+Entries in the sources list can be disabled using ``disable_suites``, which
+takes a list of suites to be disabled. If the string ``$RELEASE`` is present in
+a suite in the ``disable_suites`` list, it will be replaced with the release
+name. If a suite specified in ``disable_suites`` is not present in
+``sources.list`` it will be ignored. For convenience, several aliases are
+provided for ``disable_suites``:
+
+    - ``updates`` => ``$RELEASE-updates``
+    - ``backports`` => ``$RELEASE-backports``
+    - ``security`` => ``$RELEASE-security``
+    - ``proposed`` => ``$RELEASE-proposed``
+    - ``release`` => ``$RELEASE``
+
+.. note::
+    When a suite is disabled using ``disable_suites``, its entry in
+    ``sources.list`` is not deleted; it is just commented out.
+
+**Configure primary and security mirrors:**
+
+The primary and security archive mirrors can be specified using the ``primary``
+and ``security`` keys, respectively. Both the ``primary`` and ``security`` keys
+take a list of configs, allowing mirrors to be specified on a per-architecture
+basis. Each config is a dictionary which must have an entry for ``arches``,
+specifying which architectures that config entry is for. The keyword
+``default`` applies to any architecture not explicitly listed. The mirror url
+can be specified with the ``url`` key, or a list of mirrors to check can be
+provided in order, with the first mirror that can be resolved being selected.
+This allows the same configuration to be used in different environment, with
+different hosts used for a local apt mirror. If no mirror is provided by uri or
+search, ``search_dns`` may be used to search for dns names in the format
+``<distro>-mirror`` in each of the following:
+
+    - fqdn of this host per cloud metadata
+    - localdomain
+    - domains listed in ``/etc/resolv.conf``
+
+If there is a dns entry for ``<distro>-mirror``, then it is assumed that there
+is a distro mirror at ``http://<distro>-mirror.<domain>/<distro>``. If the
+``primary`` key is defined, but not the ``security`` key, then then
+configuration for ``primary`` is also used for ``security``. If ``search_dns``
+is used for the ``security`` key, the search pattern will be.
+``<distro>-security-mirror``.
+
+If no mirrors are specified, or all lookups fail, then default mirrors defined
+in the datasource are used. If none are present in the datasource either the
+following defaults are used:
+
+    - primary: ``http://archive.ubuntu.com/ubuntu``
+    - security: ``http://security.ubuntu.com/ubuntu``
+
+**Specify sources.list template:**
+
+A custom template for rendering ``sources.list`` can be specefied with
+``sources_list``. If no ``sources_list`` template is given, cloud-init will
+use sane default. Within this template, the following strings will be replaced
+with the appropriate values:
+
+    - ``$MIRROR``
+    - ``$RELEASE``
+    - ``$PRIMARY``
+    - ``$SECURITY``
+
+**Pass configuration to apt:**
+
+Apt configuration can be specified using ``conf``. Configuration is specified
+as a string. For multiline apt configuration, make sure to follow yaml syntax.
+
+**Configure apt proxy:**
+
+Proxy configuration for apt can be specified using ``conf``, but proxy config
+keys also exist for convenience. The proxy config keys, ``http_proxy``,
+``ftp_proxy``, and ``https_proxy`` may be used to specify a proxy for http, ftp
+and https protocols respectively. The ``proxy`` key also exists as an alias for
+``http_proxy``. Proxy url is specified in the format
+``<protocol>://[[user][:pass]@]host[:port]/``.
+
+**Add apt repos by regex:**
+
+All source entries in ``apt-sources`` that match regex in
+``add_apt_repo_match`` will be added to the system using
+``add-apt-repository``. If ``add_apt_repo_match`` is not specified, it defaults
+to ``^[\w-]+:\w``
+
+**Add source list entries:**
+
+Source list entries can be specified as a dictionary under the ``sources``
+config key, with key in the dict representing a different source file. The key
+The key of each source entry will be used as an id that can be referenced in
+other config entries, as well as the filename for the source's configuration
+under ``/etc/apt/sources.list.d``. If the name does not end with ``.list``,
+it will be appended. If there is no configuration for a key in ``sources``, no
+file will be written, but the key may still be referred to as an id in other
+``sources`` entries.
+
+Each entry under ``sources`` is a dictionary which may contain any of the
+following optional keys:
+
+    - ``source``: a sources.list entry (some variable replacements apply)
+    - ``keyid``: a key to import via shortid or fingerprint
+    - ``key``: a raw PGP key
+    - ``keyserver``: alternate keyserver to pull ``keyid`` key from
+
+The ``source`` key supports variable replacements for the following strings:
+
+    - ``$MIRROR``
+    - ``$PRIMARY``
+    - ``$SECURITY``
+    - ``$RELEASE``
+
+**Internal name:** ``cc_apt_configure``
+
+**Module frequency:** per instance
+
+**Supported distros:** ubuntu, debian
+
+**Config keys**::
+
+    apt:
+        preserve_sources_list: <true/false>
+        disable_suites:
+            - $RELEASE-updates
+            - backports
+            - $RELEASE
+            - mysuite
+        primary:
+            - arches:
+                - amd64
+                - i386
+                - default
+              uri: "http://us.archive.ubuntu.com/ubuntu";
+              search:
+                - "http://cool.but-sometimes-unreachable.com/ubuntu";
+                - "http://us.archive.ubuntu.com/ubuntu";
+              search_dns: <true/false>
+            - arches:
+                - s390x
+                - arm64
+              uri: "http://archive-to-use-for-arm64.example.com/ubuntu";
+        security:
+            - arches:
+                - default
+              search_dns: true
+        sources_list: |
+            deb $MIRROR $RELEASE main restricted
+            deb-src $MIRROR $RELEASE main restricted
+            deb $PRIMARY $RELEASE universe restricted
+            deb $SECURITY $RELEASE-security multiverse
+        conf: |
+            APT {
+                Get {
+                    Assume-Yes "true";
+                    Fix-Broken "true";
+                }
+            }
+        proxy: "http://[[user][:pass]@]host[:port]/";
+        http_proxy: "http://[[user][:pass]@]host[:port]/";
+        ftp_proxy: "ftp://[[user][:pass]@]host[:port]/";
+        https_proxy: "https://[[user][:pass]@]host[:port]/";
+        sources:
+            source1:
+                keyid: "keyid"
+                keyserver: "keyserverurl"
+                source: "deb http://<url>/ xenial main"
+            source2:
+                source "ppa:<ppa-name>"
+            source3:
+                source "deb $MIRROR $RELEASE multiverse"
+                key: |
+                    ------BEGIN PGP PUBLIC KEY BLOCK-------
+                    <key data>
+                    ------END PGP PUBLIC KEY BLOCK-------
+"""
+
 import glob
 import os
 import re
diff --git a/cloudinit/config/cc_apt_pipelining.py b/cloudinit/config/cc_apt_pipelining.py
index 40c32c8..ab9d005 100644
--- a/cloudinit/config/cc_apt_pipelining.py
+++ b/cloudinit/config/cc_apt_pipelining.py
@@ -16,6 +16,31 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Apt Pipelining
+--------------
+**Summary:** configure apt pipelining
+
+This module configures apt's ``Acquite::http::Pipeline-Depth`` option, whcih
+controls how apt handles HTTP pipelining. It may be useful for pipelining to be
+disabled, because some web servers, such as S3 do not pipeline properly (LP:
+#948461). The ``apt_pipelining`` config key may be set to ``false`` to disable
+pipelining altogether. This is the default behavior. If it is set to ``none``,
+``unchanged``, or ``os``, no change will be made to apt configuration and the
+default setting for the distro will be used. The pipeline depth can also be
+manually specified by setting ``apt_pipelining`` to a number. However, this is
+not recommended.
+
+**Internal name:** ``cc_apt_pipelining``
+
+**Module frequency:** per instance
+
+**Supported distros:** ubuntu, debian
+
+**Config keys**::
+    apt_pipelining: <false/none/unchanged/os/number>
+"""
+
 from cloudinit.settings import PER_INSTANCE
 from cloudinit import util
 
diff --git a/cloudinit/config/cc_bootcmd.py b/cloudinit/config/cc_bootcmd.py
index b763a3c..22b23f2 100644
--- a/cloudinit/config/cc_bootcmd.py
+++ b/cloudinit/config/cc_bootcmd.py
@@ -18,6 +18,34 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Bootcmd
+-------
+**Summary:** run commands early in boot process
+
+This module runs arbitrary commands very early in the boot process,
+only slightly after a boothook would run. This is very similar to a
+boothook, but more user friendly. The environment variable ``INSTANCE_ID``
+will be set to the current instance id for all run commands. Commands can be
+specified either as lists or strings. For invocation details, see ``runcmd``.
+
+.. note::
+    bootcmd should only be used for things that could not be done later in the
+    boot process.
+
+**Internal name:** ``cc_bootcmd``
+
+**Module frequency:** per always
+
+**Supported distros:** all
+
+**Config keys**::
+
+    bootcmd:
+        - echo 192.168.1.130 us.archive.ubuntu.com > /etc/hosts
+        - [ cloud-nit-per, once, mymkfs, mkfs, /dev/vdb ]
+"""
+
 import os
 
 from cloudinit.settings import PER_ALWAYS
diff --git a/cloudinit/config/cc_byobu.py b/cloudinit/config/cc_byobu.py
index ef0ce7a..1f00dd9 100644
--- a/cloudinit/config/cc_byobu.py
+++ b/cloudinit/config/cc_byobu.py
@@ -18,6 +18,39 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Byobu
+-----
+**Summary:** enable/disable byobu system wide and for default user
+
+This module controls whether byobu is enabled or disabled system wide and for
+the default system user. If byobu is to be enabled, this module will ensure it
+is installed. Likewise, if it is to be disabled, it will be removed if
+installed.
+
+Valid configuration options for this module are:
+
+  - ``enable-system``: enable byobu system wide
+  - ``enable-user``: enable byobu for the default user
+  - ``disable-system``: disable byobu system wide
+  - ``disable-user``: disable byobu for the default user
+  - ``enable``: enable byobu both system wide and for default user
+  - ``disable``: disable byobu for all users
+  - ``user``: alias for ``enable-user``
+  - ``system``: alias for ``enable-system``
+
+**Internal name:** ``cc_byobu``
+
+**Module frequency:** per instance
+
+**Supported distros:** ubuntu, debian
+
+**Config keys**::
+
+    byobu_by_default: <user/system>
+"""
+
+
 # Ensure this is aliased to a name not 'distros'
 # since the module attribute 'distros'
 # is a list of distros that are supported, not a sub-module
diff --git a/cloudinit/config/cc_ca_certs.py b/cloudinit/config/cc_ca_certs.py
index 8248b02..53d1406 100644
--- a/cloudinit/config/cc_ca_certs.py
+++ b/cloudinit/config/cc_ca_certs.py
@@ -14,6 +14,38 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+CA Certs
+--------
+**Summary:** add ca certificates
+
+This module adds CA certificates to ``/etc/ca-certificates.conf`` and updates
+the ssl cert cache using ``update-ca-certificates``. The default certificates
+can be removed from the system with the configuration option
+``remove-defaults``.
+
+.. note::
+    certificates must be specified using valid yaml. in order to specify a
+    multiline certificate, the yaml multiline list syntax must be used
+
+**Internal name:** ``cc_ca_certs``
+
+**Module frequency:** per instance
+
+**Supporte distros:** ubuntu, debian
+
+**Config keys**::
+
+    ca-certs:
+        remove-defaults: <true/false>
+        trusted:
+            - <single line cert>
+            - |
+              -----BEGIN CERTIFICATE-----
+              YOUR-ORGS-TRUSTED-CA-CERT-HERE
+              -----END CERTIFICATE-----
+"""
+
 import os
 
 from cloudinit import util
diff --git a/cloudinit/config/cc_chef.py b/cloudinit/config/cc_chef.py
index 4c28be6..922fb6a 100644
--- a/cloudinit/config/cc_chef.py
+++ b/cloudinit/config/cc_chef.py
@@ -19,9 +19,11 @@
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 """
+Chef
+----
 **Summary:** module that configures, starts and installs chef.
 
-**Description:** This module enables chef to be installed (from packages or
+This module enables chef to be installed (from packages or
 from gems, or from omnibus). Before this occurs chef configurations are
 written to disk (validation.pem, client.pem, firstboot.json, client.rb),
 and needed chef folders/directories are created (/etc/chef and /var/log/chef
@@ -33,7 +35,13 @@ chef will have forked into its own process) then a post run function can
 run that can do finishing activities (such as removing the validation pem
 file).
 
-It can be configured with the following option structure::
+**Internal name:** ``cc_chef``
+
+**Module frequency:** per always
+
+**Supported distros:** all
+
+**Config keys**::
 
     chef:
        directories: (defaulting to /etc/chef, /var/log/chef, /var/lib/chef,
diff --git a/cloudinit/config/cc_debug.py b/cloudinit/config/cc_debug.py
index bdc32fe..5ab3646 100644
--- a/cloudinit/config/cc_debug.py
+++ b/cloudinit/config/cc_debug.py
@@ -15,22 +15,28 @@
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 """
+Debug
+-----
 **Summary:** helper to debug cloud-init *internal* datastructures.
 
-**Description:** This module will enable for outputting various internal
-information that cloud-init sources provide to either a file or to the output
-console/log location that this cloud-init has been configured with when
-running.
+This module will enable for outputting various internal information that
+cloud-init sources provide to either a file or to the output console/log
+location that this cloud-init has been configured with when running.
 
-It can be configured with the following option structure::
+.. note::
+    Log configurations are not output.
 
-    debug:
-       verbose: (defaulting to true)
-       output: (location to write output, defaulting to console + log)
+**Internal name:** ``cc_debug``
 
-.. note::
+**Module frequency:** per instance
 
-    Log configurations are not output.
+**Supported distros:** all
+
+**Config keys**::
+
+    debug:
+       verbose: true/false (defaulting to true)
+       output: (location to write output, defaulting to console + log)
 """
 
 import copy
diff --git a/cloudinit/config/cc_disable_ec2_metadata.py b/cloudinit/config/cc_disable_ec2_metadata.py
index 3fd2c20..5c54e6f 100644
--- a/cloudinit/config/cc_disable_ec2_metadata.py
+++ b/cloudinit/config/cc_disable_ec2_metadata.py
@@ -18,6 +18,26 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Disable EC2 Metadata
+--------------------
+**Summary:** disable aws ec2 metadata
+
+This module can disable the ec2 datasource by rejecting the route to
+``169.254.169.254``, the usual route to the datasource. This module is disabled
+by default.
+
+**Internal name:** ``cc_disable_ec2_metadata``
+
+**Module frequency:** per always
+
+**Supported distros:** all
+
+**Config keys**::
+
+    disable_ec2_metadata: <true/false>
+"""
+
 from cloudinit import util
 
 from cloudinit.settings import PER_ALWAYS
diff --git a/cloudinit/config/cc_disk_setup.py b/cloudinit/config/cc_disk_setup.py
index b642f1f..57e42f1 100644
--- a/cloudinit/config/cc_disk_setup.py
+++ b/cloudinit/config/cc_disk_setup.py
@@ -16,6 +16,96 @@
 #
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+Disk Setup
+----------
+**Summary:** configure partitions and filesystems
+
+This module is able to configure simple partition tables and filesystems.
+
+.. note::
+    for more detail about configuration options for disk setup, see the disk
+    setup example
+
+For convenience, aliases can be specified for disks using the
+``device_aliases`` config key, which takes a dictionary of alias: path
+mappings. There are automatic aliases for ``swap`` and ``ephemeral<X>``, where
+``swap`` will always refer to the active swap partition and ``ephemeral<X>``
+will refer to the block device of the ephemeral image.
+
+Disk partitioning is done using the ``disk_setup`` directive. This config
+directive accepts a dictionary where each key is either a path to a block
+device or an alias specified in ``device_aliases``, and each value is the
+configuration options for the device. The ``table_type`` option specifies the
+partition table type, either ``mbr`` or ``gpt``. The ``layout`` option
+specifies how partitions on the device are to be arranged. If ``layout`` is set
+to ``true``, a single partition using all the space on the device will be
+created. If set to ``false``, no partitions will be created. Partitions can be
+specified by providing a list to ``layout``, where each entry in the list is
+either a size or a list containing a size and the numerical value for a
+partition type. The size for partitions is specified in **percentage** of disk
+space, not in bytes (e.g. a size of 33 would take up 1/3 of the disk space).
+The ``overwrite`` option controls whether this module tries to be safe about
+writing partition talbes or not. If ``overwrite: false`` is set, the device
+will be checked for a partition table and for a file system and if either is
+found, the operation will be skipped. If ``overwrite: true`` is set, no checks
+will be performed.
+
+.. note::
+    Using ``overwrite: true`` is dangerous and can lead to data loss, so double
+    check that the correct device has been specified if using this option.
+
+File system configuration is done using the ``fs_setup`` directive. This config
+directive accepts a list of filesystem configs. The device to create the
+filesystem on may be specified either as a path or as an alias in the format
+``<alias name>.<y>`` where ``<y>`` denotes the partition number on the device.
+The partition can also be specified by setting ``partition`` to the desired
+partition number. The ``partition`` option may also be set to ``auto``, in
+which this module will search for the existance of a filesystem matching the
+``label``, ``type`` and ``device`` of the ``fs_setup`` entry and will skip
+creating the filesystem if one is found. The ``partition`` option may also be
+set to ``any``, in which case any file system that matches ``type`` and
+``device`` will cause this module to skip filesystem creation for the
+``fs_setup`` entry, regardless of ``label`` matching or not. To write a
+filesystem directly to a device, use ``partition: none``. A label can be
+specified for the filesystem using ``label``, and the filesystem type can be
+specified using ``filesystem``.
+
+.. note::
+    If specifying device using the ``<device name>.<partition number>`` format,
+    the value of ``partition`` will be overwritten.
+
+.. note::
+    Using ``overwrite: true`` for filesystems is dangerous and can lead to data
+    loss, so double check the entry in ``fs_setup``.
+
+**Internal name:** ``cc_disk_setup``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+
+**Config keys**::
+
+    device_aliases:
+        <alias name>: <device path>
+    disk_setup:
+        <alias name/path>:
+            table_type: <'mbr'/'gpt'>
+            layout:
+                - [33,82]
+                - 66
+            overwrite: <true/false>
+    fs_setup:
+        - label: <label>
+          filesystem: <filesystem type>
+          device: <device>
+          partition: <"auto"/"any"/"none"/<partition number>>
+          overwrite: <true/false>
+          replace_fs: <filesystem type>
+"""
+
 from cloudinit.settings import PER_INSTANCE
 from cloudinit import util
 import logging
@@ -38,7 +128,7 @@ LOG = logging.getLogger(__name__)
 
 def handle(_name, cfg, cloud, log, _args):
     """
-    See doc/examples/cloud-config_disk-setup.txt for documentation on the
+    See doc/examples/cloud-config-disk-setup.txt for documentation on the
     format.
     """
     disk_setup = cfg.get("disk_setup")
diff --git a/cloudinit/config/cc_emit_upstart.py b/cloudinit/config/cc_emit_upstart.py
index 98828b9..a7be635 100644
--- a/cloudinit/config/cc_emit_upstart.py
+++ b/cloudinit/config/cc_emit_upstart.py
@@ -18,6 +18,21 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Emit Upstart
+------------
+**Summary:** emit upstart configuration
+
+Emit upstart configuration for cloud-init modules on upstart based systems. No
+user configuration should be required.
+
+**Internal name:** ``cc_emit_upstart``
+
+**Module frequency:** per always
+
+**Supported distros:** ubuntu, debian
+"""
+
 import os
 
 from cloudinit import log as logging
diff --git a/cloudinit/config/cc_fan.py b/cloudinit/config/cc_fan.py
index 545fee2..6027fdc 100644
--- a/cloudinit/config/cc_fan.py
+++ b/cloudinit/config/cc_fan.py
@@ -15,25 +15,38 @@
 #
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
 """
-fan module allows configuration of Ubuntu Fan
-  https://wiki.ubuntu.com/FanNetworking
-
-Example config:
-  #cloud-config
-  fan:
-    config: |
-      # fan 240
-      10.0.0.0/8 eth0/16 dhcp
-      10.0.0.0/8 eth1/16 dhcp off
-      # fan 241
-      241.0.0.0/8 eth0/16 dhcp
-    config_path: /etc/network/fan
-
-If cloud-init sees a 'fan' entry in cloud-config it will
- a.) write 'config_path' with the contents
- b.) install the package 'ubuntu-fan' if it is not installed
- c.) ensure the service is started (or restarted if was previously running)
+Fan
+---
+**Summary:** configure ubuntu fan networking
+
+This module installs, configures and starts the ubuntu fan network system. For
+more information about Ubuntu Fan, see:
+``https://wiki.ubuntu.com/FanNetworking``.
+
+If cloud-init sees a ``fan`` entry in cloud-config it will:
+
+    - write ``config_path`` with the contents of the ``config`` key
+    - install the package ``ubuntu-fan`` if it is not installed
+    - ensure the service is started (or restarted if was previously running)
+
+**Internal name:** ``cc_fan``
+
+**Module frequency:** per instance
+
+**Supported distros:** ubuntu
+
+**Config keys**::
+
+    fan:
+        config: |
+            # fan 240
+            10.0.0.0/8 eth0/16 dhcp
+            10.0.0.0/8 eth1/16 dhcp off
+            # fan 241
+            241.0.0.0/8 eth0/16 dhcp
+        config_path: /etc/network/fan
 """
 
 from cloudinit import log as logging
diff --git a/cloudinit/config/cc_final_message.py b/cloudinit/config/cc_final_message.py
index c9021eb..5e144fd 100644
--- a/cloudinit/config/cc_final_message.py
+++ b/cloudinit/config/cc_final_message.py
@@ -18,6 +18,31 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Final Message
+-------------
+**Summary:** output final message when cloud-init has finished
+
+This module configures the final message that cloud-init writes. The message is
+specified as a jinja template with the following variables set:
+
+    - ``version``: cloud-init version
+    - ``timestamp``: time at cloud-init finish
+    - ``datasource``: cloud-init data source
+    - ``uptime``: system uptime
+
+**Internal name:** ``cc_final_message``
+
+**Module frequency:** per always
+
+**Supported distros:** all
+
+**Config keys**::
+
+    final_message: <message>
+
+"""
+
 from cloudinit import templater
 from cloudinit import util
 from cloudinit import version
diff --git a/cloudinit/config/cc_foo.py b/cloudinit/config/cc_foo.py
index 95aab4d..ad0e046 100644
--- a/cloudinit/config/cc_foo.py
+++ b/cloudinit/config/cc_foo.py
@@ -18,6 +18,20 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Foo
+---
+**Summary:** example module
+
+Example to show module structure. Does not do anything.
+
+**Internal name:** ``cc_foo``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+"""
+
 from cloudinit.settings import PER_INSTANCE
 
 # Modules are expected to have the following attributes.
@@ -35,7 +49,7 @@ from cloudinit.settings import PER_INSTANCE
 #    Typically those are from module configuration where the module
 #    is defined with some extra configuration that will eventually
 #    be translated from yaml into arguments to this module.
-# 2. A optional 'frequency' that defines how often this module should be ran.
+# 2. A optional 'frequency' that defines how often this module should be run.
 #    Typically one of PER_INSTANCE, PER_ALWAYS, PER_ONCE. If not
 #    provided PER_INSTANCE will be assumed.
 #    See settings.py for these constants.
diff --git a/cloudinit/config/cc_growpart.py b/cloudinit/config/cc_growpart.py
index 40560f1..a95e6c8 100644
--- a/cloudinit/config/cc_growpart.py
+++ b/cloudinit/config/cc_growpart.py
@@ -18,6 +18,63 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Growpart
+--------
+**Summary:** grow partitions
+
+Growpart resizes partitions to fill the available disk space.
+This is useful for cloud instances with a larger amount of disk space available
+than the pristine image uses, as it allows the instance to automatically make
+use of the extra space.
+
+The devices run growpart on are specified as a list under the ``devices`` key.
+Each entry in the devices list can be either the path to the device's
+mountpoint in the filesystem or a path to the block device in ``/dev``.
+
+The utility to use for resizing can be selected using the ``mode`` config key.
+If ``mode`` key is set to ``auto``, then any available utility (either
+``growpart`` or ``gpart``) will be used. If neither utility is available, no
+error will be raised. If ``mode`` is set to ``growpart``, then the ``growpart``
+utility will be used. If this utility is not available on the system, this will
+result in an error. If ``mode`` is set to ``off`` or ``false``, then
+``cc_growpart`` will take no action.
+
+There is some functionality overlap between this module and the ``growroot``
+functionality of ``cloud-initramfs-tools``. However, there are some situations
+where one tool is able to function and the other is not. The default
+configuration for both should work for most cloud instances. To explicitly
+prevent ``cloud-initramfs-tools`` from running ``growroot``, the file
+``/etc/growroot-disabled`` can be created. By default, both ``growroot`` and
+``cc_growpart`` will check for the existance of this file and will not run if
+it is present. However, this file can be ignored for ``cc_growpart`` by setting
+``ignore_growroot_disabled`` to ``true``. For more information on
+``cloud-initramfs-tools`` see: https://launchpad.net/cloud-initramfs-tools
+
+Growpart is enabled by default on the root partition. The default config for
+growpart is::
+
+    growpart:
+        mode: auto
+        devices: ["/"]
+        ignore_growroot_disabled: false
+
+**Internal name:** ``cc_growpart``
+
+**Module frequency:** per always
+
+**Supported distros:** all
+
+**Config keys**::
+
+    growpart:
+        mode: <auto/growpart/off/false>
+        devices:
+            - "/"
+            - "/dev/vdb1"
+        ignore_growroot_disabled: <true/false>
+"""
+
 import os
 import os.path
 import re
diff --git a/cloudinit/config/cc_grub_dpkg.py b/cloudinit/config/cc_grub_dpkg.py
index 156722d..33ca40a 100644
--- a/cloudinit/config/cc_grub_dpkg.py
+++ b/cloudinit/config/cc_grub_dpkg.py
@@ -18,6 +18,40 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Grub Dpkg
+---------
+**Summary:** configure grub debconf installation device
+
+Configure which device is used as the target for grub installation. This module
+should work correctly by default without any user configuration. It can be
+enabled/disabled using the ``enabled`` config key in the ``grub_dpkg`` config
+dict. The global config key ``grub-dpkg`` is an alias for ``grub_dpkg``. If no
+installation device is specified this module will look for the first existing
+device in:
+
+    - ``/dev/sda``
+    - ``/dev/vda``
+    - ``/dev/xvda``
+    - ``/dev/sda1``
+    - ``/dev/vda1``
+    - ``/dev/xvda1``
+
+**Internal name:** ``cc_grub_dpkg``
+
+**Module frequency:** per instance
+
+**Supported distros:** ubuntu, debian
+
+**Config keys**::
+
+    grub_dpkg:
+        enabled: <true/false>
+        grub-pc/install_devices: <devices>
+        grub-pc/install_devices_empty: <devices>
+    grub-dpkg: (alias for grub_dpkg)
+"""
+
 import os
 
 from cloudinit import util
diff --git a/cloudinit/config/cc_keys_to_console.py b/cloudinit/config/cc_keys_to_console.py
index 9a02f05..d4b2013 100644
--- a/cloudinit/config/cc_keys_to_console.py
+++ b/cloudinit/config/cc_keys_to_console.py
@@ -18,6 +18,30 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Keys to Console
+---------------
+**Summary:** control which ssh keys may be written to console
+
+For security reasons it may be desirable not to write ssh fingerprints and keys
+to the console. To avoid the fingerprint of types of ssh keys being written to
+console the ``ssh_fp_console_blacklist`` config key can be used. By default all
+types of keys will have their fingerprints written to console. To avoid keys
+of a key type being written to console the ``ssh_key_console_blacklist`` config
+key can be used. By default ``ssh-dss`` keys are not written to console.
+
+**Internal name:** ``cc_keys_to_console``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+
+**Config keys**::
+
+    ssh_fp_console_blacklist: <list of key types>
+    ssh_key_console_blacklist: <list of key types>
+"""
+
 import os
 
 from cloudinit.settings import PER_INSTANCE
diff --git a/cloudinit/config/cc_landscape.py b/cloudinit/config/cc_landscape.py
index 68fcb27..11c8451 100644
--- a/cloudinit/config/cc_landscape.py
+++ b/cloudinit/config/cc_landscape.py
@@ -18,6 +18,55 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Landscape
+---------
+**Summary:** install and configure landscape client
+
+This module installs and configures ``landscape-client``. The landscape client
+will only be installed if the key ``landscape`` is present in config. Landscape
+client configuration is given under the ``client`` key under the main
+``landscape`` config key. The config parameters are not interpreted by
+cloud-init, but rather are converted into a ConfigObj formatted file and
+written out to ``/etc/landscape/client.conf``.
+
+The following default client config is provided, but can be overridden::
+
+    landscape:
+        client:
+            log_level: "info"
+            url: "https://landscape.canonical.com/message-system";
+            ping_url: "http://landscape.canoncial.com/ping";
+            data_path: "/var/lib/landscape/client"
+
+.. note::
+    see landscape documentation for client config keys
+
+.. note::
+    if ``tags`` is defined, its contents should be a string delimited with
+    ``,`` rather than a list
+
+**Internal name:** ``cc_landscape``
+
+**Module frequency:** per instance
+
+**Supported distros:** ubuntu
+
+**Config keys**::
+
+    landscape:
+        client:
+            url: "https://landscape.canonical.com/message-system";
+            ping_url: "http://landscape.canonical.com/ping";
+            data_path: "/var/lib/landscape/client"
+            http_proxy: "http://my.proxy.com/foobar";
+            https_proxy: "https://my.proxy.com/foobar";
+            tags: "server,cloud"
+            computer_title: "footitle"
+            registration_key: "fookey"
+            account_name: "fooaccount"
+"""
+
 import os
 
 from six import StringIO
diff --git a/cloudinit/config/cc_locale.py b/cloudinit/config/cc_locale.py
index bbe5fca..268888e 100644
--- a/cloudinit/config/cc_locale.py
+++ b/cloudinit/config/cc_locale.py
@@ -18,6 +18,26 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Locale
+------
+**Summary:** set system locale
+
+Configure the system locale and apply it system wide. By default use the locale
+specified by the datasource.
+
+**Internal name:** ``cc_locale``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+
+**Config keys**::
+
+    locale: <locale str>
+    locale_configfile: <path to locale config file>
+"""
+
 from cloudinit import util
 
 
diff --git a/cloudinit/config/cc_lxd.py b/cloudinit/config/cc_lxd.py
index 0086840..0c28c2b 100644
--- a/cloudinit/config/cc_lxd.py
+++ b/cloudinit/config/cc_lxd.py
@@ -17,32 +17,46 @@
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 """
-This module initializes lxd using 'lxd init'
-
-Example config:
-  #cloud-config
-  lxd:
-    init:
-      network_address: <ip addr>
-      network_port: <port>
-      storage_backend: <zfs/dir>
-      storage_create_device: <dev>
-      storage_create_loop: <size>
-      storage_pool: <name>
-      trust_password: <password>
-    bridge:
-      mode: <new, existing or none>
-      name: <name>
-      ipv4_address: <ip addr>
-      ipv4_netmask: <cidr>
-      ipv4_dhcp_first: <ip addr>
-      ipv4_dhcp_last: <ip addr>
-      ipv4_dhcp_leases: <size>
-      ipv4_nat: <bool>
-      ipv6_address: <ip addr>
-      ipv6_netmask: <cidr>
-      ipv6_nat: <bool>
-      domain: <domain>
+LXD
+---
+**Summary:** configure lxd with ``lxd init`` and optionally lxd-bridge
+
+This module configures lxd with user specified options using ``lxd init``.
+If lxd is not present on the system but lxd configuration is provided, then
+lxd will be installed. If the selected storage backend is zfs, then zfs will
+be installed if missing. If network bridge configuration is provided, then
+lxd-bridge will be configured accordingly.
+
+**Internal name:** ``cc_lxd``
+
+**Module frequency:** per instance
+
+**Supported distros:** ubuntu
+
+**Config keys**::
+
+    lxd:
+        init:
+            network_address: <ip addr>
+            network_port: <port>
+            storage_backend: <zfs/dir>
+            storage_create_device: <dev>
+            storage_create_loop: <size>
+            storage_pool: <name>
+            trust_password: <password>
+        bridge:
+            mode: <new, existing or none>
+            name: <name>
+            ipv4_address: <ip addr>
+            ipv4_netmask: <cidr>
+            ipv4_dhcp_first: <ip addr>
+            ipv4_dhcp_last: <ip addr>
+            ipv4_dhcp_leases: <size>
+            ipv4_nat: <bool>
+            ipv6_address: <ip addr>
+            ipv6_netmask: <cidr>
+            ipv6_nat: <bool>
+            domain: <domain>
 """
 
 from cloudinit import util
diff --git a/cloudinit/config/cc_mcollective.py b/cloudinit/config/cc_mcollective.py
index b3089f3..c447f26 100644
--- a/cloudinit/config/cc_mcollective.py
+++ b/cloudinit/config/cc_mcollective.py
@@ -19,6 +19,47 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Mcollective
+-----------
+**Summary:** install, configure and start mcollective
+
+This module installs, configures and starts mcollective. If the ``mcollective``
+key is present in config, then mcollective will be installed and started.
+
+Configuration for ``mcollective`` can be specified in the ``conf`` key under
+``mcollective``. Each config value consists of a key value pair and will be
+written to ``/etc/mcollective/server.cfg``. The ``public-cert`` and
+``private-cert`` keys, if present in conf may be used to specify the public and
+private certificates for mcollective. Their values will be written to
+``/etc/mcollective/ssl/server-public.pem`` and
+``/etc/mcollective/ssl/server-private.pem``.
+
+.. note::
+    The ec2 metadata service is readable by non-root users.
+    If security is a concern, use include-once and ssl urls.
+
+**Internal name:** ``cc_mcollective``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+
+**Config keys**::
+
+    mcollective:
+        conf:
+            <key>: <value>
+            public-cert: |
+                -------BEGIN CERTIFICATE--------
+                <cert data>
+                -------END CERTIFICATE--------
+            private-cert: |
+                -------BEGIN CERTIFICATE--------
+                <cert data>
+                -------END CERTIFICATE--------
+"""
+
 import errno
 
 import six
diff --git a/cloudinit/config/cc_migrator.py b/cloudinit/config/cc_migrator.py
index facaa53..6e0bf4b 100644
--- a/cloudinit/config/cc_migrator.py
+++ b/cloudinit/config/cc_migrator.py
@@ -16,6 +16,28 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Migrator
+--------
+**Summary:** migrate old versions of cloud-init data to new
+
+This module handles moving old versions of cloud-init data to newer ones.
+Currently, it only handles renaming cloud-init's per-frequency semaphore files
+to canonicalized name and renaming legacy semaphore names to newer ones. This
+module is enabled by default, but can be disabled by specifying ``migrate:
+false`` in config.
+
+**Internal name:** ``cc_migrator``
+
+**Module frequency:** per always
+
+**Supported distros:** all
+
+**Config keys**::
+
+    migrate: <true/false>
+"""
+
 import os
 import shutil
 
diff --git a/cloudinit/config/cc_mounts.py b/cloudinit/config/cc_mounts.py
index 2b98193..57a9c04 100644
--- a/cloudinit/config/cc_mounts.py
+++ b/cloudinit/config/cc_mounts.py
@@ -18,6 +18,54 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Mounts
+------
+**Summary:** configure mount points and swap files
+
+This module can add or remove mountpoints from ``/etc/fstab`` as well as
+configure swap. The ``mounts`` config key takes a list of fstab entries to add.
+Each entry is specified as a list of ``[ fs_spec, fs_file, fs_vfstype,
+fs_mntops, fs-freq, fs_passno ]``. For more information on these options,
+consult the manual for ``/etc/fstab``. When specifying the ``fs_spec``, if the
+device name starts with one of ``xvd``, ``sd``, ``hd``, or ``vd``, the leading
+``/dev`` may be omitted.
+
+In order to remove a previously listed mount, an entry can be added to the
+mounts list containing ``fs_spec`` for the device to be removed but no
+mountpoint (i.e. ``[ sda1 ]`` or ``[ sda1, null ]``).
+
+The ``mount_default_fields`` config key allows default options to be specified
+for the values in a ``mounts`` entry that are not specified, aside from the
+``fs_spec`` and the ``fs_file``. If specified, this must be a list containing 7
+values. It defaults to::
+
+    mount_default_fields: [none, none, "auto", "defaults,nobootwait", "0", "2"]
+
+Swap files can be configured by setting the path to the swap file to create
+with ``filename``, the size of the swap file with ``size`` maximum size of
+the swap file if using an ``size: auto`` with ``maxsize``. By default no
+swap file is created.
+
+**Internal name:** ``cc_mounts``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+
+**Config keys**::
+
+    mounts:
+        - [ /dev/ephemeral0, /mnt, auto, "defaults,noexec" ]
+        - [ sdc, /opt/data ]
+        - [ xvdh, /opt/data, "auto", "defaults,nobootwait", "0", "0" ]
+    mount_default_fields: [None, None, "auto", "nefaults,nobootwait", "0", "2"]
+    swap:
+        filename: <file>
+        size: <"auto"/size in bytes>
+        maxsize: <size in bytes>
+"""
+
 from string import whitespace
 
 import logging
diff --git a/cloudinit/config/cc_ntp.py b/cloudinit/config/cc_ntp.py
index ad69aa3..7cda317 100644
--- a/cloudinit/config/cc_ntp.py
+++ b/cloudinit/config/cc_ntp.py
@@ -16,6 +16,38 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+NTP
+---
+**Summary:** enable and configure ntp
+
+Handle ntp configuration. If ntp is not installed on the system and ntp
+configuration is specified, ntp will be installed. If there is a default ntp
+config file in the image or one is present in the distro's ntp package, it will
+be copied to ``/etc/ntp.conf.dist`` before any changes are made. A list of ntp
+pools and ntp servers can be provided under the ``ntp`` config key. If no ntp
+servers or pools are provided, 4 pools will be used in the format
+``{0-3}.{distro}.pool.ntp.org``.
+
+**Internal name:** ``cc_ntp``
+
+**Module frequency:** per instance
+
+**Supported distros:** centos, debian, fedora, opensuse, ubuntu
+
+**Config keys**::
+
+    ntp:
+        pools:
+            - 0.company.pool.ntp.org
+            - 1.company.pool.ntp.org
+            - ntp.myorg.org
+        servers:
+            - my.ntp.server.local
+            - ntp.ubuntu.com
+            - 192.168.23.2
+"""
+
 from cloudinit import log as logging
 from cloudinit.settings import PER_INSTANCE
 from cloudinit import templater
diff --git a/cloudinit/config/cc_package_update_upgrade_install.py b/cloudinit/config/cc_package_update_upgrade_install.py
index 73b0e30..6d71761 100644
--- a/cloudinit/config/cc_package_update_upgrade_install.py
+++ b/cloudinit/config/cc_package_update_upgrade_install.py
@@ -16,6 +16,41 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Package Update Upgrade Install
+------------------------------
+**Summary:** update, upgrade, and install packages
+
+This module allows packages to be updated, upgraded or installed during boot.
+If any packages are to be installed or an upgrade is to be performed then the
+package cache will be updated first. If a package installation or upgrade
+requires a reboot, then a reboot can be performed if
+``package_reboot_if_required`` is specified. A list of packages to install can
+be provided. Each entry in the list can be either a package name or a list with
+two entries, the first being the package name and the second being the specific
+package version to install.
+
+**Internal name:** ``cc_package_update_upgrade_install``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+
+**Config keys**::
+
+    packages:
+        - pwgen
+        - pastebinit
+        - [libpython2.7, 2.7.3-0ubuntu3.1]
+    package_update: <true/false>
+    package_upgrade: <true/false>
+    package_reboot_if_required: <true/false>
+
+    apt_update: (alias for package_update)
+    apt_upgrade: (alias for package_upgrade)
+    apt_reboot_if_required: (alias for package_reboot_if_required)
+"""
+
 import os
 import time
 
diff --git a/cloudinit/config/cc_phone_home.py b/cloudinit/config/cc_phone_home.py
index ae720bd..cb70d39 100644
--- a/cloudinit/config/cc_phone_home.py
+++ b/cloudinit/config/cc_phone_home.py
@@ -18,6 +18,40 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Phone Home
+----------
+**Summary:** post data to url
+
+This module can be used to post data to a remote host after boot is complete.
+If the post url contains the string ``$INSTANCE_ID`` it will be replaced with
+the id of the current instance. Either all data can be posted or a list of
+keys to post. Available keys are:
+
+    - ``pub_key_dsa``
+    - ``pub_key_rsa``
+    - ``pub_key_ecdsa``
+    - ``instance_id``
+    - ``hostname``
+    - ``fdqn``
+
+**Internal name:** ``cc_phone_home``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+
+**Config keys**::
+
+    phone_home:
+        url: http://example.com/$INSTANCE_ID/
+        post:
+            - pub_key_dsa
+            - instance_id
+            - fqdn
+        tries: 10
+"""
+
 from cloudinit import templater
 from cloudinit import util
 
diff --git a/cloudinit/config/cc_power_state_change.py b/cloudinit/config/cc_power_state_change.py
index cc3f7f7..61b5416 100644
--- a/cloudinit/config/cc_power_state_change.py
+++ b/cloudinit/config/cc_power_state_change.py
@@ -16,6 +16,51 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Power State Change
+------------------
+**Summary:** change power state
+
+This module handles shutdown/reboot after all config modules have been run. By
+default it will take no action, and the system will keep running unless a
+package installation/upgrade requires a system reboot (e.g. installing a new
+kernel) and ``package_reboot_if_required`` is true. The ``power_state`` config
+key accepts a dict of options. If ``mode`` is any value other than
+``poweroff``, ``halt``, or ``reboot``, then no action will be taken.
+
+The system
+can be shutdown before cloud-init has finished using the ``timeout`` option.
+The ``delay`` key specifies a duration to be added onto any shutdown command
+used. Therefore, if a 5 minute delay and a 120 second shutdown are specified,
+the maximum amount of time between cloud-init starting and the system shutting
+down is 7 minutes, and the minimum amount of time is 5 minutes. The ``delay``
+key must have an argument in a form that the ``shutdown`` utility recognizes.
+The most common format is the form ``+5`` for 5 minutes. See ``man shutdown``
+for more options.
+
+Optionally, a command can be run to determine whether or not
+the system should shut down. The command to be run should be specified in the
+``condition`` key. For command formatting, see the documentation for
+``cc_runcmd``. The specified shutdown behavior will only take place if the
+``condition`` key is omitted or the command specified by the ``condition``
+key returns 0.
+
+**Internal name:** ``cc_power_state_change``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+
+**Config keys**::
+
+    power_state:
+        delay: <now/'+minutes'>
+        mode: <poweroff/halt/reboot>
+        message: <shutdown message>
+        timeout: <seconds>
+        condition: <true/false/command>
+"""
+
 from cloudinit.settings import PER_INSTANCE
 from cloudinit import util
 
diff --git a/cloudinit/config/cc_puppet.py b/cloudinit/config/cc_puppet.py
index 774d332..bfd630d 100644
--- a/cloudinit/config/cc_puppet.py
+++ b/cloudinit/config/cc_puppet.py
@@ -18,6 +18,51 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Puppet
+------
+**Summary:** install, configure and start puppet
+
+This module handles puppet installation and configuration. If the ``puppet``
+key does not exist in global configuration, no action will be taken. If a
+config entry for ``puppet`` is present, then by default the latest version of
+puppet will be installed. If ``install`` is set to ``false``, puppet will not
+be installed. However, this may result in an error if puppet is not already
+present on the system. The version of puppet to be installed can be specified
+under ``version``, and defaults to ``none``, which selects the latest version
+in the repos. If the ``puppet`` config key exists in the config archive, this
+module will attempt to start puppet even if no installation was performed.
+
+Puppet configuration can be specified under the ``conf`` key. The configuration
+is specified as a dictionary which is converted into ``<key>=<value>`` format
+and appended to ``puppet.conf`` under the ``[puppetd]`` section. The
+``certname`` key supports string substitutions for ``%i`` and ``%f``,
+corresponding to the instance id and fqdn of the machine respectively.
+If ``ca_cert`` is present under ``conf``, it will not be written to
+``puppet.conf``, but instead will be used as the puppermaster certificate.
+It should be specified in pem format as a multi-line string (using the ``|``
+yaml notation).
+
+**Internal name:** ``cc_puppet``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+
+**Config keys**::
+
+    puppet:
+        install: <true/false>
+        version: <version>
+        conf:
+            server: "puppetmaster.example.org"
+            certname: "%i.%f"
+            ca_cert: |
+                -------BEGIN CERTIFICATE-------
+                <cert data>
+                -------END CERTIFICATE-------
+"""
+
 from six import StringIO
 
 import os
diff --git a/cloudinit/config/cc_resizefs.py b/cloudinit/config/cc_resizefs.py
index 2a2a9f5..1b91796 100644
--- a/cloudinit/config/cc_resizefs.py
+++ b/cloudinit/config/cc_resizefs.py
@@ -18,6 +18,32 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Resizefs
+--------
+**Summary:** resize filesystem
+
+Resize a filesystem to use all avaliable space on partition. This module is
+useful along with ``cc_growpart`` and will ensure that if the root partition
+has been resized the root filesystem will be resized along with it. By default,
+``cc_resizefs`` will resize the root partition and will block the boot process
+while the resize command is running. Optionally, the resize operation can be
+performed in the background while cloud-init continues running modules. This
+can be enabled by setting ``resize_rootfs`` to ``true``. This module can be
+disabled altogether by setting ``resize_rootfs`` to ``false``.
+
+**Internal name:** ``cc_resizefs``
+
+**Module frequency:** per always
+
+**Supported distros:** all
+
+**Config keys**::
+
+    resize_rootfs: <true/false/"noblock">
+    resize_rootfs_tmp: <directory>
+"""
+
 import errno
 import os
 import stat
diff --git a/cloudinit/config/cc_resolv_conf.py b/cloudinit/config/cc_resolv_conf.py
index 71d9e3a..feea565 100644
--- a/cloudinit/config/cc_resolv_conf.py
+++ b/cloudinit/config/cc_resolv_conf.py
@@ -18,36 +18,45 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-#    Note:
-#    This module is intended to manage resolv.conf in environments where
-#    early configuration of resolv.conf is necessary for further
-#    bootstrapping and/or where configuration management such as puppet or
-#    chef own dns configuration. As Debian/Ubuntu will, by default, utilize
-#    resovlconf, and similarly RedHat will use sysconfig, this module is
-#    likely to be of little use unless those are configured correctly.
-#
-#    For RedHat with sysconfig, be sure to set PEERDNS=no for all DHCP
-#    enabled NICs.  And, in Ubuntu/Debian it is recommended that DNS
-#    be configured via the standard /etc/network/interfaces configuration
-#    file.
-#
-#
-#    Usage Example:
-#
-#    #cloud-config
-#    manage_resolv_conf: true
-#
-#    resolv_conf:
-#      nameservers: ['8.8.4.4', '8.8.8.8']
-#      searchdomains:
-#        - foo.example.com
-#        - bar.example.com
-#      domain: example.com
-#      options:
-#        rotate: true
-#        timeout: 1
-#
-
+"""
+Resolv Conf
+-----------
+**Summary:** configure resolv.conf
+
+This module is intended to manage resolv.conf in environments where early
+configuration of resolv.conf is necessary for further bootstrapping and/or
+where configuration management such as puppet or chef own dns configuration.
+As Debian/Ubuntu will, by default, utilize resovlconf, and similarly RedHat
+will use sysconfig, this module is likely to be of little use unless those
+are configured correctly.
+
+.. note::
+    For RedHat with sysconfig, be sure to set PEERDNS=no for all DHCP
+    enabled NICs.
+
+.. note::
+    And, in Ubuntu/Debian it is recommended that DNS be configured via the
+    standard /etc/network/interfaces configuration file.
+
+**Internal name:** ``cc_resolv_conf``
+
+**Module frequency:** per instance
+
+**Supported distros:** fedora, rhel, sles
+
+**Config keys**::
+
+    manage_resolv_conf: <true/false>
+    resolv_conf:
+        nameservers: ['8.8.4.4', '8.8.8.8']
+        searchdomains:
+            - foo.example.com
+            - bar.example.com
+        domain: example.com
+        options:
+            rotate: <true/false>
+            timeout: 1
+"""
 
 from cloudinit import log as logging
 from cloudinit.settings import PER_INSTANCE
diff --git a/cloudinit/config/cc_rh_subscription.py b/cloudinit/config/cc_rh_subscription.py
index d4ad724..d858f65 100644
--- a/cloudinit/config/cc_rh_subscription.py
+++ b/cloudinit/config/cc_rh_subscription.py
@@ -16,6 +16,40 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+RedHat Subscription
+-------------------
+**Summary:** register red hat enterprise linux based system
+
+Register a RedHat system either by username and password *or* activation and
+org. Following a sucessful registration, you can auto-attach subscriptions, set
+the service level, add subscriptions based on pool id, enable/disable yum
+repositories based on repo id, and alter the rhsm_baseurl and server-hostname
+in ``/etc/rhsm/rhs.conf``. For more details, see the ``Register RedHat
+Subscription`` example config.
+
+**Internal name:** ``cc_rh_subscription``
+
+**Module frequency:** per instance
+
+**Supported distros:** rhel, fedora
+
+**Config keys**::
+
+    rh_subscription:
+        username: <username>
+        password: <password>
+        activation-key: <activation key>
+        org: <org number>
+        auto-attach: <true/false>
+        service-level: <service level>
+        add-pool: <list of pool ids>
+        enable-repo: <list of yum repo ids>
+        disable-repo: <list of yum repo ids>
+        rhsm-baseurl: <url>
+        server-hostname: <hostname>
+"""
+
 from cloudinit import util
 
 distros = ['fedora', 'rhel']
diff --git a/cloudinit/config/cc_rightscale_userdata.py b/cloudinit/config/cc_rightscale_userdata.py
index 8118fac..6cf8c94 100644
--- a/cloudinit/config/cc_rightscale_userdata.py
+++ b/cloudinit/config/cc_rightscale_userdata.py
@@ -18,6 +18,32 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Rightscale Userdata
+-------------------
+**Summary:** support rightscale configuration hooks
+
+This module adds support for RightScale configuration hooks to cloud-init.
+RightScale adds a entry in the format ``CLOUD_INIT_REMOTE_HOOK=http://...`` to
+ec2 user-data. This module checks for this line in the raw userdata and
+retrieves any scripts linked by the RightScale user data and places them in the
+user scripts configuration directory, to be run later by ``cc_scripts_user``.
+
+.. note::
+    the ``CLOUD_INIT_REMOTE_HOOK`` config variable is present in the raw ec2
+    user data only, not in any cloud-config parts
+
+**Internal name:** ``cc_rightscale_userdata``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+
+**Config keys**::
+
+    CLOUD_INIT_REMOTE_HOOK=<url>
+"""
+
 #
 # The purpose of this script is to allow cloud-init to consume
 # rightscale style userdata.  rightscale user data is key-value pairs
diff --git a/cloudinit/config/cc_rsyslog.py b/cloudinit/config/cc_rsyslog.py
index b8642d6..48f1862 100644
--- a/cloudinit/config/cc_rsyslog.py
+++ b/cloudinit/config/cc_rsyslog.py
@@ -18,90 +18,175 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
-rsyslog module allows configuration of syslog logging via rsyslog
-Configuration is done under the cloud-config top level 'rsyslog'.
-
-Under 'rsyslog' you can define:
-  - configs:  [default=[]]
-    this is a list.  entries in it are a string or a dictionary.
-    each entry has 2 parts:
-       * content
-       * filename
-    if the entry is a string, then it is assigned to 'content'.
-    for each entry, content is written to the provided filename.
-    if filename is not provided, its default is read from 'config_filename'
-
-    Content here can be any valid rsyslog configuration.  No format
-    specific format is enforced.
-
-    For simply logging to an existing remote syslog server, via udp:
-      configs: ["*.* @192.168.1.1"]
-
-  - remotes: [default={}]
-    This is a dictionary of name / value pairs.
-    In comparison to 'config's, it is more focused in that it only supports
-    remote syslog configuration.  It is not rsyslog specific, and could
-    convert to other syslog implementations.
-
-    Each entry in remotes is a 'name' and a 'value'.
-     * name: an string identifying the entry.  good practice would indicate
-       using a consistent and identifiable string for the producer.
-       For example, the MAAS service could use 'maas' as the key.
-     * value consists of the following parts:
-       * optional filter for log messages
-         default if not present: *.*
-       * optional leading '@' or '@@' (indicates udp or tcp respectively).
-         default if not present (udp): @
-         This is rsyslog format for that. if not present, is '@'.
-       * ipv4 or ipv6 or hostname
-         ipv6 addresses must be in [::1] format. (@[fd00::1]:514)
-       * optional port
-         port defaults to 514
-
-  - config_filename: [default=20-cloud-config.conf]
-    this is the file name to use if none is provided in a config entry.
-
-  - config_dir: [default=/etc/rsyslog.d]
-    this directory is used for filenames that are not absolute paths.
-
-  - service_reload_command: [default="auto"]
-    this command is executed if files have been written and thus the syslog
-    daemon needs to be told.
-
-Note, since cloud-init 0.5 a legacy version of rsyslog config has been
-present and is still supported. See below for the mappings between old
-value and new value:
-   old value           -> new value
-   'rsyslog'           -> rsyslog/configs
-   'rsyslog_filename'  -> rsyslog/config_filename
-   'rsyslog_dir'       -> rsyslog/config_dir
-
-the legacy config does not support 'service_reload_command'.
-
-Example config:
-  #cloud-config
-  rsyslog:
-    configs:
-      - "*.* @@192.158.1.1"
-      - content: "*.*   @@192.0.2.1:10514"
-        filename: 01-example.conf
-      - content: |
-        *.*   @@syslogd.example.com
-    remotes:
-      maas: "192.168.1.1"
-      juju: "10.0.4.1"
-    config_dir: config_dir
-    config_filename: config_filename
-    service_reload_command: [your, syslog, restart, command]
-
-Example Legacy config:
-  #cloud-config
-  rsyslog:
-    - "*.* @@192.158.1.1"
-  rsyslog_dir: /etc/rsyslog-config.d/
-  rsyslog_filename: 99-local.conf
+Rsyslog
+-------
+**Summary:** configure system loggig via rsyslog
+
+This module configures remote system logging using rsyslog.
+
+The rsyslog config file to write to can be specified in ``config_filename``,
+which defaults to ``20-cloud-config.conf``. The rsyslog config directory to
+write config files to may be specified in ``config_dir``, which defaults to
+``/etc/rsyslog.d``.
+
+A list of configurations for for rsyslog can be specified under the ``configs``
+key in the ``rsyslog`` config. Each entry in ``configs`` is either a string or
+a dictionary. Each config entry contains a configuration string and a file to
+write it to. For config entries that are a dictionary, ``filename`` sets the
+target filename and ``content`` specifies the config string to write. For
+config entries that are only a string, the string is used as the config string
+to write. If the filename to write the config to is not specified, the value of
+the ``config_filename`` key is used. A file with the selected filename will
+be written inside the directory specified by ``config_dir``.
+
+The command to use to reload the rsyslog service after the config has been
+updated can be specified in ``service_reload_command``. If this is set to
+``auto``, then an appropriate command for the distro will be used. This is the
+default behavior. To manually set the command, use a list of command args (e.g.
+``[systemctl, restart, rsyslog]``).
+
+Configuration for remote servers can be specified in ``configs``, but for
+convenience it can be specified as key value pairs in ``remotes``. Each key
+is the name for an rsyslog remote entry. Each value holds the contents of the
+remote config for rsyslog. The config consists of the following parts:
+
+    - filter for log messages (defaults to ``*.*``)
+    - optional leading ``@`` or ``@@``, indicating udp and tcp respectively
+      (defaults to ``@``, for udp)
+    - ipv4 or ipv6 hostname or address. ipv6 addresses must be in ``[::1]``
+      format, (e.g. ``@[fd00::1]:514``)
+    - optional port number (defaults to ``514``)
+
+This module will provide sane defaults for any part of the remote entry that is
+not specified, so in most cases remote hosts can be specified just using
+``<name>: <address>``.
+
+For backwards compatibility, this module still supports legacy names for the
+config entries. Legacy to new mappings are as follows:
+
+    - ``rsyslog`` -> ``rsyslog/configs``
+    - ``rsyslog_filename`` -> ``rsyslog/config_filename``
+    - ``rsyslog_dir`` -> ``rsyslog/config_dir``
+
+.. note::
+    The legacy config format does not support specifying
+    ``service_reload_command``.
+
+**Internal name:** ``cc_rsyslog``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+
+**Config keys**::
+
+    rsyslog:
+        config_dir: config_dir
+        config_filename: config_filename
+        configs:
+            - "*.* @@192.158.1.1"
+            - content: "*.*   @@192.0.2.1:10514"
+              filename: 01-example.conf
+            - content: |
+                *.*   @@syslogd.example.com
+        remotes:
+            maas: "192.168.1.1"
+            juju: "10.0.4.1"
+        service_reload_command: [your, syslog, restart, command]
+
+**Legacy config keys**::
+
+    rsyslog:
+        - "*.* @@192.158.1.1"
+    rsyslog_dir: /etc/rsyslog-config.d/
+    rsyslog_filename: 99-local.conf
 """
 
+# Old rsyslog documentation, kept for reference:
+#
+# rsyslog module allows configuration of syslog logging via rsyslog
+# Configuration is done under the cloud-config top level 'rsyslog'.
+#
+# Under 'rsyslog' you can define:
+#   - configs:  [default=[]]
+#     this is a list.  entries in it are a string or a dictionary.
+#     each entry has 2 parts:
+#        * content
+#        * filename
+#     if the entry is a string, then it is assigned to 'content'.
+#     for each entry, content is written to the provided filename.
+#     if filename is not provided, its default is read from 'config_filename'
+#
+#     Content here can be any valid rsyslog configuration.  No format
+#     specific format is enforced.
+#
+#     For simply logging to an existing remote syslog server, via udp:
+#       configs: ["*.* @192.168.1.1"]
+#
+#   - remotes: [default={}]
+#     This is a dictionary of name / value pairs.
+#     In comparison to 'config's, it is more focused in that it only supports
+#     remote syslog configuration.  It is not rsyslog specific, and could
+#     convert to other syslog implementations.
+#
+#     Each entry in remotes is a 'name' and a 'value'.
+#      * name: an string identifying the entry.  good practice would indicate
+#        using a consistent and identifiable string for the producer.
+#        For example, the MAAS service could use 'maas' as the key.
+#      * value consists of the following parts:
+#        * optional filter for log messages
+#          default if not present: *.*
+#        * optional leading '@' or '@@' (indicates udp or tcp respectively).
+#          default if not present (udp): @
+#          This is rsyslog format for that. if not present, is '@'.
+#        * ipv4 or ipv6 or hostname
+#          ipv6 addresses must be in [::1] format. (@[fd00::1]:514)
+#        * optional port
+#          port defaults to 514
+#
+#   - config_filename: [default=20-cloud-config.conf]
+#     this is the file name to use if none is provided in a config entry.
+#
+#   - config_dir: [default=/etc/rsyslog.d]
+#     this directory is used for filenames that are not absolute paths.
+#
+#   - service_reload_command: [default="auto"]
+#     this command is executed if files have been written and thus the syslog
+#     daemon needs to be told.
+#
+# Note, since cloud-init 0.5 a legacy version of rsyslog config has been
+# present and is still supported. See below for the mappings between old
+# value and new value:
+#    old value           -> new value
+#    'rsyslog'           -> rsyslog/configs
+#    'rsyslog_filename'  -> rsyslog/config_filename
+#    'rsyslog_dir'       -> rsyslog/config_dir
+#
+# the legacy config does not support 'service_reload_command'.
+#
+# Example config:
+#   #cloud-config
+#   rsyslog:
+#     configs:
+#       - "*.* @@192.158.1.1"
+#       - content: "*.*   @@192.0.2.1:10514"
+#         filename: 01-example.conf
+#       - content: |
+#         *.*   @@syslogd.example.com
+#     remotes:
+#       maas: "192.168.1.1"
+#       juju: "10.0.4.1"
+#     config_dir: config_dir
+#     config_filename: config_filename
+#     service_reload_command: [your, syslog, restart, command]
+#
+# Example Legacy config:
+#   #cloud-config
+#   rsyslog:
+#     - "*.* @@192.158.1.1"
+#   rsyslog_dir: /etc/rsyslog-config.d/
+#   rsyslog_filename: 99-local.conf
+
 import os
 import re
 import six
diff --git a/cloudinit/config/cc_runcmd.py b/cloudinit/config/cc_runcmd.py
index bc09d38..23e1e89 100644
--- a/cloudinit/config/cc_runcmd.py
+++ b/cloudinit/config/cc_runcmd.py
@@ -18,6 +18,38 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Runcmd
+------
+**Summary:** run commands
+
+Run arbitrary commands at a rc.local like level with output to the console.
+Each item can be either a list or a string. If the item is a list, it will be
+properly executed as if passed to ``execve()`` (with the first arg as the
+command). If the item is a string, it will be written to a file and interpreted
+using ``sh``.
+
+.. note::
+    all commands must be proper yaml, so you have to quote any characters yaml
+    would eat (':' can be problematic)
+
+**Internal name:** ``cc_runcmd``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+
+**Config keys**::
+
+    runcmd:
+        - [ ls, -l, / ]
+        - [ sh, -xc, "echo $(date) ': hello world!'" ]
+        - [ sh, -c, echo "=========hello world'=========" ]
+        - ls -l /root
+        - [ wget, "http://example.org";, -O, /tmp/index.html ]
+"""
+
+
 import os
 
 from cloudinit import util
diff --git a/cloudinit/config/cc_salt_minion.py b/cloudinit/config/cc_salt_minion.py
index 13d70c8..9078665 100644
--- a/cloudinit/config/cc_salt_minion.py
+++ b/cloudinit/config/cc_salt_minion.py
@@ -14,6 +14,39 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Salt Minion
+-----------
+**Summary:** set up and run salt minion
+
+This module installs, configures and starts salt minion. If the ``salt_minion``
+key is present in the config parts, then salt minion will be installed and
+started. Configuration for salt minion can be specified in the ``conf`` key
+under ``salt_minion``. Any conf values present there will be assigned in
+``/etc/salt/minion``. The public and private keys to use for salt minion can be
+specified with ``public_key`` and ``private_key`` respectively.
+
+**Internal name:** ``cc_salt_minion``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+
+**Config keys**::
+
+    salt_minion:
+        conf:
+            master: salt.example.com
+        public_key: |
+            ------BEGIN PUBLIC KEY-------
+            <key data>
+            ------END PUBLIC KEY-------
+        private_key: |
+            ------BEGIN PRIVATE KEY------
+            <key data>
+            ------END PRIVATE KEY-------
+"""
+
 import os
 
 from cloudinit import util
diff --git a/cloudinit/config/cc_scripts_per_boot.py b/cloudinit/config/cc_scripts_per_boot.py
index ee3b6c9..0736cf7 100644
--- a/cloudinit/config/cc_scripts_per_boot.py
+++ b/cloudinit/config/cc_scripts_per_boot.py
@@ -18,6 +18,22 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Scripts Per Boot
+----------------
+**Summary:** run per boot scripts
+
+Any scripts in the ``scripts/per-boot`` directory on the datasource will be run
+every time the system boots. Scripts will be run in alphabetical order. This
+module does not accept any config keys.
+
+**Internal name:** ``cc_scripts_per_boot``
+
+**Module frequency:** per always
+
+**Supported distros:** all
+"""
+
 import os
 
 from cloudinit import util
diff --git a/cloudinit/config/cc_scripts_per_instance.py b/cloudinit/config/cc_scripts_per_instance.py
index c0d62b1..c71d154 100644
--- a/cloudinit/config/cc_scripts_per_instance.py
+++ b/cloudinit/config/cc_scripts_per_instance.py
@@ -18,6 +18,22 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Scripts Per Instance
+--------------------
+**Summary:** run per instance scripts
+
+Any scripts in the ``scripts/per-instance`` directory on the datasource will
+be run when a new instance is first booted. Scripts will be run in alphabetical
+order. This module does not accept any config keys.
+
+**Internal name:** ``cc_scripts_per_instance``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+"""
+
 import os
 
 from cloudinit import util
diff --git a/cloudinit/config/cc_scripts_per_once.py b/cloudinit/config/cc_scripts_per_once.py
index ecb527f..bf637ee 100644
--- a/cloudinit/config/cc_scripts_per_once.py
+++ b/cloudinit/config/cc_scripts_per_once.py
@@ -18,6 +18,22 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Scripts Per Once
+----------------
+**Summary:** run one time scripts
+
+Any scripts in the ``scripts/per-once`` directory on the datasource will be run
+only once. Scripts will be run in alphabetical order. This module does not
+accept any config keys.
+
+**Internal name:** ``cc_scripts_per_once``
+
+**Module frequency:** per once
+
+**Supported distros:** all
+"""
+
 import os
 
 from cloudinit import util
diff --git a/cloudinit/config/cc_scripts_user.py b/cloudinit/config/cc_scripts_user.py
index 699857d..54338a4 100644
--- a/cloudinit/config/cc_scripts_user.py
+++ b/cloudinit/config/cc_scripts_user.py
@@ -18,6 +18,25 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Scripts User
+------------
+**Summary:** run user scripts
+
+This module runs all user scripts. User scripts are not specified in the
+``scripts`` directory in the datasource, but rather are present in the
+``scripts`` dir in the instance configuration. Any cloud-config parts with a
+``#!`` will be treated as a script and run. Scripts specified as cloud-config
+parts will be run in the order they are specified in the configuration.
+This module does not accept any config keys.
+
+**Internal name:** ``cc_scripts_user``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+"""
+
 import os
 
 from cloudinit import util
diff --git a/cloudinit/config/cc_scripts_vendor.py b/cloudinit/config/cc_scripts_vendor.py
index 80bf10f..b5777df 100644
--- a/cloudinit/config/cc_scripts_vendor.py
+++ b/cloudinit/config/cc_scripts_vendor.py
@@ -16,6 +16,28 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Scripts Vendor
+--------------
+**Summary:** run vendor scripts
+
+Any scripts in the ``scripts/vendor`` directory in the datasource will be run
+when a new instance is first booted. Scripts will be run in alphabetical order.
+Vendor scripts can be run with an optional prefix specified in the ``prefix``
+entry under the ``vendor_data`` config key.
+
+**Internal name:** ``cc_scripts_vendor``
+
+**Module frequency:** per instance
+
+**Supporte distros:** all
+
+**Config keys**::
+
+    vendor_data:
+        prefix: <vendor data prefix>
+"""
+
 import os
 
 from cloudinit import util
diff --git a/cloudinit/config/cc_seed_random.py b/cloudinit/config/cc_seed_random.py
index 5085c23..d84255e 100644
--- a/cloudinit/config/cc_seed_random.py
+++ b/cloudinit/config/cc_seed_random.py
@@ -19,6 +19,58 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Seed Random
+-----------
+**Summary:** provide random seed data
+
+Since all cloud instances started from the same image will produce very similar
+data when they are first booted, as they are all starting with the same seed
+for the kernel's entropy keyring. To avoid this, random seed data can be
+provided to the instance either as a string or by specifying a command to run
+to generate the data.
+
+Configuration for this module is under the ``random_seed`` config key. The
+``file`` key specifies the path to write the data to, defaulting to
+``/dev/urandom``. Data can be passed in directly with ``data``, and may
+optionally be specified in encoded form, with the encoding specified in
+``encoding``.
+
+.. note::
+    when using a multiline value for ``data`` or specifying binary data, be
+    sure to follow yaml syntax and use the ``|`` and ``!binary`` yaml format
+    specifiers when appropriate
+
+Instead of specifying a data string, a command can be run to generate/collect
+the data to be written. The command should be specified as a list of args in
+the ``command`` key. If a command is specified that cannot be run, no error
+will be reported unless ``command_required`` is set to true.
+
+For example, to use ``pollinate`` to gather data from a
+remote entropy server and write it to ``/dev/urandom``, the following could be
+used::
+
+    random_seed:
+        file: /dev/urandom
+        command: ["pollinate", "--server=http://local.polinate.server";]
+        command_required: true
+
+**Internal name:** ``cc_seed_random``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+
+**Config keys**::
+
+    random_seed:
+        file: <file>
+        data: <random string>
+        encoding: <raw/base64/b64/gzip/gz>
+        command: [<cmd name>, <arg1>, <arg2>...]
+        command_required: <true/false>
+"""
+
 import base64
 import os
 
diff --git a/cloudinit/config/cc_set_hostname.py b/cloudinit/config/cc_set_hostname.py
index f43d8d5..c35cefe 100644
--- a/cloudinit/config/cc_set_hostname.py
+++ b/cloudinit/config/cc_set_hostname.py
@@ -18,6 +18,32 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Set Hostname
+------------
+**Summary:** set hostname and fqdn
+
+This module handles setting the system hostname and fqdn. If
+``preserve_hostname`` is set, then the hostname will not be altered.
+
+A hostname and fqdn can be provided by specifying a full domain name under the
+``fqdn`` key. Alternatively, a hostname can be specified using the ``hostname``
+key, and the fqdn of the cloud wil be used. If a fqdn specified with the
+``hostname`` key, it will be handled properly, although it is better to use
+the ``fqdn`` config key. If both ``fqdn`` and ``hostname`` are set, ``fqdn``
+will be used.
+
+**Internal name:** per instance
+
+**Supported distros:** all
+
+**Config keys**::
+
+    perserve_hostname: <true/false>
+    fqdn: <fqdn>
+    hostname: <fqdn/hostname>
+"""
+
 from cloudinit import util
 
 
diff --git a/cloudinit/config/cc_set_passwords.py b/cloudinit/config/cc_set_passwords.py
index 5c8c23b..9471601 100644
--- a/cloudinit/config/cc_set_passwords.py
+++ b/cloudinit/config/cc_set_passwords.py
@@ -18,6 +18,52 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Set Passwords
+-------------
+**Summary:** Set user passwords
+
+Set system passwords and enable or disable ssh password authentication.
+The ``chpasswd`` config key accepts a dictionary containing a single one of two
+keys, either ``expire`` or ``list``. If ``expire`` is specified and is set to
+``false``, then the ``password`` global config key is used as the password for
+all user accounts. If the ``expire`` key is specified and is set to ``true``
+then user passwords will be expired, preventing the default system passwords
+from being used.
+
+If the ``list`` key is provided, a list of
+``username:password`` pairs can be specified. The usernames specified
+must already exist on the system, or have been created using the
+``cc_users_groups`` module. A password can be randomly generated using
+``username:RANDOM`` or ``username:R``. Password ssh authentication can be
+enabled, disabled, or left to system defaults using ``ssh_pwauth``.
+
+.. note::
+    if using ``expire: true`` then a ssh authkey should be specified or it may
+    not be possible to login to the system
+
+**Internal name:** ``cc_set_passwords``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+
+**Config keys**::
+
+    ssh_pwauth: <yes/no/unchanged>
+
+    password: password1
+    chpasswd:
+        expire: <true/false>
+
+    chpasswd:
+        list:
+            - user1:password1
+            - user2:Random
+            - user3:password3
+            - user4:R
+"""
+
 import sys
 
 # Ensure this is aliased to a name not 'distros'
diff --git a/cloudinit/config/cc_snappy.py b/cloudinit/config/cc_snappy.py
index 6bcd838..36db9e6 100644
--- a/cloudinit/config/cc_snappy.py
+++ b/cloudinit/config/cc_snappy.py
@@ -1,49 +1,76 @@
 # vi: ts=4 expandtab
 #
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License version 3, as
+#    published by the Free Software Foundation.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
 """
-snappy modules allows configuration of snappy.
-Example config:
-  #cloud-config
-  snappy:
-    system_snappy: auto
-    ssh_enabled: auto
-    packages: [etcd, pkg2.smoser]
-    config:
-      pkgname:
-        key2: value2
-      pkg2:
-        key1: value1
-    packages_dir: '/writable/user-data/cloud-init/snaps'
-
- - ssh_enabled:
-   This controls the system's ssh service.  The default value is 'auto'.
-     True:  enable ssh service
-     False: disable ssh service
-     auto:  enable ssh service if either ssh keys have been provided
-            or user has requested password authentication (ssh_pwauth).
-
- - snap installation and config
-   The above would install 'etcd', and then install 'pkg2.smoser' with a
-   '<config-file>' argument where 'config-file' has 'config-blob' inside it.
-   If 'pkgname' is installed already, then 'snappy config pkgname <file>'
-   will be called where 'file' has 'pkgname-config-blob' as its content.
-
-   Entries in 'config' can be namespaced or non-namespaced for a package.
-   In either case, the config provided to snappy command is non-namespaced.
-   The package name is provided as it appears.
-
-   If 'packages_dir' has files in it that end in '.snap', then they are
-   installed.  Given 3 files:
-     <packages_dir>/foo.snap
-     <packages_dir>/foo.config
-     <packages_dir>/bar.snap
-   cloud-init will invoke:
-     snappy install <packages_dir>/foo.snap <packages_dir>/foo.config
-     snappy install <packages_dir>/bar.snap
-
-   Note, that if provided a 'config' entry for 'ubuntu-core', then
-   cloud-init will invoke: snappy config ubuntu-core <config>
-   Allowing you to configure ubuntu-core in this way.
+Snappy
+------
+**Summary:** snappy modules allows configuration of snappy.
+
+The below example config config would install ``etcd``, and then install
+``pkg2.smoser`` with a ``<config-file>`` argument where ``config-file`` has
+``config-blob`` inside it. If ``pkgname`` is installed already, then
+``snappy config pkgname <file>``
+will be called where ``file`` has ``pkgname-config-blob`` as its content.
+
+Entries in ``config`` can be namespaced or non-namespaced for a package.
+In either case, the config provided to snappy command is non-namespaced.
+The package name is provided as it appears.
+
+If ``packages_dir`` has files in it that end in ``.snap``, then they are
+installed.  Given 3 files:
+
+  - <packages_dir>/foo.snap
+  - <packages_dir>/foo.config
+  - <packages_dir>/bar.snap
+
+cloud-init will invoke:
+
+  - snappy install <packages_dir>/foo.snap <packages_dir>/foo.config
+  - snappy install <packages_dir>/bar.snap
+
+.. note::
+    that if provided a ``config`` entry for ``ubuntu-core``, then
+    cloud-init will invoke: snappy config ubuntu-core <config>
+    Allowing you to configure ubuntu-core in this way.
+
+The ``ssh_enabled`` key controls the system's ssh service. The default value
+is ``auto``. Options are:
+
+  - **True:** enable ssh service
+  - **False:** disable ssh service
+  - **auto:** enable ssh service if either ssh keys have been provided
+    or user has requested password authentication (ssh_pwauth).
+
+**Internal name:** ``cc_snappy``
+
+**Module frequency:** per instance
+
+**Supported distros:** ubuntu
+
+**Config keys**::
+
+    #cloud-config
+    snappy:
+        system_snappy: auto
+        ssh_enabled: auto
+        packages: [etcd, pkg2.smoser]
+        config:
+            pkgname:
+                key2: value2
+            pkg2:
+                key1: value1
+        packages_dir: '/writable/user-data/cloud-init/snaps'
 """
 
 from cloudinit import log as logging
diff --git a/cloudinit/config/cc_spacewalk.py b/cloudinit/config/cc_spacewalk.py
index f3c1a66..99b63a8 100644
--- a/cloudinit/config/cc_spacewalk.py
+++ b/cloudinit/config/cc_spacewalk.py
@@ -13,15 +13,30 @@
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 """
-**Summary:** helper to setup https://fedorahosted.org/spacewalk/
+Spacewalk
+---------
+**Summary:** install and configure spacewalk
 
-**Description:** This module will enable for configuring the needed
-actions to setup spacewalk on redhat based systems.
+This module installs spacewalk and applies basic configuration. If the
+``spacewalk`` config key is present spacewalk will be installed. The server to
+connect to after installation must be provided in the ``server`` in spacewalk
+configuration. A proxy to connect through and a activation key may optionally
+be specified.
 
-It can be configured with the following option structure::
+For more information about spacewalk see: https://fedorahosted.org/spacewalk/
+
+**Internal name:** ``cc_spacewalk``
+
+**Module frequency:** per instance
+
+**Supported distros:** redhat, fedora
+
+**Config keys**::
 
     spacewalk:
-       server: spacewalk api server (required)
+       server: <url>
+       proxy: <proxy host>
+       activation_key: <key>
 """
 
 from cloudinit import util
diff --git a/cloudinit/config/cc_ssh.py b/cloudinit/config/cc_ssh.py
index cb9b70a..6138fb5 100644
--- a/cloudinit/config/cc_ssh.py
+++ b/cloudinit/config/cc_ssh.py
@@ -18,6 +18,93 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+SSH
+---
+**Summary:** configure ssh and ssh keys
+
+This module handles most configuration for ssh and ssh keys. Many images have
+default ssh keys, which can be removed using ``ssh_deletekeys``. Since removing
+default keys is usually the desired behavior this option is enabled by default.
+
+Keys can be added using the ``ssh_keys`` configuration key. The argument to
+this config key should be a dictionary entries for the public and private keys
+of each desired key type. Entries in the ``ssh_keys`` config dict should
+have keys in the format ``<key type>_private`` and ``<key type>_public``, e.g.
+``rsa_private: <key>`` and ``rsa_public: <key>``. See below for supported key
+types. Not all key types have to be specified, ones left unspecified will not
+be used. If this config option is used, then no keys will be generated.
+
+.. note::
+    when specifying private keys in cloud-config, care should be taken to
+    ensure that the communication between the data source and the instance is
+    secure
+
+.. note::
+    to specify multiline private keys, use yaml multiline syntax
+
+If no keys are specified using ``ssh_keys``, then keys will be generated using
+``ssh-keygen``. By default one public/private pair of each supported key type
+will be generated. The key types to generate can be specified using the
+``ssh_genkeytypes`` config flag, which accepts a list of key types to use. For
+each key type for which this module has been instructed to create a keypair, if
+a key of the same type is already present on the system (i.e. if
+``ssh_deletekeys`` was false), no key will be generated.
+
+Supported key types for the ``ssh_keys`` and the ``ssh_genkeytypes`` config
+flags are:
+
+    - rsa
+    - dsa
+    - ecdsa
+    - ed25519
+
+Root login can be enabled/disabled using the ``disable_root`` config key. Root
+login options can be manually specified with ``disable_root_opts``. If
+``disable_root_opts`` is specified and contains the string ``$USER``,
+it will be replaced with the username of the default user. By default,
+root login is disabled, and root login opts are set to::
+
+    no-port-forwarding,no-agent-forwarding,no-X11-forwarding
+
+Authorized keys for the default user/first user defined in ``users`` can be
+specified using `ssh_authorized_keys``. Keys should be specified as a list of
+public keys.
+
+.. note::
+    see the ``cc_set_passwords`` module documentation to enable/disable ssh
+    password authentication
+
+**Internal name:** ``cc_ssh``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+
+**Config keys**::
+
+    ssh_deletekeys: <true/false>
+    ssh_keys:
+        rsa_private: |
+            -----BEGIN RSA PRIVATE KEY-----
+            MIIBxwIBAAJhAKD0YSHy73nUgysO13XsJmd4fHiFyQ+00R7VVu2iV9Qco
+            ...
+            -----END RSA PRIVATE KEY-----
+        rsa_public: ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAGEAoPRhIfLvedSDKw7Xd ...
+        dsa_private: |
+            -----BEGIN DSA PRIVATE KEY-----
+            MIIBxwIBAAJhAKD0YSHy73nUgysO13XsJmd4fHiFyQ+00R7VVu2iV9Qco
+            ...
+            -----END DSA PRIVATE KEY-----
+        dsa_public: ssh-dsa AAAAB3NzaC1yc2EAAAABIwAAAGEAoPRhIfLvedSDKw7Xd ...
+    ssh_genkeytypes: <key type>
+    disable_root: <true/false>
+    disable_root_opts: <disable root options string>
+    ssh_authorized_keys:
+        - ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAGEA3FSyQwBI6Z+nCSjUU ...
+        - ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3I7VUf2l5gSn5uavROsc5HRDpZ ...
+"""
+
 import glob
 import os
 import sys
diff --git a/cloudinit/config/cc_ssh_authkey_fingerprints.py b/cloudinit/config/cc_ssh_authkey_fingerprints.py
index 6ce831b..6f3d0ee 100644
--- a/cloudinit/config/cc_ssh_authkey_fingerprints.py
+++ b/cloudinit/config/cc_ssh_authkey_fingerprints.py
@@ -16,6 +16,27 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+SSH Authkey Fingerprints
+------------------------
+**Summary:** log fingerprints of user ssh keys
+
+Write fingerprints of authorized keys for each user to log. This is enabled by
+default, but can be disabled using ``no_ssh_fingerprints``. The hash type for
+the keys can be specified, but defaults to ``md5``.
+
+**Internal name:** `` cc_ssh_authkey_fingerprints``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+
+**Config keys**::
+
+    no_ssh_fingerprints: <true/false>
+    authkey_hash: <hash type>
+"""
+
 import base64
 import hashlib
 
diff --git a/cloudinit/config/cc_ssh_import_id.py b/cloudinit/config/cc_ssh_import_id.py
index 28c4585..99359c8 100644
--- a/cloudinit/config/cc_ssh_import_id.py
+++ b/cloudinit/config/cc_ssh_import_id.py
@@ -18,6 +18,30 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+SSH Import Id
+-------------
+**Summary:** import ssh id
+
+This module imports ssh keys from either a public keyserver, usually launchpad
+or github using ``ssh-import-id``. Keys are referenced by the username they are
+associated with on the keyserver. The keyserver can be specified by prepending
+either ``lp:`` for launchpad or ``gh:`` for github to the username.
+
+**Internal name:** ``cc_ssh_import_id``
+
+**Module frequency:** per instance
+
+**Supported distros:** ubuntu, debian
+
+**Config keys**::
+
+    ssh_import_id:
+        - user
+        - gh:user
+        - lp:user
+"""
+
 # Ensure this is aliased to a name not 'distros'
 # since the module attribute 'distros'
 # is a list of distros that are supported, not a sub-module
diff --git a/cloudinit/config/cc_timezone.py b/cloudinit/config/cc_timezone.py
index b9eb85b..7024b07 100644
--- a/cloudinit/config/cc_timezone.py
+++ b/cloudinit/config/cc_timezone.py
@@ -18,6 +18,26 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Timezone
+--------
+**Summary:** set system timezone
+
+Set the system timezone. If any args are passed to the module then the first
+will be used for the timezone. Otherwise, the module will attempt to retrieve
+the timezone from cloud config.
+
+**Internal name:** ``cc_timezone``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+
+**Config keys**::
+
+    timezone: <timezone>
+"""
+
 from cloudinit import util
 
 from cloudinit.settings import PER_INSTANCE
diff --git a/cloudinit/config/cc_ubuntu_init_switch.py b/cloudinit/config/cc_ubuntu_init_switch.py
index bffb438..31a96e4 100644
--- a/cloudinit/config/cc_ubuntu_init_switch.py
+++ b/cloudinit/config/cc_ubuntu_init_switch.py
@@ -17,27 +17,33 @@
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 """
+Ubuntu Init Switch
+------------------
 **Summary:** reboot system into another init.
 
-**Description:** This module provides a way for the user to boot with systemd
-even if the image is set to boot with upstart.  It should be run as one of the
-first ``cloud_init_modules``, and will switch the init system and then issue a
-reboot. The next boot will come up in the target init system and no action will
-be taken.
+This module provides a way for the user to boot with systemd even if the image
+is set to boot with upstart. It should be run as one of the first
+``cloud_init_modules``, and will switch the init system and then issue a
+reboot. The next boot will come up in the target init system and no action
+will be taken. This should be inert on non-ubuntu systems, and also
+exit quickly.
 
-This should be inert on non-ubuntu systems, and also exit quickly.
+.. note::
+    best effort is made, but it's possible this system will break, and probably
+    won't interact well with any other mechanism you've used to switch the init
+    system.
+
+**Internal name:** ``cc_ubuntu_init_switch``
+
+**Module frequency:** once per instance
+
+**Supported distros:** ubuntu
 
-It can be configured with the following option structure::
+**Config keys**::
 
     init_switch:
       target: systemd (can be 'systemd' or 'upstart')
       reboot: true (reboot if a change was made, or false to not reboot)
-
-.. note::
-
-    Best effort is made, but it's possible
-    this system will break, and probably won't interact well with any other
-    mechanism you've used to switch the init system.
 """
 
 from cloudinit.distros import ubuntu
diff --git a/cloudinit/config/cc_update_etc_hosts.py b/cloudinit/config/cc_update_etc_hosts.py
index 15703ef..3fcb265 100644
--- a/cloudinit/config/cc_update_etc_hosts.py
+++ b/cloudinit/config/cc_update_etc_hosts.py
@@ -18,6 +18,49 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Update Etc Hosts
+----------------
+**Summary:** update ``/etc/hosts``
+
+This module will update the contents of ``/etc/hosts`` based on the
+hostname/fqdn specified in config. Management of ``/etc/hosts`` is controlled
+using ``manage_etc_hosts``. If this is set to false, cloud-init will not manage
+``/etc/hosts`` at all. This is the default behavior.
+
+If set to ``true`` or ``template``, cloud-init will generate ``/etc/hosts``
+using the template located in ``/etc/cloud/templates/hosts.tmpl``. In the
+``/etc/cloud/templates/hosts.tmpl`` template, the strings ``$hostname`` and
+``$fqdn`` will be replaced with the hostname and fqdn respectively.
+
+If ``manage_etc_hosts`` is set to ``localhost``, then cloud-init will not
+rewrite ``/etc/hosts`` entirely, but rather will ensure that a entry for the
+fqdn with ip ``127.0.1.1`` is present in ``/etc/hosts`` (i.e.
+``ping <hostname>`` will ping ``127.0.1.1``).
+
+.. note::
+    if ``manage_etc_hosts`` is set ``true`` or ``template``, the contents
+    of ``/etc/hosts`` will be updated every boot. to make any changes to
+    ``/etc/hosts`` persistant they must be made in
+    ``/etc/cloud/templates/hosts.tmpl``
+
+.. note::
+    for instructions on specifying hostname and fqdn, see documentation for
+    ``cc_set_hostname``
+
+**Internal name:** ``cc_update_etc_hosts``
+
+**Module frequency:** per always
+
+**Supported distros:** all
+
+**Config keys**::
+
+    manage_etc_hosts: <true/"template"/false/"localhost">
+    fqdn: <fqdn>
+    hostname: <fqdn/hostname>
+"""
+
 from cloudinit import templater
 from cloudinit import util
 
diff --git a/cloudinit/config/cc_update_hostname.py b/cloudinit/config/cc_update_hostname.py
index 5b78afe..315b7b6 100644
--- a/cloudinit/config/cc_update_hostname.py
+++ b/cloudinit/config/cc_update_hostname.py
@@ -18,6 +18,31 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Update Hostname
+---------------
+**Summary:** update hostname and fqdn
+
+This module will update the system hostname and fqdn. If ``preserve_hostname``
+is set, then the hostname will not be altered.
+
+.. note::
+    for instructions on specifying hostname and fqdn, see documentation for
+    ``cc_set_hostname``
+
+**Internal name:** ``cc_update_hostname``
+
+**Module frequency:** per always
+
+**Supported distros:** all
+
+**Config keys**::
+
+    preserve_hostname: <true/false>
+    fqdn: <fqdn>
+    hostname: <fqdn/hostname>
+"""
+
 import os
 
 from cloudinit.settings import PER_ALWAYS
diff --git a/cloudinit/config/cc_users_groups.py b/cloudinit/config/cc_users_groups.py
index bf5b458..cf9a625 100644
--- a/cloudinit/config/cc_users_groups.py
+++ b/cloudinit/config/cc_users_groups.py
@@ -16,6 +16,86 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Users and Groups
+----------------
+**Summary:** configure users and groups
+
+This module configures users and groups. For more detailed information on user
+options, see the ``Including users and groups`` config example.
+
+Groups to add to the system can be specified as a list under the ``groups``
+key. Each entry in the list should either contain a the group name as a string,
+or a dictionary with the group name as the key and a list of users who should
+be members of the group as the value.
+
+The ``users`` config key takes a list of users to configure. The first entry in
+this list is used as the default user for the system. To preserve the standard
+default user for the distro, the string ``default`` may be used as the first
+entry of the ``users`` list. Each entry in the ``users`` list, other than a
+``default`` entry, should be a dictionary of options for the user. Supported
+config keys for an entry in ``users`` are as follows:
+
+    - ``name``: The user's login name
+    - ``homedir``: Optional. Home dir for user. Default is ``/home/<username>``
+    - ``primary-group``: Optional. Primary group for user. Default to new group
+      named after user.
+    - ``groups``: Optional. Additional groups to add the user to. Default: none
+    - ``selinux-user``: Optional. SELinux user for user's login. Default to
+      default SELinux user.
+    - ``lock_passwd``: Optional. Disable password login. Default: true
+    - ``inactive``: Optional. Mark user inactive. Default: false
+    - ``passwd``: Hash of user password
+    - ``no-create-home``: Optional. Do not create home directory. Default:
+      false
+    - ``no-user-group``: Optional. Do not create group named after user.
+      Default: false
+    - ``no-log-init``: Optional. Do not initialize lastlog and faillog for
+      user. Default: false
+    - ``ssh-import-id``: Optional. SSH id to import for user. Default: none
+    - ``ssh-autorized-keys``: Optional. List of ssh keys to add to user's
+      authkeys file. Default: none
+    - ``sudo``: Optional. Sudo rule to use, or list of sudo rules to use.
+      Default: none.
+    - ``system``: Optional. Create user as system user with no home directory.
+      Default: false
+
+.. note::
+    Specifying a hash of a user's password with ``passwd`` is a security risk
+    if the cloud-config can be intercepted. SSH authentication is preferred.
+
+.. note::
+    If specifying a sudo rule for a user, ensure that the syntax for the rule
+    is valid, as it is not checked by cloud-init.
+
+**Internal name:** ``cc_users_groups``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+
+**Config keys**::
+
+    groups:
+        - ubuntu: [foo, bar]
+        - cloud-users
+
+    users:
+        - default
+        - name: <username>
+          gecos: <real name>
+          primary-group: <primary group>
+          groups: <additional groups>
+          selinux-user: <selinux username>
+          expiredate: <date>
+          ssh-import-id: <none/id>
+          lock_passwd: <true/false>
+          passwd: <password>
+          sudo: <sudo config>
+          inactive: <true/false>
+          system: <true/false>
+"""
+
 # Ensure this is aliased to a name not 'distros'
 # since the module attribute 'distros'
 # is a list of distros that are supported, not a sub-module
diff --git a/cloudinit/config/cc_write_files.py b/cloudinit/config/cc_write_files.py
index b1096b9..b5956bd 100644
--- a/cloudinit/config/cc_write_files.py
+++ b/cloudinit/config/cc_write_files.py
@@ -16,6 +16,48 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Write Files
+-----------
+**Summary:** write arbitrary files
+
+Write out arbitrary content to files, optionally setting permissions. Content
+can be specified in plain text or binary. Data encoded with either base64 or
+binary gzip data can be specified and will be decoded before being written.
+
+.. note::
+    if multiline data is provided, care should be taken to ensure that it
+    follows yaml formatting standargs. to specify binary data, use the yaml
+    option ``!!binary``
+
+**Internal name:** ``cc_write_files``
+
+**Module frequency:** per instance
+
+**Supported distros:** all
+
+**Config keys**::
+
+    write_files:
+        - encoding: b64
+          content: CiMgVGhpcyBmaWxlIGNvbnRyb2xzIHRoZSBzdGF0ZSBvZiBTRUxpbnV4...
+          owner: root:root
+          path: /etc/sysconfig/selinux
+          permissions: '0644'
+        - content: |
+            # My new /etc/sysconfig/samba file
+
+            SMDBOPTIONS="-D"
+          path: /etc/sysconfig/samba
+        - content: !!binary |
+            f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAwARAAAAAAABAAAAAAAAAAJAVAAAAAA
+            AEAAHgAdAAYAAAAFAAAAQAAAAAAAAABAAEAAAAAAAEAAQAAAAAAAwAEAAAAAAA
+            AAAAAAAAAwAAAAQAAAAAAgAAAAAAAAACQAAAAAAAAAJAAAAAAAAcAAAAAAAAAB
+            ...
+          path: /bin/arch
+          permissions: '0555'
+"""
+
 import base64
 import os
 import six
diff --git a/cloudinit/config/cc_yum_add_repo.py b/cloudinit/config/cc_yum_add_repo.py
index 22549e6..eb94c1f 100644
--- a/cloudinit/config/cc_yum_add_repo.py
+++ b/cloudinit/config/cc_yum_add_repo.py
@@ -16,6 +16,32 @@
 #    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+"""
+Yum Add Repo
+------------
+**Summary:** add yum repository configuration to the system
+
+Add yum repository configuration to ``/etc/yum.repos.d``. Configuration files
+are named based on the dictionary key under the ``yum_repos`` they are
+specified with. If a config file already exists with the same name as a config
+entry, the config entry will be skipped.
+
+**Internal name:** ``cc_yum_add_repo``
+
+**Module frequency:** per always
+
+**Supported distros:** fedora, rhel
+
+**Config keys**::
+
+    yum_repos:
+        <repo-name>:
+            baseurl: <repo url>
+            name: <repo name>
+            enabled: <true/false>
+            # any repository configuration options (see man yum.conf)
+"""
+
 import os
 
 import configobj
diff --git a/doc/examples/cloud-config-seed-random.txt b/doc/examples/cloud-config-seed-random.txt
index 08f69a9..142b10c 100644
--- a/doc/examples/cloud-config-seed-random.txt
+++ b/doc/examples/cloud-config-seed-random.txt
@@ -24,7 +24,7 @@
 # Note: command could be ['pollinate',
 #                         '--server=http://local.pollinate.server']
 # which would have pollinate populate /dev/urandom from provided server
-seed_random:
+random_seed:
   file: '/dev/urandom'
   data: 'my random string'
   encoding: 'raw'
diff --git a/doc/rtd/topics/examples.rst b/doc/rtd/topics/examples.rst
index 36508bd..2e6cfa1 100644
--- a/doc/rtd/topics/examples.rst
+++ b/doc/rtd/topics/examples.rst
@@ -1,11 +1,11 @@
 .. _yaml_examples:
 
-=========
+=====================
 Cloud config examples
-=========
+=====================
 
 Including users and groups
----------------------------
+--------------------------
 
 .. literalinclude:: ../../examples/cloud-config-user-groups.txt
    :language: yaml
@@ -21,21 +21,21 @@ Writing out arbitrary files
 
 
 Adding a yum repository
----------------------------
+-----------------------
 
 .. literalinclude:: ../../examples/cloud-config-yum-repo.txt
    :language: yaml
    :linenos:
 
 Configure an instances trusted CA certificates
-------------------------------------------------------
+----------------------------------------------
 
 .. literalinclude:: ../../examples/cloud-config-ca-certs.txt
    :language: yaml
    :linenos:
 
 Configure an instances resolv.conf
-------------------------------------------------------
+----------------------------------
 
 *Note:* when using a config drive and a RHEL like system resolv.conf
 will also be managed 'automatically' due to the available information
@@ -47,28 +47,28 @@ that wish to have different settings use this module.
    :linenos:
 
 Install and run `chef`_ recipes
-------------------------------------------------------
+-------------------------------
 
 .. literalinclude:: ../../examples/cloud-config-chef.txt
    :language: yaml
    :linenos:
 
 Setup and run `puppet`_
-------------------------------------------------------
+-----------------------
 
 .. literalinclude:: ../../examples/cloud-config-puppet.txt
    :language: yaml
    :linenos:
 
 Add apt repositories
----------------------------
+--------------------
 
 .. literalinclude:: ../../examples/cloud-config-add-apt-repos.txt
    :language: yaml
    :linenos:
 
 Run commands on first boot
----------------------------
+--------------------------
 
 .. literalinclude:: ../../examples/cloud-config-boot-cmds.txt
    :language: yaml
@@ -80,21 +80,21 @@ Run commands on first boot
 
 
 Alter the completion message
----------------------------
+----------------------------
 
 .. literalinclude:: ../../examples/cloud-config-final-message.txt
    :language: yaml
    :linenos:
 
 Install arbitrary packages
----------------------------
+--------------------------
 
 .. literalinclude:: ../../examples/cloud-config-install-packages.txt
    :language: yaml
    :linenos:
 
 Run apt or yum upgrade
----------------------------
+----------------------
 
 .. literalinclude:: ../../examples/cloud-config-update-packages.txt
    :language: yaml
@@ -108,26 +108,46 @@ Adjust mount points mounted
    :linenos:
 
 Call a url when finished
----------------------------
+------------------------
 
 .. literalinclude:: ../../examples/cloud-config-phone-home.txt
    :language: yaml
    :linenos:
 
 Reboot/poweroff when finished
----------------------------
+-----------------------------
 
 .. literalinclude:: ../../examples/cloud-config-power-state.txt
    :language: yaml
    :linenos:
 
 Configure instances ssh-keys
----------------------------
+----------------------------
 
 .. literalinclude:: ../../examples/cloud-config-ssh-keys.txt
    :language: yaml
    :linenos:
    
+Additional apt configuration
+----------------------------
+
+.. literalinclude:: ../../examples/cloud-config-apt.txt
+    :language: yaml
+    :linenos:
+
+Disk setup
+----------
+
+.. literalinclude:: ../../examples/cloud-config-disk-setup.txt
+    :language: yaml
+    :linenos:
+
+Register RedHat Subscription
+----------------------------
+
+.. literalinclude:: ../../examples/cloud-config-rh_subscription.txt
+    :language: yaml
+    :linenos:
 
 .. _chef: http://www.opscode.com/chef/
 .. _puppet: http://puppetlabs.com/
diff --git a/doc/rtd/topics/modules.rst b/doc/rtd/topics/modules.rst
index 4202338..57892f2 100644
--- a/doc/rtd/topics/modules.rst
+++ b/doc/rtd/topics/modules.rst
@@ -1,342 +1,57 @@
 =======
 Modules
 =======
-
-Apt Configure
--------------
-
-**Internal name:** ``cc_apt_configure``
-
 .. automodule:: cloudinit.config.cc_apt_configure
-
-Apt Pipelining
---------------
-
-**Internal name:** ``cc_apt_pipelining``
-
 .. automodule:: cloudinit.config.cc_apt_pipelining
-
-Bootcmd
--------
-
-**Internal name:** ``cc_bootcmd``
-
 .. automodule:: cloudinit.config.cc_bootcmd
-
-Byobu
------
-
-**Internal name:** ``cc_byobu``
-
 .. automodule:: cloudinit.config.cc_byobu
-
-Ca Certs
---------
-
-**Internal name:** ``cc_ca_certs``
-
 .. automodule:: cloudinit.config.cc_ca_certs
-
-Chef
-----
-
-**Internal name:** ``cc_chef``
-
 .. automodule:: cloudinit.config.cc_chef
-    :members:
-
-Debug
------
-
-**Internal name:** ``cc_debug``
-
 .. automodule:: cloudinit.config.cc_debug
-    :members:
-
-Disable Ec2 Metadata
---------------------
-
-**Internal name:** ``cc_disable_ec2_metadata``
-
 .. automodule:: cloudinit.config.cc_disable_ec2_metadata
-
-Disk Setup
-----------
-
-**Internal name:** ``cc_disk_setup``
-
 .. automodule:: cloudinit.config.cc_disk_setup
-
-Emit Upstart
-------------
-
-**Internal name:** ``cc_emit_upstart``
-
 .. automodule:: cloudinit.config.cc_emit_upstart
-
-Final Message
--------------
-
-**Internal name:** ``cc_final_message``
-
+.. automodule:: cloudinit.config.cc_fan
 .. automodule:: cloudinit.config.cc_final_message
-
-Foo
----
-
-**Internal name:** ``cc_foo``
-
 .. automodule:: cloudinit.config.cc_foo
-
-Growpart
---------
-
-**Internal name:** ``cc_growpart``
-
 .. automodule:: cloudinit.config.cc_growpart
-
-Grub Dpkg
----------
-
-**Internal name:** ``cc_grub_dpkg``
-
 .. automodule:: cloudinit.config.cc_grub_dpkg
-
-Keys To Console
----------------
-
-**Internal name:** ``cc_keys_to_console``
-
 .. automodule:: cloudinit.config.cc_keys_to_console
-
-Landscape
----------
-
-**Internal name:** ``cc_landscape``
-
 .. automodule:: cloudinit.config.cc_landscape
-
-Locale
-------
-
-**Internal name:** ``cc_locale``
-
 .. automodule:: cloudinit.config.cc_locale
-
-Mcollective
------------
-
-**Internal name:** ``cc_mcollective``
-
+.. automodule:: cloudinit.config.cc_lxd
 .. automodule:: cloudinit.config.cc_mcollective
-
-Migrator
---------
-
-**Internal name:** ``cc_migrator``
-
 .. automodule:: cloudinit.config.cc_migrator
-
-Mounts
-------
-
-**Internal name:** ``cc_mounts``
-
 .. automodule:: cloudinit.config.cc_mounts
-
-Package Update Upgrade Install
-------------------------------
-
-**Internal name:** ``cc_package_update_upgrade_install``
-
+.. automodule:: cloudinit.config.cc_ntp
 .. automodule:: cloudinit.config.cc_package_update_upgrade_install
-
-Phone Home
-----------
-
-**Internal name:** ``cc_phone_home``
-
 .. automodule:: cloudinit.config.cc_phone_home
-
-Power State Change
-------------------
-
-**Internal name:** ``cc_power_state_change``
-
 .. automodule:: cloudinit.config.cc_power_state_change
-
-Puppet
-------
-
-**Internal name:** ``cc_puppet``
-
 .. automodule:: cloudinit.config.cc_puppet
-
-Resizefs
---------
-
-**Internal name:** ``cc_resizefs``
-
 .. automodule:: cloudinit.config.cc_resizefs
-
-Resolv Conf
------------
-
-**Internal name:** ``cc_resolv_conf``
-
 .. automodule:: cloudinit.config.cc_resolv_conf
-
-Rightscale Userdata
--------------------
-
-**Internal name:** ``cc_rightscale_userdata``
-
+.. automodule:: cloudinit.config.cc_rh_subscription
 .. automodule:: cloudinit.config.cc_rightscale_userdata
-
-Rsyslog
--------
-
-**Internal name:** ``cc_rsyslog``
-
 .. automodule:: cloudinit.config.cc_rsyslog
-
-Runcmd
-------
-
-**Internal name:** ``cc_runcmd``
-
 .. automodule:: cloudinit.config.cc_runcmd
-
-Salt Minion
------------
-
-**Internal name:** ``cc_salt_minion``
-
 .. automodule:: cloudinit.config.cc_salt_minion
-
-Scripts Per Boot
-----------------
-
-**Internal name:** ``cc_scripts_per_boot``
-
 .. automodule:: cloudinit.config.cc_scripts_per_boot
-
-Scripts Per Instance
---------------------
-
-**Internal name:** ``cc_scripts_per_instance``
-
 .. automodule:: cloudinit.config.cc_scripts_per_instance
-
-Scripts Per Once
-----------------
-
-**Internal name:** ``cc_scripts_per_once``
-
 .. automodule:: cloudinit.config.cc_scripts_per_once
-
-Scripts User
-------------
-
-**Internal name:** ``cc_scripts_user``
-
 .. automodule:: cloudinit.config.cc_scripts_user
-
-Scripts Vendor
---------------
-
-**Internal name:** ``cc_scripts_vendor``
-
 .. automodule:: cloudinit.config.cc_scripts_vendor
-
-Seed Random
------------
-
-**Internal name:** ``cc_seed_random``
-
 .. automodule:: cloudinit.config.cc_seed_random
-
-Set Hostname
-------------
-
-**Internal name:** ``cc_set_hostname``
-
 .. automodule:: cloudinit.config.cc_set_hostname
-
-Set Passwords
--------------
-
-**Internal name:** ``cc_set_passwords``
-
 .. automodule:: cloudinit.config.cc_set_passwords
-
-Ssh
----
-
-**Internal name:** ``cc_ssh``
-
+.. automodule:: cloudinit.config.cc_snappy
+.. automodule:: cloudinit.config.cc_spacewalk
 .. automodule:: cloudinit.config.cc_ssh
-
-Ssh Authkey Fingerprints
-------------------------
-
-**Internal name:** ``cc_ssh_authkey_fingerprints``
-
 .. automodule:: cloudinit.config.cc_ssh_authkey_fingerprints
-
-Ssh Import Id
--------------
-
-**Internal name:** ``cc_ssh_import_id``
-
 .. automodule:: cloudinit.config.cc_ssh_import_id
-
-Timezone
---------
-
-**Internal name:** ``cc_timezone``
-
 .. automodule:: cloudinit.config.cc_timezone
-
-Ubuntu Init Switch
-------------------
-
-**Internal name:** ``cc_ubuntu_init_switch``
-
 .. automodule:: cloudinit.config.cc_ubuntu_init_switch
-    :members:
-
-Update Etc Hosts
-----------------
-
-**Internal name:** ``cc_update_etc_hosts``
-
 .. automodule:: cloudinit.config.cc_update_etc_hosts
-
-Update Hostname
----------------
-
-**Internal name:** ``cc_update_hostname``
-
 .. automodule:: cloudinit.config.cc_update_hostname
-
-Users Groups
-------------
-
-**Internal name:** ``cc_users_groups``
-
 .. automodule:: cloudinit.config.cc_users_groups
-
-Write Files
------------
-
-**Internal name:** ``cc_write_files``
-
 .. automodule:: cloudinit.config.cc_write_files
-
-Yum Add Repo
-------------
-
-**Internal name:** ``cc_yum_add_repo``
-
 .. automodule:: cloudinit.config.cc_yum_add_repo

Follow ups