ngine-io / ansible-collection-cloudstack

CloudStack Ansible Collections
https://galaxy.ansible.com/ngine_io/cloudstack
GNU General Public License v3.0
21 stars 27 forks source link

Inventory plugin filter by tags #115

Open martialblog opened 1 year ago

martialblog commented 1 year ago

Hi,

First of all, great collection! Works like a charm.

I'm having a use case in which I need to filter the instances by tags.

I quickly hacked something together like this:

    def instance_tags_in_filter_tags(self, filter_tags, instance):
        instance_tags = instance.get('tags', [])
        for tag in filter_tags:
            if not tag.items() <= instance_tags.items():
                return False
        return True

    def parse(self, inventory, loader, path, cache=False):
        ...
        for instance in instances:
            filter_tags = self.get_option('filter_by_tags')
            if filter_tags and not self.instance_tags_in_filter_tags(filter_tags, instance):
                continue

Example in the cloudstack-instances.yml

filter_by_tags: 
  - foo: bar
  - bar: foo

Maybe not ideal yet, just to prototype the idea.

Before I open a PR, is that something you would consider adding?

Cheers Markus

resmo commented 1 year ago

Hi @martialblog,

So what you already could do is to group instances either by a key or using a group "condition":

keyed_groups:
  - key: tags.key
    prefix: tag_key
    separator: ""
groups:
  # add hosts to the group development if any of the dictionary's keys or values is the word 'devel'
  development: "'devel' in (tags|list)"

and use them as hosts target in playbooks:

- hosts:  tag_key_mykey

or

- hosts:  development

That said, I would be okay in a "filter by tag" PR (since we already have other filters) .

rvalle commented 1 year ago

I also use a generic way of grouping instances by tags like this:

keyed_groups:
  - prefix: grp
    key: tags.groups.split(',')

In this case, if your instance had, for example, the tags: docker, monitor and volatile it would get added to the ansible groups grp_docker, grp_monitor and grp_volatile.

martialblog commented 1 year ago

Hi, thanks for the replies.

In the particular use case the instances in a tier (production, staging, etc) might be in multiple VPCs and are identified by a tag (key: tier, value: staging).

And since I might want to have only the instances in that tier in my inventory, I thought filtering by tag would be the way to go.

@resmo In your suggestion I would have to have multiple playbooks if I want to use the same playbook on a different tier. Or I'd have to parameterize the playbook. Right?

resmo commented 1 year ago

Well, I could probably write a book about "separating tiers" in ansible and cloud environments.

Let's say you have 2 tiers, production, staging which contain instances and one inventory file. One thing you could do is to have a generic playbook for hosts in group "cloud" (so no specified tier) which contains all cloud hosts:

- hosts: cloud

and in your playbook run you limit the the hosts to that tier (basically a filter):

ansible-playbook cloud.yml --limit grp_staging

inventory cloudstack..yml

#...
groups:
  cloud: true
keyed_groups:
  - prefix: grp
    key: tags.groups.split(',')

But this can be error prune if you "forget" the --limit, the target is a mixed tier of staging and production which can lead to other problems when you have clusters and so forth.

So, my solution is to have separate inventories, cloudstack accounts/projects and API keys per tier:

ansible-playbook cloud.yml --inventory ./inventory/staging.cloudstack.yml 

you can even "hardcode" then the a group tier

#...
groups:
  cloud: true
  staging: true

and put the api key in a group_vars/staging/somehing.yml or group_vars/staging.yml resp. group_vars/production.yml for production hosts and because of this separation the hosts returned only consists of the separate projects/account.

I hope this makes sense.

martialblog commented 1 year ago

Yeah makes sense, that is kinda what is happening here. Different inventory files for different tiers. I don't trust people, including myself, to not forget the --limit

The only thing that was missing was a way to differentiate the instances by tags, since other methods (accounts,projects,vpc,etc) couldn't be applied. filter_by_tag seemed like a good solution.

rvalle commented 1 year ago

@martialblog adding support to group by vpc should be straight forward too check #106