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

Add asg refresh and asg refresh info modules #795

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
69b03cd
Add module and tests for ec2_asg_instance_refreshes_info
danquixote Feb 18, 2021
06c7652
Add module and tests for ec2_asg_instance_refresh
danquixote Feb 18, 2021
fcc78ec
Fix documentation
danquixote Feb 25, 2021
23ddd64
Update runtime.yml for new EC2 ASG refresh modules
danquixote Mar 19, 2021
fcabb37
Fixup documentation for ec2_asg_instance_refresh.py and ec2_asg_insta…
danquixote May 16, 2021
9f01ec0
Fix AMI selection and fact-setting
danquixote May 16, 2021
cb6fb06
Make subnet selection more random
danquixote May 16, 2021
0184248
Fix/combine aliases files for ec2_asg_instance_refresh and ec2_asg_in…
danquixote May 16, 2021
232df24
Remove unneeded AWS environment variables
danquixote May 16, 2021
9ba2018
Fix spelling of 'cancelled'
danquixote May 16, 2021
0f60592
Remove trailing whitespace in YAML
danquixote May 16, 2021
1594a64
Fix YaML bug in main testfile
danquixote May 26, 2021
1ac7e8c
Re-fix YAML
danquixote May 27, 2021
0bca9c3
Add vpc_seed variable to defaults
danquixote May 27, 2021
df1110f
Fix 'subnet_a_cidr' var invocation
danquixote May 27, 2021
c8b6e93
Make test asertion more specific, due to spelling bug on AWS' side
danquixote May 27, 2021
b3b02d4
Merge ec2_asg_instance_refresh and ec2_asg_instance_refreshes_info ta…
danquixote May 30, 2021
f7bebee
Try to re-fix aliases
danquixote Jun 1, 2021
4b6333f
Move mistakenly deleted YaML file to proper place.
danquixote Jun 1, 2021
e704d76
Remove extra blank line in YaML
danquixote Jun 1, 2021
a6ff601
Fix spelling
danquixote Jun 1, 2021
41816e9
Improve loop and fixup assertion
danquixote Jun 2, 2021
2b6b5d2
Fix another assertion
danquixote Jun 2, 2021
32ada82
Fix asertion based on AWS' new token obfuscation
danquixote Jun 2, 2021
70f86c3
Fix another assertion - after merging targets
danquixote Jun 2, 2021
8e4b23b
Resolving merge conflicts
mandar242 Feb 23, 2022
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
2 changes: 2 additions & 0 deletions meta/runtime.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ action_groups:
- ec2_ami_copy
- ec2_asg
- ec2_asg_info
- ec2_asg_instance_refresh
- ec2_asg_instance_refreshes_info
- ec2_asg_scheduled_action
- ec2_asg_lifecycle_hook
- ec2_customer_gateway
Expand Down
197 changes: 197 additions & 0 deletions plugins/modules/ec2_asg_instance_refresh.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
#!/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


DOCUMENTATION = '''
---
module: ec2_asg_instance_refresh
version_added: 1.0.0
short_description: Start or cancel an EC2 Auto Scaling Group (ASG) instance refresh in AWS
description:
- Start or cancel an EC2 Auto Scaling Group instance refresh in AWS.
- Can be used with ec2_asg_instance_refreshes_info to track the subsequent progress
requirements: [ boto3 ]
author: "Dan Khersonsky (@danquixote)"
options:
state:
description:
- Desired state of the ASG
type: str
required: true
choices: [ 'started', 'cancelled' ]
name:
description:
- The name of the auto scaling group you are searching for.
type: str
required: true
strategy:
description:
- The strategy to use for the instance refresh. The only valid value is Rolling.
- A rolling update is an update that is applied to all instances in an Auto Scaling group until all instances have been updated.
- A rolling update can fail due to failed health checks or if instances are on standby or are protected from scale in.
- If the rolling update process fails, any instances that were already replaced are not rolled back to their previous configuration.
type: str
default: 'Rolling'
preferences:
description:
- Set of preferences associated with the instance refresh request.
- If not provided, the default values are used.
- For I(min_healthy_percentage), the default value is C(90).
- For InstanceWarmup, the default is to use the value specified for the health check grace period for the Auto Scaling group.
required: false
suboptions:
min_healthy_percentage:
description:
- The amount of capacity in the Auto Scaling group that must remain healthy during an instance refresh to allow the operation to continue,
- as a percentage of the desired capacity of the Auto Scaling group (rounded up to the nearest integer).
- The default is 90.
type: int
instance_warmup:
description:
- The number of seconds until a newly launched instance is configured and ready to use.
- During this time, Amazon EC2 Auto Scaling does not immediately move on to the next replacement.
- The default is to use the value for the health check grace period defined for the group.
type: int
type: dict
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: Start a refresh
community.aws.ec2_asg_instance_refresh:
name: some-asg
state: started

- name: Cancel a refresh
community.aws.ec2_asg_instance_refresh:
name: some-asg
state: cancelled

- name: Start a refresh and pass preferences
community.aws.ec2_asg_instance_refresh:
name: some-asg
state: started
preferences:
min_healthy_percentage: 91
instance_warmup: 60

'''

RETURN = '''
---
instance_refresh_id:
description: instance refresh id
returned: success
type: str
sample: "08b91cf7-8fa6-48af-b6a6-d227f40f1b9b"
'''

try:
from botocore.exceptions import BotoCoreError, ClientError
except ImportError:
pass # caught by AnsibleAWSModule


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


def start_or_cancel_instance_refresh(conn, module):
"""
Args:
conn (boto3.AutoScaling.Client): Valid Boto3 ASG client.
name (str): Mandatory name of the ASG you are looking for.
state (str): Start or Cancel a refresh

Returns:
Dict
{
'instance_refresh_id': 'string'
}
"""

asg_state = module.params.get('state')
asg_name = module.params.get('name')
preferences = module.params.get('preferences')

args = {}
args['AutoScalingGroupName'] = asg_name
if asg_state == 'started':
args['Strategy'] = 'Rolling'
if preferences:
if asg_state == 'cancelled':
module.fail_json(msg='can not pass preferences dict when canceling a refresh')
_prefs = scrub_none_parameters(preferences)
args['Preferences'] = snake_dict_to_camel_dict(_prefs, capitalize_first=True)
cmd_invocations = {
'cancelled': conn.cancel_instance_refresh,
'started': conn.start_instance_refresh,
}
try:
result = cmd_invocations[asg_state](aws_retry=True, **args)
result = dict(
instance_refresh_id=result['InstanceRefreshId']
)
return module.exit_json(**result)
except (BotoCoreError, ClientError) as e:
module.fail_json_aws(
e,
msg='Failed to {0} InstanceRefresh'.format(
asg_state.replace('ed', '')
)
)


def main():

argument_spec = dict(
state=dict(
type='str',
required=True,
choices=['started', 'cancelled'],
),
name=dict(required=True),
strategy=dict(
type='str',
default='Rolling',
required=False
),
preferences=dict(
type='dict',
required=False,
options=dict(
min_healthy_percentage=dict(type='int'),
instance_warmup=dict(type='int'),
)
),
)

module = AnsibleAWSModule(argument_spec=argument_spec)
autoscaling = module.client(
'autoscaling',
retry_decorator=AWSRetry.jittered_backoff(
retries=10,
catch_extra_error_codes=['InstanceRefreshInProgress']
)
)
results = start_or_cancel_instance_refresh(
autoscaling,
module,
)
return results


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