heat_template_version: 2013-05-23
description: >
  HOT template to deploy two servers (database and web server) into an existing
  neutron tenant network and create a load balancer.  The load balancer will be 
  assigned a floating IP addresses to route traffic from the internet to the web
  servers.  Alarms ar create to scale the web server up and down based on CPU
  utilization rates.
parameters:
  key_name:
    type: string
    description: Name of keypair to assign to servers
    default: as
  image:
    type: string
    description: Name of image to use for servers
    default: ebdd698d-acaf-4272-952e-cbbd4f7e6205
    constraints:
      - allowed_values: [ebdd698d-acaf-4272-952e-cbbd4f7e6205]
        description: Image ID must be rhel6.5-x86_64
  flavor:
    type: string
    description: Flavor to use for servers
    default: m1.tiny
    constraints:
      - allowed_values: [m1.tiny, m1.medium]
  db_name:
    type: string
    description: WordPress database name
    default: wordpress
    constraints:
      - length: { min: 1, max: 64 }
        description: db_name must be between 1 and 64 characters
      - allowed_pattern: '[a-zA-Z][a-zA-Z0-9]*'
        description: >
          db_name must begin with a letter and contain only alphanumeric
          characters
  db_username:
    type: string
    description: The WordPress database admin account username
    default: admin
    hidden: true
    constraints:
      - length: { min: 1, max: 16 }
        description: db_username must be between 1 and 64 characters
      - allowed_pattern: '[a-zA-Z][a-zA-Z0-9]*'
        description: >
          db_username must begin with a letter and contain only alphanumeric
          characters
  db_password:
    type: string
    description: The WordPress database admin account password
    default: admin
    hidden: true
    constraints:
      - length: { min: 1, max: 41 }
        description: db_username must be between 1 and 64 characters
      - allowed_pattern: '[a-zA-Z0-9]*'
        description: db_password must contain only alphanumeric characters
  db_root_password:
    type: string
    description: Root password for MySQL
    default: admin
    hidden: true
    constraints:
      - length: { min: 1, max: 41 }
        description: db_username must be between 1 and 64 characters
      - allowed_pattern: '[a-zA-Z0-9]*'
        description: db_password must contain only alphanumeric characters
  public_net_id:
    type: string
    description: ID of public network for which floating IP addresses will be allocated
    default: f953d55d-d4af-41d6-baf8-42f15aaa9b6b
  private_net_id:
    type: string
    description: ID of private network into which servers get deployed
    default: 401a1c69-5b3b-4d11-a43f-c6e4a6e447c1
  private_subnet_id:
    type: string
    description: ID of private sub network into which servers get deployed
    default: 3de3aeb8-79ff-478a-adae-791093de61ef
resources:
  wp_dbserver:
    type: OS::Nova::Server
    properties:
      name: wp_dbserver
      image: { get_param: image }
      flavor: { get_param: flavor }
      key_name: { get_param: key_name }
      networks:
        - port: { get_resource: wp_dbserver_port }
      user_data:
        str_replace:
          template: |
            #!/bin/bash -v
 
            lokkit --port=3306:tcp
             
            cat << EOF > /etc/yum.repos.d/local.repo
            [wordpress]
            name=WordPress for Enterprise Linux 6 
            baseurl=http://192.168.0.1/repos/wordpress_rhel6
            enabled=1
            gpgcheck=0
            EOF
 
            yum -y install mysql mysql-server 
            chkconfig mysqld on
            service mysqld start
             
            # Setup MySQL root password and create a user
            mysqladmin -u root password db_rootpassword
            cat << EOF | mysql -u root --password=db_rootpassword
            CREATE DATABASE db_name;
            GRANT ALL PRIVILEGES ON db_name.* TO "db_user"@"%" IDENTIFIED BY "db_password";
            FLUSH PRIVILEGES;
            EXIT
            EOF
          params:
            db_rootpassword: { get_param: db_root_password }
            db_name: { get_param: db_name }
            db_user: { get_param: db_username }
            db_password: { get_param: db_password }
  wp_dbserver_port:
    type: OS::Neutron::Port
    properties:
      network_id: { get_param: private_net_id }
      fixed_ips:
        - subnet_id: { get_param: private_subnet_id }
  web_server_group:
    type: OS::Heat::AutoScalingGroup
    properties:
      min_size: 1
      max_size: 3
      resource:
        type: http://10.233.28.82/templates/lb_server.yaml
        properties:
          flavor: {get_param: flavor}
          image: {get_param: image}
          key_name: {get_param: key_name}
          pool_id: {get_resource: pool}
          metadata: {"metering.stack": {get_param: "OS::stack_id"}}
          user_data:
            str_replace:
              template: |
                #!/bin/bash -v
 
                lokkit --service=http                
 
                cat << EOF > /etc/yum.repos.d/local.repo
                [wordpress]
                name=WordPress for Enterprise Linux 6 
                baseurl=http://192.168.0.1/repos/wordpress_rhel6
                enabled=1
                gpgcheck=0
                EOF
 
                yum -y install httpd wordpress
                setsebool -P httpd_can_network_connect=1
                chkconfig httpd on
                service httpd start
 
                sed -i "/Deny from All/d" /etc/httpd/conf.d/wordpress.conf
                sed -i "s/Require local/Require all granted/" /etc/httpd/conf.d/wordpress.conf
                sed -i s/database_name_here/db_name/ /etc/wordpress/wp-config.php
                sed -i s/username_here/db_user/ /etc/wordpress/wp-config.php
                sed -i s/password_here/db_password/ /etc/wordpress/wp-config.php
                sed -i s/localhost/db_address/ /etc/wordpress/wp-config.php
 
                service httpd restart
              params:
                db_name: { get_param: db_name }
                db_user: { get_param: db_username }
                db_password: { get_param: db_password }
                db_address: { get_attr: [ wp_dbserver, first_address ] }
  web_server_scaleup_policy:
    type: OS::Heat::ScalingPolicy
    properties:
      adjustment_type: change_in_capacity
      auto_scaling_group_id: {get_resource: web_server_group}
      cooldown: 60
      scaling_adjustment: 1
 
  web_server_scaledown_policy:
    type: OS::Heat::ScalingPolicy
    properties:
      adjustment_type: change_in_capacity
      auto_scaling_group_id: {get_resource: web_server_group}
      cooldown: 60
      scaling_adjustment: -1
  cpu_alarm_high:
    type: OS::Ceilometer::Alarm
    properties:
      description: Scale-up if the average CPU > 50% for 1 minute
      meter_name: cpu_util
      statistic: avg
      period: 60
      evaluation_periods: 1
      threshold: 50
      alarm_actions:
      - {get_attr: [web_server_scaleup_policy, alarm_url]}
      matching_metadata: {'metadata.user_metadata.stack': {get_param: "OS::stack_id"}}
      comparison_operator: gt
 
  cpu_alarm_low:
    type: OS::Ceilometer::Alarm
    properties:
      description: Scale-down if the average CPU < 15% for 10 minutes
      meter_name: cpu_util
      statistic: avg
      period: 600
      evaluation_periods: 1
      threshold: 15
      alarm_actions:
      - {get_attr: [web_server_scaledown_policy, alarm_url]}
      matching_metadata: {'metadata.user_metadata.stack': {get_param: "OS::stack_id"}}
      comparison_operator: lt
  lb_vip_port:
    type: OS::Neutron::Port
    properties:
      network_id: { get_param: private_net_id }
      fixed_ips:
      - subnet_id: { get_param: private_subnet_id }
 
  lb_vip_floating_ip:
    type: OS::Neutron::FloatingIP
    properties:
      floating_network_id: { get_param: public_net_id }  
      port_id: { get_resource: lb_vip_port }
 
  lb_pool_vip:
    type: OS::Neutron::FloatingIPAssociation
    properties:
      floatingip_id: { get_resource: lb_vip_floating_ip }
      port_id: { 'Fn::Select': ['port_id', {get_attr: [pool, vip]}]}
 
  monitor:
    type: OS::Neutron::HealthMonitor
    properties:
      type: TCP
      delay: 3
      max_retries: 5
      timeout: 5
 
  pool:
    type: OS::Neutron::Pool
    properties:
      protocol: HTTP
      monitors: [{get_resource: monitor}]
      subnet_id: {get_param: private_subnet_id}
      lb_method: ROUND_ROBIN
      vip:
        protocol_port: 80
      ## session_persistence:
      ##   type: SOURCE_IP
 
  lb:
    type: OS::Neutron::LoadBalancer
    properties:
      protocol_port: 80
      pool_id: {get_resource: pool}
