diff --git a/plugins/modules/autoscaling_instance_refresh.py b/plugins/modules/autoscaling_instance_refresh.py index d9325cd4035..05fefa6b024 100644 --- a/plugins/modules/autoscaling_instance_refresh.py +++ b/plugins/modules/autoscaling_instance_refresh.py @@ -63,6 +63,7 @@ - Indicates whether skip matching is enabled. - If enabled V(true), then Amazon EC2 Auto Scaling skips replacing instances that match the desired configuration. type: bool + version_added: 9.0.0 max_healthy_percentage: description: - Specifies the maximum percentage of the group that can be in service and healthy, or pending, @@ -71,6 +72,7 @@ - Value range is V(100) to V(200). - When specified, you must also specify O(preferences.min_healthy_percentage), and the difference between them cannot be greater than 100. type: int + version_added: 9.0.0 type: dict extends_documentation_fragment: - amazon.aws.common.modules @@ -192,8 +194,8 @@ def validate_healthy_percentage(preferences: Dict[str, Union[bool, int]]) -> Opt min_healthy_percentage = preferences.get("min_healthy_percentage") max_healthy_percentage = preferences.get("max_healthy_percentage") - if min_healthy_percentage is not None and (min_healthy_percentage < 0 or min_healthy_percentage > 90): - return "The value range for the min_healthy_percentage is 0 to 90." + if min_healthy_percentage is not None and (min_healthy_percentage < 0 or min_healthy_percentage > 100): + return "The value range for the min_healthy_percentage is 0 to 100." if max_healthy_percentage is not None: if max_healthy_percentage < 100 or max_healthy_percentage > 200: return "The value range for the max_healthy_percentage is 100 to 200." diff --git a/tests/integration/targets/autoscaling_instance_refresh/tasks/instance_refresh_info.yml b/tests/integration/targets/autoscaling_instance_refresh/tasks/instance_refresh_info.yml index 060bf69c99d..18621027535 100644 --- a/tests/integration/targets/autoscaling_instance_refresh/tasks/instance_refresh_info.yml +++ b/tests/integration/targets/autoscaling_instance_refresh/tasks/instance_refresh_info.yml @@ -4,89 +4,98 @@ name: "{{ asg_name }}" register: output -- assert: +- name: Assert that the correct number of records are returned + assert: that: - output | community.general.json_query(inst_refresh_id_json_query) | unique | length == 7 vars: inst_refresh_id_json_query: instance_refreshes[].instance_refresh_id -- name: test using fake refresh ID +- name: Test using fake refresh ID autoscaling_instance_refresh_info: name: "{{ asg_name }}" ids: ['0e367f58-blabla-bla-bla-ca870dc5dbfe'] register: output -- assert: +- name: Assert that no record is returned + assert: that: - output.instance_refreshes | length == 0 -- name: test using a real refresh ID +- name: Test using a real refresh ID autoscaling_instance_refresh_info: name: "{{ asg_name }}" ids: [ '{{ refreshout.instance_refreshes.instance_refresh_id }}' ] register: output -- assert: +- name: Assert that the correct record is returned + assert: that: - output.instance_refreshes | length == 1 -- name: test getting info for an ASG name which doesn't exist +- name: Test getting info for an ASG name which doesn't exist autoscaling_instance_refresh_info: name: n0n3x1stentname27b ignore_errors: yes register: output -- assert: +- name: Assert that module failed to return record + assert: that: - "'Failed to describe InstanceRefreshes: An error occurred (ValidationError) when calling the DescribeInstanceRefreshes operation: AutoScalingGroup name not found - AutoScalingGroup n0n3x1stentname27b not found' in output.msg" -- name: assert that the correct number of records are returned +- name: Retrieve instance refresh info autoscaling_instance_refresh_info: name: "{{ asg_name }}" register: output -- assert: +- name: Assert that the correct number of records are returned + assert: that: - output.instance_refreshes | length == 7 -- name: assert that valid message with fake-token is returned +- name: Retrieve instance refresh info using next_token autoscaling_instance_refresh_info: name: "{{ asg_name }}" next_token: "fake-token-123" ignore_errors: yes register: output -- assert: +- name: Assert that valid message with fake-token is returned + assert: that: - '"Failed to describe InstanceRefreshes: An error occurred (InvalidNextToken) when calling the DescribeInstanceRefreshes operation: The token ''********'' is invalid." in output.msg' -- name: assert that max records=1 returns no more than one record +- name: Retrieve instance refresh info using max_records autoscaling_instance_refresh_info: name: "{{ asg_name }}" max_records: 1 register: output_with_token -- assert: +- name: Assert that max records=1 returns no more than one record + assert: that: - output_with_token.instance_refreshes | length == 1 -- name: assert that valid message with real-token is returned +- name: Retrieve instance refresh using valid token autoscaling_instance_refresh_info: name: "{{ asg_name }}" next_token: "{{ output_with_token.next_token }}" register: output -- assert: +- name: Assert that valid message with real-token is returned + assert: that: - output.instance_refreshes | length == 6 -- name: test using both real nextToken and max_records=1 +- name: Test using both real nextToken and max_records=1 autoscaling_instance_refresh_info: name: "{{ asg_name }}" max_records: 1 next_token: "{{ output_with_token.next_token }}" register: output -- assert: +- name: Assert that only one instance refresh is returned + assert: that: - output.instance_refreshes | length == 1 diff --git a/tests/integration/targets/autoscaling_instance_refresh/tasks/main.yml b/tests/integration/targets/autoscaling_instance_refresh/tasks/main.yml index 804c29e9763..380072a09b5 100644 --- a/tests/integration/targets/autoscaling_instance_refresh/tasks/main.yml +++ b/tests/integration/targets/autoscaling_instance_refresh/tasks/main.yml @@ -35,7 +35,7 @@ Name: "{{ subnet_name }}" register: testing_subnet - - name: create routing rules + - name: Create routing rules ec2_vpc_route_table: vpc_id: "{{ testing_vpc.vpc.id }}" tags: @@ -46,7 +46,7 @@ subnets: - "{{ testing_subnet.subnet.id }}" - - name: create a security group with the vpc created in the ec2_setup + - name: Create a security group with the vpc created in the ec2_setup ec2_security_group: name: "{{ sg_name }}" description: a security group for ansible tests @@ -62,7 +62,7 @@ cidr_ip: 0.0.0.0/0 register: sg - - name: ensure launch configs exist + - name: Ensure launch configs exist autoscaling_launch_config: name: "{{ item }}" assign_public_ip: true @@ -80,7 +80,7 @@ - "{{ lc_name_1 }}" - "{{ lc_name_2 }}" - - name: launch asg and do not wait for instances to be deemed healthy (no ELB) + - name: Launch asg and do not wait for instances to be deemed healthy (no ELB) autoscaling_group: name: "{{ asg_name }}" launch_config_name: "{{ lc_name_1 }}" @@ -92,7 +92,8 @@ state: present register: output - - assert: + - name: Assert that there is no viable instance + assert: that: - "output.viable_instances == 0" @@ -111,7 +112,7 @@ always: - - name: kill asg + - name: Kill asg autoscaling_group: name: "{{ asg_name }}" state: absent @@ -121,7 +122,7 @@ retries: 10 # Remove the testing dependencies - - name: remove the load balancer + - name: Remove the load balancer elb_classic_lb: name: "{{ load_balancer_name }}" state: absent @@ -147,7 +148,7 @@ ignore_errors: yes retries: 10 - - name: remove launch configs + - name: Remove launch configs autoscaling_launch_config: name: "{{ item }}" state: absent @@ -159,7 +160,7 @@ - "{{ lc_name_1 }}" - "{{ lc_name_2 }}" - - name: delete launch template + - name: Delete launch template ec2_launch_template: name: "{{ resource_prefix }}-lt" state: absent @@ -168,7 +169,7 @@ until: del_lt is not failed ignore_errors: true - - name: remove the security group + - name: Remove the security group ec2_security_group: name: "{{ sg_name }}" description: a security group for ansible tests @@ -179,7 +180,7 @@ ignore_errors: yes retries: 10 - - name: remove routing rules + - name: Remove routing rules ec2_vpc_route_table: state: absent vpc_id: "{{ testing_vpc.vpc.id }}" @@ -195,7 +196,7 @@ ignore_errors: yes retries: 10 - - name: remove internet gateway + - name: Remove internet gateway ec2_vpc_igw: vpc_id: "{{ testing_vpc.vpc.id }}" state: absent @@ -204,7 +205,7 @@ ignore_errors: yes retries: 10 - - name: remove the subnet + - name: Remove the subnet ec2_vpc_subnet: state: absent vpc_id: "{{ testing_vpc.vpc.id }}" @@ -214,7 +215,7 @@ ignore_errors: yes retries: 10 - - name: remove the VPC + - name: Remove the VPC ec2_vpc_net: name: "{{ vpc_name }}" cidr_block: '{{ subnet_a_cidr }}' diff --git a/tests/integration/targets/autoscaling_instance_refresh/tasks/refresh_and_cancel_three_times.yml b/tests/integration/targets/autoscaling_instance_refresh/tasks/refresh_and_cancel_three_times.yml index bdf74c38083..b376eba463f 100644 --- a/tests/integration/targets/autoscaling_instance_refresh/tasks/refresh_and_cancel_three_times.yml +++ b/tests/integration/targets/autoscaling_instance_refresh/tasks/refresh_and_cancel_three_times.yml @@ -1,5 +1,5 @@ --- -- name: test starting a refresh with an ASG name +- name: Test starting a refresh with an ASG name autoscaling_instance_refresh: name: "{{ asg_name }}" state: "started" @@ -9,7 +9,7 @@ register: refreshout until: refreshout is not failed -- name: test cancelling a refresh with an ASG name +- name: Test cancelling a refresh with an ASG name autoscaling_instance_refresh: name: "{{ asg_name }}" state: "cancelled" diff --git a/tests/integration/targets/autoscaling_instance_refresh/tasks/start_cancel_instance_refresh.yml b/tests/integration/targets/autoscaling_instance_refresh/tasks/start_cancel_instance_refresh.yml index b29e676edce..52fa496fe3c 100644 --- a/tests/integration/targets/autoscaling_instance_refresh/tasks/start_cancel_instance_refresh.yml +++ b/tests/integration/targets/autoscaling_instance_refresh/tasks/start_cancel_instance_refresh.yml @@ -6,113 +6,123 @@ ignore_errors: true register: result -- assert: +- name: Assert that module failed with proper message + assert: that: - "'An error occurred (ActiveInstanceRefreshNotFound) when calling the CancelInstanceRefresh operation: No in progress or pending Instance Refresh found for Auto Scaling group ' ~ resource_prefix ~ '-asg' in result.msg" -- name: test starting a refresh with a valid ASG name - check_mode +- name: Test starting a refresh with a valid ASG name - check_mode autoscaling_instance_refresh: name: "{{ asg_name }}" state: "started" check_mode: true register: output -- assert: +- name: Validate starting in check_mode + assert: that: - output is changed - '"autoscaling:StartInstanceRefresh" not in output.resource_actions' -- name: test starting a refresh with a valid ASG name +- name: Test starting a refresh with a valid ASG name autoscaling_instance_refresh: name: "{{ asg_name }}" state: "started" register: output -- assert: +- name: Validate start + assert: that: - "'instance_refresh_id' in output.instance_refreshes" -- name: test starting a refresh with a valid ASG name - Idempotent +- name: Test starting a refresh with a valid ASG name - Idempotent autoscaling_instance_refresh: name: "{{ asg_name }}" state: "started" ignore_errors: true register: output -- assert: +- name: Validate starting Idempotency + assert: that: - output is not changed - '"Failed to start InstanceRefresh: An error occurred (InstanceRefreshInProgress) when calling the StartInstanceRefresh operation: An Instance Refresh is already in progress and blocks the execution of this Instance Refresh." in output.msg' -- name: test starting a refresh with a valid ASG name - Idempotent (check_mode) +- name: Test starting a refresh with a valid ASG name - Idempotent (check_mode) autoscaling_instance_refresh: name: "{{ asg_name }}" state: "started" check_mode: true register: output -- assert: +- name: Validate starting Idempotency in check_mode + assert: that: - output is not changed - '"In check_mode - Instance Refresh is already in progress, can not start new instance refresh." in output.msg' -- name: test starting a refresh with a nonexistent ASG name +- name: Test starting a refresh with a nonexistent ASG name autoscaling_instance_refresh: name: "nonexistentname-asg" state: "started" ignore_errors: yes register: result -- assert: +- name: Assert that module failed with proper message + assert: that: - "'Failed to start InstanceRefresh: An error occurred (ValidationError) when calling the StartInstanceRefresh operation: AutoScalingGroup name not found' in result.msg" -- name: test canceling a refresh with an ASG name - check_mode +- name: Test canceling a refresh with an ASG name - check_mode autoscaling_instance_refresh: name: "{{ asg_name }}" state: "cancelled" check_mode: true register: output -- assert: +- name: Validate cancelation + assert: that: - output is not failed - output is changed - '"autoscaling:CancelInstanceRefresh" not in output.resource_actions' -- name: test canceling a refresh with an ASG name +- name: Test canceling a refresh with an ASG name autoscaling_instance_refresh: name: "{{ asg_name }}" state: "cancelled" register: output -- assert: +- name: Validate cancelation + assert: that: - "'instance_refresh_id' in output.instance_refreshes" -- name: test canceling a refresh with a ASG name - Idempotent +- name: Test canceling a refresh with a ASG name - Idempotent autoscaling_instance_refresh: name: "{{ asg_name }}" state: "cancelled" register: output ignore_errors: true -- assert: +- name: Validate cancelling Idempotency + assert: that: - output is not changed -- name: test cancelling a refresh with a valid ASG name - Idempotent (check_mode) +- name: Test cancelling a refresh with a valid ASG name - Idempotent (check_mode) autoscaling_instance_refresh: name: "{{ asg_name }}" state: "cancelled" check_mode: true register: output -- assert: +- name: Validate cancelling Idempotency in check_mode + assert: that: - output is not changed -- name: test starting a refresh with an ASG name and preferences dict +- name: Test starting a refresh with an ASG name and preferences dict autoscaling_instance_refresh: name: "{{ asg_name }}" state: "started" @@ -123,21 +133,23 @@ register: output until: output is not failed -- assert: +- name: Assert that module succeed with preferences + assert: that: - "'instance_refresh_id' in output.instance_refreshes" -- name: re-test canceling a refresh with an ASG name +- name: Re-test canceling a refresh with an ASG name autoscaling_instance_refresh: name: "{{ asg_name }}" state: "cancelled" register: output -- assert: +- name: Assert that module returned instance refresh id + assert: that: - "'instance_refresh_id' in output.instance_refreshes" -- name: test valid start - V1 - (with preferences missing instance_warmup) +- name: Test valid start - V1 - (with preferences missing instance_warmup) autoscaling_instance_refresh: name: "{{ asg_name }}" state: "started" @@ -147,21 +159,23 @@ register: output until: output is not failed -- assert: +- name: Validate start with preferences missing instance warmup + assert: that: - "'instance_refresh_id' in output.instance_refreshes" -- name: re-test canceling a refresh with an ASG name +- name: Re-test canceling a refresh with an ASG name autoscaling_instance_refresh: name: "{{ asg_name }}" state: "cancelled" register: output -- assert: +- name: Validate canceling Idempotency + assert: that: - "'instance_refresh_id' in output.instance_refreshes" -- name: test valid start - V2 - (with preferences missing min_healthy_percentage) +- name: Test valid start - V2 - (with preferences missing min_healthy_percentage) autoscaling_instance_refresh: name: "{{ asg_name }}" state: "started" @@ -171,11 +185,12 @@ register: output until: output is not failed -- assert: +- name: Assert that module did not returned and instance refresh id + assert: that: - "'instance_refresh_id' in output.instance_refreshes" -- name: test invalid cancelation - V2 - (with preferences) +- name: Test invalid cancelation - V2 - (with preferences) autoscaling_instance_refresh: name: "{{ asg_name }}" state: "cancelled" @@ -185,6 +200,7 @@ ignore_errors: yes register: result -- assert: +- name: Assert that module failed with proper message + assert: that: - "'can not pass preferences dict when canceling a refresh' in result.msg" diff --git a/tests/integration/targets/autoscaling_instance_refresh/vars/main.yml b/tests/integration/targets/autoscaling_instance_refresh/vars/main.yml deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/tests/unit/plugins/modules/test_autoscaling_instance_refresh.py b/tests/unit/plugins/modules/test_autoscaling_instance_refresh.py index a032b6953eb..590074367a2 100644 --- a/tests/unit/plugins/modules/test_autoscaling_instance_refresh.py +++ b/tests/unit/plugins/modules/test_autoscaling_instance_refresh.py @@ -10,8 +10,8 @@ "min_healthy, max_healthy, expected_error", [ (90, None, None), - (-1, None, "The value range for the min_healthy_percentage is 0 to 90."), - (91, None, "The value range for the min_healthy_percentage is 0 to 90."), + (-1, None, "The value range for the min_healthy_percentage is 0 to 100."), + (101, None, "The value range for the min_healthy_percentage is 0 to 100."), (None, 90, "The value range for the max_healthy_percentage is 100 to 200."), (None, 201, "The value range for the max_healthy_percentage is 100 to 200."), (None, 100, "You must also specify min_healthy_percentage when max_healthy_percentage is specified."),