Using Rackspace OpenStack Flex Orchestration

Leveraging Orchestration to automate topology buildouts.

What is Orchestration?

In OpenStack, Orchestration is a component provided by the Heat service. This tool that allows users to automate the deployment and management of cloud resources. Heat uses templates, written in YAML, called Heat Orchestration Templates (HOT), to define the infrastructure as code.

Why Use Orchestration?

Automation and Efficiency

  • Automate the deployment of infrastructure, reducing manual effort.
  • Streamline resource provisioning, ensuring consistency and repeatability.

Scalability

  • Enable auto-scaling of resources based on predefined conditions.
  • Easily scale applications up or down to meet demand.

Infrastructure as Code

  • Manage and version infrastructure definitions just like software code.
  • Enhance collaboration by sharing templates across teams.

Multi-Resource Management

  • Deploy complex environments with multiple interdependent resources (e.g., servers, networks, storage) from a single template.

Key Features

  • Template-driven deployment using YAML-based HOT templates.
  • Support for diverse resources, including Nova instances, Neutron networks, Cinder volumes, Octavia load balancers, and more.
  • Custom configurations via software deployments and configurations.
  • Dependency management to ensure resources are created and deleted in the correct order.

How to Create Stacks in Skyline

To create Orchestration Stacks from templates in Skyline, you need to login to the OpenStack Flex Portal first.

  1. From the left-hand pane click Orchestration
  2. Click Stacks
  3. Click the 'Create Stack' button
  4. In the space provided labeled "Template Content" paste your YAML file.
  5. Click "Next: Orchestration Information"
  6. On Step 2, you'll be prompted for information based on the template file you're using. The fields may be automatically populated with a default value, but you can adjust them if necessary.
  7. Once you've filled out the required fields, click 'Confirm'
  8. Your stack will now begin building and you can check its progress from the Stacks page. Once it says 'Create Complete' it has finished successfully.

Note: If you delete your stack, all resources created by the stack will be deleted as well.

Example Templates

To help get you started with Rackspace OpenStack Flex and provide an easy starting point for building your own Orchestration templates, we've documented and provided a few below. Before you can actually use these templates you'll need to have an SSH Key setup first with your OpenStack Flex account that you can reference upon build.

Key for Layout Charts

Key for Layout Charts


Basic Network

This Basic Network template builds out the OpenStack network environment. It doesn't create any instances or other devices, only the private network, subnet, router, and security groups.

Network Template Layout

Network Template Layout

Show YAML for Network Template
heat_template_version: 2021-04-16

description: >
  OpenStack environment that sets up networking only, including a private network, subnet, router, and security groups.

parameters:
  public_net:
    type: string
    default: PUBLICNET
    description: The pre-existing public network for external access

resources:
  private_net:
    type: OS::Neutron::Net
    properties:
      name: private_net

  private_subnet:
    type: OS::Neutron::Subnet
    properties:
      name: private_subnet
      network_id: { get_resource: private_net }
      cidr: 192.168.1.0/24
      gateway_ip: 192.168.1.1
      dns_nameservers:
        - 8.8.8.8
        - 8.8.4.4

  router:
    type: OS::Neutron::Router
    properties:
      external_gateway_info:
        network: { get_param: public_net }

  router_interface:
    type: OS::Neutron::RouterInterface
    properties:
      router_id: { get_resource: router }
      subnet_id: { get_resource: private_subnet }

  security_group:
    type: OS::Neutron::SecurityGroup
    properties:
      name: default_security_group
      rules:
        - protocol: icmp
        - protocol: tcp
          port_range_min: 22
          port_range_max: 22
        - protocol: tcp
          port_range_min: 80
          port_range_max: 80
        - protocol: tcp
          port_range_min: 443
          port_range_max: 443
        - protocol: tcp
          port_range_min: 3306
          port_range_max: 3306

outputs:
  private_network_id:
    description: The ID of the created private network.
    value: { get_resource: private_net }

  private_subnet_id:
    description: The ID of the created private subnet.
    value: { get_resource: private_subnet }

  router_id:
    description: The ID of the created router.
    value: { get_resource: router }

  security_group_id:
    description: The ID of the created security group.
    value: { get_resource: security_group }



Single Public VM

A single VM with a public IP, sometimes called a "one-box wonder" is a simple deployment where all components of an application — including the web server, application logic, and database — run on a single physical or virtual machine (one box). This is often used for development, testing, or small-scale applications due to its simplicity and low cost. However, it lacks scalability, fault tolerance, and high availability, as everything depends on a single machine. If that machine fails, the entire application goes down.

Public VM Layout

Public VM Layout

Show YAML for Public VM Template
heat_template_version: 2021-04-16

description: >
  Basic OpenStack environment with a private network, router, security group, that builds a publicly available instance.

parameters:
  public_net:
    type: string
    default: PUBLICNET
    description: The pre-existing public network for external access
  image:
    type: string
    default: Ubuntu 24.04
    description: The OS for the instance. ie Ubuntu 24.04
  flavor:
    type: string
    default: gp.0.2.2
    description: The flavor to use for instances. ie gp.0.2.2
  key_name:
    type: string
    description: Name of an existing SSH keypair to use for instances

resources:
  private_net:
    type: OS::Neutron::Net
    properties:
      name: private_net

  private_subnet:
    type: OS::Neutron::Subnet
    properties:
      name: private_subnet
      network_id: { get_resource: private_net }
      cidr: 192.168.1.0/24
      gateway_ip: 192.168.1.1
      dns_nameservers:
        - 8.8.8.8
        - 8.8.4.4

  router:
    type: OS::Neutron::Router
    properties:
      external_gateway_info:
        network: { get_param: public_net }

  router_interface:
    type: OS::Neutron::RouterInterface
    properties:
      router_id: { get_resource: router }
      subnet_id: { get_resource: private_subnet }

  security_group:
    type: OS::Neutron::SecurityGroup
    properties:
      name: default_security_group
      rules:
        - protocol: icmp
        - protocol: tcp
          port_range_min: 22
          port_range_max: 22

  # Server1 server
  server1:
    type: OS::Nova::Server
    properties:
      name: server1
      image: { get_param: image }
      flavor: { get_param: flavor }
      key_name: { get_param: key_name }
      networks:
        - network: { get_resource: private_net }
      security_groups:
        - { get_resource: security_group }

  floating_ip_1:
    type: OS::Neutron::FloatingIP
    properties:
      floating_network: { get_param: public_net }

  floating_ip_association_1:
    type: OS::Neutron::FloatingIPAssociation
    properties:
      floatingip_id: { get_resource: floating_ip_1 }
      port_id: { get_attr: [server1, addresses, private_net, 0, port] }

outputs:
  instance_ips:
    description: The private IPs of the instances.
    value:
      - { get_attr: [server1, addresses, private_net, 0, addr] }

  floating_ips:
    description: The floating IPs assigned to each instance.
    value:
      - { get_attr: [floating_ip_1, floating_ip_address] }



2-Tier Architecture Template

A 2-tier architecture is a software design pattern with two layers: the client-side (presentation layer) and the server-side (data layer). In this setup, there is no load balancer or intermediary between the client and the server. The client (such as a web application or desktop application) communicates directly with the server, which handles both application logic and data management. This architecture is simpler and more cost-effective, making it suitable for small applications, but it lacks scalability and fault tolerance compared to multi-tier architectures. For example, a web application directly connected to a single database server without a load balancer or multiple web heads is a 2-tier architecture.

Layout for 2-Tier Template

Layout for 2-Tier Template

Show YAML 2-Tier Architecture Template
heat_template_version: 2021-04-16

description: >
  Basic OpenStack environment with a private network, router, security group, that builds three instances, but only one publicly available.

parameters:
  public_net:
    type: string
    default: PUBLICNET
    description: The pre-existing public network for external access
  image:
    type: string
    default: Ubuntu 24.04
    description: The OS for the instance. ie Ubuntu 24.04
  flavor:
    type: string
    default: gp.0.2.2
    description: The flavor to use for instances. ie gp.0.2.2
  key_name:
    type: string
    description: Name of an existing SSH keypair to use for instances

resources:
  private_net:
    type: OS::Neutron::Net
    properties:
      name: private_net

  private_subnet:
    type: OS::Neutron::Subnet
    properties:
      name: private_subnet
      network_id: { get_resource: private_net }
      cidr: 192.168.1.0/24
      gateway_ip: 192.168.1.1
      dns_nameservers:
        - 8.8.8.8
        - 8.8.4.4

  router:
    type: OS::Neutron::Router
    properties:
      external_gateway_info:
        network: { get_param: public_net }

  router_interface:
    type: OS::Neutron::RouterInterface
    properties:
      router_id: { get_resource: router }
      subnet_id: { get_resource: private_subnet }

  security_group:
    type: OS::Neutron::SecurityGroup
    properties:
      name: default_security_group
      rules:
        - protocol: icmp
        - protocol: tcp
          port_range_min: 22
          port_range_max: 22

  # Database server
  database:
    type: OS::Nova::Server
    properties:
      name: database
      image: { get_param: image }
      flavor: { get_param: flavor }
      key_name: { get_param: key_name }
      networks:
        - network: { get_resource: private_net }
      security_groups:
        - { get_resource: security_group }

  # App server 1
  app_server_1:
    type: OS::Nova::Server
    properties:
      name: app-server-1
      image: { get_param: image }
      flavor: { get_param: flavor }
      key_name: { get_param: key_name }
      networks:
        - network: { get_resource: private_net }
      security_groups:
        - { get_resource: security_group }

  floating_ip_2:
    type: OS::Neutron::FloatingIP
    properties:
      floating_network: { get_param: public_net }

  floating_ip_association_2:
    type: OS::Neutron::FloatingIPAssociation
    properties:
      floatingip_id: { get_resource: floating_ip_2 }
      port_id: { get_attr: [app_server_1, addresses, private_net, 0, port] }

  # App server 2
  app_server_2:
    type: OS::Nova::Server
    properties:
      name: app-server-2
      image: { get_param: image }
      flavor: { get_param: flavor }
      key_name: { get_param: key_name }
      networks:
        - network: { get_resource: private_net }
      security_groups:
        - { get_resource: security_group }

outputs:
  instance_ips:
    description: The private IP of the instance.
    value:
      - { get_attr: [app_server_1, addresses, private_net, 0, addr] }
  floating_ips:
    description: The floating IPs assigned to each instance.
    value:
      - { get_attr: [floating_ip_2, floating_ip_address] }


3-Tier Architecture

This template creates what is known as a 3-tier architecture. A 3-tier architecture is a software design pattern that divides an application into three distinct layers: the presentation layer, the application layer, and the data layer. The presentation layer, managed by a load balancer, handles user interactions and directs traffic to multiple web servers. The application layer, consisting of application servers (or web heads), processes business logic, executes application functions, and serves content. Finally, the data layer exists on an instance where databases store and manage the application's data. Additionally, the database uses persistent volume storage. This separation improves scalability, performance, and maintainability, allowing each layer to be scaled, updated, or managed independently.

Layout for a 3-Tier Template

Layout for a 3-Tier Template

Show YAML for 3-Tier Architecture Template
heat_template_version: '2021-04-16'
description: >
  OpenStack environment that sets up networking, instances with bootable volumes
  for the database, local boot for app servers, and a load balancer with a
  floating IP.
parameters:
  public_net:
    type: string
    default: PUBLICNET
    description: The pre-existing public network for external access
  image_id:
    type: string
    default: Ubuntu 24.04
    description: ID of the image to use for instances
  flavor:
    type: string
    default: gp.0.2.2
    description: Flavor to use for instances
  volume_size:
    type: number
    default: 20
    description: Size of the boot volume in GB
  delete_on_termination:
    type: boolean
    default: false
    description: Whether to delete the volume on instance termination
  volume_type:
    type: string
    default: Standard
    constraints:
      - allowed_values:
          - Performance
          - Standard
          - HA-Standard
          - HA-Performance
          - Capacity
    description: Type of the volume to be created
  key_name:
    type: string
    description: Name of the SSH key to be used for the instances
  enable_floating_ip:
    type: boolean
    default: false
    description: Whether to associate a floating IP with the instances
resources:
  private_net:
    type: OS::Neutron::Net
    properties:
      name: private_net
  private_subnet:
    type: OS::Neutron::Subnet
    properties:
      name: private_subnet
      network_id:
        get_resource: private_net
      cidr: 192.168.1.0/24
      gateway_ip: 192.168.1.1
      dns_nameservers:
        - 8.8.8.8
        - 8.8.4.4
  router:
    type: OS::Neutron::Router
    properties:
      external_gateway_info:
        network:
          get_param: public_net
  router_interface:
    type: OS::Neutron::RouterInterface
    properties:
      router_id:
        get_resource: router
      subnet_id:
        get_resource: private_subnet
  security_group:
    type: OS::Neutron::SecurityGroup
    properties:
      name: default_security_group
      rules:
        - protocol: icmp
        - protocol: tcp
          port_range_min: 22
          port_range_max: 22
        - protocol: tcp
          port_range_min: 80
          port_range_max: 80
        - protocol: tcp
          port_range_min: 443
          port_range_max: 443
        - protocol: tcp
          port_range_min: 3306
          port_range_max: 3306
  database_volume:
    type: OS::Cinder::Volume
    properties:
      size:
        get_param: volume_size
      image:
        get_param: image_id
      volume_type: HA-Standard
  database_instance:
    type: OS::Nova::Server
    properties:
      name: database
      flavor:
        get_param: flavor
      key_name:
        get_param: key_name
      networks:
        - network:
            get_resource: private_net
      block_device_mapping:
        - device_name: vda
          volume_id:
            get_resource: database_volume
          delete_on_termination:
            get_param: delete_on_termination
      security_groups:
        - get_resource: security_group
  app_instance_1:
    type: OS::Nova::Server
    properties:
      name: app-1
      flavor:
        get_param: flavor
      key_name:
        get_param: key_name
      networks:
        - network:
            get_resource: private_net
      image:
        get_param: image_id
      security_groups:
        - get_resource: security_group
  app_instance_2:
    type: OS::Nova::Server
    properties:
      name: app-2
      flavor:
        get_param: flavor
      key_name:
        get_param: key_name
      networks:
        - network:
            get_resource: private_net
      image:
        get_param: image_id
      security_groups:
        - get_resource: security_group
  load_balancer:
    type: OS::Octavia::LoadBalancer
    properties:
      vip_subnet:
        get_resource: private_subnet
  load_balancer_listener:
    type: OS::Octavia::Listener
    properties:
      loadbalancer:
        get_resource: load_balancer
      protocol: HTTP
      protocol_port: 80
  load_balancer_pool:
    type: OS::Octavia::Pool
    properties:
      listener:
        get_resource: load_balancer_listener
      protocol: HTTP
      lb_algorithm: ROUND_ROBIN
  load_balancer_members:
    type: OS::Octavia::PoolMember
    properties:
      pool:
        get_resource: load_balancer_pool
      address:
        get_attr:
          - app_instance_1
          - first_address
      protocol_port: 80
    depends_on:
      - app_instance_1
      - app_instance_2
  floating_ip_lb:
    type: OS::Neutron::FloatingIP
    properties:
      floating_network:
        get_param: public_net
  floating_ip_association_lb:
    type: OS::Neutron::FloatingIPAssociation
    properties:
      floatingip_id:
        get_resource: floating_ip_lb
      port_id:
        get_attr:
          - load_balancer
          - vip_port_id
conditions:
  enable_floating_ip:
    get_param: enable_floating_ip
outputs:
  private_network_id:
    description: The ID of the created private network.
    value:
      get_resource: private_net
  private_subnet_id:
    description: The ID of the created private subnet.
    value:
      get_resource: private_subnet
  router_id:
    description: The ID of the created router.
    value:
      get_resource: router
  security_group_id:
    description: The ID of the created security group.
    value:
      get_resource: security_group
  floating_ip_lb:
    description: The allocated floating IP for the load balancer.
    value:
      get_attr:
        - floating_ip_lb
        - floating_ip_address


Best Practices for Templates

  • Break down large templates into smaller, reusable components.
  • Use parameterization to make templates flexible and reusable.
  • Implement error handling and rollback mechanisms.
  • Regularly update and test templates to ensure compatibility with OpenStack versions.

Additional Documentation

OpenStack Heat Docs