upstream/openstack/python-heat/python-heat/templates/hot/scenarios/CFNPushStatsAutoScaling.yaml

306 lines
12 KiB
YAML

# Copyright (c) 2013 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
################################################################################
#
# Objective:
# Demonstrates creating:
# An autoscaling stack of VMs that use cfn-push-stats to emit samples from
# within the guest.
# The name of the stack will prefix the custom meter
# This template requires OAM network setup properly to allow communication
# between the VMs to the controller
#
# Pre-Reqs:
# The VM must be able to communicate with the controller
# Normal lab setup. Capable of launching 3 VMs
# A keypair called: controller-0. (nova keypair-list)
# A flavor called: small (nova flavor-list)
# A glance image called: tis-centos-guest (glance image-list)
# A network called: internal-net0 (neutron net-list)
# A nested template file CFNPushStats.yaml in the same folder as this yaml.
#
# Optional Template Parameters:
# KEYPAIR: A keypair setup for the current user (nova keypair-list)
# KEYPAIR_ADMIN_USER: Name of user to inject ssh keys from keypair on the VM
# FLAVOR: A nova flavor name or UUID for the VMs (nova flavor-list)
# IMAGE: A glance image name or UUID for launching the VMs
# (glance image-list)
# PUBLIC_NETWORK: Name or UUID of the public network to use for the VMs
# (neutron net-list)
# INTERNAL_NETWORK: Name or UUID of the internal network to use for the VMs
# (neutron net-list)
# METER_NAME: Name of the new ceilometer meter to use to trigger autoscaling
# METER_UNIT: Unit of the new ceilometer meter to use to trigger autoscaling
# HIGH_VALUE: Value for the meter to trigger a scale up.
# LOW_VALUE: Value for the meter to trigger a scale down.
#
# Tenant Considerations:
# This template must be run as Admin
#
# Sample CLI syntax:
# heat stack-create -f CFNPushStatsAutoScale.yaml STACK
#
# Expected Outcome:
# VMs running the guest image (nova list)
# New ceilometer alarm triggers (ceilometer alarm-list)
# New ceilometer meters (ceilometer meter-list) created from within the VM
#
################################################################################
heat_template_version: 2015-04-30
description: >
Demonstrates autoscaling VMs that use cfn-push-stats
to emit ceilometer meters from within the VM
parameters:
KEYPAIR:
description: keypair to use. (nova keypair-list)
type: string
default: controller-0
constraints:
- custom_constraint: nova.keypair
KEYPAIR_ADMIN_USER:
description: Name of user account to inject ssh keys from keypair
type: string
default: 'ec2-user'
FLAVOR:
description: Nova flavor to use. (nova flavor-list)
type: string
default: small
constraints:
- custom_constraint: nova.flavor
IMAGE:
description: Glance image to create a cinder volume (glance image-list)
type: string
default: tis-centos-guest
constraints:
- custom_constraint: glance.image
PUBLIC_NETWORK:
description: Name of public network to use for VMs (neutron net-list)
type: string
default: public-net0
constraints:
- custom_constraint: neutron.network
INTERNAL_NETWORK:
description: Name of internal network to use for VMs (neutron net-list)
type: string
default: internal-net0
constraints:
- custom_constraint: neutron.network
METER_NAME:
description: Ceilometer meter to query when determining autoscaling
type: string
default: vm_stat
METER_UNIT:
description: Name for custom meter to be created using cfn-push-stats
type: string
default: '%'
HIGH_VALUE:
description: Metric value that will trigger a scale up if exceeded
type: string
default: '80'
LOW_VALUE:
description: Metric value that will trigger a scale down if below
type: string
default: '30'
resources:
CfnUser:
type: AWS::IAM::User
WebKeys:
type: AWS::IAM::AccessKey
properties:
UserName: { get_resource: CfnUser }
ScaleUpPolicy:
type: OS::Heat::ScalingPolicy
properties:
adjustment_type: change_in_capacity
auto_scaling_group_id: { get_resource: ScalingGroup }
cooldown: 60
scaling_adjustment: 1
ScaleDownPolicy:
type: OS::Heat::ScalingPolicy
properties:
adjustment_type: change_in_capacity
auto_scaling_group_id: { get_resource: ScalingGroup }
cooldown: 60
scaling_adjustment: -1
# Matching metadata is not compatible with cfn-push-stats
AlarmHigh:
type: OS::Ceilometer::Alarm
properties:
meter_name:
list_join:
- "_"
- - { get_param: 'OS::stack_name'}
- { get_param: METER_NAME }
statistic: avg
period: 60
evaluation_periods: 1
threshold: { get_param: HIGH_VALUE }
alarm_actions:
- {get_attr: [ScaleUpPolicy, alarm_url]}
comparison_operator: gt
AlarmLow:
type: OS::Ceilometer::Alarm
properties:
meter_name:
list_join:
- "_"
- - { get_param: 'OS::stack_name'}
- { get_param: METER_NAME }
statistic: avg
period: 60
evaluation_periods: 1
threshold: { get_param: LOW_VALUE }
alarm_actions:
- {get_attr: [ScaleDownPolicy, alarm_url]}
comparison_operator: lt
ScalingGroup:
type: OS::Heat::AutoScalingGroup
properties:
cooldown: 60
desired_capacity: 1
max_size: 3
min_size: 1
resource:
type: OS::Nova::Server
# Special Note: CFN related metadata is located at the resource
# level (not as a property)
metadata:
wrs-groupindex-mode: true
AWS::CloudFormation::Init:
config:
files:
/etc/cfn/cfn-credentials:
content:
str_replace:
template: |
AWSAccessKeyId=_keyid_
AWSSecretKey=_secret_
params:
_keyid_:
get_resource: WebKeys
_secret_:
get_attr:
- WebKeys
- SecretAccessKey
mode: '000400'
owner: root
group: root
/etc/cfn/make_load:
content: |
#!/bin/sh
# Generate maximum CPU load for a core
# Launch this X times for X cores
# to get 100% utilization
dd if=/dev/urandom of=/dev/null &
mode: '000700'
owner: root
group: root
/etc/cfn/get_cpu_load:
content: |
#!/usr/bin/python
# Get the 1 minute CPU load average and
# divide by num cores
import os
cores = 1
n = os.sysconf("SC_NPROCESSORS_ONLN")
if isinstance(n, int) and n > 0:
cores = n
l_avg = float(os.getloadavg()[0])
# convert to a percentage
pct = (100 * l_avg) / float(cores)
print pct
mode: '000700'
owner: root
group: root
/etc/cfn/send_guest_metrics:
content:
str_replace:
template: |
#!/bin/sh
METRIC=`/etc/cfn/get_cpu_load`
/opt/aws/bin/cfn-push-stats --metric _metername_ --value ${METRIC} --units _unit_
params:
_metername_:
list_join:
- "_"
- - { get_param: 'OS::stack_name' }
- { get_param: METER_NAME }
_unit_:
get_param: METER_UNIT
mode: '000700'
owner: root
group: root
/etc/cron.d/cfn_cron:
content: |
* * * * * root /etc/cfn/send_guest_metrics
mode: '000600'
owner: root
group: root
properties:
name:
list_join:
- "_"
- - { get_param: 'OS::stack_name'}
- "vm"
- ""
key_name: { get_param: KEYPAIR }
admin_user: { get_param: KEYPAIR_ADMIN_USER }
flavor: { get_param: FLAVOR }
image: { get_param: IMAGE }
networks:
- network: { get_param: PUBLIC_NETWORK }
- network: { get_param: INTERNAL_NETWORK }
# HEAT_CFNTOOLS includes Resource Metadata in the user-data
# automatically and expects the format to comply with
# AWS::CloudFormation::Init
user_data_format: HEAT_CFNTOOLS
user_data: |
#!/bin/bash -v
# Create sym links to standard location for cfn tools
# in an aws environment
echo "Setting up symlinks" >> /var/log/heat_setup.txt
cfn-create-aws-symlinks --source /usr/bin
# invoke cfn-init which will extract cloudformation
# metadata from the userdata
echo "Running cfn-init " >> /var/log/heat_setup.txt
/usr/bin/cfn-init >> /var/log/heat_setup.txt
echo "Done cfn-init setup" >> /var/log/heat_setup.txt
outputs:
ceilometer_query:
value:
str_replace:
template: ceilometer statistics -m metername -p 60 -a avg
params:
metername:
list_join:
- "_"
- - { get_param: 'OS::stack_name' }
- { get_param: METER_NAME }