heat_template_version: 2016-10-14 description: AutoScaling Wordpress parameters: image: type: string description: Image used for servers key: type: string description: SSH key to connect to the servers flavor: type: string description: flavor used by the web servers database_flavor: type: string description: flavor used by the db server network: type: string description: Network used by the server subnet_id: type: string description: subnet on which the load balancer will be located database_name: type: string description: Name of the wordpress DB default: wordpress database_user: type: string description: Name of the wordpress user default: wordpress external_network_id: type: string description: UUID of a Neutron external network resources: database_password: type: OS::Heat::RandomString database_root_password: type: OS::Heat::RandomString db: type: OS::Nova::Server properties: flavor: {get_param: database_flavor} image: {get_param: image} key_name: {get_param: key} networks: [{network: {get_param: network} }] user_data_format: RAW user_data: str_replace: template: | #!/bin/bash -v yum -y install mariadb mariadb-server systemctl enable mariadb.service systemctl start mariadb.service 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_attr: [database_root_password, value]} $db_name: {get_param: database_name} $db_user: {get_param: database_user} $db_password: {get_attr: [database_password, value]} asg: type: OS::Heat::AutoScalingGroup properties: min_size: 1 max_size: 3 resource: type: lb_server.yaml properties: flavor: {get_param: flavor} image: {get_param: image} key_name: {get_param: key} network: {get_param: network} subnet: {get_param: subnet_id} pool_id: {get_resource: pool} metadata: {"metering.server_group": {get_param: "OS::stack_id"}} user_data: str_replace: template: | #!/bin/bash -v yum -y install httpd wordpress systemctl enable httpd.service systemctl start httpd.service setsebool -P httpd_can_network_connect_db=1 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_host/ /etc/wordpress/wp-config.php systemctl restart httpd.service params: $db_name: {get_param: database_name} $db_user: {get_param: database_user} $db_password: {get_attr: [database_password, value]} $db_host: {get_attr: [db, first_address]} web_server_scaleup_policy: type: OS::Heat::ScalingPolicy properties: adjustment_type: change_in_capacity auto_scaling_group_id: {get_resource: asg} 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: asg} cooldown: 60 scaling_adjustment: -1 cpu_alarm_high: type: OS::Aodh::GnocchiAggregationByResourcesAlarm properties: description: Scale up if CPU > 80% metric: cpu_util aggregation_method: mean granularity: 300 evaluation_periods: 1 threshold: 80 resource_type: instance comparison_operator: gt alarm_actions: - str_replace: template: trust+url params: url: {get_attr: [web_server_scaleup_policy, signal_url]} query: list_join: - '' - - {'=': {server_group: {get_param: "OS::stack_id"}}} cpu_alarm_low: type: OS::Aodh::GnocchiAggregationByResourcesAlarm properties: description: Scale down if CPU < 15% for 5 minutes metric: cpu_util aggregation_method: mean granularity: 300 evaluation_periods: 1 threshold: 15 resource_type: instance comparison_operator: lt alarm_actions: - str_replace: template: trust+url params: url: {get_attr: [web_server_scaledown_policy, signal_url]} query: list_join: - '' - - {'=': {server_group: {get_param: "OS::stack_id"}}} lb: type: OS::Octavia::LoadBalancer properties: vip_subnet: {get_param: subnet_id} listener: type: OS::Octavia::Listener properties: loadbalancer: {get_resource: lb} protocol: HTTP protocol_port: 80 pool: type: OS::Octavia::Pool properties: listener: {get_resource: listener} lb_algorithm: ROUND_ROBIN protocol: HTTP session_persistence: type: SOURCE_IP lb_monitor: type: OS::Octavia::HealthMonitor properties: pool: { get_resource: pool } type: TCP delay: 5 max_retries: 5 timeout: 5 # assign a floating ip address to the load balancer # pool. lb_floating: type: OS::Neutron::FloatingIP properties: floating_network_id: {get_param: external_network_id} port_id: {get_attr: [lb, vip_port_id]} outputs: scale_up_url: description: > This URL is the webhook to scale up the autoscaling group. You can invoke the scale-up operation by doing an HTTP POST to this URL; no body nor extra headers are needed. value: {get_attr: [web_server_scaleup_policy, alarm_url]} scale_dn_url: description: > This URL is the webhook to scale down the autoscaling group. You can invoke the scale-down operation by doing an HTTP POST to this URL; no body nor extra headers are needed. value: {get_attr: [web_server_scaledown_policy, alarm_url]} pool_ip_address: value: {get_attr: [lb, vip_address]} description: The IP address of the load balancing pool website_url: value: str_replace: template: http://host/wordpress/ params: host: { get_attr: [lb_floating, floating_ip_address] } description: > This URL is the "external" URL that can be used to access the Wordpress site. gnocchi_query: value: str_replace: template: > gnocchi measures aggregation --resource-type instance --query 'server_group="stackval"' --granularity 300 --aggregation mean -m cpu_util params: stackval: { get_param: "OS::stack_id" } description: > This is a Gnocchi query for statistics on the cpu_util measurements about OS::Nova::Server instances in this stack. The --resource-type select the type of Gnocchi resource. The --query parameter filters resources according to its attributes. When a VM's metadata includes an item of the form metering.server_group=X, the corresponding Gnocchi resource has a attribute named server_group that can queried with 'server_group="X"' In this case the nested stacks give their VMs metadata that is passed as a nested stack parameter, and this stack passes a metadata of the form metering.server_group=X, where X is this stack's ID.