heat_template_version: 2013-05-23

description: Template for setting up a multi-node Devstack environment

parameters:
  key_name:
    type: string
    description: Name of an existing key pair to use for the server
    constraints:
      - custom_constraint: nova.keypair
  controller_flavor:
    type: string
    description: Flavor for devstack controller to be created
    default: m1.medium
    constraints:
      - custom_constraint: nova.flavor
  compute_flavor:
    type: string
    description: Flavor for devstack compute to be created
    default: m1.medium
    constraints:
      - custom_constraint: nova.flavor
  controller_image:
    type: string
    description: Image ID or image name to use for devstack controller
    constraints:
      - custom_constraint: glance.image
  compute_image:
    type: string
    description: Image ID or image name to use for devstack computer
    constraints:
      - custom_constraint: glance.image
  compute_nodes:
    default: '2'
    description: Number of compute nodes
    type: string
    constraints:
      - allowed_pattern: "[0-9]+"
  public_net_id:
    type: string
    description: ID of public network for which floating IP addresses will be allocated
  private_net_id:
    type: string
    description: ID of private network into which servers get deployed
  private_subnet_id:
    type: string
    description: ID of private sub network into which servers get deployed
  admin_pass:
    type: string
    description: Admin password
    hidden: true
    constraints:
      - length: { min: 6, max: 8 }
        description: Password length must be between 6 and 8 characters
      - allowed_pattern: "[a-zA-Z0-9]+"
        description: Password must consist of characters and numbers only
  key_name:
    type: string
    description: Name of an existing key pair to use for the server
    constraints:
      - custom_constraint: nova.keypair
  DefaultSignalTransport:
    constraints:
    - allowed_values:
      - CFN_SIGNAL
      - HEAT_SIGNAL
      - NO_SIGNAL
    default: CFN_SIGNAL
    description: Transport to use for software-config signals.
    type: string

resources:

  stack_sec_grp:
    type: AWS::EC2::SecurityGroup
    properties:
      GroupDescription: stack firewall rules
      SecurityGroupIngress:
      - {IpProtocol: tcp, FromPort: '22', ToPort: '22', CidrIp: "0.0.0.0/0"}
      - {IpProtocol: icmp, FromPort: "-1", ToPort: "-1", CidrIp: "0.0.0.0/0"}
  controller_port:
    type: OS::Neutron::Port
    properties:
      security_groups: [{ get_resource: stack_sec_grp }]
      network_id: { get_param: private_net_id }
      fixed_ips:
        - subnet_id: { get_param: private_subnet_id }
  compute_port:
    type: OS::Neutron::Port
    properties:
      security_groups: [{ get_resource: stack_sec_grp }]
      network_id: { get_param: private_net_id }
      fixed_ips:
        - subnet_id: { get_param: private_subnet_id }
  controller_floating_ip:
    type: OS::Neutron::FloatingIP
    properties:
      floating_network_id: { get_param: public_net_id }
      port_id: { get_resource: controller_port }
  compute_floating_ip:
    type: OS::Neutron::FloatingIP
    properties:
      floating_network_id: { get_param: public_net_id }
      port_id: { get_resource: compute_port }

  compute_user_data:
    type: OS::Heat::SoftwareConfig
    properties:
      group: Ungrouped
      config:
        str_replace:
          template: |
            #!/bin/bash -x
            #
            compute.sh --nic eth0 --controller $Controller_ip --compute $(curl -s http://169.254.169.254/latest/meta-data/local-ipv4/)
          params:
            $Password: {get_param: admin_pass}
            $Controller_ip: {get_attr: [controller_instance, networks, private, 0]}

  controller_user_data:
    type: OS::Heat::SoftwareConfig
    properties:
      group: Ungrouped
      config:
        str_replace:
          template: |
            #!/bin/bash -x
            #
            controller.sh --nic eth0 --controller $(curl -s http://169.254.169.254/latest/meta-data/local-ipv4/)
          params:
            $Password: {get_param: admin_pass}
  controller_instance:
    type: OS::Nova::Server
    properties:
      key_name: { get_param: key_name }
      image: { get_param: controller_image }
      flavor: { get_param: controller_flavor }
      networks: 
        - port: { get_resource: controller_port }
      user_data: {get_resource: controller_user_data}
      user_data_format: SOFTWARE_CONFIG
  compute_instance:
    type: OS::Nova::Server
    properties:
      key_name: { get_param: key_name }
      image: { get_param: compute_image }
      flavor: { get_param: compute_flavor }
      networks: 
        - port: { get_resource: compute_port }
      user_data: {get_resource: compute_user_data}
      user_data_format: SOFTWARE_CONFIG

  controllerDeployment:
    properties:
      server:
        get_resource: controller_instance
      signal_transport:
        get_param: DefaultSignalTransport
    type: OS::Heat::StructuredDeployment

  computeDeployment:
    depends_on:
      - controllerDeployment
    properties:
      server:
        get_resource: compute_instance
      signal_transport:
        get_param: DefaultSignalTransport
    type: OS::Heat::StructuredDeployment
