Following is one possible approach.
1) Define first template for your compute nodes and network configuration. But define outputs in your first template to expose your compute node IDs. For example, if you create a OS::Nova::Server with name mynode1, you can expose its ID as the output for that template as follows:
outputs:
mynode1_id:
description: ID of mynode1
value: {getattr: [mynode1, id]}
Once you instantiate a heat stack, say mystack1, with this first template, then you can access the ID of mynode1 as follows:
heat output-show mystack1 mynode1_id
2) Create your second template for storage with IDs of your compute nodes from step1 as input parameters. For example:
parameters:
mynode1_id:
type: string
description: ID for mynode1
Then you can use that in your "resources:" section as follows:
resources:
...
...
my_volume_attach:
type: OS::Cinder::VolumeAttachment
properties:
instance_uuid: {get_param: mynode1_id}
...
3) Invoke your second heat stack creation as follows:
heat stack-create -f second-template.yaml -P mynode1_id=`heat output-show mystack1 mynode1_id` mystack2