Rolling update (handled by UpdatePolicy attribute) is a great feature in AWS Auto Scaling Group. With this feature, we are able to making changes without downtime. For example, replace existing instances one by one.
By design, NOT every change of the Auto Scaling Group can trigger a rolling update. Only the changes made to LaunchConfigurationName, LaunchTemplate and VPCZoneIdentifier property allow users to use UpdatePolicy to run rolling updates.
For example, we want every instance in an Auto Scaling Group to run a Ansible playbook when they launch up. This can be defined in the UserData property in the LaunchConfig. Something like:
# Clone latest Ansible playbooks
git clone https://my.github.com/ansible-repository
# Run Playbook to customize application
cd ./ansible-repository
ansible-playbook -i hosts customize_application_settings.yml
In the example, when the instance launches up, it downloads the latest Ansible playbook from Github. Then run the playbook customize_application_settings.yml. It is a playbook which pulls the metadata (e.g. Instance ID, IP address …) from the EC2 instance, then add them into the application configuration. A good example is the monitoring agent, like Splunk, New Relic …
What if I made a change in the customize_application_settings.yml playbook, and want to replace the existing instances one by one. So that they can have the latest ansible playbook. Do you think I can use rolling update here? The answer is NO. As the changes are only in the Ansible playbook, not in any one of the three properties that we mentioned above: LaunchConfigurationName, LaunchTemplate and VPCZoneIdentifier
The solution here is to have a toggle which allows you to run rolling update whenever you want.
First, lets create a new parameter in the CloudFormation template
---
Parameters:
RollingUpdateToggle:
Type: String
Description: Force rolling updates regardless if there are any launch config changes. Choose between blue and green.
Second, lets refer the parameter into the UserData.
# Print rolling update toggle
!Sub ["echo RollingUpdateToggle is ${RollingUpdateToggle}\n", RollingUpdateToggle: !Ref RollingUpdateToggle]
# Clone latest Ansible playbooks
git clone https://my.github.com/ansible-repository
# Run Playbook to customize application
cd ./ansible-repository
ansible-playbook -i hosts customize_application_settings.yml
How to use it? Simply give RollingUpdateToggle parameter a different value from previous one, like switching between blue and green back and force.
For example, I want to run a rolling update each time after I made changes to the AnsbileIt. It will be something like:
- Create cloudformation stack: RollingUpdateToggle=blue
- Make changes to Ansbile playbook then update cloudformation stack: RollingUpdateToggle=green
- Make changes to Ansbile playbook then update cloudformation stack: RollingUpdateToggle=blue
- Make changes to Ansbile playbook then update cloudformation stack: RollingUpdateToggle=green
…