Create Multiple Instances with a single Openstack CLI Command

Multiple instances in OpenStack CLI

 

I have been developing Infrastructure as code. Openstack is getting more powerful and popular everyday. You quickly get to a point when you need multiple instances. I am presently installing Openshift, which rfequires several instances. Here I will show you how to make multiple instances of the same size and flavor using Heat Stacks.

Basically all you need to do is to call your favorite heat stack from another heat stack that uses 

OS::Heat::ResourceGroup .

Single Openstack Instance

First, here is a comprehensive stack that creates the single instance.

create-instance.yaml

heat_template_version: ocata

description: >
  HOT template to create one small VM to test the compute deployment

parameters:
  image:
    type: string
    default: 'rhel-server-7.5-update-4-x86_64-kvm.qcow2'
  flavor:
    type: string
    default: 'M5 Large'
  availability_zone:
    type: string
    default: nova
  net_mng:
    type: string
    default: YOUR-NETWORK
  net_data:
    type: string
    default: None
  key_name:
    type: string
    default: YOUR-KEY

conditions:
  have_data: {not: {equals: [{get_param: net_data}, "None"]}}

resources:
  vm_name:
    type: OS::Heat::Value
    properties:
      type: string
      value: {get_param: 'OS::stack_name'}

  fw_open_ping_ssh:
    type: OS::Neutron::SecurityGroup
    properties:
      name: fw_open_ping_ssh
      description: Ping and SSH
      rules:
      - protocol: icmp
      - protocol: tcp
        port_range_min: 1
        port_range_max: 65535

  mng_port:
    type: OS::Neutron::Port
    properties:
      network: {get_param: net_mng}
      name:
        list_join: ['-', [{get_attr: [vm_name, value]}, 'mng']]

  data_port:
    type: OS::Neutron::Port
    condition: have_data
    properties:
      network: {get_param: net_data}
      binding:vnic_type: direct
      port_security_enabled: false
      name:
        list_join: ['-', [{get_attr: [vm_name, value]}, 'data']]

  ports:
    type: OS::Heat::Value
    properties:
      type: comma_delimited_list
      value:
        filter:
          - ["none"]
          -
            - {get_resource: mng_port}
            - if:
                - "have_data"
                - {get_resource: data_port}
                - "none"

  hostname_config:
    type: OS::Heat::CloudConfig
    properties:
      cloud_config:
        merge_how: 'dict(recurse_array,no_replace)+list(append)'
        hostname:
          str_replace:
            params:
              hostname: {get_attr: [vm_name, value]}
            template: hostname

  server_init:
    type: OS::Heat::MultipartMime
    properties:
      parts:
        - config: {get_resource: hostname_config}

  server:
    type: OS::Nova::Server
    properties:
      image: {get_param: image}
      flavor: {get_param: flavor}
      availability_zone: {get_param: availability_zone}
      name: {get_attr: [vm_name, value]}
      networks:
        repeat:
          for_each:
            <%port%>: {get_attr: [ports, value]}
          template:
            port: <%port%>
          permutations: false
      config_drive: true
      key_name: {get_param: key_name}
      user_data_format: RAW
      user_data: {get_resource: server_init}

You can launch this with the CLI command:

 openstack stack create --template create-instance.yaml STACK-NAME --wait

Create Mutiple Instances 

When you desire multiple instances run this as a nested stack from another template.

multiple-instances.yaml

heat_template_version: 2013-05-23

resources:
  rg:
    type: OS::Heat::ResourceGroup
    properties:
      count: 5
      resource_def: {type:  create-instance.yaml}

Note that the last line calls the name of your file that launches the single instance.

You can replace “count” and “resource_def” with parameters called from CLI, but here we just fil them in the template.

To launch 5 instances from your cli via ssh.

openstack stack create --template multiple-instances.yaml YOUR-STACKNAME --wait

Be careful not give too long a stack name since Openstack will add to the a number followed by a random string to each server name.