I want to create a dynamic inventory, and create a group to put the nodes where I scrape data from.I'm using the gcp_compute plugin in my dynamic inventory.
What I want to achieve:
I want to retrieve multiple hostnames/ip and put them in the same group. I want it to be quite modular, so I can switch nodenames easily.
This how it looks so far:
plugin: gcp_compute
auth_kind: serviceaccount
cache: true
gather_facts: false
retrieve_image_info: true
service_account_file: servicefile.json
groups:
node_exporter: "'db-vm' in name"
I want to use something like: node_exporter: "'db-vm' OR 'prometheus-vm' in name" or something similar. How can I achieve this.
This is the command I use too see if it works or not: ansible-inventory -i gce_inventory.gcp.yml --graph. All my nodes gets ungrouped.
I solved it very easily...
I believe I made some mistakes before when doing the conditional, but now accidentally solved it.
To be able to retrieve multiple, here how:
node_exporter: "'db-vm' in name or 'prometheus-vm' in name"
Related
I'm new to Ansible so be patient. I was trying to create a dynamic inventory using Ansible's dynamic inventory pluging. In particular I'm using hcloud plugin to interface with Hetzner's API.
What I'd like to do is create 3 groups : databases, nfs, k8s.
All servers have already been tag as follows :
app=mysql for mySQL database servers
app=nfs for NFS servers
app=k8s for k8s cluster servers (workers and masters)
To say the docs are lacking is using an euphemism. I've tried using label_selector as follows with no success:
plugin: hcloud
token: hehe
groups:
databases:
label_selector: app=mysql
nfs:
label_selector: app=nfs
k8s:
label_selector: app=k8s
This indeed results in the creation of 3+ groups :
all
databases
nfs
k8s
ungrouped
hcloud
yet all groups contain all hosts, regardless of the label.
So my questions are :
Assuming I'm using something like keyed_groups, which "Add hosts to group based on the values of a variable.", where can I find accepted variables?In the example they use 'location', 'image_os_flavor' and 'status' but I haven't found a list of accepted variable names that I could use.
How could I implement a dynamic Inventory that reaches the previously explained goal?
Is it possible to add group variables in dynamically generated inventories?
Thanks a lot to everyone, let me know how to improve my question as well.
You can do:
groups:
databases: labels.app == 'mysql'
nfs: labels.app == 'nfs'
k8s: labels.app == 'k8s'
The documentation is here:
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/constructed_inventory.html
Id like to populate ansible variables from a script that generated whenever a play is done. in particular, ive written something that uses an api somewhere to get users in a group on an application. Id like this to be run locally, and form the group vars for a play.
Script output:
users:
user1: jsmith
ssh_key: .......
user2: fsmith
ssh_key: .......
Is there a way to use dynamic variables? Something akin to dynamic inventory?
p.s. the first line of the output was '---' but I dont know how to get that to show here.
You can dynamically define variables within a play using set_fact: https://docs.ansible.com/ansible/2.5/modules/set_fact_module.html
Now for your use-case, imho, it would be better if your script returns a json result as it would be easier to parse using jinja filters
I have this playbook:
roles:
- { role: common}
- { role: mariadb}
- { role: wordpress}
What is want is in every role I want to have first task as some conditional which if true then I want to skip the whole role and playbook continues to next.
Now I can use when like this:
roles:
- { role: common, when: mvar is False }
But for that I have to evaluate the mvar in playbook itself but for that mvar I need all other vars etc. stuff which is in that role itself. So it will be easier for me to do in role.
Is there any way?
In each role, in tasks/main.yml include a file with tasks only when the condition is met:
- include: real_tasks.yml
when: condition_is_met
In addition to #techraf's answer, one can also use include_tasks instead of include.
- include_tasks: real_tasks.yml
when: condition_is_met
Ansible include documentation says:
Notes
Include has some unintuitive behaviours depending on if it is running in a static or dynamic in play or in playbook context, in an effort to clarify behaviours we are moving to a new set modules (include_tasks, include_role, import_playbook, import_tasks) that have well established and clear behaviours. This module will still be supported for some time but we are looking at deprecating it in the near future.
In addition to the answers above, you could also consider using Tags to skip specific tasks or roles depending on how you are calling the roles.
https://docs.ansible.com/ansible/latest/user_guide/playbooks_tags.html
This will work well if the condition is determined in a less dynamic manner - so if you have a large playbook but know at the point of execution that you want to skip certain parts.
Tags can also be used to selectively run specific tasks.
Note: using tags in this way is often a great way to test specific parts of a playbook during development without running the whole thing.
I would like to have a starter playbook, say go.yml -- and within this, I would like to be able to prompt the user for which products they would like to perform actions on (say proxy, lb, etc.).
Is there a way I can query the user for input, and then based on that input initiate playbooks? Basically, I want something like the following:
- hosts: "prod"
sudo: yes
vars_prompt:
product: "What product do you want to deploy?"
if product == proxy:
- include proxy.yml
if product == lb:
- include lb.yml
...
I'm not very comfortable with how playbooks flow, and how they differ distinctly from task/handler files. Is anything like this possible? My goal is to avoid having a dozen different playbook files to choose from, and instead just have a default initiation type playbook which can always be used.
A playbook can include other playbooks. So you can have multiple playbooks which are triggered through a single entry point playbook. But on playbook level there are not conditions. All included playbooks will be executed.
Your conditions on roles theoretically would work. The correct syntax would be:
roles:
- role: proxy
when: product == "proxy"
- role: lb
when: product == "lb"
But this is kind of re-inventing the wheel. To limit which roles should be executed one usually uses tags (and skip-tags).
roles:
- role: proxy
tags: proxy
- role: lb
tags: lb
Then, for example, call you playbook with --tags "proxy". This also works with included playbooks.
The downside of using vars_prompt and conditions on roles is, you'll get tons of skipped tasks when executing the playbook. When filtered by tag the non-matching roles/tasks will not be shown with a skipped state.
(This is a cross-post from the mailing list, since I haven't gotten any answers there.)
I've recently set up fail2ban for ssh on one of my servers using https://galaxy.ansible.com/tersmitten/fail2ban/ . This was very easy, and I'm loving galaxy.
Now, I'm wanting to extend fail2ban to also block IPs that have failed basic auth checks in Apache too many times. Since all my hosts run ssh, but not all run Apache, I've created a new role for this (cleverly named 'apache', while the first is 'common'). However, as shown in the fail2ban role's README, configuration of individual services is done with an array, fail2ban_services, and redefining that in my apache role overwrites what was defined in common (or, due to timing, vice versa).
I've seen that I can change the hash behavior, which would seem to do what I want. I'm wary of this, however, since it's a global change.
There is also the combine filter for jinja, but reports indicate I can't do what I want, which would be
fail2ban_services: "{{ fail2ban_services | combine({...}) }}"
Is there another method to do this combination? Or perhaps am I going about this the wrong way, and should be architecting this differently?
I'm using ansible 2.0.1.0.
hash_behavior: merge and the combine filter would not be helpful, because those are for hashes. If I get the docs of fail2ban right, the fail2ban_services variable though is a list of hashes:
fail2ban_services:
- name: serviceA
...
- name: serviceB
...
- name: serviceC
...
You can easily merge lists:
listA: "{{ listB + listC }}"
... but the same limitations apply as for the combine filter. You can not override a variable which depends on itself, Ansible will complain about some "recursive loop detected" or so. No clue why this is such a big problem for Ansible, there should nothing be recursive in doing a = a + b. But unfortunately that's how it is.
If I understood your description, you define the fail2ban_services list in your role common. Then later you want to re-define it in the role apache. How is actually the fail2ban role implemented? Do you have 3 roles then in your playbook like so?
roles:
- common
- apache
- fail2ban
And the goal is, the first roles define what the last role then is using?
Given the mentioned limitations, my only idea then would be to rename your variables. The role common will define fail2ban_services_common, the role apache will define fail2ban_services_apache and then you pass the combined value to fail2ban:
roles:
- common
- apache
- role: fail2ban
fail2ban_services: "{{ fail2ban_services_common + fail2ban_services_apache}}"