Rob Wilkerson
Rob Wilkerson

Reputation: 41236

Filtering multiple tags in Ansible dynamic inventory

I think I've seen an answer to this somewhere, but I can't seem to find it now. I'm creating a dynamic development inventory file for my EC2 instances. I'd like to group all instances tagged with Stack=Development. Moreover, I'd like to specifically identify the development API servers. Those would not only have the Stack=Development tag, but also the API=Yes tag.

My basic setup uses inventory folders:

<root>/development
  ├── base
  ├── ec2.ini
  └── ec2.py

In my base file, I'd like to have something like this:

[servers]
tag_Stack_Development

[apiservers]
tag_Stack_Development && tag_API_Yes

Then I'd be able to run this to ping all of my development api servers:

ansible -i development -u myuser apiservers -m ping

Can something like that be done? I know the syntax isn't right, but hopefully the intent is reasonably clear? I can't imagine I'm the only one who's ever needed to filter on multiple tags, but I haven't been able to find anything that gets me where I'm trying to go.

Upvotes: 11

Views: 14602

Answers (3)

James Morgan
James Morgan

Reputation: 61

The answer provided by xiong-chiamiov does actually work. I've just been using it in my ansible deployment.

So I have a playbook using the dynamic inventory script. with this piece of code:

    ---
    - name: AWS Deploy
      hosts: tag_Environment_dev:&tag_Project_integration
      gather_facts: true

And the process does filter the hosts by both of those tags.

EDIT

Actually expanding on this, you can also use variables to make the host group specification dynamic. like this:

    ---
    - name: AWS Deploy
      hosts: "tag_Environment_{{env}}:&tag_Project_{{tag_project}}"
      sudo: true
      gather_facts: true

I use the {{env}} and {{tag_project}} vars from variable files and arguments given to ansible at runtime. It successfully changes the hosts the playbook runs against.

Upvotes: 6

Xiong Chiamiov
Xiong Chiamiov

Reputation: 13694

The Ansible documentation has a section on patterns. Rather than creating a new section, you can do a tag intersection when you specify the hosts:

[$] ansible -i development -u myuser tag_Stack_Development:&tag_API_Yes

This also works within playbooks.

Upvotes: 2

Rob Wilkerson
Rob Wilkerson

Reputation: 41236

It's not the answer I had in my head, but sometimes what's in my head just gets in the way. Since each inventory directory has its own ec2.ini, I just filter the stack there and then group within that filter.

# <root>/development/ec2.ini
...
instance_filters = tag:Stack=Development

# <root>/development/base
[tag_Role_webserver]
[tag_API_Yes]

[webservers:children]
tag_Role_webserver

[apiservers:children]
tag_API_Yes

Upvotes: 9

Related Questions