amazon.aws icon indicating copy to clipboard operation
amazon.aws copied to clipboard

aws_ec2_inventory: An option to sort by hostname

Open giner opened this issue 4 years ago • 3 comments

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

giner avatar Nov 01 '21 08:11 giner

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.

click here for bot help

ansibullbot avatar Nov 01 '21 08:11 ansibullbot

Hi @giner,

I believe you can do the same thing with a ec2 tag. And the inventory plugin supports tag.

goneri avatar Nov 16 '21 20:11 goneri

Sorting by a tag would work as well if the inventory plugin supported it.

giner avatar Nov 16 '21 21:11 giner