heat_template_version: 2014-10-16 description: > This template will boot a Docker Swarm-Mode cluster. A swarm cluster is made up of several master nodes, and N worker nodes. Every node in the cluster, including the master, is running a Docker daemon and joins the swarm as a manager or as a worker. The managers are listening on port 2375. By default, the cluster is made up of one master node and one worker node. parameters: # # REQUIRED PARAMETERS # ssh_key_name: type: string description: name of ssh key to be provisioned on our server default: "" external_network: type: string description: uuid/name of a network to use for floating ip addresses fixed_network: type: string description: uuid/name of an existing network to use to provision machines default: "" fixed_subnet: type: string description: uuid/name of an existing subnet to use to provision machines default: "" cluster_uuid: type: string description: identifier for the cluster this template is generating magnum_url: type: string description: endpoint to retrieve TLS certs from server_image: type: string description: glance image used to boot the server # # OPTIONAL PARAMETERS # master_flavor: type: string description: flavor to use when booting the swarm master default: m1.small node_flavor: type: string description: flavor to use when booting the swarm node dns_nameserver: type: string description: address of a dns nameserver reachable in your environment default: 8.8.8.8 http_proxy: type: string description: http proxy address for docker default: "" https_proxy: type: string description: https proxy address for docker default: "" no_proxy: type: string description: no proxies for docker default: "" number_of_masters: type: number description: how many swarm masters to spawn default: 1 number_of_nodes: type: number description: how many swarm nodes to spawn default: 1 number_of_secondary_masters: type: number description: how many secondary masters to spawn fixed_network_cidr: type: string description: network range for fixed ip network default: "10.0.0.0/24" tls_disabled: type: boolean description: whether or not to enable TLS default: False docker_volume_size: type: number description: > size of a cinder volume to allocate to docker for container/image storage default: 0 docker_volume_type: type: string description: > type of a cinder volume to allocate to docker for container/image storage docker_storage_driver: type: string description: docker storage driver name default: "devicemapper" loadbalancing_protocol: type: string description: > The protocol which is used for load balancing. If you want to change tls_disabled option to 'True', please change this to "HTTP". default: TCP constraints: - allowed_values: ["TCP", "HTTP"] swarm_port: type: number description: > The port which are used by swarm manager to provide swarm service. default: 2375 trustee_domain_id: type: string description: domain id of the trustee default: "" trustee_user_id: type: string description: user id of the trustee default: "" trustee_username: type: string description: username of the trustee default: "" trustee_password: type: string description: password of the trustee default: "" hidden: true trust_id: type: string description: id of the trust which is used by the trustee default: "" hidden: true auth_url: type: string description: url for keystone volume_driver: type: string description: volume driver to use for container storage default: "" constraints: - allowed_values: ["","rexray"] rexray_preempt: type: string description: > enables any host to take control of a volume irrespective of whether other hosts are using the volume default: "false" verify_ca: type: boolean description: whether or not to validate certificate authority openstack_ca: type: string hidden: true description: The OpenStack CA certificate to install on the node. nodes_affinity_policy: type: string description: > affinity policy for nodes server group constraints: - allowed_values: ["affinity", "anti-affinity", "soft-affinity", "soft-anti-affinity"] availability_zone: type: string description: > availability zone for master and nodes default: "" resources: ###################################################################### # # network resources. allocate a network and router for our server. # it would also be possible to take advantage of existing network # resources (and have the deployer provide network and subnet ids, # etc, as parameters), but I wanted to minmize the amount of # configuration necessary to make this go. network: type: ../../common/templates/network.yaml properties: existing_network: {get_param: fixed_network} existing_subnet: {get_param: fixed_subnet} private_network_cidr: {get_param: fixed_network_cidr} dns_nameserver: {get_param: dns_nameserver} external_network: {get_param: external_network} api_lb: type: ../../common/templates/lb.yaml properties: fixed_subnet: {get_attr: [network, fixed_subnet]} external_network: {get_param: external_network} protocol: {get_param: loadbalancing_protocol} port: {get_param: swarm_port} ###################################################################### # # security groups. we need to permit network traffic of various # sorts. # secgroup_swarm_manager: type: "OS::Neutron::SecurityGroup" properties: rules: - protocol: icmp - protocol: tcp port_range_min: 22 port_range_max: 22 - protocol: tcp port_range_min: 2375 port_range_max: 2375 - protocol: tcp port_range_min: 2377 port_range_max: 2377 - protocol: tcp remote_ip_prefix: {get_param: fixed_network_cidr} port_range_min: 1 port_range_max: 65535 - protocol: udp port_range_min: 53 port_range_max: 53 secgroup_swarm_node: type: "OS::Neutron::SecurityGroup" properties: rules: - protocol: icmp - protocol: tcp - protocol: udp ###################################################################### # # resources that expose the IPs of either the swarm master or a given # LBaaS pool depending on whether LBaaS is enabled for the cluster. # api_address_lb_switch: type: Magnum::ApiGatewaySwitcher properties: pool_public_ip: {get_attr: [api_lb, floating_address]} pool_private_ip: {get_attr: [api_lb, address]} master_public_ip: {get_attr: [swarm_primary_master, resource.0.swarm_master_external_ip]} master_private_ip: {get_attr: [swarm_primary_master, resource.0.swarm_master_ip]} ###################################################################### # # resources that expose the IPs of either floating ip or a given # fixed ip depending on whether FloatingIP is enabled for the cluster. # api_address_floating_switch: type: Magnum::FloatingIPAddressSwitcher properties: public_ip: {get_attr: [api_address_lb_switch, public_ip]} private_ip: {get_attr: [api_address_lb_switch, private_ip]} ###################################################################### # # resources that expose the server group for all nodes include master # and minions. # nodes_server_group: type: OS::Nova::ServerGroup properties: policies: [{get_param: nodes_affinity_policy}] ###################################################################### # # Swarm manager is responsible for the entire cluster and manages the # resources of multiple Docker hosts at scale. # It supports high availability by create a primary manager and multiple # replica instances. swarm_primary_master: type: "OS::Heat::ResourceGroup" depends_on: - network properties: count: 1 resource_def: type: swarmmaster.yaml properties: name: list_join: - '-' - [{ get_param: 'OS::stack_name' }, 'primary-master', '%index%'] is_primary_master: True ssh_key_name: {get_param: ssh_key_name} server_image: {get_param: server_image} server_flavor: {get_param: master_flavor} docker_volume_size: {get_param: docker_volume_size} docker_volume_type: {get_param: docker_volume_type} docker_storage_driver: {get_param: docker_storage_driver} fixed_network_id: {get_attr: [network, fixed_network]} fixed_subnet_id: {get_attr: [network, fixed_subnet]} external_network: {get_param: external_network} http_proxy: {get_param: http_proxy} https_proxy: {get_param: https_proxy} no_proxy: {get_param: no_proxy} swarm_api_ip: {get_attr: [api_lb, address]} cluster_uuid: {get_param: cluster_uuid} magnum_url: {get_param: magnum_url} tls_disabled: {get_param: tls_disabled} secgroup_swarm_master_id: {get_resource: secgroup_swarm_manager} swarm_port: {get_param: swarm_port} api_pool_id: {get_attr: [api_lb, pool_id]} api_ip_address: {get_attr: [api_lb, floating_address]} trustee_user_id: {get_param: trustee_user_id} trustee_password: {get_param: trustee_password} trust_id: {get_param: trust_id} auth_url: {get_param: auth_url} volume_driver: {get_param: volume_driver} rexray_preempt: {get_param: rexray_preempt} verify_ca: {get_param: verify_ca} openstack_ca: {get_param: openstack_ca} nodes_server_group_id: {get_resource: nodes_server_group} availability_zone: {get_param: availability_zone} swarm_secondary_masters: type: "OS::Heat::ResourceGroup" depends_on: - network - swarm_primary_master properties: count: {get_param: number_of_secondary_masters} resource_def: type: swarmmaster.yaml properties: name: list_join: - '-' - [{ get_param: 'OS::stack_name' }, 'secondary-master', '%index%'] ssh_key_name: {get_param: ssh_key_name} server_image: {get_param: server_image} server_flavor: {get_param: master_flavor} docker_volume_size: {get_param: docker_volume_size} docker_volume_type: {get_param: docker_volume_type} docker_storage_driver: {get_param: docker_storage_driver} fixed_network_id: {get_attr: [network, fixed_network]} fixed_subnet_id: {get_attr: [network, fixed_subnet]} external_network: {get_param: external_network} http_proxy: {get_param: http_proxy} https_proxy: {get_param: https_proxy} no_proxy: {get_param: no_proxy} swarm_api_ip: {get_attr: [api_address_lb_switch, private_ip]} cluster_uuid: {get_param: cluster_uuid} magnum_url: {get_param: magnum_url} tls_disabled: {get_param: tls_disabled} secgroup_swarm_master_id: {get_resource: secgroup_swarm_manager} swarm_port: {get_param: swarm_port} api_pool_id: {get_attr: [api_lb, pool_id]} api_ip_address: {get_attr: [api_lb, floating_address]} trustee_user_id: {get_param: trustee_user_id} trustee_password: {get_param: trustee_password} trust_id: {get_param: trust_id} auth_url: {get_param: auth_url} volume_driver: {get_param: volume_driver} rexray_preempt: {get_param: rexray_preempt} verify_ca: {get_param: verify_ca} openstack_ca: {get_param: openstack_ca} nodes_server_group_id: {get_resource: nodes_server_group} availability_zone: {get_param: availability_zone} swarm_nodes: type: "OS::Heat::ResourceGroup" depends_on: - network - swarm_primary_master properties: count: {get_param: number_of_nodes} resource_def: type: swarmnode.yaml properties: name: list_join: - '-' - [{ get_param: 'OS::stack_name' }, 'node', '%index%'] ssh_key_name: {get_param: ssh_key_name} server_image: {get_param: server_image} server_flavor: {get_param: node_flavor} docker_volume_size: {get_param: docker_volume_size} docker_volume_type: {get_param: docker_volume_type} docker_storage_driver: {get_param: docker_storage_driver} fixed_network_id: {get_attr: [network, fixed_network]} fixed_subnet_id: {get_attr: [network, fixed_subnet]} external_network: {get_param: external_network} http_proxy: {get_param: http_proxy} https_proxy: {get_param: https_proxy} no_proxy: {get_param: no_proxy} swarm_api_ip: {get_attr: [api_address_lb_switch, private_ip]} cluster_uuid: {get_param: cluster_uuid} magnum_url: {get_param: magnum_url} tls_disabled: {get_param: tls_disabled} secgroup_swarm_node_id: {get_resource: secgroup_swarm_node} api_ip_address: {get_attr: [api_address_lb_switch, public_ip]} trustee_domain_id: {get_param: trustee_domain_id} trustee_user_id: {get_param: trustee_user_id} trustee_username: {get_param: trustee_username} trustee_password: {get_param: trustee_password} trust_id: {get_param: trust_id} auth_url: {get_param: auth_url} volume_driver: {get_param: volume_driver} rexray_preempt: {get_param: rexray_preempt} verify_ca: {get_param: verify_ca} openstack_ca: {get_param: openstack_ca} nodes_server_group_id: {get_resource: nodes_server_group} availability_zone: {get_param: availability_zone} outputs: api_address: value: str_replace: template: api_ip_address params: api_ip_address: {get_attr: [api_address_floating_switch, ip_address]} description: > This is the API endpoint of the Swarm masters. Use this to access the Swarm API server from outside the cluster. swarm_primary_master_private: value: {get_attr: [swarm_primary_master, swarm_master_ip]} description: > This is a list of the "private" addresses of all the Swarm masters. swarm_primary_master: value: {get_attr: [swarm_primary_master, swarm_master_external_ip]} description: > This is a list of "public" ip addresses of all Swarm masters. Use these addresses to log into the Swarm masters via ssh. swarm_secondary_masters: value: {get_attr: [swarm_secondary_masters, swarm_master_external_ip]} description: > This is a list of "public" ip addresses of all Swarm masters. Use these addresses to log into the Swarm masters via ssh. swarm_nodes_private: value: {get_attr: [swarm_nodes, swarm_node_ip]} description: > This is a list of the "private" addresses of all the Swarm nodes. swarm_nodes: value: {get_attr: [swarm_nodes, swarm_node_external_ip]} description: > This is a list of the "public" addresses of all the Swarm nodes. Use these addresses to, e.g., log into the nodes.