Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Webhooks respond 'incomplete-signature'-error

Hi there,

as I wanted to check out the autoscaling features of heat in combination with ceilometer, I tried to adapt one of the example HOT's. Meanwhile, the HOT is starting successfully, but whatever I do to stress my VM in the web_server_group, no scaling reaction is observable.
Executing the webhook manually, there's an error response, which google hardly knows, so I try my best here - maybe you can help me to solve this problem.
Additionally I'm wondering, why AWS is mentioned in the error - actually I don't want to use it. Are webhooks only possible via AWS?

Core Issue:

 curl -XPOST -i http://xxx.xxx.xxx.xxx:8000/v1/signal/arn%3Aopenstack%3Aheat%3A%3A9036a06bb9f648beb8b4d4592e693735%3Astacks%2FTestStack%2F3d0054f4-401a-4578-b9fd-4b6374bc69b2%2Fresources%2Fweb_server_scaleup_policy?Timestamp=2014-11-06T02%3A47%3A19Z&SignatureMethod=HmacSHA256&AWSAccessKeyId=e4f6cefc18a34695b1aba1bd5e0bbb0a&SignatureVersion=2&Signature=dOjsDdfO37Ym0%2F3t5A1qzxNmrjfYHdohJZ%2FQ3HBJafU%3D
[1] 7073
[2] 7074
[3] 7075
[4] 7076
root@foo:/home/bar# HTTP/1.1 400 IncompleteSignature
Content-Type: application/xml; charset=UTF-8
Content-Length: 171
Date: Thu, 06 Nov 2014 03:11:55 GMT

<ErrorResponse><Error><Message>The request signature does not conform to AWS standards</Message><Code>IncompleteSignature</Code><Type>Sender</Type></Error></ErrorResponse>

Further specs:
Version OpenStack Icehouse VM: Ubuntu 14.04
stress command: 'stress --cpu 8 --io 8 --vm 2 --vm-bytes 256M &' causing permanent usage of ~60% CPU usage.

alarm:

ceilometer alarm-history -a 69edb170-c3d2-4e3e-98bb-40b99e266a4e
+------------------+----------------------------+-------------------------------------------------------------+
| Type             | Timestamp                  | Detail                                                      |
+------------------+----------------------------+-------------------------------------------------------------+
| creation         | 2014-11-06T02:47:21.514014 | name: TestStack-cpu_alarm_high-jft5kuz42vzx                 |
|                  |                            | description: Scale-up if the average CPU > 50% for 1 minute |
|                  |                            | type: threshold                                             |
|                  |                            | rule: cpu_util > 50.0 during 1 x 60s                        |
| state transition | 2014-11-06T03:04:03.772689 | state: ok                                                   |
| state transition | 2014-11-06T03:06:03.769424 | state: insufficient data                                    |
| state transition | 2014-11-06T03:14:03.844720 | state: ok                                                   |
| state transition | 2014-11-06T03:16:03.834233 | state: insufficient data                                    |
| state transition | 2014-11-06T03:24:07.262171 | state: alarm                                                |
| state transition | 2014-11-06T03:26:03.895120 | state: insufficient data                                    |
| state transition | 2014-11-06T03:34:03.979063 | state: alarm                                                |
| state transition | 2014-11-06T03:36:03.963650 | state: insufficient data                                    |
+------------------+----------------------------+-------------------------------------------------------------+

scaling HOT:

heat_template_version: 2013-05-23
description: AutoScaling Test Template
parameters:
    image:
        type: string
        description: Image used for servers
        default: cirros-x86_64
        constraints:
        - allowed_values:
            - cirros-x86_64
            - Ubuntu 14.04.1 LTS        
    key:
        type: string
        description: SSH key to connect to the servers
        default: default
    flavor:
        type: string
        description: flavor used by the web servers
        default: m1.tiny
        constraints:
            - allowed_values:
                - m1.tiny
                - m1.subsmall
                - m1.small
                - m1.medium
                - m1.large
                - m1.xlarge
    internal_net_id:
        type: string
        default: d9cdfb7b-1ab9-46be-a5e3-76eda2c267d7
        description: private network UUID on which the autoscaling instances will be mounted
    internal_subnet_id:
        type: string
        default: 006f6995-79bf-4353-b56a-d5d0196bfa33
        description: subnet on which the load balancer will be located
    external_network_id:
        type: string
        default: e5197561-556e-4da2-b441-3c9d03669855
        description: UUID of a Neutron external network
resources:  
    web_server_group:
        type: OS::Heat::AutoScalingGroup
        properties:
            min_size: 1
            max_size: 3
            resource:
                type: http://xxx.xxx.xxx.xxxx/y/z/lb_server.yaml
                properties:
                    flavor: {get_param: flavor}
                    image: {get_param: image}
                    key_name: {get_param: key}
                    pool_id: {get_resource: pool}
                    metadata: {"metering.stack": {get_param: "OS::stack_id"}} 
                    network_id: {"uuid": {get_param: internal_net_id}}
    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
    monitor:
        type: OS::Neutron::HealthMonitor
        properties:
            type: TCP
            delay: 5
            max_retries: 5
            timeout: 5
    pool:
        type: OS::Neutron::Pool
        properties:
            protocol: HTTP
            monitors: [{get_resource: monitor}]
            subnet_id: {get_param: internal_subnet_id}
            lb_method: ROUND_ROBIN
            vip:
                protocol_port: 80
    lb:
        type: OS::Neutron::LoadBalancer
        properties:
            protocol_port: 80
            pool_id: {get_resource: pool}

    # 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: [pool, 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: [pool, vip, address]}
        description: The IP address of the load balancing pool
    ceilometer_query:
        value:
            str_replace:
            template: >
                ceilometer statistics -m cpu_util
                -q metadata.user_metadata.stack=stackval -p 600 -a avg
            params:
                stackval: { get_param: "OS::stack_id" }
        description: >
            This is a Ceilometer query for statistics on the cpu_util meter
            Samples about OS::Nova::Server instances in this stack.  The -q
            parameter selects Samples according to the subject's metadata.
            When a VM's metadata includes an item of the form metering.X=Y,
            the corresponding Ceilometer resource has a metadata item of the
            form user_metadata.X=Y and samples about resources so tagged can
            be queried with a Ceilometer query term of the form
            metadata.user_metadata.X=Y.  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.stack=Y,
            where Y is this stack's ID.

server-config:

heat_template_version: 2013-05-23
description: A load-balancer server
parameters:
    image:
        type: string
        description: Image used for servers
    key_name:
        type: string
        description: SSH key to connect to the servers
    flavor:
        type: string
        description: flavor used by the servers
    pool_id:
        type: string
        description: Pool to contact
    network_id: 
        type: json
        description: network to attach the server instances to
#  user_data:
#    type: string
#    description: Server user_data
    metadata:
        type: json
resources:    
    server:
        type: OS::Nova::Server
        properties:
            flavor: {get_param: flavor}
            image: {get_param: image}
            key_name: {get_param: key_name}
            metadata: {get_param: metadata}
            networks:
                 - {get_param: network_id}
#                - uuid: {get_param: network_id}
#           user_data_format: SOFTWARE_CONFIG
#      user_data: {get_param: user_data}
#      user_data_format: RAW
    member:
        type: OS::Neutron::PoolMember
        properties:
            pool_id: {get_param: pool_id}
            address: {get_attr: [server, first_address]}
            protocol_port: 80

Webhooks Heats webhook respond 'incomplete-signature'-error'incomplete-signature'-error (not conform to AWS standards)

Hi there,

as I wanted to check out the autoscaling features of heat in combination with ceilometer, I tried to adapt one of the example HOT's. Meanwhile, the HOT is starting successfully, but whatever I do to stress my VM in the web_server_group, no scaling reaction is observable.
Executing the webhook manually, there's an error response, which google hardly knows, so I try my best here - maybe you can help me to solve this problem.
Additionally I'm wondering, why AWS is mentioned in the error - actually I don't want to use it. Are webhooks only possible via AWS?

Core Issue:

 curl -XPOST -i http://xxx.xxx.xxx.xxx:8000/v1/signal/arn%3Aopenstack%3Aheat%3A%3A9036a06bb9f648beb8b4d4592e693735%3Astacks%2FTestStack%2F3d0054f4-401a-4578-b9fd-4b6374bc69b2%2Fresources%2Fweb_server_scaleup_policy?Timestamp=2014-11-06T02%3A47%3A19Z&SignatureMethod=HmacSHA256&AWSAccessKeyId=e4f6cefc18a34695b1aba1bd5e0bbb0a&SignatureVersion=2&Signature=dOjsDdfO37Ym0%2F3t5A1qzxNmrjfYHdohJZ%2FQ3HBJafU%3D
[1] 7073
[2] 7074
[3] 7075
[4] 7076
root@foo:/home/bar# HTTP/1.1 400 IncompleteSignature
Content-Type: application/xml; charset=UTF-8
Content-Length: 171
Date: Thu, 06 Nov 2014 03:11:55 GMT

<ErrorResponse><Error><Message>The request signature does not conform to AWS standards</Message><Code>IncompleteSignature</Code><Type>Sender</Type></Error></ErrorResponse>

Another try:

curl -X POST http://xxx.xxx.xxx.xxx:8000/v1/signal/arn%3Aopenstack%3Aheat%3A%3A9036a06bb9f648beb8b4d4592e693735%3Astacks%2FTestStack%2F3d0054f4-401a-4578-b9fd-4b6374bc69b2%2Fresources%2Fweb_server_scaleup_policy?Timestamp=2014-11-06T02%3A47%3A19Z
[3]   Done                    SignatureMethod=HmacSHA256
[4]   Done                    AWSAccessKeyId=e4f6cefc18a34695b1aba1bd5e0bbb0a
[5]   Done                    SignatureVersion=2
user@vm-foo:~$ <ErrorResponse><Error><Message>The request signature does not conform to AWS standards</Message><Code>IncompleteSignature</Code><Type>Sender</Type></Error></ErrorResponse>

Further specs:
Version OpenStack Icehouse VM: Ubuntu 14.04
stress command: 'stress --cpu 8 --io 8 --vm 2 --vm-bytes 256M &' causing permanent usage of ~60% CPU usage.usage. On the host, heat-api-cfn is running, and port 8000 is in use.

alarm:

ceilometer alarm-history -a 69edb170-c3d2-4e3e-98bb-40b99e266a4e
+------------------+----------------------------+-------------------------------------------------------------+
| Type             | Timestamp                  | Detail                                                      |
+------------------+----------------------------+-------------------------------------------------------------+
| creation         | 2014-11-06T02:47:21.514014 | name: TestStack-cpu_alarm_high-jft5kuz42vzx                 |
|                  |                            | description: Scale-up if the average CPU > 50% for 1 minute |
|                  |                            | type: threshold                                             |
|                  |                            | rule: cpu_util > 50.0 during 1 x 60s                        |
| state transition | 2014-11-06T03:04:03.772689 | state: ok                                                   |
| state transition | 2014-11-06T03:06:03.769424 | state: insufficient data                                    |
| state transition | 2014-11-06T03:14:03.844720 | state: ok                                                   |
| state transition | 2014-11-06T03:16:03.834233 | state: insufficient data                                    |
| state transition | 2014-11-06T03:24:07.262171 | state: alarm                                                |
| state transition | 2014-11-06T03:26:03.895120 | state: insufficient data                                    |
| state transition | 2014-11-06T03:34:03.979063 | state: alarm                                                |
| state transition | 2014-11-06T03:36:03.963650 | state: insufficient data                                    |
+------------------+----------------------------+-------------------------------------------------------------+

scaling HOT:

heat_template_version: 2013-05-23
description: AutoScaling Test Template
parameters:
    image:
        type: string
        description: Image used for servers
        default: cirros-x86_64
        constraints:
        - allowed_values:
            - cirros-x86_64
            - Ubuntu 14.04.1 LTS        
    key:
        type: string
        description: SSH key to connect to the servers
        default: default
    flavor:
        type: string
        description: flavor used by the web servers
        default: m1.tiny
        constraints:
            - allowed_values:
                - m1.tiny
                - m1.subsmall
                - m1.small
                - m1.medium
                - m1.large
                - m1.xlarge
    internal_net_id:
        type: string
        default: d9cdfb7b-1ab9-46be-a5e3-76eda2c267d7
        description: private network UUID on which the autoscaling instances will be mounted
    internal_subnet_id:
        type: string
        default: 006f6995-79bf-4353-b56a-d5d0196bfa33
        description: subnet on which the load balancer will be located
    external_network_id:
        type: string
        default: e5197561-556e-4da2-b441-3c9d03669855
        description: UUID of a Neutron external network
resources:  
    web_server_group:
        type: OS::Heat::AutoScalingGroup
        properties:
            min_size: 1
            max_size: 3
            resource:
                type: http://xxx.xxx.xxx.xxxx/y/z/lb_server.yaml
                properties:
                    flavor: {get_param: flavor}
                    image: {get_param: image}
                    key_name: {get_param: key}
                    pool_id: {get_resource: pool}
                    metadata: {"metering.stack": {get_param: "OS::stack_id"}} 
                    network_id: {"uuid": {get_param: internal_net_id}}
    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
    monitor:
        type: OS::Neutron::HealthMonitor
        properties:
            type: TCP
            delay: 5
            max_retries: 5
            timeout: 5
    pool:
        type: OS::Neutron::Pool
        properties:
            protocol: HTTP
            monitors: [{get_resource: monitor}]
            subnet_id: {get_param: internal_subnet_id}
            lb_method: ROUND_ROBIN
            vip:
                protocol_port: 80
    lb:
        type: OS::Neutron::LoadBalancer
        properties:
            protocol_port: 80
            pool_id: {get_resource: pool}

    # 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: [pool, 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: [pool, vip, address]}
        description: The IP address of the load balancing pool
    ceilometer_query:
        value:
            str_replace:
            template: >
                ceilometer statistics -m cpu_util
                -q metadata.user_metadata.stack=stackval -p 600 -a avg
            params:
                stackval: { get_param: "OS::stack_id" }
        description: >
            This is a Ceilometer query for statistics on the cpu_util meter
            Samples about OS::Nova::Server instances in this stack.  The -q
            parameter selects Samples according to the subject's metadata.
            When a VM's metadata includes an item of the form metering.X=Y,
            the corresponding Ceilometer resource has a metadata item of the
            form user_metadata.X=Y and samples about resources so tagged can
            be queried with a Ceilometer query term of the form
            metadata.user_metadata.X=Y.  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.stack=Y,
            where Y is this stack's ID.

server-config:

heat_template_version: 2013-05-23
description: A load-balancer server
parameters:
    image:
        type: string
        description: Image used for servers
    key_name:
        type: string
        description: SSH key to connect to the servers
    flavor:
        type: string
        description: flavor used by the servers
    pool_id:
        type: string
        description: Pool to contact
    network_id: 
        type: json
        description: network to attach the server instances to
#  user_data:
#    type: string
#    description: Server user_data
    metadata:
        type: json
resources:    
    server:
        type: OS::Nova::Server
        properties:
            flavor: {get_param: flavor}
            image: {get_param: image}
            key_name: {get_param: key_name}
            metadata: {get_param: metadata}
            networks:
                 - {get_param: network_id}
#                - uuid: {get_param: network_id}
#           user_data_format: SOFTWARE_CONFIG
#      user_data: {get_param: user_data}
#      user_data_format: RAW
    member:
        type: OS::Neutron::PoolMember
        properties:
            pool_id: {get_param: pool_id}
            address: {get_attr: [server, first_address]}
            protocol_port: 80

Heats webhook respond 'incomplete-signature'-error (not conform to AWS standards)

Hi there,

as I wanted to check out the autoscaling features of heat in combination with ceilometer, I tried to adapt one of the example HOT's. Meanwhile, the HOT is starting successfully, but whatever I do to stress my VM in the web_server_group, no scaling reaction is observable.
Executing the webhook manually, there's an error response, which google hardly knows, so I try my best here - maybe you can help me to solve this problem.
Additionally I'm wondering, why AWS is mentioned in the error - actually I don't want to use it. Are webhooks only possible via AWS?

Core Issue:

 curl -XPOST -i http://xxx.xxx.xxx.xxx:8000/v1/signal/arn%3Aopenstack%3Aheat%3A%3A9036a06bb9f648beb8b4d4592e693735%3Astacks%2FTestStack%2F3d0054f4-401a-4578-b9fd-4b6374bc69b2%2Fresources%2Fweb_server_scaleup_policy?Timestamp=2014-11-06T02%3A47%3A19Z&SignatureMethod=HmacSHA256&AWSAccessKeyId=e4f6cefc18a34695b1aba1bd5e0bbb0a&SignatureVersion=2&Signature=dOjsDdfO37Ym0%2F3t5A1qzxNmrjfYHdohJZ%2FQ3HBJafU%3D
[1] 7073
[2] 7074
[3] 7075
[4] 7076
root@foo:/home/bar# HTTP/1.1 400 IncompleteSignature
Content-Type: application/xml; charset=UTF-8
Content-Length: 171
Date: Thu, 06 Nov 2014 03:11:55 GMT

<ErrorResponse><Error><Message>The request signature does not conform to AWS standards</Message><Code>IncompleteSignature</Code><Type>Sender</Type></Error></ErrorResponse>

Another try:

curl -X POST http://xxx.xxx.xxx.xxx:8000/v1/signal/arn%3Aopenstack%3Aheat%3A%3A9036a06bb9f648beb8b4d4592e693735%3Astacks%2FTestStack%2F3d0054f4-401a-4578-b9fd-4b6374bc69b2%2Fresources%2Fweb_server_scaleup_policy?Timestamp=2014-11-06T02%3A47%3A19Z
[3]   Done                    SignatureMethod=HmacSHA256
[4]   Done                    AWSAccessKeyId=e4f6cefc18a34695b1aba1bd5e0bbb0a
[5]   Done                    SignatureVersion=2
user@vm-foo:~$ <ErrorResponse><Error><Message>The request signature does not conform to AWS standards</Message><Code>IncompleteSignature</Code><Type>Sender</Type></Error></ErrorResponse>

Further specs:
Version OpenStack Icehouse VM: Ubuntu 14.04
stress command: 'stress --cpu 8 --io 8 --vm 2 --vm-bytes 256M &' causing permanent usage of ~60% CPU usage. On the host, heat-api-cfn is running, and port 8000 is in use.

alarm:

ceilometer alarm-history -a 69edb170-c3d2-4e3e-98bb-40b99e266a4e
+------------------+----------------------------+-------------------------------------------------------------+
| Type             | Timestamp                  | Detail                                                      |
+------------------+----------------------------+-------------------------------------------------------------+
| creation         | 2014-11-06T02:47:21.514014 | name: TestStack-cpu_alarm_high-jft5kuz42vzx                 |
|                  |                            | description: Scale-up if the average CPU > 50% for 1 minute |
|                  |                            | type: threshold                                             |
|                  |                            | rule: cpu_util > 50.0 during 1 x 60s                        |
| state transition | 2014-11-06T03:04:03.772689 | state: ok                                                   |
| state transition | 2014-11-06T03:06:03.769424 | state: insufficient data                                    |
| state transition | 2014-11-06T03:14:03.844720 | state: ok                                                   |
| state transition | 2014-11-06T03:16:03.834233 | state: insufficient data                                    |
| state transition | 2014-11-06T03:24:07.262171 | state: alarm                                                |
| state transition | 2014-11-06T03:26:03.895120 | state: insufficient data                                    |
| state transition | 2014-11-06T03:34:03.979063 | state: alarm                                                |
| state transition | 2014-11-06T03:36:03.963650 | state: insufficient data                                    |
+------------------+----------------------------+-------------------------------------------------------------+

scaling HOT:

heat_template_version: 2013-05-23
description: AutoScaling Test Template
parameters:
    image:
        type: string
        description: Image used for servers
        default: cirros-x86_64
        constraints:
        - allowed_values:
            - cirros-x86_64
            - Ubuntu 14.04.1 LTS        
    key:
        type: string
        description: SSH key to connect to the servers
        default: default
    flavor:
        type: string
        description: flavor used by the web servers
        default: m1.tiny
        constraints:
            - allowed_values:
                - m1.tiny
                - m1.subsmall
                - m1.small
                - m1.medium
                - m1.large
                - m1.xlarge
    internal_net_id:
        type: string
        default: d9cdfb7b-1ab9-46be-a5e3-76eda2c267d7
        description: private network UUID on which the autoscaling instances will be mounted
    internal_subnet_id:
        type: string
        default: 006f6995-79bf-4353-b56a-d5d0196bfa33
        description: subnet on which the load balancer will be located
    external_network_id:
        type: string
        default: e5197561-556e-4da2-b441-3c9d03669855
        description: UUID of a Neutron external network
resources:  
    web_server_group:
        type: OS::Heat::AutoScalingGroup
        properties:
            min_size: 1
            max_size: 3
            resource:
                type: http://xxx.xxx.xxx.xxxx/y/z/lb_server.yaml
                properties:
                    flavor: {get_param: flavor}
                    image: {get_param: image}
                    key_name: {get_param: key}
                    pool_id: {get_resource: pool}
                    metadata: {"metering.stack": {get_param: "OS::stack_id"}} 
                    network_id: {"uuid": {get_param: internal_net_id}}
    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
    monitor:
        type: OS::Neutron::HealthMonitor
        properties:
            type: TCP
            delay: 5
            max_retries: 5
            timeout: 5
    pool:
        type: OS::Neutron::Pool
        properties:
            protocol: HTTP
            monitors: [{get_resource: monitor}]
            subnet_id: {get_param: internal_subnet_id}
            lb_method: ROUND_ROBIN
            vip:
                protocol_port: 80
    lb:
        type: OS::Neutron::LoadBalancer
        properties:
            protocol_port: 80
            pool_id: {get_resource: pool}

    # 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: [pool, 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: [pool, vip, address]}
        description: The IP address of the load balancing pool
    ceilometer_query:
        value:
            str_replace:
            template: >
                ceilometer statistics -m cpu_util
                -q metadata.user_metadata.stack=stackval -p 600 -a avg
            params:
                stackval: { get_param: "OS::stack_id" }
        description: >
            This is a Ceilometer query for statistics on the cpu_util meter
            Samples about OS::Nova::Server instances in this stack.  The -q
            parameter selects Samples according to the subject's metadata.
            When a VM's metadata includes an item of the form metering.X=Y,
            the corresponding Ceilometer resource has a metadata item of the
            form user_metadata.X=Y and samples about resources so tagged can
            be queried with a Ceilometer query term of the form
            metadata.user_metadata.X=Y.  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.stack=Y,
            where Y is this stack's ID.

server-config:

heat_template_version: 2013-05-23
description: A load-balancer server
parameters:
    image:
        type: string
        description: Image used for servers
    key_name:
        type: string
        description: SSH key to connect to the servers
    flavor:
        type: string
        description: flavor used by the servers
    pool_id:
        type: string
        description: Pool to contact
    network_id: 
        type: json
        description: network to attach the server instances to
#  user_data:
#    type: string
#    description: Server user_data
    metadata:
        type: json
resources:    
    server:
        type: OS::Nova::Server
        properties:
            flavor: {get_param: flavor}
            image: {get_param: image}
            key_name: {get_param: key_name}
            metadata: {get_param: metadata}
            networks:
                 - {get_param: network_id}
#                - uuid: {get_param: network_id}
#           user_data_format: SOFTWARE_CONFIG
#      user_data: {get_param: user_data}
#      user_data_format: RAW
    member:
        type: OS::Neutron::PoolMember
        properties:
            pool_id: {get_param: pool_id}
            address: {get_attr: [server, first_address]}
            protocol_port: 80