heat_template_version: 2014-10-16

description: OpenShift cluster

parameters:

  cluster_env:
    type: string
    label: Cluster environment
    description: Environment of the cluster

  cluster_id:
    type: string
    label: Cluster ID
    description: Identifier of the cluster

  subnet_24_prefix:
    type: string
    label: subnet /24 prefix
    description: /24 subnet prefix of the network of the cluster (dot separated number triplet)

  dns_nameservers:
    type: comma_delimited_list
    label: DNS nameservers list
    description: List of DNS nameservers

  external_net:
    type: string
    label: External network
    description: Name of the external network
    default: external

  ssh_public_key:
    type: string
    label: SSH public key
    description: SSH public key
    hidden: true

  ssh_incoming:
    type: string
    label: Source of ssh connections
    description: Source of legitimate ssh connections
    default: 0.0.0.0/0

  node_port_incoming:
    type: string
    label: Source of node port connections
    description: Authorized sources targeting node ports
    default: 0.0.0.0/0

  num_etcd:
    type: number
    label: Number of etcd nodes
    description: Number of etcd nodes

  num_masters:
    type: number
    label: Number of masters
    description: Number of masters

  num_nodes:
    type: number
    label: Number of compute nodes
    description: Number of compute nodes

  num_infra:
    type: number
    label: Number of infrastructure nodes
    description: Number of infrastructure nodes

  etcd_image:
    type: string
    label: Etcd image
    description: Name of the image for the etcd servers

  master_image:
    type: string
    label: Master image
    description: Name of the image for the master servers

  node_image:
    type: string
    label: Node image
    description: Name of the image for the compute node servers

  infra_image:
    type: string
    label: Infra image
    description: Name of the image for the infra node servers

  etcd_flavor:
    type: string
    label: Etcd flavor
    description: Flavor of the etcd servers

  master_flavor:
    type: string
    label: Master flavor
    description: Flavor of the master servers

  node_flavor:
    type: string
    label: Node flavor
    description: Flavor of the compute node servers

  infra_flavor:
    type: string
    label: Infra flavor
    description: Flavor of the infra node servers

outputs:

  etcd_names:
    description: Name of the etcds
    value: { get_attr: [ etcd, name ] }

  etcd_ips:
    description: IPs of the etcds
    value: { get_attr: [ etcd, private_ip ] }

  etcd_floating_ips:
    description: Floating IPs of the etcds
    value: { get_attr: [ etcd, floating_ip ] }

  master_names:
    description: Name of the masters
    value: { get_attr: [ masters, name ] }

  master_ips:
    description: IPs of the masters
    value: { get_attr: [ masters, private_ip ] }

  master_floating_ips:
    description: Floating IPs of the masters
    value: { get_attr: [ masters, floating_ip ] }

  node_names:
    description: Name of the nodes
    value: { get_attr: [ compute_nodes, name ] }

  node_ips:
    description: IPs of the nodes
    value: { get_attr: [ compute_nodes, private_ip ] }

  node_floating_ips:
    description: Floating IPs of the nodes
    value: { get_attr: [ compute_nodes, floating_ip ] }

  infra_names:
    description: Name of the nodes
    value: { get_attr: [ infra_nodes, name ] }

  infra_ips:
    description: IPs of the nodes
    value: { get_attr: [ infra_nodes, private_ip ] }

  infra_floating_ips:
    description: Floating IPs of the nodes
    value: { get_attr: [ infra_nodes, floating_ip ] }

resources:

  net:
    type: OS::Neutron::Net
    properties:
      name:
        str_replace:
          template: openshift-ansible-cluster_id-net
          params:
            cluster_id: { get_param: cluster_id }

  subnet:
    type: OS::Neutron::Subnet
    properties:
      name:
        str_replace:
          template: openshift-ansible-cluster_id-subnet
          params:
            cluster_id: { get_param: cluster_id }
      network: { get_resource: net }
      cidr:
        str_replace:
          template: subnet_24_prefix.0/24
          params:
            subnet_24_prefix: { get_param: subnet_24_prefix }
      dns_nameservers: { get_param: dns_nameservers }

  router:
    type: OS::Neutron::Router
    properties:
      name:
        str_replace:
          template: openshift-ansible-cluster_id-router
          params:
            cluster_id: { get_param: cluster_id }
      external_gateway_info:
        network: { get_param: external_net }

  interface:
    type: OS::Neutron::RouterInterface
    properties:
      router_id: { get_resource: router }
      subnet_id: { get_resource: subnet }

  keypair:
    type: OS::Nova::KeyPair
    properties:
      name:
        str_replace:
          template: openshift-ansible-cluster_id-keypair
          params:
            cluster_id: { get_param: cluster_id }
      public_key: { get_param: ssh_public_key }

  master-secgrp:
    type: OS::Neutron::SecurityGroup
    properties:
      name:
        str_replace:
          template: openshift-ansible-cluster_id-master-secgrp
          params:
            cluster_id: { get_param: cluster_id }
      description:
        str_replace:
          template: Security group for cluster_id OpenShift cluster master
          params:
            cluster_id: { get_param: cluster_id }
      rules:
        - direction: ingress
          protocol: tcp
          port_range_min: 22
          port_range_max: 22
          remote_ip_prefix: { get_param: ssh_incoming }
        - direction: ingress
          protocol: tcp
          port_range_min: 4001
          port_range_max: 4001
        - direction: ingress
          protocol: tcp
          port_range_min: 8443
          port_range_max: 8443
        - direction: ingress
          protocol: tcp
          port_range_min: 8444
          port_range_max: 8444
        - direction: ingress
          protocol: tcp
          port_range_min: 53
          port_range_max: 53
        - direction: ingress
          protocol: udp
          port_range_min: 53
          port_range_max: 53
        - direction: ingress
          protocol: tcp
          port_range_min: 8053
          port_range_max: 8053
        - direction: ingress
          protocol: udp
          port_range_min: 8053
          port_range_max: 8053
        - direction: ingress
          protocol: tcp
          port_range_min: 24224
          port_range_max: 24224
        - direction: ingress
          protocol: udp
          port_range_min: 24224
          port_range_max: 24224
        - direction: ingress
          protocol: tcp
          port_range_min: 2224
          port_range_max: 2224
        - direction: ingress
          protocol: udp
          port_range_min: 5404
          port_range_max: 5404
        - direction: ingress
          protocol: udp
          port_range_min: 5405
          port_range_max: 5405
        - direction: ingress
          protocol: tcp
          port_range_min: 9090
          port_range_max: 9090

  etcd-secgrp:
    type: OS::Neutron::SecurityGroup
    properties:
      name:
        str_replace:
          template: openshift-ansible-cluster_id-etcd-secgrp
          params:
            cluster_id: { get_param: cluster_id }
      description:
        str_replace:
          template: Security group for cluster_id etcd cluster
          params:
            cluster_id: { get_param: cluster_id }
      rules:
        - direction: ingress
          protocol: tcp
          port_range_min: 22
          port_range_max: 22
          remote_ip_prefix: { get_param: ssh_incoming }
        - direction: ingress
          protocol: tcp
          port_range_min: 2379
          port_range_max: 2379
          remote_mode: remote_group_id
          remote_group_id: { get_resource: master-secgrp }
        - direction: ingress
          protocol: tcp
          port_range_min: 2380
          port_range_max: 2380
          remote_mode: remote_group_id

  node-secgrp:
    type: OS::Neutron::SecurityGroup
    properties:
      name:
        str_replace:
          template: openshift-ansible-cluster_id-node-secgrp
          params:
            cluster_id: { get_param: cluster_id }
      description:
        str_replace:
          template: Security group for cluster_id OpenShift cluster nodes
          params:
            cluster_id: { get_param: cluster_id }
      rules:
        - direction: ingress
          protocol: tcp
          port_range_min: 22
          port_range_max: 22
          remote_ip_prefix: { get_param: ssh_incoming }
        - direction: ingress
          protocol: tcp
          port_range_min: 10250
          port_range_max: 10250
          remote_mode: remote_group_id
        - direction: ingress
          protocol: udp
          port_range_min: 4789
          port_range_max: 4789
          remote_mode: remote_group_id
        - direction: ingress
          protocol: tcp
          port_range_min: 30000
          port_range_max: 32767
          remote_ip_prefix: { get_param: node_port_incoming }

  infra-secgrp:
    type: OS::Neutron::SecurityGroup
    properties:
      name:
        str_replace:
          template: openshift-ansible-cluster_id-infra-secgrp
          params:
            cluster_id: { get_param: cluster_id }
      description:
        str_replace:
          template: Security group for cluster_id OpenShift infrastructure cluster nodes
          params:
            cluster_id: { get_param: cluster_id }
      rules:
        - direction: ingress
          protocol: tcp
          port_range_min: 80
          port_range_max: 80
        - direction: ingress
          protocol: tcp
          port_range_min: 443
          port_range_max: 443

  etcd:
    type: OS::Heat::ResourceGroup
    properties:
      count: { get_param: num_etcd }
      resource_def:
        type: heat_stack_server.yaml
        properties:
          name:
            str_replace:
              template: cluster_id-k8s_type-%index%
              params:
                cluster_id: { get_param: cluster_id }
                k8s_type: etcd
          cluster_env: { get_param: cluster_env }
          cluster_id:  { get_param: cluster_id }
          type:        etcd
          image:       { get_param: etcd_image }
          flavor:      { get_param: etcd_flavor }
          key_name:    { get_resource: keypair }
          net:         { get_resource: net }
          subnet:      { get_resource: subnet }
          secgrp:
            - { get_resource: etcd-secgrp }
          floating_network: { get_param: external_net }
          net_name:
            str_replace:
              template: openshift-ansible-cluster_id-net
              params:
                cluster_id: { get_param: cluster_id }
    depends_on:
      - interface

  masters:
    type: OS::Heat::ResourceGroup
    properties:
      count: { get_param: num_masters }
      resource_def:
        type: heat_stack_server.yaml
        properties:
          name:
            str_replace:
              template: cluster_id-k8s_type-%index%
              params:
                cluster_id: { get_param: cluster_id }
                k8s_type: master
          cluster_env: { get_param: cluster_env }
          cluster_id:  { get_param: cluster_id }
          type:        master
          image:       { get_param: master_image }
          flavor:      { get_param: master_flavor }
          key_name:    { get_resource: keypair }
          net:         { get_resource: net }
          subnet:      { get_resource: subnet }
          secgrp:
            - { get_resource: master-secgrp }
            - { get_resource: node-secgrp }
          floating_network: { get_param: external_net }
          net_name:
            str_replace:
              template: openshift-ansible-cluster_id-net
              params:
                cluster_id: { get_param: cluster_id }
    depends_on:
      - interface

  compute_nodes:
    type: OS::Heat::ResourceGroup
    properties:
      count: { get_param: num_nodes }
      resource_def:
        type: heat_stack_server.yaml
        properties:
          name:
            str_replace:
              template: cluster_id-k8s_type-sub_host_type-%index%
              params:
                cluster_id: { get_param: cluster_id }
                k8s_type: node
                sub_host_type: compute
          cluster_env: { get_param: cluster_env }
          cluster_id:  { get_param: cluster_id }
          type:        node
          subtype:     compute
          image:       { get_param: node_image }
          flavor:      { get_param: node_flavor }
          key_name:    { get_resource: keypair }
          net:         { get_resource: net }
          subnet:      { get_resource: subnet }
          secgrp:
            - { get_resource: node-secgrp }
          floating_network: { get_param: external_net }
          net_name:
            str_replace:
              template: openshift-ansible-cluster_id-net
              params:
                cluster_id: { get_param: cluster_id }
    depends_on:
      - interface

  infra_nodes:
    type: OS::Heat::ResourceGroup
    properties:
      count: { get_param: num_infra }
      resource_def:
        type: heat_stack_server.yaml
        properties:
          name:
            str_replace:
              template: cluster_id-k8s_type-sub_host_type-%index%
              params:
                cluster_id: { get_param: cluster_id }
                k8s_type: node
                sub_host_type: infra
          cluster_env: { get_param: cluster_env }
          cluster_id:  { get_param: cluster_id }
          type:        node
          subtype:     infra
          image:       { get_param: infra_image }
          flavor:      { get_param: infra_flavor }
          key_name:    { get_resource: keypair }
          net:         { get_resource: net }
          subnet:      { get_resource: subnet }
          secgrp:
            - { get_resource: node-secgrp }
            - { get_resource: infra-secgrp }
          floating_network: { get_param: external_net }
          net_name:
            str_replace:
              template: openshift-ansible-cluster_id-net
              params:
                cluster_id: { get_param: cluster_id }
    depends_on:
      - interface
