I have a group of servers in EC2 that will be a cluster of Consul server nodes, but on some of them I also want to run LDAP.
I believe in a static inventory file this would be:
[consul]
server1
server2
server3
[ldap]
server1
server 2
I’m using the pattern from the EC2 guide of calling out to the ec2 module to create or persist/no-op the instances and then using add_host to group them (so it does ec2/add_host during every call to ansible-playbook). I’m passing ‘type: consul’ in to the ec2 role which ends up in some of the naming tags and being used for idempotence/exact_count.
My question is: Where do I create the second group (‘ldap’)?
I’m kind of hoping I could slice the existing ‘consul’ group into an ldap group or start a play (within the same run of ansible-playbook) on only some of the hosts in the consul group:
name: Create instances
hosts: localhost
connection: local
roles:
role: ec2
type: consul
count: 3
name: Install Consul
hosts: consul
roles:
role: consul
name: Install LDAP
hosts: “A subset of ‘consul’, or a new ‘ldap’ subgroup created from a subset of ‘consul’”
roles:
role: ldap
And finally… the catch.
I’m using just enough tags to name the instances and get ‘count_tags’+‘exact_count’ to work with the EC2 module. I’d rather not add more tags to get an ‘ldap’ group out of ec2.py because I want to be able to use this with other cloud providers (existing playbooks already work with EC2 and Rackspace). In the past I’ve found that some providers may only support one tag/group, may not allow changing groups via API, or don’t do tags/groups at all and impotence is based on the instance name alone.
I’m hoping I’m overlooking an obvious fix but right now I’m planning to do:
name: Create instances
hosts: localhost
connection: local
roles:
role: ec2
type: consul_ldap
count: 2
role: ec2
type: consul
count: 1
name: Install Consul
hosts: consul_ldap:consul
roles:
Hi Mark, the way you’re planning is the correct way to do this, however you could use a conditional on the ldap role such that it would only run if the consul_ldap group was in the current host’s groups:
{ role: consul_ldap, when: “‘consul_ldap’ is in group_names” }
I don’t really recommend doing that, but it’s there should you decide to use it.
Thanks for the feedback on this back when… I just got a semi-permanent solution added that I wanted to share/see if I could get any thoughts on.
I added a couple tasks in my VM provisioning Ansible roles that process a new fact named “additional_roles” (with ‘roles’ in this context meaning “things this host does”. I need to do some term-fixing… this is using ‘role’, ‘service’, and ‘type’ fairly interchangably… but anyway)
This is the call which would set the new fact, and ‘provider’ may be ec2, rax, vagrant, or etc.:
and then the tasks within the ec2_add role, for example (new tasks in bold):
name: Set up a new host instance on EC2
local_action:
module: ec2
region: “{{ region }}”
… …
register: ec2
name: Add instance(s) to group representing type of host such as webnode or dbnode
local_action: add_host hostname={{ item.private_ip }} ansible_ssh_host={{ item.private_ip }} groupname={{ type }}
with_items: ec2.tagged_instances
when: wait == “yes”
name: Add instance(s) to combo service_type group, such as prod_dbnode, or staging_webnode
local_action: add_host hostname={{ item.private_ip }} ansible_ssh_host={{ item.private_ip }} groupname=“{{ service }}_{{ type }}”
with_items: ec2.tagged_instances
when: wait == “yes”
name: Add instance(s) to group representing type of host such as webnode or dbnode
local_action: add_host hostname={{ item[0].private_ip }} ansible_ssh_host={{ item[0].private_ip }} groupname={{ item[1] }}
with_nested:
ec2.tagged_instances
additional_roles
when: wait == “yes”
name: Add instance(s) to combo service_type group, such as prod_dbnode, or staging_webnode
local_action: add_host hostname={{ item[0].private_ip }} ansible_ssh_host={{ item[0].private_ip }} groupname=“{{ service }}_{{ item[1] }}”
with_nested:
ec2.tagged_instances
additional_roles
when: wait == “yes”
So, the method for my original goal of 3 consul nodes and 2 ldap nodes would be: