diff --git a/examples/README.rst b/examples/README.rst
new file mode 100644
index 0000000..ade636b
--- /dev/null
+++ b/examples/README.rst
@@ -0,0 +1,77 @@
+InfraCloud Development
+======================
+
+This example provides a set of DIB elements, libvirt templates, and
+instructions for creating a local development environment that simulates the
+InfraCloud production environment. This means the networking and everything
+ansible sets up in preparation for running puppet apply, including a dummy
+hiera database. It also includes a script to do a short smoke test.
+
+Setup
+-----
+
+These instructions assume libvirt and disk-image-builder are already installed,
+and that there is a public SSH key in ~/.ssh/id_rsa.pub for the devuser element
+to copy.
+
+Create two disk images::
+
+ export DIB_DEV_USER_PWDLESS_SUDO=yes
+ export ELEMENTS_PATH=$HOME/infracloud-development/elements
+ DIB_ROLE=controller disk-image-create -u ubuntu devuser system-config puppet \
+ motd smoke-test infracloud-static-net vm cloud-init-nocloud \
+ -o "/tmp/infracloud-controller.qcow2" --image-size 20 \
+ -p git,vim,vlan,bridge-utils
+ DIB_ROLE=compute disk-image-create -u ubuntu devuser system-config puppet \
+ motd infracloud-static-net vm cloud-init-nocloud \
+ -o "/tmp/infracloud-compute.qcow2" --image-size 20 \
+ -p git,vim,vlan,bridge-utils
+
+These images have static IP addresses and hostnames baked into them. This
+simulates the production environment for most purposes but avoids too much
+complexity setting up local networks.
+
+Define the network::
+
+ virsh net-define definitions/network.xml
+
+Start the network::
+
+ virsh net-start public
+
+Define the VMs::
+
+ virsh define definitions/controller.xml
+ virsh define definitions/compute.xml
+
+Start the VMs::
+
+ virsh start controller
+ virsh start compute
+
+Puppet
+------
+
+SSH into the controller::
+
+ source functions/sshvm
+ sshvm controller
+
+Apply any puppet changes you're testing to /etc/puppet/modules/infracloud or
+/opt/system-config/production.
+
+Run puppet apply::
+
+ puppet apply /opt/system-config/production/manifests/site.pp
+
+Do the same on the compute node once the controller is finished::
+
+ sshvm compute
+ puppet apply /opt/system-config/production/manifests/site.pp
+
+Test
+----
+
+Run the smoke test script::
+
+ bash -ex /opt/smoke-test
diff --git a/examples/definitions/compute.xml b/examples/definitions/compute.xml
new file mode 100644
index 0000000..b3e0d59
--- /dev/null
+++ b/examples/definitions/compute.xml
@@ -0,0 +1,52 @@
+
+ compute
+ 4096
+ 1
+
+ hvm
+
+
+
+
+
+
+
+
+
+ destroy
+ restart
+ restart
+
+ /usr/bin/kvm-spice
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/definitions/controller.xml b/examples/definitions/controller.xml
new file mode 100644
index 0000000..9218962
--- /dev/null
+++ b/examples/definitions/controller.xml
@@ -0,0 +1,52 @@
+
+ controller
+ 4096
+ 1
+
+ hvm
+
+
+
+
+
+
+
+
+
+ destroy
+ restart
+ restart
+
+ /usr/bin/kvm-spice
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/definitions/network.xml b/examples/definitions/network.xml
new file mode 100644
index 0000000..db59f8f
--- /dev/null
+++ b/examples/definitions/network.xml
@@ -0,0 +1,13 @@
+
+ public
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/elements/infracloud-static-net/element-deps b/examples/elements/infracloud-static-net/element-deps
new file mode 100644
index 0000000..0a65984
--- /dev/null
+++ b/examples/elements/infracloud-static-net/element-deps
@@ -0,0 +1 @@
+install-static
diff --git a/examples/elements/infracloud-static-net/post-install.d/05-set-hostname b/examples/elements/infracloud-static-net/post-install.d/05-set-hostname
new file mode 100755
index 0000000..77d64b1
--- /dev/null
+++ b/examples/elements/infracloud-static-net/post-install.d/05-set-hostname
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+set -ux
+
+if [ "$DIB_ROLE" == "controller" ] ; then
+ HOSTNAME="controller00"
+elif [ "$DIB_ROLE" == "compute" ] ; then
+ HOSTNAME="compute000"
+else
+ echo "DIB_ROLE must be either 'controller' or 'compute'."
+ exit 1
+fi
+
+echo $HOSTNAME > /etc/hostname
diff --git a/examples/elements/infracloud-static-net/post-install.d/10-set-ips b/examples/elements/infracloud-static-net/post-install.d/10-set-ips
new file mode 100755
index 0000000..530e692
--- /dev/null
+++ b/examples/elements/infracloud-static-net/post-install.d/10-set-ips
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+set -u
+
+if [ "$DIB_ROLE" == "controller" ] ; then
+ ip="192.168.25.4"
+elif [ "$DIB_ROLE" == "compute" ] ; then
+ ip="192.168.25.5"
+else
+ echo "DIB_ROLE must be either 'controller' or 'compute'."
+ exit 1
+fi
+
+cat > /etc/network/interfaces <&1) # Check for connection refused and try again
+ if [[ ! $error =~ .*Connection\ refused.* ]] ; then
+ echo "SSHing to $vm_ip"
+ ssh_cmd $vm_ip "$*"
+ break
+ else
+ echo "SSH is not ready yet. Trying again in 5 seconds."
+ sleep 5
+ fi
+ else
+ if [ $tries -eq 0 ] ; then
+ echo "Could not reach VM."
+ else
+ echo "VM is not ready yet. Trying $tries more time(s) in 15 seconds."
+ sleep 15
+ fi
+ vm_ip=$(arp -n | grep $vm_mac | cut -d ' ' -f 1)
+ tries=$(echo "${tries}-1" | bc)
+ fi
+ done
+}