It took me several re-stacks, but I finally got a working devstack with Ironic and Heat services running. I mostly followed directions here, but I ended up making a few changes in the local.conf file.

Start with cloning the repo and creating the stack user:

$ git clone https://github.com/openstack-dev/devstack.git devstack
$ sudo ./devstack/tools/create-stack-user.sh 

Now, switch to the ‘stack’ user and clone again:

$ sudo su stack
$ cd ~
$ git clone https://github.com/openstack-dev/devstack.git devstack
$ cd devstack

Create local.conf file in devstack directory:

[[local|localrc]]

# Credentials
DATABASE_PASSWORD=secrete
ADMIN_PASSWORD=secrete
SERVICE_PASSWORD=secrete
SERVICE_TOKEN=secrete
RABBIT_PASSWORD=secrete

# Enable Ironic API and Ironic Conductor
enable_service ironic
enable_service ir-api
enable_service ir-cond

# Enable Neutron which is required by Ironic and disable nova-network.
ENABLED_SERVICES=rabbit,mysql,key
ENABLED_SERVICES+=,n-api,n-crt,n-obj,n-cpu,n-cond,n-sch,n-novnc,n-cauth
ENABLED_SERVICES+=,neutron,q-svc,q-agt,q-dhcp,q-l3,q-meta,q-lbaas
ENABLED_SERVICES+=,g-api,g-reg
ENABLED_SERVICES+=,cinder,c-api,c-vol,c-sch,c-bak
ENABLED_SERVICES+=,ironic,ir-api,ir-cond
ENABLED_SERVICES+=,heat,h-api,h-api-cfn,h-api-cw,h-eng
ENABLED_SERVICES+=,horizon

# Create 3 virtual machines to pose as Ironic's baremetal nodes.
IRONIC_VM_COUNT=3
IRONIC_VM_SSH_PORT=22
IRONIC_BAREMETAL_BASIC_OPS=True

# The parameters below represent the minimum possible values to create
# functional nodes.
IRONIC_VM_SPECS_RAM=1024
IRONIC_VM_SPECS_DISK=10

# Size of the ephemeral partition in GB. Use 0 for no ephemeral partition.
IRONIC_VM_EPHEMERAL_DISK=0

VIRT_DRIVER=ironic

# By default, DevStack creates a 10.0.0.0/24 network for instances.
# If this overlaps with the hosts network, you may adjust with the
# following.
NETWORK_GATEWAY=10.1.0.1
FIXED_RANGE=10.1.0.0/24
FIXED_NETWORK_SIZE=256

# Log all output to files
LOGFILE=$HOME/devstack.log
SCREEN_LOGDIR=$HOME/logs
IRONIC_VM_LOG_DIR=$HOME/ironic-bm-logs

Now your devstack is ready for setup, simply run

./stack.sh

After devstack finishes running, you should see something similar to:

Horizon is now available at http://10.0.0.1/
Keystone is serving at http://10.0.0.1:5000/v2.0/
Examples on using novaclient command line is in exercise.sh
The default users are: admin and demo
The password: secrete
This is your host ip: 10.0.0.1

Source the credentials for the demo user:

$ source ~/devstack/openrc

Create ssh key:

$ nova keypair-add test > test.pem
chmod 600 test.pem

Check available flavors, note that baremetal is one of the flavors:

$ nova flavor-list
+-----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| ID  | Name      | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
+-----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| 1   | m1.tiny   | 512       | 1    | 0         |      | 1     | 1.0         | True      |
| 2   | m1.small  | 2048      | 20   | 0         |      | 1     | 1.0         | True      |
| 3   | m1.medium | 4096      | 40   | 0         |      | 2     | 1.0         | True      |
| 4   | m1.large  | 8192      | 80   | 0         |      | 4     | 1.0         | True      |
| 5   | m1.xlarge | 16384     | 160  | 0         |      | 8     | 1.0         | True      |
| 551 | baremetal | 1024      | 10   | 0         |      | 1     | 1.0         | True      |
+-----+-----------+-----------+------+-----------+------+-------+-------------+-----------+

Create first image using ironic:

$ image=$(nova image-list | egrep "$DEFAULT_IMAGE_NAME"'[^-]' | awk '{ print $2 }')

$ nova boot --flavor baremetal --image $image --key_name test my-first-metal
+--------------------------------------+----------------------------------------------------------------+
| Property                             | Value                                                          |
+--------------------------------------+----------------------------------------------------------------+
| OS-DCF:diskConfig                    | MANUAL                                                         |
| OS-EXT-AZ:availability_zone          | nova                                                           |
| OS-EXT-STS:power_state               | 0                                                              |
| OS-EXT-STS:task_state                | scheduling                                                     |
| OS-EXT-STS:vm_state                  | building                                                       |
| OS-SRV-USG:launched_at               | -                                                              |
| OS-SRV-USG:terminated_at             | -                                                              |
| accessIPv4                           |                                                                |
| accessIPv6                           |                                                                |
| adminPass                            | 99wcXpnQFkck                                                   |
| config_drive                         |                                                                |
| created                              | 2014-11-12T04:56:42Z                                           |
| flavor                               | baremetal (551)                                                |
| hostId                               |                                                                |
| id                                   | 53094f5d-5f48-4059-9547-9e297a5f324b                           |
| image                                | cirros-0.3.2-x86_64-uec (183b8227-10a0-4cf1-afd9-c4ff1272dc41) |
| key_name                             | test                                                           |
| metadata                             | {}                                                             |
| name                                 | my-first-metal                                                 |
| os-extended-volumes:volumes_attached | []                                                             |
| progress                             | 0                                                              |
| security_groups                      | default                                                        |
| status                               | BUILD                                                          |
| tenant_id                            | c6cf561507d2425480279f2209209b77                               |
| updated                              | 2014-11-12T04:56:43Z                                           |
| user_id                              | ad3318ff89014b7a8bbf6d589806e501                               |
+--------------------------------------+----------------------------------------------------------------+
stack@egle-node:~$ nova list
+--------------------------------------+----------------+--------+------------+-------------+------------------+
| ID                                   | Name           | Status | Task State | Power State | Networks         |
+--------------------------------------+----------------+--------+------------+-------------+------------------+
| 53094f5d-5f48-4059-9547-9e297a5f324b | my-first-metal | ACTIVE | -          | Running     | private=10.1.0.4 |
+--------------------------------------+----------------+--------+------------+-------------+------------------+

To see all the “bare metal” nodes and what is going on with them, use admin user:

. ~/devstack/openrc admin admin 

There were 3 “bare metal” nodes created for us using the local.conf file configuration. Since this is devstack, the nodes magically appeared for us thanks to virtualization magic.

Before any nodes are built, all the “bare metal” instances will be powered off and not provisioned. Remember to use admin user for all the ironic commands.

$ ironic node-list
+--------------------------------------+---------------+-------------+--------------------+-------------+
| UUID                                 | Instance UUID | Power State | Provisioning State | Maintenance |
+--------------------------------------+---------------+-------------+--------------------+-------------+
| 321122bf-a187-456b-9232-d34ec2279941 | None          | power off   | None               | False       |
| a636cb12-3491-4abb-91a1-05ebd7137e8a | None          | power off   | None               | False       |
| 1af459b4-ba3a-4356-8d7a-c2e7ce70a900 | None          | power off   | None               | False       |
+--------------------------------------+---------------+-------------+--------------------+-------------+

Once the instance above is booted, this will change, pay attention to the “Provisioning State” and “Power State”:

$ ironic node-list
+--------------------------------------+--------------------------------------+-------------+--------------------+-------------+
| UUID                                 | Instance UUID                        | Power State | Provisioning State | Maintenance |
+--------------------------------------+--------------------------------------+-------------+--------------------+-------------+
| 321122bf-a187-456b-9232-d34ec2279941 | 53094f5d-5f48-4059-9547-9e297a5f324b | power off   | deploying          | False       |
| a636cb12-3491-4abb-91a1-05ebd7137e8a | None                                 | power off   | None               | False       |
| 1af459b4-ba3a-4356-8d7a-c2e7ce70a900 | None                                 | power off   | None               | False       |
+--------------------------------------+--------------------------------------+-------------+--------------------+-------------+
stack@egle-node:~/devstack$ ironic node-list
+--------------------------------------+--------------------------------------+-------------+--------------------+-------------+
| UUID                                 | Instance UUID                        | Power State | Provisioning State | Maintenance |
+--------------------------------------+--------------------------------------+-------------+--------------------+-------------+
| 321122bf-a187-456b-9232-d34ec2279941 | 53094f5d-5f48-4059-9547-9e297a5f324b | power on    | wait call-back     | False       |
| a636cb12-3491-4abb-91a1-05ebd7137e8a | None                                 | power off   | None               | False       |
| 1af459b4-ba3a-4356-8d7a-c2e7ce70a900 | None                                 | power off   | None               | False       |
+--------------------------------------+--------------------------------------+-------------+--------------------+-------------+
$ ironic node-list
+--------------------------------------+--------------------------------------+-------------+--------------------+-------------+
| UUID                                 | Instance UUID                        | Power State | Provisioning State | Maintenance |
+--------------------------------------+--------------------------------------+-------------+--------------------+-------------+
| 321122bf-a187-456b-9232-d34ec2279941 | 53094f5d-5f48-4059-9547-9e297a5f324b | power on    | active             | False       |
| a636cb12-3491-4abb-91a1-05ebd7137e8a | None                                 | power off   | None               | False       |
| 1af459b4-ba3a-4356-8d7a-c2e7ce70a900 | None                                 | power off   | None               | False       |
+--------------------------------------+--------------------------------------+-------------+--------------------+-------------+

Remember to check official documentation for devstack + ironic: http://docs.openstack.org/developer/ironic/dev/dev-quickstart.html#deploying-ironic-with-devstack

Happy stacking!
-eglute