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.
- From the left-hand pane click Orchestration
- Click Stacks
- Click the 'Create Stack' button
- In the space provided labeled "Template Content" paste your YAML file.
- Click "Next: Orchestration Information"
- 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.
- Once you've filled out the required fields, click 'Confirm'
- 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
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
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
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
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
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
Updated about 6 hours ago