How can I set in Ansible block vars (visible only for tasks in block) ?
I tried:
---
- hosts: test
tasks:
- block:
- name: task 1
shell: "echo {{item}}"
with_items:
- one
- two
but it seems that it's a wrong way.
If you want to define a variable for a block:
- block:
- debug:
var: var_for_block
vars:
var_for_block: "value for var_for_block"
If you want to "loop over blocks" as your code suggests - you can't. It's not implemented in Ansible.
Follow this thread.
For now consider saving the tasks to a separate file and use include instead.
#Shasha99
you might be able to include a file with a block in it so you can still benefit from the try/catch
includeFile.yml :
- block
- name: Finding the package.
shell: rpm -qa | grep "{{pkgName}}"
register: package
- name: Uninstalling the package.
shell: rpm -e "{{package}}"
always:
- debug: msg="this always executes"
main.yml:
---
- hosts: all
vars:
- packageList : ["pkg1","pkg2","pkg3","pkg4"]
tasks:
- include: includeFile.yml pkgName="{{item}}"
with_items: packageList
Related
I am trying to create a Galaxy role for our org's internal galaxy, which I am testing first locally. In our org we use a common list of defaults across all roles.
Ansible is throwing me a "The task includes an option with an undefined variable The error was: 'redis_download_url' is undefined" error when running my playbook, despite me having defined the variable in defaults/main.yml:
# Download
redis_version: "6.2.3"
redis_download_url: "https://download.redis.io/releases/redis-{{ redis_version }}.tar.gz"
When running my simple role/playbook.yml
---
- hosts: all
become: true
tasks:
- include: tasks/main.yml
Linked to tasks/main.yml
---
- name: Check ansible version
assert:
that: "ansible_version.full is version_compare('2.4', '>=')"
msg: "Please use Ansible 2.4 or later"
- include: download.yml
tags:
- download
- include: install.yml
tags:
- install
It should pull the tar file from tasks/download.yml as stated:
---
- name: Download Redis
get_url:
url: "{{ redis_download_url }}"
dest: /usr/local/src/redis-{{ redis_version }}.tar.gz
- name: Extract Redis tarball
unarchive:
src: /usr/local/src/redis-{{ redis_version }}.tar.gz
dest: /usr/local/src
creates: /usr/local/src/redis-{{ redis_version }}/Makefile
copy: no
The redis_download_url var is defined in defaults/main.yml which as I understand ansible should be able to locate there. I also have similar vars defined in defaults/task.yml eg.
redis_user: redis
redis_group: "{{ redis_user }}"
redis_port: "6379"
redis_root_dir: "/opt/redis"
redis_config_dir: "/etc/redis"
redis_conf_file: "{{ redis_config_dir }}/{{ redis_port }}.conf"
redis_password: "change-me"
redis_protected_mode: "yes"
and I assume they are also not able to be found/seen by ansible (but it does not get that far). I have also checked all file permissions and they seem to be fine.
Apologies in advance if the question is badly formatted.
As per documentation:
If you include a task file from a role, it will NOT trigger role behavior, this only happens when running as a role, include_role will work.
To get the role functionality of reading variables from defaults/main.yml, you'll need to use include_role or roles: [].
- hosts: all
become: true
tasks:
- include_role:
name: myrole
OR
- hosts: all
become: true
roles:
- myrole
So I'm trying to run a little playbook to test out the openssl_certificate module documented here: https://docs.ansible.com/ansible/2.7/modules/openssl_certificate_module.html
My playbook:
---
- name: play to run opensll verification
hosts: localhost
tasks:
- name: Running OpenSSL Module.
openssl_certificate:
path: "bleh.crt"
provider: assertonly
valid_in: "{{ (20*3600*24) | int }}"
register: VALIDATION_OUTPUT
ignore_errors: true
Basically I wanna see if the cert is valid in the given time frame. However, when I run
ansible-playbook openssl_test.yml
I get:
ERROR! 'openssl_certificate' is not a valid attribute for a Play
The error appears to be in '/path/to/my/yaml/openssl_test.yml': line 6, column 3, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
tasks:
- name: Running OpenSSL Module.
^ here
What am I doing wrong here? I'm sure it's something small.
Your indentation is wrong. while copying the yaml data, you may use :set paste if using vim editor to persevere the indentation.
---
- name: play to run opensll verification
hosts: localhost
tasks:
- name: Running OpenSSL Module.
openssl_certificate:
path: "bleh.crt"
provider: assertonly
valid_in: "{{ (20*3600*24) | int }}"
register: VALIDATION_OUTPUT
ignore_errors: true
Concerning: Ansible-Playbooks
Is it possible to run a command on the remote machine and store the resulting output into a variable?
I am trying to get the kernel version and install the matching headers like this:
---
- hosts: all
tasks:
- name: install headers
become: yes
become_method: sudo
apt:
name: "{{ packages }}"
vars:
packages:
- linux-headers-`uname -r`
#- a lot of other packages here
Unfortunately uname -r is not executed here.
I am aware of this question: Ansible: Store command's stdout in new variable?
But it looks like this is another topic.
By definition:
Ansible facts are data related to your remote systems, including
operating systems, IP addresses, attached filesystems, and more.
In this link you can see all ansible facts that you can use.
https://docs.ansible.com/ansible/latest/user_guide/playbooks_vars_facts.html
One of those variables is ansible_kernel, this is the version of the kernel of your remote system. By default ansible gets this variables, but if you want to be sure that ansible will get this variables you have to use gather_facts: yes.
---
- hosts: all
gather_facts: yes
tasks:
- name: install
become: yes
become_method: sudo
apt:
name: "{{ packages }}"
vars:
packages:
- linux-headers-{{ ansible_kernel }}
I found a solution but I am not sure if this is really elegant
---
- hosts: all
tasks:
- name: Getting Kernel Version
command: "uname -r"
register: kernel_version
- name: install
become: yes
become_method: sudo
apt:
name: "{{ packages }}"
vars:
packages:
- linux-headers-{{ kernel_version.stdout }}
Im currently querying multiple databases and capturing the results of the query
The way Im doing it is, Im writing a task which copies a shell script, something like below
#!/bin/bash
source $HOME/bin/gsd_xenv $1 &> /dev/null
sqlplus -s <<EOF
/ as sysdba
set heading off
select d.name||','||i.instance_name||','||i.host_name||';' from v\$database d,v\$instance i;
EOF
In the playbook, Im writing the task as below:
- name: List Query [Host and DB]
shell: "/tmp/sqlscript/sql_select.sh {{item}} >> /tmp/sqlscript/output.out"
become: yes
become_method: sudo
become_user: oracle
environment:
PATH: "/home/oracle/bin:/usr/orasys/12.1.0.2r10/bin:/usr/bin:/bin:/usr/ucb:/sbin:/usr/sbin:/etc:/usr/local/bin:/oradata/epdmat/goldengate/config/sys"
ORACLE_HOME: "/usr/orasys/12.1.0.2r10"
with_items: "{{ factor_dbs.split('\n') }}"
However I have noticed that the different hosts have different ORACLE_HOME and PATHS. How can I define those variables in the playbook, so that the task picks the right ORACLE_HOME and PATH variables and execute the task successfully
you can define host specific variables for each of the hosts. You can write your inventory file like:
[is_hosts]
greenhat ORACLE_HOME=/tmp
localhost ORACLE_HOME=/sbin
similarly for the PATH variable
then your task:
sample playbook that demonstrates the results:
- hosts: is_hosts
gather_facts: false
vars:
tasks:
- name: task 1
shell: "env | grep -e PATH -e ORACLE_HOME"
environment:
# PATH: "{{ hostvars[inventory_hostname]['PATH']}}"
ORACLE_HOME: "{{ hostvars[inventory_hostname]['ORACLE_HOME'] }}"
register: shell_output
- name: print results
debug:
var: shell_output.stdout_lines
sample output, you can see ORACLE_HOME variable was indeed changed, and as defined per host:
TASK [print results] ************************************************************************************************************************************************************************************************
ok: [greenhat] => {
"shell_output.stdout_lines": [
"ORACLE_HOME=/tmp",
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"
]
}
ok: [localhost] => {
"shell_output.stdout_lines": [
"ORACLE_HOME=/sbin",
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"
]
}
I have an ansible variable passed in on the command line as such:
ansible-playbook -e environment=staging ansible/make_server.yml
I want to load in some variables in my role dependeing on the value of environment. I have tried a lot of different methods such as:
- include_vars: staging_vars.yml
when: environment | staging
and
- include_vars: staging_vars.yml
when: "{{environment}} == "staging"
and
- include_vars: staging_vars.yml
when: "{{environment}} | match('staging')"
but nothing seems to work. How do I do this?
Details:
I am using ansible 1.7.2
Be careful with a variable called environment, it can cause problems because Ansible uses it internally. I can't remember if it's in the docs, but here's a mailing list thread:
https://groups.google.com/forum/#!topic/ansible-project/fP0hX2Za4I0
We use a variable called stage.
It looks like you'll end up with a bunch of these in a row:
- include_vars: testing_vars.yml
when: stage == "testing"
- include_vars: staging_vars.yml
when: stage == "staging"
- include_vars: production_vars.yml
when: stage == "production"
But you could also just include your environment:
- include_vars: "{{ stage }}_vars.yml"
Or, use the vars_files on a playbook level:
vars_files:
- vars/{{ stage }}_vars.yml