[cloud] New module aws_scaling_policy (#31241)

* Add scaling_policy module

* Change exception format

* Rename scaling_policy module to aws_application_scaling_policy
pull/25818/merge
Gustavo Maia 7 years ago committed by Ryan Brown
parent 18ea816a0e
commit 8fba6e6684

@ -0,0 +1,294 @@
#!/usr/bin/python
# Copyright: Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: aws_application_scaling_policy
short_description: Manage Application Auto Scaling Scaling Policies
notes:
- for details of the parameters and returns see
U(http://boto3.readthedocs.io/en/latest/reference/services/application-autoscaling.html#ApplicationAutoScaling.Client.put_scaling_policy)
description:
- Creates, updates or removes a Scaling Policy
version_added: "2.5"
author:
- Gustavo Maia(@gurumaia)
requirements: [ json, botocore, boto3 ]
options:
policy_name:
description: The name of the scaling policy.
required: yes
service_namespace:
description: The namespace of the AWS service.
required: yes
choices: ['ecs', 'elasticmapreduce', 'ec2', 'appstream', 'dynamodb']
resource_id:
description: The identifier of the resource associated with the scalable target.
required: yes
scalable_dimension:
description: The scalable dimension associated with the scalable target.
required: yes
choices: [ 'ecs:service:DesiredCount',
'ec2:spot-fleet-request:TargetCapacity',
'elasticmapreduce:instancegroup:InstanceCount',
'appstream:fleet:DesiredCapacity',
'dynamodb:table:ReadCapacityUnits',
'dynamodb:table:WriteCapacityUnits',
'dynamodb:index:ReadCapacityUnits',
'dynamodb:index:WriteCapacityUnits']
policy_type:
description: The policy type.
required: yes
choices: ['StepScaling', 'TargetTrackingScaling']
step_scaling_policy_configuration:
description: A step scaling policy. This parameter is required if you are creating a policy and the policy type is StepScaling.
required: no
target_tracking_scaling_policy_configuration:
description: A target tracking policy. This parameter is required if you are creating a new policy and the policy type is TargetTrackingScaling.
required: no
extends_documentation_fragment:
- aws
- ec2
'''
EXAMPLES = '''
# Note: These examples do not set authentication details, see the AWS Guide for details.
# Create scaling policy for ECS Service
- name: scaling_policy
aws_application_scaling_policy:
state: present
policy_name: test_policy
service_namespace: ecs
resource_id: service/poc-pricing/test-as
scalable_dimension: ecs:service:DesiredCount
policy_type: StepScaling
step_scaling_policy_configuration:
AdjustmentType: ChangeInCapacity
StepAdjustments:
- MetricIntervalUpperBound: 123
ScalingAdjustment: 2
- MetricIntervalLowerBound: 123
ScalingAdjustment: -2
Cooldown: 123
MetricAggregationType: Average
# Remove scalable target for ECS Service
- name: scaling_policy
aws_application_scaling_policy:
state: absent
policy_name: test_policy
policy_type: StepScaling
service_namespace: ecs
resource_id: service/cluster-name/service-name
scalable_dimension: ecs:service:DesiredCount
'''
RETURN = '''
service_namespace:
description: The namespace of the AWS service.
returned: when state present
type: string
sample: ecs
resource_id:
description: The identifier of the resource associated with the scalable target.
returned: when state present
type: string
sample: service/cluster-name/service-name
scalable_dimension:
description: The scalable dimension associated with the scalable target.
returned: when state present
type: string
sample: ecs:service:DesiredCount
min_capacity:
description: The minimum value to scale to in response to a scale in event. Required if I(state) is C(present).
returned: when state present
type: int
sample: 1
max_capacity:
description: The maximum value to scale to in response to a scale out event. Required if I(state) is C(present).
returned: when state present
type: int
sample: 2
role_arn:
description: The ARN of an IAM role that allows Application Auto Scaling to modify the scalable target on your behalf. Required if I(state) is C(present).
returned: when state present
type: string
sample: arn:aws:iam::123456789123:role/roleName
creation_time:
description: The Unix timestamp for when the scalable target was created.
returned: when state present
type: string
sample: '2017-09-28T08:22:51.881000-03:00'
''' # NOQA
import traceback
try:
import boto3
HAS_BOTO3 = True
except ImportError:
HAS_BOTO3 = False
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.ec2 import _camel_to_snake, camel_dict_to_snake_dict, boto3_conn, ec2_argument_spec, get_aws_connection_info
try:
import botocore
except ImportError:
pass # will be detected by imported HAS_BOTO3
def delete_scaling_policy(connection, module):
changed = False
scaling_policy = connection.describe_scaling_policies(
ServiceNamespace=module.params.get('service_namespace'),
ResourceId=module.params.get('resource_id'),
ScalableDimension=module.params.get('scalable_dimension'),
PolicyNames=[module.params.get('policy_name')],
MaxResults=1
)
if scaling_policy['ScalingPolicies']:
try:
connection.delete_scaling_policy(
ServiceNamespace=module.params.get('service_namespace'),
ResourceId=module.params.get('resource_id'),
ScalableDimension=module.params.get('scalable_dimension'),
PolicyName=module.params.get('policy_name'),
)
changed = True
except Exception as e:
module.fail_json(msg=str(e), exception=traceback.format_exc())
module.exit_json(changed=changed)
def create_scaling_policy(connection, module):
scaling_policy = connection.describe_scaling_policies(
ServiceNamespace=module.params.get('service_namespace'),
ResourceId=module.params.get('resource_id'),
ScalableDimension=module.params.get('scalable_dimension'),
PolicyNames=[module.params.get('policy_name')],
MaxResults=1
)
changed = False
if scaling_policy['ScalingPolicies']:
scaling_policy = scaling_policy['ScalingPolicies'][0]
# check if the input parameters are equal to what's already configured
for attr in ('PolicyName',
'ServiceNamespace',
'ResourceId',
'ScalableDimension',
'PolicyType',
'StepScalingPolicyConfiguration',
'TargetTrackingScalingPolicyConfiguration'):
if attr in scaling_policy and scaling_policy[attr] != module.params.get(_camel_to_snake(attr)):
changed = True
scaling_policy[attr] = module.params.get(_camel_to_snake(attr))
else:
changed = True
scaling_policy = {
'PolicyName': module.params.get('policy_name'),
'ServiceNamespace': module.params.get('service_namespace'),
'ResourceId': module.params.get('resource_id'),
'ScalableDimension': module.params.get('scalable_dimension'),
'PolicyType': module.params.get('policy_type'),
'StepScalingPolicyConfiguration': module.params.get('step_scaling_policy_configuration'),
'TargetTrackingScalingPolicyConfiguration': module.params.get('target_tracking_scaling_policy_configuration')
}
if changed:
try:
if (module.params.get('step_scaling_policy_configuration')):
connection.put_scaling_policy(
PolicyName=scaling_policy['PolicyName'],
ServiceNamespace=scaling_policy['ServiceNamespace'],
ResourceId=scaling_policy['ResourceId'],
ScalableDimension=scaling_policy['ScalableDimension'],
PolicyType=scaling_policy['PolicyType'],
StepScalingPolicyConfiguration=scaling_policy['StepScalingPolicyConfiguration']
)
elif (module.params.get('target_tracking_scaling_policy_configuration')):
connection.put_scaling_policy(
PolicyName=scaling_policy['PolicyName'],
ServiceNamespace=scaling_policy['ServiceNamespace'],
ResourceId=scaling_policy['ResourceId'],
ScalableDimension=scaling_policy['ScalableDimension'],
PolicyType=scaling_policy['PolicyType'],
TargetTrackingScalingPolicyConfiguration=scaling_policy['TargetTrackingScalingPolicyConfiguration']
)
except Exception as e:
module.fail_json(msg=str(e), exception=traceback.format_exc())
try:
response = connection.describe_scaling_policies(
ServiceNamespace=module.params.get('service_namespace'),
ResourceId=module.params.get('resource_id'),
ScalableDimension=module.params.get('scalable_dimension'),
PolicyNames=[module.params.get('policy_name')],
MaxResults=1
)
except Exception as e:
module.fail_json(msg=str(e), exception=traceback.format_exc())
if (response['ScalingPolicies']):
snaked_response = camel_dict_to_snake_dict(response['ScalingPolicies'][0])
else:
snaked_response = {}
module.exit_json(changed=changed, response=snaked_response)
def main():
argument_spec = ec2_argument_spec()
argument_spec.update(dict(
state=dict(required=True, choices=['present', 'absent'], type='str'),
policy_name=dict(required=True, type='str'),
service_namespace=dict(required=True, choices=['ecs', 'elasticmapreduce', 'ec2', 'appstream', 'dynamodb'], type='str'),
resource_id=dict(required=True, type='str'),
scalable_dimension=dict(required=True, choices=['ecs:service:DesiredCount',
'ec2:spot-fleet-request:TargetCapacity',
'elasticmapreduce:instancegroup:InstanceCount',
'appstream:fleet:DesiredCapacity',
'dynamodb:table:ReadCapacityUnits',
'dynamodb:table:WriteCapacityUnits',
'dynamodb:index:ReadCapacityUnits',
'dynamodb:index:WriteCapacityUnits'
], type='str'),
policy_type=dict(required=True, choices=['StepScaling', 'TargetTrackingScaling'], type='str'),
step_scaling_policy_configuration=dict(required=False, type='dict'),
target_tracking_scaling_policy_configuration=dict(required=False, type='dict')
))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
if not HAS_BOTO3:
module.fail_json(msg='boto3 is required.')
try:
region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module, boto3=True)
if not region:
module.fail_json(msg="Region must be specified as a parameter, in EC2_REGION or AWS_REGION environment variables or in boto configuration file")
connection = boto3_conn(module, conn_type='client', resource='application-autoscaling', region=region, endpoint=ec2_url, **aws_connect_kwargs)
except botocore.exceptions.ProfileNotFound as e:
module.fail_json(msg=str(e))
if module.params.get("state") == 'present':
create_scaling_policy(connection, module)
else:
delete_scaling_policy(connection, module)
if __name__ == '__main__':
main()
Loading…
Cancel
Save