Jump to: navigation, search

Heat/Blueprints/Multi Region Support for Heat

< Heat
Revision as of 00:02, 16 July 2013 by Hanney (talk | contribs)

--bartosz-gorski (talk) 23:51, 15 July 2013 (UTC)

Overview

Introduction

Most of enterprises are focusing on Multi-cloud (using both private and public clouds) as enterprise cloud strategy. They will not completely migrate to Service Provider's cloud (public cloud). They will still keep their mission critical information assets to their premise or collocation space (private cloud).

Our goal is to create Hybrid-cloud (combination of public and private cloud). Creating Hybrid-cloud requires:

  • Seamless operation among heterogeneous environment
  • End-to-end automatic provisioning based on system template (VM, network, topology)
  • Unified control and monitoring
    • Multi-Hypervisor including bare-metal
    • Multi-Region control
    • Secure network access via Internet (VPN connection)
Multi Region Heat

Requirements & Challenges

Requirements for Heat:

  • Mapping between Regions and API endpoints
  • Mapping between Regions and Images
  • Specifying Region for each resource
  • Support for VPN as resource
  • Horizon interface for Heat with multi regions


Challenges:

  • dealing with dependencies between resources in different regions
  • minimizing number of single region templates for which multi region template will be split
  • figure out efficient way to update multi region stack

Goal

Basic Use Case Scenario

Multi region first use case

We have two regions (East and West) with separate OpenStack installations. We want to use Heat with multi region support to create in both regions:

  • Quantum Network
  • Quantum Subnet
    • 10.1.0.0/24 in East
    • 10.2.0.0/24 in West
  • Router
    • Router Interface for created subnet
    • Router Gateway for external network
  • VPN Service for created router
    • IKE Policy
    • IPsec Policy
    • VPN Connection
  • Server connected to created subnet


Template file example in appendix (Multiregion.template).

Architecture

Overview

Components Diagram

Description:

  • More than one region (for example two: East and West)
  • Separate OpenStack installation (Nova, Glance, Swift, Neutron and Cinder) in each region
  • One Keystone service for all regions
  • One Horizon with multi region support
  • One Heat for multi region orchestration - to be clear right now it does not exist

Template Flow

Template flow

Challenges & Solutions

Challenge First step Future work
Dependencies between resources from different regions. There will be not such dependencies and we do not need to deal with them. Multi region Heat component will be responsible for dealing with dependencies and creation order (needs to create dependencies graph where each node is a single region template).
Amount of single region templates. Only one template for each region containing all resources from that region. It is possible because there is not dependencies between regions. Decreasing number of templates by putting independent resources to the same template (assuming we have dependencies between resources from different regions).
Update stack Silly update (Delete old and Create new) More efficient update.

What needs to be done

Heat

Engine

Adding new resources types:

  • VPNServices
  • IKEPolicy
  • IPsecPolicy
  • VPNConnections
VPNServices
Property Description
name Name of the VPN Service.
description Description of the VPN Service.
admin_state_up Administrative state of vpnservice. If false (down), port does not forward packets.
subnet_id Subnet id in which the tenant wants the vpn service.
router_id Router id to which the vpn service is inserted.

Example:

...
"Resources" : {
    ...
    "VPNService" : {
        "Type" : "OS::Quantum::VPNService",
        "Properties" : {
            "name" : "My VPN",
            "description" : "My new VPN",
            "admin_state_up" : True,
            "subnet_Id" : { "Ref" : "Subnet" },
            "router_Id" : { "Ref" : "Router" }
        }
    }
    ...
},
...
IKEPolicy
Property Description
name Friendly name for the IKE policy.
description Description of the IKE policy.
auth_algorithm Authentication Hash algorithms "sha1".
encryption_algorithm Encryption Algorithms "3des", "aes-128", "aes-256", "aes-192" etc.
phase1_negotiation_mode IKE mode "main".
lifetime_units Lifetime of the SA unit in "seconds" or "kilobytes".
lifetime_value Lifetime value in seconds or kilobytes.
pfs Perfect Forward Secrecy (group2, group5, group14).
ike_version v1 or v2 version.

Example:

...
"Resources" : {
    ...
    "IKEPolicy" : {
        "Type" : "OS::Quantum::IKEPolicy",
        "Properties" : {
            "name" : "My IKEPolicy",
            "description" : "My new IKE policy",
            "auth_algorithm" : "sha1",
            "encryption_algorithm" : "3des",
            "phase1_negotiation_mode" : "main",
            "lifetime_units" : "seconds",
            "lifetime_value" : 3600,
            "pfs" : "group5",
            "ike_version" : "v1"
        }
    }
    ...
},
...
IPsecPolicy
Property Description
name Friendly name for the IPsec policy.
description Description of the IPsec policy.
transform_protocol Transform Protocol used such as "esp" or "ah" or "ah-esp".
encapsulation_mode Encapsulation mode either "tunnel" mode or "transport" mode.
auth_algorithm Authentication Hash algorithms "sha1".
encryption_algorithm Encryption Algorithms "3des", "aes-128", "aes-256", "aes-192" etc.
lifetime_units Lifetime of the SA unit in "seconds" or "kilobytes".
lifetime_value Lifetime value in seconds or kilobytes.
pfs Perfect Forward Secrecy (group2, group5, group14).

Example:

...
"Resources" : {
    ...
    "IPsecPolicy" : {
        "Type" : "OS::Quantum::IPsecPolicy",
        "Properties" : {
            "name" : "My IKEPolicy",
            "description" : "My new IKE policy",
            "transform_protocol": "esp",
            "encapsulation_mode" : "tunnel",
            "auth_algorithm" : "sha1",
            "encryption_algorithm" : "3des",
            "lifetime_units" : "seconds",
            "lifetime_value" : 3600,
            "pfs" : "group5"
        }
    }
    ...
},
...
VPNConnections
Property Description
name Friendly Name for the VPN connection.
description Description of the VPN connection.
peer_address Peer VPN gateway public address or FQDN.
peer_id Peer identifier (Can be name, string or FQDN).
mtu Maximum transmission unit to address fragmentation.
dpd_actions DPD actions controls the use of Dead Peer Detection Protocol. ("clear", "hold", "restart", "disabled", "restart-by-peer").
dpd_interval Number of seconds for DPD delay.
dpd_timeout Number of seconds for DPD timeout.
psk Pre-shared-key any string.
initiator Whether this VPN can only respond to connections or can initiate as well.
admin_state_up Administrative state of vpn connection. If false (down), VPN connection does not forward packets.
ikepolicy_id UUID id of IKE policy.
ipsecpolicy_id UUID id of IPsec policy.
vpnservice_id UUID id of VPN service.

Example:

...
"Resources" : {
    ...
    "VPNConnection" : {
        "Type" : "OS::Quantum::VPNConnection",
        "Properties" : {
            "name" : "My VPN connection",
            "description" : "My new VPN connection",
            "peer_address" : "10.0.0.1",
            "peer_id" : "peer",
            "peer_cidrs" : ["10.0.0.0/24"],
            "mtu" : "1500",
            "dpd_actions" : "hold",
            "dpd_interval" : "30",
            "dpd_timeout" : "120",
            "psk" : "secret",
            "initiator" : "bi-directional",
            "admin_state_up" : True,
            "ikepolicy_id" : { "Ref" : "IKEPolicy" },
            "ipsecpolicy_Id" : { "Ref" : "IPsecPolicy" },
            "vpnservice_id" : { "Ref" : "VPNService" }
        }
    }
    ...
},
...

API/CLI

Probably we do not need to add any new command.

UI

Existing UI views:

  • Stack List for Tenant
Heat UI Stacks
  • Launch new Stack
Heat UI Launch Stack
  • Stack Details
    • Overview tab
Heat UI Stack Detail Overview Tab.png
    • Resources tab
Heat UI Stack Detail Resources Tab
    • Events tab
Heat UI Stack Detail Events Tab
  • Resource Details
Heat UI Resource Detail

Multi region Heat [DRAFT - WORK IN PROGRESS]

Engine

Representing Multi region stack:

  • Raw template
  • Region names list
  • Mapping between stack and region
  • Mapping between resource and stack
  • List of Single Stacks data
    • (region_name, single_region_template, single_region_stack_id)
Mapping regions with API endpoints [SUPPORTED]

Concerns:

  • maybe we can get those information from Keystone?
  • what about multi endpoints for one region?

Example:

...
"Mappings" : {
    ...
        "Region2EndPoints" : {
            "East" : { "orchestration" : "orchestration.east.openstack.com"}, 
            "West" : { "orchestration" : "orchestration.west.openstack.com"}
        }
    ...
},
...
Mapping regions with images [SUPPORTED]

Example:

...
"Mappings" : {
    ...
    "Region2Image" : {
        "East" : { "F17" : "F17-x86_64-cfntools", "U12" : "ubuntu-vm-heat-cfntools" },
        "West" : { "F17" : "F17-x86_64-cfntools", "U12" : "ubuntu-vm-heat-cfntools" }
    }
    ...
},
...
Specify RegionName property for resource [NOT SUPPORTED]

Example:

...
"Resources" : {
    ...
    "Ec2Instance" : {
        "Type" : "AWS::EC2::Instance",
        '''"RegionName" : { "Ref" : "RegionName" },'''
        "Properties" : {
            "ImageId" : { "Ref" : "ImageId" },
            "KeyName" : { "Ref" : "KeyName" },
            "InstanceType" : { "Ref" : "InstanceType" }
            "SubnetId" : { "Ref" : "SubnetWest" }
        }
    }
    ...
},
...

API/CLI

Should provide the same API functionalities as single region Heat API:

  • Events
    • event-list - List events for a stack.
      • querying each region API with event-list request
      • aggregating results and sorting events by date
    • event-show - Describe the event
      • querying each region API with event-show request to find it
  • Resources
    • resource-list - Show list of resources belonging to a stack
      • querying each region API with resource-list request and aggregating results
    • resource-metadata - List resource metadata
      • checking in which region given resource was created and querying it API for result
    • resource-show - Describe the resource
      • checking in which region given resource was created and querying it API for result
  • Stacks
    • stack-create - Create the stack
      • parsing multi region template and creating set of single region templates
      • creating stack for each single region template in specified region
    • stack-delete - Delete the stack
      • getting list of single stack ids and for each one querying appropriate region API to delete it
    • stack-update - Update the stack
      • dummy update
        • deleting old multi region stack
        • creating new multi region stack for new template
    • stack-list - List the user's stacks
      • returning list of created multi region stacks
    • stack-show - Describe the stack
      • querying each region API with stack-show request for each single region stack
      • aggregating results
  • Templates
    • template-show - Get the template for the specified stack
      • returning multi region template
    • template-validate - Validate a template with parameters
      • validating whole multi region template

UI

Additional tab for multi region stack is required. To be continue...

Horizon support for multi regions

  • Project Tab
    • Dropbox to choose one of the available regions
  • Admin Tab
    • Dropbox to choose one of the available regions

Dropbox will appear only if more than one region is available in keystone catalog.

Dependencies & References

  • BL: Implement a Heat UI for managing stacks (MERGED)
    • patch
  • BL: Support multiple endpoints for the same service (MERGED)
    • patch
  • BL: VPN as a Service providing IPsec VPN with Static routing (UNDER REVIEW)
    • UI patch
    • backend patch
    • API patch
    • instruction

Action Plan

  • Add VPNaaS to supported resources in Heat engine [Done]
  • Create template to set up one side VPN connection [Done]
  • Create simple version of Multi Heat engine
    • splits multi region template to set of simple region templates
    • creates a stack for each single template in appropriate region
  • Create multi region template to set up VPN connection between two devstacks
  • Test template for first use case (the one described above)
  • Add support for dependencies between resources from different regions to multi heat engine

Appendix

Templates

  • Multiregion.template
{
  "AWSTemplateFormatVersion" : "2010-09-09",

  "Description" : "Creates VPN connection between to different regions and lanuches one server in each region",

  "Parameters" : {

    "KeyName" : {
      "Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instances",
      "Type" : "String"
    },
    
    "InstanceType" : {
      "Description" : "EC2 instance type",
      "Type" : "String",
      "Default" : "m1.small",
      "AllowedValues" : [ "m1.tiny", "m1.small", "m1.medium", "m1.large", "m1.xlarge" ],
      "ConstraintDescription" : "must be a valid EC2 instance type."
    },
    
    "LinuxDistribution": {
      "Default": "U12",
      "Description" : "Distribution of choice",
      "Type": "String",
      "AllowedValues" : [ "F17", "U12" ]
    },
    
    "RegionEast" : {
      "Description" : "Name of the East region",
      "Type" : "String",
      "Default" : "RegionEast",
      "ConstraintDescription" : "must be a existing OpenStack region"
    },

    "RegionWest" : {
      "Description" : "Name of the West region",
      "Type" : "String",
      "Default" : "RegionWest",
      "ConstraintDescription" : "must be a existing OpenStack region"
    },

    "ExternalNetworkIdEast" : {
      "Description" : "External network id on East",
      "Type" : "String",
      "ConstraintDescription" : "must be a id of existing external network on East"
    },
    
    "ExternalNetworkIdWest" : {
      "Description" : "External network id on West",
      "Type" : "String",
      "ConstraintDescription" : "must be a id of existing external network on West"
    },
    
    "ExternalGatewayIPAddressEast" : {
      "Description" : "External Gateway IP address on East",
      "Type" : "String",
      "Default" : "172.24.4.233",
      "ConstraintDescription" : "must be an IP address of external gateway on East"
    },

    "ExternalGatewayIPAddressWest" : {
      "Description" : "External Gateway IP address on West",
      "Type" : "String",
      "Default" : "172.24.4.226",
      "ConstraintDescription" : "must be an IP address of external gateway on West"
    }

  },

  "Mappings" : {
    "OpenstackRegion2Image" : {
      "RegionEast" : { 
	"F17" : "F17-x86_64-cfntools",
	"U12" : "ubuntu-vm-heat-cfntools"
      },
      "RegionWest" : {
	"F17" : "F17-x86_64-cfntools",
	"U12" : "ubuntu-vm-heat-cfntools"
      }
    },

    "OpenStack2EndPoints" : {
      "RegionEast" : { "orchestration" : "orchestration.RegionEast.com" }, 
      "RegionWest" : { "orchestration" : "orchestration.RegionWest.com" }
    }
  },

  "Resources" : {
  
    "NetworkEast": {
      "Type": "OS::Quantum::Net",
      "RegionName" : { "Ref" : "RegionEast" },
      "Properties": {
        "name": "East Region Network"
      }
    },

    "SubnetEast": {
      "Type": "OS::Quantum::Subnet",
      "RegionName" : { "Ref" : "RegionEast" },
      "Properties": {
        "network_id": { "Ref" : "NetworkEast" },
        "ip_version": 4,
        "cidr": "10.1.0.0/24",
        "allocation_pools": [ {
          "start": "10.1.0.10",
          "end": "10.1.0.200"
          }
        ]
      }
    },

    "RouterEast": {
      "Type": "OS::Quantum::Router",
      "RegionName" : { "Ref" : "RegionEast" },
      "Properties": {
        "name": "East Router"
      }
    },

    "RouterInterfaceEast": {
      "Type": "OS::Quantum::RouterInterface",
      "RegionName" : { "Ref" : "RegionEast" },
      "Properties": {
        "router_id": { "Ref" : "RouterEast" },
        "subnet_id": { "Ref" : "SubnetEast" }
      }
    },
    
    "RouterGatewayEast": {
      "Type": "OS::Quantum::RouterGateway",
      "RegionName" : { "Ref" : "RegionEast" },
      "Properties": {
        "router_id": { "Ref" : "RouterEast" },
        "network_id": { "Ref" : "ExternalNetworkIdEast" }
      }
    },

    "NetworkWest": {
      "Type": "OS::Quantum::Net",
      "RegionName" : { "Ref" : "RegionWest" },
      "Properties": {
        "name": "West Region Network"
      }
    },

    "SubnetWest": {
      "Type": "OS::Quantum::Subnet",
      "RegionName" : { "Ref" : "RegionWest" },
      "Properties": {
        "network_id": { "Ref" : "NetworkWest" },
        "ip_version": 4,
        "cidr": "10.2.0.0/24",
        "allocation_pools": [ {
          "start": "10.2.0.10",
          "end": "10.2.0.200"
          }
        ]
      }
    },

    "RouterWest": {
      "Type": "OS::Quantum::Router",
      "RegionName" : { "Ref" : "RegionWest" },
      "Properties": {
        "name": "West Router"
      }
    },

    "RouterInterfaceWest": {
      "Type": "OS::Quantum::RouterInterface",
      "RegionName" : { "Ref" : "RegionWest" },
      "Properties": {
        "router_id": { "Ref" : "RouterWest" },
        "subnet_id": { "Ref" : "SubnetWest" }
      }
    },
    
    "RouterGatewayWest": {
      "Type": "OS::Quantum::RouterGateway",
      "RegionName" : { "Ref" : "RegionWest" },
      "Properties": {
        "router_id": { "Ref" : "RouterWest" },
        "network_id": { "Ref" : "ExternalNetworkIdWest" }
      }
    },

    "VPNServiceEast" : {
      "Type" : "OS::Quantum::VPNService",
      "RegionName" : { "Ref" : "RegionEast" },
      "Properties" : {
        "name" : "VPNServiceEast",
        "description" : "My new VPN service on East",
        "router_id" : { "Ref" : "RouterEast" },
        "subnet_id" : { "Ref" : "SubnetEast" }
      }
    },

   "IKEPolicyEast" : {
      "Type" : "OS::Quantum::IKEPolicy",
      "RegionName" : { "Ref" : "RegionEast" },
      "Properties" : {
        "name" : "IKEPolicyEast",
        "description" : "My new IKE policy on East"
      }
    },

    "IPsecPolicyEast" : {
      "Type" : "OS::Quantum::IPsecPolicy",
      "RegionName" : { "Ref" : "RegionEast" },
      "Properties" : {
        "name" : "IPsecPolicyEast",
        "description" : "My new IPsec policy on East"
      }
    },

    "VPNConnectionEast" : {
      "Type" : "OS::Quantum::VPNConnection",
      "RegionName" : { "Ref" : "RegionEast" },
      "Properties" : {
        "name" : "VPNConnectionEast",
        "description" : "My new VPN connection on East",
        "peer_address" : { "Ref" : "ExternalGatewayIPAddressEast" },
        "peer_id" : { "Ref" : "ExternalGatewayIPAddressEast" },
        "peer_cidrs" : [ "10.2.0.0/24" ],
        "psk" : "secret",
        "initiator" : "bi-directional"
        "ikepolicy_id" : { "Ref" : "IKEPolicyEast" },
        "ipsecpolicy_id" : { "Ref" : "IPsecPolicyEast" },
        "vpnservice_id" : { "Ref" : "VPNServiceEast" }
      }
    },

    "VPNServiceWest" : {
      "Type" : "OS::Quantum::VPNService",
      "RegionName" : { "Ref" : "RegionWest" },
      "Properties" : {
        "name" : "VPNServiceWest",
        "description" : "My new VPN service on West",
        "router_id" : { "Ref" : "RouterWest" },
        "subnet_id" : { "Ref" : "SubnetWest" }
      }
    },

   "IKEPolicyWest" : {
      "Type" : "OS::Quantum::IKEPolicy",
      "RegionName" : { "Ref" : "RegionWest" },
      "Properties" : {
        "name" : "IKEPolicyWest",
        "description" : "My new IKE policy on West"
      }
    },

    "IPsecPolicyWest" : {
      "Type" : "OS::Quantum::IPsecPolicy",
      "RegionName" : { "Ref" : "RegionWest" },
      "Properties" : {
        "name" : "IPsecPolicyWest",
        "description" : "My new IPsec policy on West"
      }
    },

    "VPNConnectionWest" : {
      "Type" : "OS::Quantum::VPNConnection",
      "RegionName" : { "Ref" : "RegionEast" },
      "Properties" : {
        "name" : "VPNConnectionWest",
        "description" : "My new VPN connection on West",
        "peer_address" : { "Ref" : "ExternalGatewayIPAddressWest" },
        "peer_id" : { "Ref" : "ExternalGatewayIPAddressWest" },
        "peer_cidrs" : [ "10.1.0.0/24" ],
        "auth_mode" : "psk",
        "psk" : "secret",
        "ikepolicy_id" : { "Ref" : "IKEPolicyWest" },
        "ipsecpolicy_id" : { "Ref" : "IPsecPolicyWest" },
        "vpnservice_id" : { "Ref" : "VPNServiceWest" }
      }
    },
    
    "ServerEast" : {
      "Type": "AWS::EC2::Instance",
      "RegionName" : { "Ref" : "RegionEast" },
      "Properties": {
        "ImageId"      : { "Fn::FindInMap" : [ "OpenstackRegion2Image",
                                               { "Ref" : "RegionEast" },
                                               { "Ref" : "LinuxDistribution" } ] },
        "InstanceType" : { "Ref" : "InstanceType" },
        "KeyName"      : { "Ref" : "KeyName" },
        "SubnetId"     : { "Ref" : "SubnetEast" }
      }
    },
    
    "ServerWest" : {
      "Type": "AWS::EC2::Instance",
      "RegionName" : { "Ref" : "RegionWest" },
      "Properties": {
        "ImageId"      : { "Fn::FindInMap" : [ "OpenstackRegion2Image",
                                               { "Ref" : "RegionWest" },
                                               { "Ref" : "LinuxDistribution" } ] },
        "InstanceType" : { "Ref" : "InstanceType" },
        "KeyName"      : { "Ref" : "KeyName" },
        "SubnetId"     : { "Ref" : "SubnetWest" }
      }
    }
  },

  "Outputs" : {
    "ServerEastIP" : {
      "Description" : "East Server IP address",
      "Value" : { "Fn::GetAtt" : [ "ServerEast", "PublicIp" ] }
    },
    
    "ServerWestIP" : {
      "Description" : "West Server IP address",
      "Value" : { "Fn::GetAtt" : [ "ServerWest", "PublicIp" ] }
    }
  }
}


  • VPNaaS.template
{
  "AWSTemplateFormatVersion" : "2010-09-09",

  "Description" : "Creates one sided VPN connection between to different regions",

  "Parameters" : {
    
    "ExternalNetworkId" : {
      "Description" : "External network id",
      "Type" : "String",
      "ConstraintDescription" : "must be a uuid of existing external network"
    },
    
    "ExternalGatewayIPAddress" : {
      "Description" : "External Gateway IP address",
      "Type" : "String",
      "Default" : "172.24.4.233",
      "ConstraintDescription" : "must be an IP address of external gateway"
    }

  },

  "Resources" : {
  
    "Network": {
      "Type": "OS::Quantum::Net",
      "Properties": {
        "name": "My Network"
      }
    },

    "Subnet": {
      "Type": "OS::Quantum::Subnet",
      "Properties": {
        "name": "My Subnet",
        "network_id": { "Ref" : "Network" },
        "ip_version": 4,
        "cidr": "10.1.0.0/24",
        "allocation_pools": [ {
          "start": "10.1.0.10",
          "end": "10.1.0.200"
          }
        ]
      }
    },

    "Router": {
      "Type": "OS::Quantum::Router",
      "Properties": {
        "name": "My Router"
      }
    },

    "RouterInterface": {
      "Type": "OS::Quantum::RouterInterface",
      "Properties": {
        "router_id": { "Ref" : "Router" },
        "subnet_id": { "Ref" : "Subnet" }
      }
    },
    
    "RouterGateway": {
      "Type": "OS::Quantum::RouterGateway",
      "Properties": {
        "router_id": { "Ref" : "Router" },
        "network_id": { "Ref" : "ExternalNetworkId" }
      }
    },
  
    "VPNService" : {
      "Type" : "OS::Quantum::VPNService",
      "Properties" : {
        "name" : "VPNService",
        "description" : "My new VPN service",
        "router_id" : { "Ref" : "Router" },
        "subnet_id" : { "Ref" : "Subnet" }
      }
    },

   "IKEPolicy" : {
      "Type" : "OS::Quantum::IKEPolicy",
      "Properties" : {
        "name" : "IKEPolicy",
        "description" : "My new IKE policy"
      }
    },

    "IPsecPolicy" : {
      "Type" : "OS::Quantum::IPsecPolicy",
      "Properties" : {
        "name" : "IPsecPolicy",
        "description" : "My new IPsec policy"
      }
    },

    "VPNConnection" : {
      "Type" : "OS::Quantum::VPNConnection",
      "Properties" : {
        "name" : "VPNConnection",
        "description" : "My new VPN connection",
        "peer_address" : { "Ref" : "ExternalGatewayIPAddress" },
        "peer_id" : { "Ref" : "ExternalGatewayIPAddress" },
        "peer_cidrs" : [ "10.2.0.0/24" ],
        "psk" : "secret",
        "ikepolicy_id" : { "Ref" : "IKEPolicy" },
        "ipsecpolicy_id" : { "Ref" : "IPsecPolicy" },
        "vpnservice_id" : { "Ref" : "VPNService" }
      }
    }
  },

  "Outputs" : {
    "router_name" : {
      "Value" : { "Fn::GetAtt" : [ "Router", "name" ]},
      "Description" : "Router name"
    }
  }
}

Heat UI screenshots

  • heat_ui_launch_stack.png
  • heat_ui_resource_detail.png
  • heat_ui_stack_detail_events_tab.png
  • heat_ui_stack_detail_overview_tab.png
  • heat_ui_stack_detail_resources_tab.png
  • heat_ui_stacks.png

Horizon Multi region support screenshots

  • horizon_multi_region_admin_tab.png
  • horizon_multi_region_project_tab.png