amazon.aws
amazon.aws copied to clipboard
aws_ec2_inventory: An option to sort by hostname
Summary
The current implementation of ec2_inventory plugin is sorting the hosts by InstanceId. This is good enough to ensure stable ordering of the hosts within a hostgroup as long as no more nodes are added or deleted. However this implementation becomes an issue when the nodes in the group are not equal, for example, one node is supposed to be a master or initial node and treated differently than others.
With static inventories the problem has a simple solution: taking the first node of the group (e.g. hostvars[groups['db_cluster'][0]] where db_cluster includes db1, db2 and db3). This doesn't work well with aws_ec2_inventory as the first node in the group could be any of the three.
One solution could be sorting the hostnames in-place, e.g. db_primary_node: "{{ groups['db_cluster'] | sort | first }}" however we would have to do this everywhere, in all playbooks, roles and inventories where we rely on the host order. Another slightly relevant problem is run_once implementation (and everything else that is using the same logic) which makes the tasks run only on the first node in the group but skipped if the first node is skipped (see https://github.com/ansible/ansible/issues/19966).
An easy fix for these would be an option to sort hosts by their hostnames within a group.
Issue Type
Feature Idea
Component Name
aws_ec2_inventory, ec2_inventory
Additional Information
A naive hard-coded implementation:
diff --git a/collections/ansible_collections/amazon/aws/plugins/inventory/aws_ec2.py b/collections/ansible_collections/amazon/aws/plugins/inventory/aws_ec2.py
index 3806a0a2..113aba23 100644
--- a/collections/ansible_collections/amazon/aws/plugins/inventory/aws_ec2.py
+++ b/collections/ansible_collections/amazon/aws/plugins/inventory/aws_ec2.py
@@ -615,7 +615,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
instances.append(i)
ids_to_ignore.append(i['InstanceId'])
- instances = sorted(instances, key=lambda x: x['InstanceId'])
+ instances = sorted(instances, key=lambda x: self._get_hostname(x, self.get_option('hostnames')))
return {'aws_ec2': instances}
Code of Conduct
- [X] I agree to follow the Ansible Code of Conduct
Files identified in the description: None
If these files are inaccurate, please update the component name section of the description or use the !component bot command.
Hi @giner,
I believe you can do the same thing with a ec2 tag. And the inventory plugin supports tag.
Sorting by a tag would work as well if the inventory plugin supported it.