Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ec2_asg_lifecycle_hook: add integration tests #1048

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- ec2_asg_lifecycle_hook - add integration tests (https://github.com/ansible-collections/community.aws/pull/1048).
54 changes: 33 additions & 21 deletions plugins/modules/ec2_asg_lifecycle_hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,17 @@

'''

from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule

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

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


def create_lifecycle_hook(connection, module):
changed = False

lch_name = module.params.get('lifecycle_hook_name')
asg_name = module.params.get('autoscaling_group_name')
Expand All @@ -120,6 +121,9 @@ def create_lifecycle_hook(connection, module):
heartbeat_timeout = module.params.get('heartbeat_timeout')
default_result = module.params.get('default_result')

return_object = {}
return_object['changed'] = False

lch_params = {
'LifecycleHookName': lch_name,
'AutoScalingGroupName': asg_name,
Expand Down Expand Up @@ -150,23 +154,30 @@ def create_lifecycle_hook(connection, module):
module.fail_json_aws(e, msg="Failed to get Lifecycle Hook")

if not existing_hook:
changed = True
else:
# GlobalTimeout is not configurable, but exists in response.
# Removing it helps to compare both dicts in order to understand
# what changes were done.
del(existing_hook[0]['GlobalTimeout'])
added, removed, modified, same = dict_compare(lch_params, existing_hook[0])
if added or removed or modified:
changed = True

if changed:
try:
return_object['changed'] = True
connection.put_lifecycle_hook(**lch_params)
return_object['lifecycle_hook_info'] = connection.describe_lifecycle_hooks(
AutoScalingGroupName=asg_name, LifecycleHookNames=[lch_name])['LifecycleHooks']
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg="Failed to create LifecycleHook")

return(changed)
else:
added, removed, modified, same = dict_compare(lch_params, existing_hook[0])
if modified:
# GlobalTimeout is not configurable, but exists in response.
# Removing it helps to compare both dicts in order to understand
# what changes were done.
del(existing_hook[0]['GlobalTimeout'])
mandar242 marked this conversation as resolved.
Show resolved Hide resolved
try:
return_object['changed'] = True
connection.put_lifecycle_hook(**lch_params)
return_object['lifecycle_hook_info'] = connection.describe_lifecycle_hooks(
AutoScalingGroupName=asg_name, LifecycleHookNames=[lch_name])['LifecycleHooks']
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg="Failed to create LifecycleHook")

module.exit_json(**camel_dict_to_snake_dict(return_object))
mandar242 marked this conversation as resolved.
Show resolved Hide resolved


def dict_compare(d1, d2):
Expand All @@ -186,11 +197,13 @@ def dict_compare(d1, d2):


def delete_lifecycle_hook(connection, module):
changed = False

lch_name = module.params.get('lifecycle_hook_name')
asg_name = module.params.get('autoscaling_group_name')

return_object = {}
return_object['changed'] = False

try:
all_hooks = connection.describe_lifecycle_hooks(
AutoScalingGroupName=asg_name
Expand All @@ -207,13 +220,14 @@ def delete_lifecycle_hook(connection, module):

try:
connection.delete_lifecycle_hook(**lch_params)
changed = True
return_object['changed'] = True
return_object['lifecycle_hook_removed'] = {'LifecycleHookName': lch_name, 'AutoScalingGroupName': asg_name}
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg="Failed to delete LifecycleHook")
else:
pass

return(changed)
module.exit_json(**camel_dict_to_snake_dict(return_object))


def main():
Expand All @@ -238,11 +252,9 @@ def main():
changed = False

if state == 'present':
changed = create_lifecycle_hook(connection, module)
create_lifecycle_hook(connection, module)
elif state == 'absent':
changed = delete_lifecycle_hook(connection, module)

module.exit_json(changed=changed)
delete_lifecycle_hook(connection, module)


if __name__ == '__main__':
Expand Down
1 change: 1 addition & 0 deletions tests/integration/targets/ec2_asg_lifecycle_hook/aliases
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cloud/aws
6 changes: 6 additions & 0 deletions tests/integration/targets/ec2_asg_lifecycle_hook/inventory
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[tests]
create_update_delete

[all:vars]
ansible_connection=local
ansible_python_interpreter="{{ ansible_playbook_python }}"
40 changes: 40 additions & 0 deletions tests/integration/targets/ec2_asg_lifecycle_hook/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
# Beware: most of our tests here are run in parallel.
# To add new tests you'll need to add a new host to the inventory and a matching
# '{{ inventory_hostname }}'.yml file in roles/ec2_asg_lifecycle_hook/tasks/


# Prepare the VPC and figure out which AMI to use
- hosts: all
gather_facts: no
tasks:
- module_defaults:
group/aws:
aws_access_key: "{{ aws_access_key }}"
aws_secret_key: "{{ aws_secret_key }}"
security_token: "{{ security_token | default(omit) }}"
region: "{{ aws_region }}"
vars:
# We can't just use "run_once" because the facts don't propagate when
# running an 'include' that was run_once
setup_run_once: yes
block:
- include_role:
name: 'ec2_asg_lifecycle_hook'
tasks_from: env_setup.yml
rescue:
- include_role:
name: 'ec2_asg_lifecycle_hook'
tasks_from: env_cleanup.yml
run_once: yes
- fail:
msg: 'Environment preparation failed'
run_once: yes

# VPC should get cleaned up once all hosts have run
- hosts: all
gather_facts: no
strategy: free
serial: 6
roles:
- ec2_asg_lifecycle_hook
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
# defaults file for ec2_asg_lifecycle_hook
# Amazon Linux 2 AMI 2019.06.12 (HVM), GP2 Volume Type
ec2_ami_name: 'amzn2-ami-hvm-2.0.20190612-x86_64-gp2'
load_balancer_name: "{{ tiny_prefix }}-lb"
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
---
- name: Test create/update/delete AutoScalingGroups Lifecycle Hooks with ec2_asg_lifecycle_hook

block:
#----------------------------------------------------------------------
- name: create a launch configuration
ec2_lc:
name: "{{ resource_prefix }}-lc"
image_id: "{{ ec2_ami_image }}"
region: "{{ aws_region }}"
instance_type: t2.micro
assign_public_ip: yes
register: create_lc

- name: ensure that lc is created
assert:
that:
- create_lc is changed
- create_lc.failed is false

#----------------------------------------------------------------------
- name: create a AutoScalingGroup
ec2_asg:
name: "{{ resource_prefix }}-asg"
launch_config_name: "{{ resource_prefix }}-lc"
health_check_period: 60
health_check_type: ELB
replace_all_instances: yes
min_size: 1
max_size: 1
desired_capacity: 1
region: "{{ aws_region }}"
register: create_asg

- name: ensure that AutoScalingGroup is created
assert:
that:
- create_asg is changed
- create_asg.failed is false
- '"autoscaling:CreateAutoScalingGroup" in create_asg.resource_actions'

#----------------------------------------------------------------------

- name: Create lifecycle hook
community.aws.ec2_asg_lifecycle_hook:
region: "{{ aws_region }}"
autoscaling_group_name: "{{ resource_prefix }}-asg"
lifecycle_hook_name: "{{ resource_prefix }}-test-hook"
transition: autoscaling:EC2_INSTANCE_LAUNCHING
heartbeat_timeout: 7000
default_result: ABANDON
state: present
register: output

- assert:
that:
- output is changed
- output is not failed
- '"lifecycle_hook_info" in output'
- output.lifecycle_hook_info[0].heartbeat_timeout == 7000

- name: Create lifecycle hook - Idempotency
community.aws.ec2_asg_lifecycle_hook:
region: "{{ aws_region }}"
autoscaling_group_name: "{{ resource_prefix }}-asg"
lifecycle_hook_name: "{{ resource_prefix }}-test-hook"
transition: autoscaling:EC2_INSTANCE_LAUNCHING
heartbeat_timeout: 7000
default_result: ABANDON
state: present
register: output

- assert:
that:
- output is not changed
- output is not failed
- '"lifecycle_hook_info" not in output'

- name: Update lifecycle hook
community.aws.ec2_asg_lifecycle_hook:
region: "{{ aws_region }}"
autoscaling_group_name: "{{ resource_prefix }}-asg"
lifecycle_hook_name: "{{ resource_prefix }}-test-hook"
transition: autoscaling:EC2_INSTANCE_LAUNCHING
heartbeat_timeout: 6000
default_result: ABANDON
state: present
register: output

- assert:
that:
- output is changed
- output is not failed
- '"lifecycle_hook_info" in output'
- output.lifecycle_hook_info[0].heartbeat_timeout == 6000

- name: Update lifecycle hook - Idempotency
community.aws.ec2_asg_lifecycle_hook:
region: "{{ aws_region }}"
autoscaling_group_name: "{{ resource_prefix }}-asg"
lifecycle_hook_name: "{{ resource_prefix }}-test-hook"
transition: autoscaling:EC2_INSTANCE_LAUNCHING
heartbeat_timeout: 6000
default_result: ABANDON
state: present
register: output

- assert:
that:
- output is not changed
- output is not failed
- '"lifecycle_hook_info" not in output'

- name: Delete lifecycle hook
community.aws.ec2_asg_lifecycle_hook:
region: "{{ aws_region }}"
autoscaling_group_name: "{{ resource_prefix }}-asg"
lifecycle_hook_name: "{{ resource_prefix }}-test-hook"
state: absent
register: output

- assert:
that:
- output is changed
- output is not failed
- '"lifecycle_hook_removed" in output'

- name: Delete lifecycle hook - Idempotency
community.aws.ec2_asg_lifecycle_hook:
region: "{{ aws_region }}"
autoscaling_group_name: "{{ resource_prefix }}-asg"
lifecycle_hook_name: "{{ resource_prefix }}-test-hook"
state: absent
register: output

- assert:
that:
- output is not changed
- output is not failed
- '"lifecycle_hook_removed" not in output'
Loading