heat_template_version: 2014-10-16

description: >
  This template will boot a coreos cluster with one or more minions (as
  specified by the number_of_minions parameter, which defaults to 1) and one
  master node. Allowing multiple masters is a work in progress.

parameters:

  ssh_key_name:
    type: string
    description: name of ssh key to be provisioned on the servers

  external_network:
    type: string
    description: uuid/name of a network to use for floating ip addresses
    default: public

  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: ""

  server_image:
    type: string
    default: CoreOS
    description: glance image used to boot the servers

  master_flavor:
    type: string
    default: m1.small
    description: flavor to use when booting the server for master node

  minion_flavor:
    type: string
    default: m1.small
    description: flavor to use when booting the servers for minions

  discovery_url:
    type: string
    description: >
      Discovery URL used for bootstrapping the etcd cluster.

  dns_nameserver:
    type: string
    description: address of a dns nameserver reachable in your environment
    default: 8.8.8.8

  number_of_masters:
    type: number
    description: how many kubernetes masters to spawn
    default: 1

  number_of_minions:
    type: number
    description: how many kubernetes minions to spawn
    default: 1

  fixed_network_cidr:
    type: string
    description: network range for fixed ip network
    default: 10.0.0.0/24

  portal_network_cidr:
    type: string
    description: >
      address range used by kubernetes for service portals
    default: 10.254.0.0/16

  flannel_network_cidr:
    type: string
    description: network range for flannel overlay network
    default: 10.100.0.0/16

  flannel_network_subnetlen:
    type: number
    description: size of subnet assigned to each minion
    default: 24

  flannel_backend:
    type: string
    description: >
      specify the backend for flannel, default udp backend
    default: "udp"
    constraints:
      - allowed_values: ["udp", "vxlan", "host-gw"]

  system_pods_initial_delay:
    type: number
    description: >
      health check, time to wait for system pods (podmaster, scheduler) to boot
      (in seconds)
    default: 30

  system_pods_timeout:
    type: number
    description: >
      health check, timeout for system pods (podmaster, scheduler) to answer.
      (in seconds)
    default: 5

  kube_allow_priv:
    type: string
    description: >
      whether or not kubernetes should permit privileged containers.
    default: "true"
    constraints:
      - allowed_values: ["true", "false"]

  minions_to_remove:
    type: comma_delimited_list
    description: >
      List of minions to be removed when doing an update. Individual minion may
      be referenced several ways: (1) The resource name (e.g. ['1', '3']),
      (2) The private IP address ['10.0.0.4', '10.0.0.6']. Note: the list should
      be empty when doing a create.
    default: []

  network_driver:
    type: string
    description: network driver to use for instantiating container networks
    default: flannel

  tls_disabled:
    type: boolean
    description: whether or not to disable TLS
    default: False

  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"]

  kubernetes_port:
    type: number
    description: >
      The port which are used by kube-apiserver to provide Kubernetes
      service.
    default: 6443

  cluster_uuid:
    type: string
    description: identifier for the cluster this template is generating

  magnum_url:
    type: string
    description: endpoint to retrieve TLS certs from

  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: ""

  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

  kube_version:
    type: string
    description: version of kubernetes used for kubernetes cluster
    default: v1.2.0

  registry_enabled:
    type: boolean
    description: >
      Indicates whether the docker registry is enabled.
    default: false

  registry_port:
    type: number
    description: port of registry service
    default: 5000

  wait_condition_timeout:
    type: number
    description: >
      timeout for the Wait Conditions
    default: 6000

resources:

  ######################################################################
  #
  # network resources. allocate a network and router for our server.
  # Important: the Load Balancer feature in Kubernetes requires that
  # the name for the fixed_network must be "private" for the
  # address lookup in Kubernetes to work properly
  #

  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}
      private_network_name: private

  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: kubernetes_port}

  etcd_lb:
    type: ../../common/templates/lb.yaml
    properties:
      fixed_subnet: {get_attr: [network, fixed_subnet]}
      external_network: {get_param: external_network}
      protocol: HTTP
      port: 2379

 ######################################################################
  #
  # security groups.  we need to permit network traffic of various
  # sorts.
  #

  secgroup_master:
    type: OS::Neutron::SecurityGroup
    properties:
      rules:
        - protocol: icmp
        - protocol: tcp
          port_range_min: 22
          port_range_max: 22
        - protocol: tcp
          port_range_min: 7080
          port_range_max: 7080
        - protocol: tcp
          port_range_min: 8080
          port_range_max: 8080
        - protocol: tcp
          port_range_min: 2379
          port_range_max: 2379
        - protocol: tcp
          port_range_min: 2380
          port_range_max: 2380
        - protocol: tcp
          port_range_min: 6443
          port_range_max: 6443

  secgroup_minion_all_open:
    type: OS::Neutron::SecurityGroup
    properties:
      rules:
        - protocol: icmp
        - protocol: tcp
        - protocol: udp

  ######################################################################
  #
  # resources that expose the IPs of either the kube 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: [kube_masters, resource.0.kube_master_external_ip]}
      master_private_ip: {get_attr: [kube_masters, resource.0.kube_master_ip]}

  etcd_address_lb_switch:
    type: Magnum::ApiGatewaySwitcher
    properties:
      pool_private_ip: {get_attr: [etcd_lb, address]}
      master_private_ip: {get_attr: [kube_masters, resource.0.kube_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]}

  ######################################################################
  #
  # kubernetes masters. This is a resource group that will create
  # <number_of_masters> master.
  #

  kube_masters:
    type: OS::Heat::ResourceGroup
    depends_on:
      - network
    properties:
      count: {get_param: number_of_masters}
      resource_def:
        type: kubemaster.yaml
        properties:
          api_public_address: {get_attr: [api_lb, floating_address]}
          api_private_address: {get_attr: [api_lb, address]}
          ssh_key_name: {get_param: ssh_key_name}
          server_image: {get_param: server_image}
          master_flavor: {get_param: master_flavor}
          external_network: {get_param: external_network}
          kube_allow_priv: {get_param: kube_allow_priv}
          flannel_network_cidr: {get_param: flannel_network_cidr}
          flannel_network_subnetlen: {get_param: flannel_network_subnetlen}
          flannel_backend: {get_param: flannel_backend}
          system_pods_initial_delay: {get_param: system_pods_initial_delay}
          system_pods_timeout: {get_param: system_pods_timeout}
          portal_network_cidr: {get_param: portal_network_cidr}
          fixed_network: {get_attr: [network, fixed_network]}
          fixed_subnet: {get_attr: [network, fixed_subnet]}
          discovery_url: {get_param: discovery_url}
          network_driver: {get_param: network_driver}
          kubernetes_port: {get_param: kubernetes_port}
          tls_disabled: {get_param: tls_disabled}
          secgroup_kube_master_id: {get_resource: secgroup_master}
          http_proxy: {get_param: http_proxy}
          https_proxy: {get_param: https_proxy}
          no_proxy: {get_param: no_proxy}
          kube_version: {get_param: kube_version}
          wait_condition_timeout: {get_param: wait_condition_timeout}
          cluster_uuid: {get_param: cluster_uuid}
          api_pool_id: {get_attr: [api_lb, pool_id]}
          etcd_pool_id: {get_attr: [etcd_lb, pool_id]}
          magnum_url: {get_param: magnum_url}
          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}

  ######################################################################
  #
  # kubernetes minions. This is a resource group that will initially
  # create <number_of_minions> minions, and needs to be manually scaled.
  #

  kube_minions:
    type: OS::Heat::ResourceGroup
    depends_on:
      - network
      - kube_masters
    properties:
      count: {get_param: number_of_minions}
      removal_policies: [{resource_list: {get_param: minions_to_remove}}]
      resource_def:
        type: kubeminion.yaml
        properties:
          ssh_key_name: {get_param: ssh_key_name}
          server_image: {get_param: server_image}
          minion_flavor: {get_param: minion_flavor}
          fixed_network: {get_attr: [network, fixed_network]}
          fixed_subnet: {get_attr: [network, fixed_subnet]}
          flannel_network_cidr: {get_param: flannel_network_cidr}
          kube_master_ip: {get_attr: [api_address_lb_switch, private_ip]}
          etcd_server_ip: {get_attr: [etcd_address_lb_switch, private_ip]}
          external_network: {get_param: external_network}
          kube_allow_priv: {get_param: kube_allow_priv}
          network_driver: {get_param: network_driver}
          kubernetes_port: {get_param: kubernetes_port}
          tls_disabled: {get_param: tls_disabled}
          secgroup_kube_minion_id: {get_resource: secgroup_minion_all_open}
          http_proxy: {get_param: http_proxy}
          https_proxy: {get_param: https_proxy}
          no_proxy: {get_param: no_proxy}
          kube_version: {get_param: kube_version}
          wait_condition_timeout: {get_param: wait_condition_timeout}
          cluster_uuid: {get_param: cluster_uuid}
          magnum_url: {get_param: magnum_url}
          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}

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 Kubernetes cluster. Use this to access
      the Kubernetes API.

  kube_masters_private:
    value: {get_attr: [kube_masters, kube_master_ip]}
    description: >
      This is a list of the "private" IP addresses of all the Kubernetes masters.

  kube_masters:
    value: {get_attr: [kube_masters, kube_master_external_ip]}
    description: >
      This is a list of the "public" IP addresses of all the Kubernetes masters.
      Use these IP addresses to log in to the Kubernetes masters via ssh or to access
      the Kubernetes API.

  kube_minions_private:
    value: {get_attr: [kube_minions, kube_minion_ip]}
    description: >
      This is a list of the "private" IP addresses of all the Kubernetes minions.

  kube_minions:
    value: {get_attr: [kube_minions, kube_minion_external_ip]}
    description: >
      This is a list of the "public" IP addresses of all the Kubernetes minions.
      Use these IP addresses to log in to the Kubernetes minions via ssh.
