I've an Ansible vars_file like:
jmeter:
version: "5.3"
name: "apache-jmeter-{{ jmeter.version }}"
archive: "{{ jmeter.name }}.zip"
url: "https://archive.apache.org/dist/jmeter/binaries/{{ jmeter.archive }}"
Is it the way to go? I'm getting error. Anyone has suggestions?
You need to flatten that, as jmeter is not defined yet when you are trying to use it.
jmeter_version: "5.3"
jmeter_name: "apache-jmeter-{{ jmeter_version }}"
jmeter_archive: "{{ jmeter_name }}.zip"
jmeter_url: "https://archive.apache.org/dist/jmeter/binaries/{{ jmeter_archive }}"
Related
I have a file called values.txt on each of the server in the directory /tmp/values.txt and it has some values. And I have a jinja template and I am substituting some values from the the values.txt
But the problem is, when i use the lookup command it looks in the controller server and not the remote servers
Here's what I tried:
- name: Create /etc/systemd/system/etcd.service
template:
src: etcd.service.j2
dest: /etc/systemd/system/etcd.service
vars:
value_from_file: "{{ lookup('file', '/tmp/values.txt').split('\n') }}"
vars_from_jinja: [SELF_NAME, SELF_IP, NODE_1_NAME, NODE_1_IP, NODE_2_NAME, NODE_2_IP, NODE_3_NAME, NODE_3_IP, NODE_4_NAME, NODE_4_IP]
my_dict: "{{ dict(vars_from_jinja|zip(value_from_file)) }}"
How can I can this task remotely? Or is there another workaround to substitute the values to the jinja template?
PS: I can't fetch the values.txt to the controller because the content of values.txt in each server is slightly different from the other.
Can someone please help me?
The lookup find the file (or stream) on the controller. If you file is on the remote node, you can't use the lookup
Lookup plugins are an Ansible-specific extension to the Jinja2 templating language. You can use lookup plugins to access data from outside sources (files, databases, key/value stores, APIs, and other services) within your playbooks. Like all templating, lookups execute and are evaluated on the Ansible control machine. Ansible makes the data returned by a lookup plugin available using the standard templating system. You can use lookup plugins to load variables or templates with information from external sources.
try the cat file instead:
- name: read the values.txt
shell: cat /tmp/values.txt
register: data
- name: Create /etc/systemd/system/etcd.service
template:
src: etcd.service.j2
dest: /etc/systemd/system/etcd.service
vars:
value_from_file: "{{ data.stdout_lines }}"
vars_from_jinja: [ SELF_NAME, SELF_IP, NODE_1_NAME, NODE_1_IP, NODE_2_NAME, NODE_2_IP, NODE_3_NAME, NODE_3_IP, NODE_4_NAME, NODE_4_IP ]
my_dict: "{{ dict(vars_from_jinja|zip(value_from_file)) }}"
Use slurp:
- name: read remote values.txt
register: values
ansible.builtin.slurp:
src: /tmp/values.txt
- name: Create /etc/systemd/system/etcd.service
template:
src: etcd.service.j2
dest: /etc/systemd/system/etcd.service
vars:
value_from_file: "{{ (values.content | b64decode).split('\n') }}"
vars_from_jinja: [SELF_NAME, SELF_IP, NODE_1_NAME, NODE_1_IP, NODE_2_NAME, NODE_2_IP, NODE_3_NAME, NODE_3_IP, NODE_4_NAME, NODE_4_IP]
my_dict: "{{ dict(vars_from_jinja|zip(value_from_file)) }}"
I am trying to build up a config file that contains the list of my inventory host servers and their fields eg. IP,FQDN etc.
Here is my part of inventory file :
ocp_cluster:
hosts:
anbootstrap.ocp.hattusas.tst:
fqdn: anbootstrap.ocp.hattusas.tst
ip: 10.72.217.92
anmaster1.ocp.hattusas.tst:
fqdn: anmaster1.ocp.hattusas.tst
ip: 10.72.217.93
anmaster2.ocp.hattusas.tst:
fqdn: anmaster2.ocp.hattusas.tst
ip: 10.72.217.94
anmaster3.ocp.hattusas.tst:
And here is my playbook:
- name: Adding OCP Clusters to DHCP configuration
debug:
"{{ hostvars[item][fqdn] }}"
loop: "{{ groups['ocp_cluster'] }}"
(I will use blockinfile soon)
When I ran my playbook I am getting undefined error fqdn. I tried using a for loop and it didn't help. Any suggestions?
Thanks a lot.
The fixed task is below
- debug:
msg: "{{ hostvars[item]['fqdn'] }}"
loop: "{{ groups['ocp_cluster'] }}"
Debug parameter msg was missing
fqdn is an attribute of a dictionary. It must be quoted in brackets. Similar to ocp_cluster.
It's possible to use the dot notation and simplify the references to the attributes of the dictionaries
- debug:
msg: "{{ hostvars[item].fqdn }}"
loop: "{{ groups.ocp_cluster }}"
I have a variable client: client1 and I want to use it to fetch multiple facts into a template like below.
"{{ hostvars[{{ client }}][ansible_default_ipv4][address] }}"
"{{ hostvars[{{ client }}][ansible_hostname] }}"
"{{ hostvars[{{ client }}][ansible_fqdn] }}"
I have tried removing the braces, using a dictionary[key] in place of client but couldn't figure out. What is the right usage here?
The right answer is: "{{ hostvars[client]['ansible_default_ipv4']['address'] }}"
How can an Ansible playbook register in a variable the result of including another playbook?
For example, would the following register the result of executing tasks/foo.yml in result_of_foo?
tasks:
- include: tasks/foo.yml
- register: result_of_foo
How else can Ansible record the result of a task sequence?
The short answer is that this can't be done.
The register statement is used to store the output of a single task into a variable. The exact contents of the registered variable can vary widely depending on the type of task (for example a shell task will include stdout & stderr output from the command you run in the registered variable, while the stat task will provide details of the file that is passed to the task).
If you have an include file with an arbitrary number of tasks within it then Ansible would have no way of knowing what to store in the variable in your example.
Each individual task within your include file can register variables, and you can reference those variables elsewhere, so there's really no need to even do something like this.
I was able to do this by passing a variable name as a variable to be used in the task. I included my main.yaml and included cgw.yaml files below.
main.yaml:
- name: Create App A CGW
include: cgw.yaml
vars:
bgp_asn: "{{ asn_spoke }}"
ip_address: "{{ eip_app_a.public_ip }}"
name: cgw-app-a
region: "{{ aws_region }}"
aws_access_key: "{{ ec2_access_key }}"
aws_secret_key: "{{ ec2_secret_key }}"
register: cgw_app_a
cgw.yaml:
- name: "{{ name }}"
ec2_customer_gateway:
bgp_asn: "{{ bgp_asn }}"
ip_address: "{{ ip_address }}"
name: "{{ name }}"
region: "{{ region }}"
aws_access_key: "{{ aws_access_key }}"
aws_secret_key: "{{ aws_secret_key }}"
register: "{{ register }}"
I'm using the ec2 module with ansible-playbook I want to set a variable to the contents of a file. Here's how I'm currently doing it.
Var with the filename
shell task to cat the file
use the result of the cat to pass to the ec2 module.
Example contents of my playbook.
vars:
amazon_linux_ami: "ami-fb8e9292"
user_data_file: "base-ami-userdata.sh"
tasks:
- name: user_data_contents
shell: cat {{ user_data_file }}
register: user_data_action
- name: launch ec2-instance
local_action:
...
user_data: "{{ user_data_action.stdout }}"
I assume there's a much easier way to do this, but I couldn't find it while searching Ansible docs.
You can use lookups in Ansible in order to get the contents of a file, e.g.
user_data: "{{ lookup('file', user_data_file) }}"
Caveat: This lookup will work with local files, not remote files.
Here's a complete example from the docs:
- hosts: all
vars:
contents: "{{ lookup('file', '/etc/foo.txt') }}"
tasks:
- debug: msg="the value of foo.txt is {{ contents }}"
You can use the slurp module to fetch a file from the remote host: (Thanks to #mlissner for suggesting it)
vars:
amazon_linux_ami: "ami-fb8e9292"
user_data_file: "base-ami-userdata.sh"
tasks:
- name: Load data
slurp:
src: "{{ user_data_file }}"
register: slurped_user_data
- name: Decode data and store as fact # You can skip this if you want to use the right hand side directly...
set_fact:
user_data: "{{ slurped_user_data.content | b64decode }}"
You can use fetch module to copy files from remote hosts to local, and lookup module to read the content of fetched files.
lookup only works on localhost. If you want to retrieve variables from a variables file you made remotely use include_vars: {{ varfile }} . Contents of {{ varfile }} should be a dictionary of the form {"key":"value"}, you will find ansible gives you trouble if you include a space after the colon.