Is it possible to force the function to_nice_yaml to avoid generating aliases?
The following line in the Ansible template
scrape_configs:
{{ scrape_configs | to_nice_yaml(indent=2) | indent(2,False) }}
where
common_relabeling:
- stuff1
- stuff2
scrape_configs:
- job_name: process_exporter
relabel_configs: "{{ common_relabeling }}"
- job_name: node_exporter
relabel_configs: "{{ common_relabeling }}"
expands in a YAML file using aliases (see below), which I'm not sure is supported by Prometheus' configuration parser. Obviously I'd like to fix it without hardcoding common_relabeling in every entry
scrape_configs:
- job_name: process_exporter
relabel_configs: &id001
- stuff1
- stuff2
- job_name: node_exporter
relabel_configs: *id001
You can just leave the anchor and alias as is.
Prometheus uses the package gopkg.in/yaml.v2, and if you read through the documentation of that package, you'll see that it is based on libyaml, which has been parsing anchors and aliases for over a decade now. And the documentation for gopkg.in/yaml.v2 explicitly states that anchors are supported:
The yaml package supports most of YAML 1.1 and 1.2, including support for anchors, tags ...
Related
I'm trying to configure a prometheus server working with ansible. I want to monitor some aws instances (ec2) but I'm stuck with the targets of prometheus. I probably should use a json file to define my targets but I don't know how to update the file when I create a new instance with ansible. Also I'm using the aws_ec2 plugin for the dynamic inventory on ansible.
So my question is: how can I use the inventory plugin to keep update the target file of prometheus without doing it manually?
You can use prometheus service discovery with the same / similar filters that you use for aws_ec2 inventory. I spent time on this issue as well but am very happy with the outcome. Basic example:
scrape_configs:
- ec2_sd_configs:
- filters:
- name: tag:Environment
values:
- PROD
job_name: ec2
relabel_configs:
- replacement: ${1}.prod.yourdomain.com:9100
source_labels:
- __meta_ec2_tag_dnsname
target_label: __address__
- source_labels:
- __meta_ec2_tag_Name
target_label: instance
- ec2_sd_configs:
- filters:
- name: tag:Environment
values:
- PROD
job_name: application_actuators
relabel_configs:
- replacement: ${1}.prod.yourdomain.com:9001
source_labels:
- __meta_ec2_tag_dnsname
target_label: __address__
- source_labels:
- __meta_ec2_tag_Name
target_label: instance
- action: drop
regex: ^$
source_labels:
- __meta_ec2_tag_application
- regex: (.+)
replacement: /$1/api/actuator/prometheus
source_labels:
- __meta_ec2_tag_application
target_label: __metrics_path__
ec2_sd_config documentation
This config is generated by ansible.
I am trying to simplify the Prometheus configuration so that when we add/remove servers, we can easily replace the IP address.
Here is my prometheus.yml file
scrape_configs:
- job_name: 'MAP-map-health-test'
scrape_interval: 5s
metrics_path: /probe
params:
module: [prod-map-servers]
file_sd_configs:
- files:
- 'map-servers.yml'
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: blackbox_exporter:9115
and here is my map-servers.yml
targets:
- http://10.0.2.16
- http://10.0.2.11
- http://10.0.2.12
- http://10.0.2.13
- http://10.0.2.14
- http://10.0.2.17
- http://10.0.2.44
The above works if I only have to check the Apache service.
What I want to achive is I can add multiple checks with same IPs:
- 'map-server.yml'/test1.php
...
...
- 'map-server.yml'/test2.php
Is there a way that I can achieve this?
If you want alternative metric paths for the same set of IP addresses, you can just create another job using a different metric path:
scrape_configs:
- job_name: 'MAP-map-health-test_probe-a'
scrape_interval: 5s
metrics_path: /probe-a
params:
module: [prod-map-servers]
file_sd_configs:
- files:
- 'map-servers.yml'
relabel_configs:
# ...
- job_name: 'MAP-map-health-test_probe-b'
scrape_interval: 5s
metrics_path: /probe-b
params:
module: [prod-map-servers]
file_sd_configs:
- files:
- 'map-servers.yml'
relabel_configs:
# ...
This will scrape http://10.0.2.16/probe-a, http://10.0.2.16/probe-b, http://10.0.2.11/probe-a, http://10.0.2.11/probe-b, etc.
If an IP address changes, it is reflected immediately in both jobs.
In some ansible roles (e.g. roles/my-role/) I've got quite some big default variables files (defaults/main.yml). I'd like to split the main.yml into several smaller files. Is it possible to do that?
I've tried creating the files defaults/1.yml and defaults/2.yml, but they aren't loaded by ansible.
The feature I'm describing below has been available since Ansible 2.6, but got a bugfix in v2.6.2 and another (minor) one in v2.7.
To see a solution for older versions, see Paul's answer.
defaults/main/
Instead of creating defaults/main.yml, create a directory — defaults/main/ — and place all YAML files in there.
defaults/main.yml → defaults/main/*.yml
Ansible will load any *.yml file inside that directory, so you can name your files like roles/my-role/defaults/main/{1,2}.yml.
Note, the old file — defaults/main.yml — must not exist. See this Github comment.
vars/main/
By the way, the above solution also works for vars/:
vars/main.yml → vars/main/*.yml
further details
The feature has been introduced in v2.6 — git commit, Pull Request, main Github issue.
There have been two bugfixes:
v2.7 fix: git commit, Pull Request — backported to v2.6.2: commit, Pull Request
v2.7 fix: git commit, Pull Request, bug discussion
If you aren't using 2.6 (which you probably should, but I understand that isn't always an option), then you might find include_vars useful.
- name: Include vars of stuff.yaml into the 'stuff' variable (2.2).
include_vars:
file: stuff.yaml
name: stuff
- name: Conditionally decide to load in variables into 'plans' when x is 0, otherwise do not. (2.2)
include_vars:
file: contingency_plan.yaml
name: plans
when: x == 0
- name: Load a variable file based on the OS type, or a default if not found. Using free-form to specify the file.
include_vars: "{{ item }}"
with_first_found:
- "{{ ansible_distribution }}.yaml"
- "{{ ansible_os_family }}.yaml"
- default.yaml
- name: Bare include (free-form)
include_vars: myvars.yaml
- name: Include all .json and .jsn files in vars/all and all nested directories (2.3)
include_vars:
dir: vars/all
extensions:
- json
- jsn
- name: Include all default extension files in vars/all and all nested directories and save the output in test. (2.2)
include_vars:
dir: vars/all
name: test
- name: Include default extension files in vars/services (2.2)
include_vars:
dir: vars/services
depth: 1
- name: Include only files matching bastion.yaml (2.2)
include_vars:
dir: vars
files_matching: bastion.yaml
Note that this is a task directive, though. It isn't as neat as just being able to include it into the defaults file itself.
I'm trying to run the Ansible modules junos_cli and junos_rollback and I get the following error:
ERROR! no action detected in task. This often indicates a misspelled module name, or incorrect module path.
The error appears to have been in '/home/quake/network-ansible/roles/junos-rollback/tasks/main.yml': line 2, column 3, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
---
- name: I've made a huge mistake
^ here
This is the role in question:
---
- name: I've made a huge mistake
junos_rollback:
host={{ inventory_hostname }}
user=ansible
comment={{ comment }}
confirm={{ confirm }}
rollback={{ rollback }}
logfile={{ playbook_dir }}/library/logs/rollback.log
diffs_file={{ playbook_dir }}/configs/{{ inventory_hostname }}
Here is the Juniper page:
http://junos-ansible-modules.readthedocs.io/en/1.3.1/junos_rollback.html
Their example's syntax is a little odd. host uses a colon while the rest uses = signs. I've tried mixing both and only using one or the other. I keep getting errors.
I also confirmed that my junos-eznc version is higher than 1.2.2 (I have 2.0.1)
I've been able to use junos_cli before, I don't know if a version mismatch happened. On the official Ansible documentation, there is no mention of junos_cli or junos_rollback. Perhaps they're not supported anymore?
http://docs.ansible.com/ansible/list_of_network_modules.html#junos
Thanks,
junos_cli & junos_rollback are part of Galaxy and not core modules. You can find them at
https://galaxy.ansible.com/Juniper/junos/
Is the content posted here has whole content of your playbook? if yes, You need to define other items too in your playbook such as roles, connection, local. For example
refer https://github.com/Juniper/ansible-junos-stdlib#example-playbook
```
---
- name: rollback example
hosts: all
roles:
- Juniper.junos
connection: local
gather_facts: no
tasks:
- name: I've made a huge mistake
junos_rollback:
host = {{inventory_hostname}}
----
----
```
Where have you saved the content of juniper.junos modules?. Can you post the content of your playbook and the output of the tree command to see your file structure? That could help.
I had a similar problem where Ansible was not finding my modules and what I did was to copy the juniper.junos folder to my roles folder and then added a tasks folder within it to execute the main.yaml from there.
Something like this:
/Users/macuared/Ansible_projects/roles/Juniper.junos/tasks
---
- name: "TEST 1 - Gather Facts"
junos_get_facts:
host: "{{ inventory_hostname}}"
user: "uuuuu"
passwd: "yyyyyy"
savedir: "/Users/macuared/Ansible_projects/Ouput/Facts"
ignore_errors: True
register: junos
- name: Checking Device Version
debug: msg="{{ junos.facts.serialnumber }}"
Additionally, I would add "" to the string values in your YAML. Something like this:
---
- name: I've made a huge mistake
junos_rollback:
host="{{ inventory_hostname }}"
user=ansible
comment="{{ comment }}"
confirm={{ confirm }}
rollback={{ rollback }}
logfile="{{ playbook_dir }}/library/logs/rollback.log"
diffs_file="{{ playbook_dir }}/configs/{{ inventory_hostname }}"
Regarding this "I've tried mixing both and only using one or the other. I keep getting errors."
I've used just colon and mine works fine even when in the documentation suggests = signs. See junos_get_facts
I'm used to see Ansible examples as:
- file: path=/tmp/file state=touch
but someone at work told me that I should be consistent using only YAML syntax like this:
- file:
path: /tmp/file
state: touch
or,
- file: {path: /tmp/file, state:touch}
Which one satisfies Ansible best practices?
Taken from https://www.ansible.com/blog/ansible-best-practices-essentials
At its core, the Ansible playbook runner is a YAML parser with added logic such as commandline key=value pairs shorthand. While convenient when cranking out a quick playbook or a docs example, that style of formatting reduces readability. We recommend you refrain from using that shorthand (even with YAML folded style) as a best practice.
Here is an example of some tasks using the key=value shorthand:
- name: install telegraf
yum:
name: telegraf-{{ telegraf_version }} state=present update_cache=yes disable_gpg_check=yes enablerepo=telegraf
notify: restart telegraf
- name: configure telegraf
template: src=telegraf.conf.j2 dest=/etc/telegraf/telegraf.conf
notify: restart telegraf
- name: start telegraf
service: name=telegraf state=started enabled=yes
Now here is the same tasks using native YAML syntax:
- name: install telegraf
yum: telegraf-{{ telegraf_version }}
state: present
update_cache: yes
disable_gpg_check: yes
enablerepo: telegraf
notify: restart telegraf
- name: configure telegraf
template:
src: telegraf.conf.j2
dest: /etc/telegraf/telegraf.conf
notify: restart telegraf
- name: start telegraf
service:
name: telegraf
state: started
enabled: yes
Native YAML has more lines; however, those lines are shorter, reducing horizontal scrolling and line wrapping. It lets the eyes scan straight down the play. The task parameters are stacked and easily distinguished from the next. Native YAML syntax also has the benefit of improved syntax highlighting in virtually any modern text editor out there. Being native YAML, editors such as vim and Atom will highlight YAML keys (module names, directives, parameter names) from their values further aiding the readability of your content. Many of our own docs use this shorthand for legacy reasons though we’re progressively changing that. (Documentation pull requests accepted.)