Skip to content

Commit

Permalink
new module: cloudwatch_metric_alarm_info (ansible-collections#988)
Browse files Browse the repository at this point in the history
new module: cloudwatch_metric_alarm_info

SUMMARY
Depends-On: ansible-collections#1066
Should be merged only after ansible-collections#1028 is merged.

Adding a new module for retrieving cloudwatch metric alarms info.

Currently supports following boto API(s)
describe_alarms()
ISSUE TYPE


New Module Pull Request

COMPONENT NAME

cloudwatch_metric_alarm_info
ADDITIONAL INFORMATION


Will be useful in moving these tasks from aws cli commands to amazon.aws module.
https://github.com/ansible-collections/community.aws/blob/main/tests/integration/targets/cloudwatch_metric_alarm/tasks/main.yml#L63-L70
ansible-collections#1440
The integration tests for this info module will be added to above tests, after the cloudwatch_metric_alarm module is migrated from community.aws to amazon.aws.

Sample playbook
---
- name: Create a metric alarm & get info
  hosts: localhost
  gather_facts: false
  tasks:
    - name: create alarm
      community.aws.cloudwatch_metric_alarm:
        state: present
        region: us-east-2
        name: "cpu-low-test-metric-alarm-1234"
        metric: "CPUUtilization"
        namespace: "AWS/EC2"
        statistic: Average
        comparison: "LessThanOrEqualToThreshold"
        threshold: 50.0
        period: 180
        evaluation_periods: 3
        unit: "Percent"
        description: "This will alarm when a instance's CPU usage average is lower than 50%"
        dimensions: {'InstanceId':'i-00a8b34xxxxxxxxxx'}

    - name: describe the metric alarm based on metric name and namespace
      amazon.aws.cloudwatch_metric_alarm_info:
        alarm_names:
          - cpu-low-test-metric-alarm-1234
      register: alarm_info

    - debug:
        var: alarm_info

Reviewed-by: Alina Buzachis <None>
Reviewed-by: Mandar Kulkarni <[email protected]>
Reviewed-by: Jill R <None>
Reviewed-by: Mark Chappell <None>
Reviewed-by: Gonéri Le Bouder <[email protected]>
  • Loading branch information
mandar242 authored Sep 27, 2022
1 parent d750318 commit d78a0e9
Show file tree
Hide file tree
Showing 4 changed files with 446 additions and 184 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- cloudwatch_metric_alarm_info - Added a new module that describes the cloudwatch metric alarms (https://github.com/ansible-collections/amazon.aws/pull/988).
1 change: 1 addition & 0 deletions meta/runtime.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ action_groups:
- cloudwatchlogs_log_group
- cloudwatchlogs_log_group_info
- cloudwatchlogs_log_group_metric_filter
- cloudwatch_metric_alarm_info
- ec2_ami
- ec2_ami_info
- ec2_eip
Expand Down
321 changes: 321 additions & 0 deletions plugins/modules/cloudwatch_metric_alarm_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,321 @@
#!/usr/bin/python
# This file is part of Ansible
# GNU General Public License v3.0+ (see COPYING or https://wwww.gnu.org/licenses/gpl-3.0.txt)

from __future__ import absolute_import, division, print_function
__metaclass__ = type


DOCUMENTATION = '''
---
module: cloudwatch_metric_alarm_info
version_added: 5.0.0
short_description: Gather information about the alarms for the specified metric
description:
- Retrieves the alarms for the specified metric.
author:
- Mandar Vijay Kulkarni (@mandar242)
options:
alarm_names:
description:
- The name of the metric.
required: false
type: list
elements: str
alarm_name_prefix:
description:
- An alarm name prefix to retrieve information about alarms that have names that start with this prefix.
- Can not be used with I(alarm_names).
required: false
type: str
alarm_type:
description:
- Specify this to return metric alarms or composite alarms.
- Module is defaulted to return metric alarms but can return composite alarms if I(alarm_type=CompositeAlarm).
required: false
type: str
default: MetricAlarm
choices: ['CompositeAlarm', 'MetricAlarm']
children_of_alarm_name:
description:
- If specified returns information about the "children" alarms of the alarm name specified.
required: false
type: str
parents_of_alarm_name:
description:
- If specified returns information about the "parent" alarms of the alarm name specified.
required: false
type: str
state_value:
description:
- If specified returns information only about alarms that are currently in the particular state.
required: false
type: str
choices: ['OK', 'ALARM', 'INSUFFICIENT_DATA']
action_prefix:
description:
- This parameter can be used to filter the results of the operation to only those alarms that use a certain alarm action.
required: false
type: str
extends_documentation_fragment:
- amazon.aws.aws
- amazon.aws.ec2
'''

EXAMPLES = '''
# Note: These examples do not set authentication details, see the AWS Guide for details.
- name: describe the metric alarm based on alarm names
amazon.aws.cloudwatch_metric_alarm_info:
alarm_names:
- my-test-alarm-1
- my-test-alarm-2
- name: describe the metric alarm based alarm names and state value
amazon.aws.cloudwatch_metric_alarm_info:
alarm_names:
- my-test-alarm-1
- my-test-alarm-2
state_value: OK
- name: describe the metric alarm based alarm names prefix
amazon.aws.cloudwatch_metric_alarm_info:
alarm_name_prefix: my-test-
'''

RETURN = '''
metric_alarms:
description: The gathered information about specified metric alarms.
returned: when success
type: list
elements: dict
contains:
alarm_name:
description: Unique name for the alarm.
returned: always
type: str
alarm_arn:
description: The Amazon Resource Name (ARN) of the alarm.
returned: always
type: str
alarm_description:
description: The description of the alarm.
returned: always
type: str
alarm_configuration_updated_timestamp:
description: The time stamp of the last update to the alarm configuration.
returned: always
type: str
actions_enabled:
description: Indicates whether actions should be executed during any changes to the alarm state.
returned: always
type: bool
ok_actions:
description: The actions to execute when this alarm transitions to an OK state from any other state.
returned: always
type: list
elements: str
alarm_actions:
description: The actions to execute when this alarm transitions to an ALARM state from any other state.
returned: always
type: list
elements: str
insufficient_data_actions:
description: The actions to execute when this alarm transitions to an INSUFFICIENT_DATA state from any other state.
returned: always
type: list
elements: str
state_value:
description: The state value for the alarm.
returned: always
type: str
state_reason:
description: An explanation for the alarm state, in text format.
returned: always
type: str
state_reason_data:
description: An explanation for the alarm state, in JSON format.
returned: always
type: str
state_updated_timestamp:
description: The time stamp of the last update to the alarm state.
returned: always
type: str
metric_name:
description: Name of the monitored metric (e.g. C(CPUUtilization)).
returned: always
type: str
namespace:
description:
- Name of the appropriate namespace (C(AWS/EC2), C(System/Linux), etc.).
- Determines the category it will appear under in CloudWatch.
returned: always
type: str
statistic:
description: The statistic for the metric associated with the alarm, other than percentile.
returned: always
type: str
extended_statistic:
description: The percentile statistic for the metric associated with the alarm.
returned: always
type: str
dimensions:
description: The dimensions for the metric.
returned: always
type: list
elements: dict
contains:
name:
description: The name of the dimension.
returned: always
type: str
value:
description: The value of the dimension.
returned: always
type: str
period:
description:
- The length, in seconds, used each time the metric specified in MetricName is evaluated.
- Valid values are 10, 30, and any multiple of 60.
returned: always
type: int
unit:
description: Unit used when storing the metric
returned: always
type: str
evaluation_period:
description: The number of periods over which data is compared to the specified threshold.
returned: always
type: int
datapoints_to_alarm:
description: The number of data points that must be breaching to trigger the alarm.
returned: always
type: int
threshold:
description: The value to compare with the specified statistic.
returned: always
type: float
comparison_operator:
description: The arithmetic operation to use when comparing the specified statistic and threshold.
returned: always
type: str
treat_missing_data:
description: Sets how alarm is to handle missing data points.
returned: always
type: str
evaluate_low_sample_count_percentile:
description:
- Used only for alarms based on percentiles.
- If I(ignore), the alarm state does not change during periods with too few data points to be statistically significant.
- If I(evaluate) or this parameter is not used, the alarm is always evaluated and possibly changes state.
returned: always
type: str
metrics:
description: An array of MetricDataQuery structures, used in an alarm based on a metric math expression.
returned: always
type: list
elements: dict
threshold_metric_id:
description: This is the ID of the ANOMALY_DETECTION_BAND function used as the threshold for the alarm.
returned: always
type: str
'''


try:
import botocore
except ImportError:
pass # Handled by AnsibleAWSModule

from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule
from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry
from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict


@AWSRetry.jittered_backoff(retries=10)
def _describe_alarms(connection, **params):
paginator = connection.get_paginator('describe_alarms')
return paginator.paginate(**params).build_full_result()


def describe_metric_alarms_info(connection, module):

params = build_params(module)

alarm_type_to_return = module.params.get('alarm_type')

try:
describe_metric_alarms_info_response = _describe_alarms(connection, **params)
# describe_metric_alarms_info_response = describe_metric_alarms_info_response[alarm_type_to_return]
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg='Failed to describe cloudwatch metric alarm')

result = []

if alarm_type_to_return == 'CompositeAlarm':
for response_list_item in describe_metric_alarms_info_response['CompositeAlarms']:
result.append(camel_dict_to_snake_dict(response_list_item))
module.exit_json(composite_alarms=result)

for response_list_item in describe_metric_alarms_info_response['MetricAlarms']:
result.append(camel_dict_to_snake_dict(response_list_item))

module.exit_json(metric_alarms=result)


def build_params(module):

params = {}

if module.params.get('alarm_names'):
params['AlarmNames'] = module.params.get('alarm_names')

if module.params.get('alarm_name_prefix'):
params['AlarmNamePrefix'] = module.params.get('alarm_name_prefix')

if module.params.get('children_of_alarm_name'):
params['ChildrenOfAlarmName'] = module.params.get('children_of_alarm_name')

if module.params.get('parents_of_alarm_name'):
params['ParentsOfAlarmName'] = module.params.get('parents_of_alarm_name')

if module.params.get('state_value'):
params['StateValue'] = module.params.get('state_value')

if module.params.get('action_prefix'):
params['ActionPrefix'] = module.params.get('action_prefix')

return params


def main():

argument_spec = dict(
alarm_names=dict(type='list', elements='str', required=False),
alarm_name_prefix=dict(type='str', required=False),
alarm_type=dict(type='str', choices=['CompositeAlarm', 'MetricAlarm'], default='MetricAlarm', required=False),
children_of_alarm_name=dict(type='str', required=False),
parents_of_alarm_name=dict(type='str', required=False),
state_value=dict(type='str', choices=['OK', 'ALARM', 'INSUFFICIENT_DATA'], required=False),
action_prefix=dict(type='str', required=False),
)

module = AnsibleAWSModule(
argument_spec=argument_spec,
mutually_exclusive=[['alarm_names', 'alarm_name_prefix']],
supports_check_mode=True
)

try:
connection = module.client('cloudwatch', retry_decorator=AWSRetry.jittered_backoff())
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg='Failed to connect to AWS')

describe_metric_alarms_info(connection, module)


if __name__ == '__main__':
main()
Loading

0 comments on commit d78a0e9

Please sign in to comment.