My inventory file is having below host groups:
[uat1]
123.11.23.22 ansible_user="xxx"
[OS_uat2]
123.45.6.7 ansible_user="yyy"
[uat1_childs:children]
uat1
OS_uat2
I am having the vars file which is having param for below hosts. I am running a playbook to run a shell command. I am passing some parameters with the playbook. I am passing deployment_environment as uat1_childs. This is giving me error. Playbook is:
- name: play to ping test
gather_facts: false
hosts: "{{ deployment_environment }}"
ignore_unreachable: yes
vars_files:
- r_params.yml
vars:
package: "{{ package }}"
tasks:
- set_fact:
env_param: "{{ deployment_environment }}"
- name: ping test
ping:
data: pong
- name: Deploy Services on "{{ deployment_environment }}"
shell: cd "{{ env_select[env_param].script_path }}"; sh "{{ env_select[env_param].script_path }}/deploy.sh" "param1" "param2" "{{ env_select[env_param].repo }}" "{{ artifact_version }}" "{{ env_select[env_param].ENV }}" "{{ arti_username }}" "{{ arti_pass }}" "{{ deployer }}" "{{ package }}" "{{ env_select[env_param].deployment_path }}"
when: (package == "abc")
with_items: "{{ groups[{{ 'deployment_environment' }}] }}"
This is giving me error as:
fatal: [123.11.23.22]: FAILED! =>
{
"msg": "'dict object' has no attribute 'deployment_environment'"
}
fatal: [123.45.6.7]: FAILED! =>
{
"msg": "'dict object' has no attribute 'deployment_environment'"
}
I tried removing apostrophe in with items, still it is giving me error. Cant identify how to run the task in all children host group.
Related
I have some codes like below, I want to iterate each host in groups['A'] and groups['B'] to create the group.
- name: Create a group
group:
name: "test_group"
state: "present"
delegate_to: "{{ item }}"
vars:
ansible_ssh_user: "{{ lookup('env', 'USER') }}#user#{{ item }}"
with_items:
- "{{ groups['A'] }}"
- "{{ groups['B'] }}"
Because I want to modify the ansible ssh connection user to connect to the "delegate_to" host, I override the ansible_ssh_user in this task, but it won't work and give me the error message like
FAILED! => {"msg": "'item' is undefined"}
But if I comment out the lines of
vars:
ansible_ssh_user: "{{ lookup('env', 'USER') }}#user#{{ item }}"
It gives no errors.
try changing the var to:
ansible_ssh_user: "{{ lookup('env', 'USER') }}#user#{{ ansible_hostname }}
this works fine for me:
- name: 'install public key on every server'
authorized_key:
user: '{{ myuser}}'
key: "{{ myuser.ssh_public_key }}"
delegate_to: '{{ item }}'
with_items:
- '{{ groups["A"] }}'
- '{{ groups["B"] }}'
- '{{ groups["C"] }}'
maybe you could try
but before I delegated a set_fact and recovered it locally...
Finally, I got a workaround, it involves all groups I need to use in my playbook.
And use "when" condition like
delegate_to: "{{ item }}"
with_items:
- "{{ groups['A'] }}"
- "{{ groups['B'] }}"
when: "inventory_hostname == item"
to let the task only run on the hosts mentioned in the "with_items" section.
It's not a very cool workaround but works for me...
Thank you for looking at this problem!
I am executing below as ansible playbook in loop with_together but need to know the status of the each task which is defined switch-host-config.yaml, but when i print register variable "sw_output" its not showing the task result it shows the with_together defined list...
is there any method or way to identify the task status in defined switch-host-config.yaml playbook.
- hosts: "{{ data_sw_ip1 }}"
connection: local
gather_facts: False
tasks:
- name: sw-host task
include_tasks: switch-host-config.yaml
vars:
- nic1_swport: "{{ item.0 }}"
- nic2_swport: "{{ item.1 }}"
- id_host: "{{ item.2}}"
register: sw_output
with_together:
- "{{ nic1_swport1 }}"
- "{{ nic2_swport }}"
- "{{ id_host }}"
ignore_errors: yes
- debug:
msg: "{{ sw_output }}"
I'm trying to get the inventory host group names by below process which is not working
- debug:
msg: "{{ groups['{{ item }}'] }}"
with_items: "{{ vm.stdout_lines }}"
this is what actually I'm trying to do
I will get a list of servers by a shell script
- name: Getting the servers list
shell: |
sh getServers.sh
register: vm
Then adding them into inventory by add_host
- name: Creating Logical host_group for each server
add_host:
name: "{{ item }}"
groups: ["{{item }}"]
with_items: "{{ vm.stdout_lines }}"
register: inv
Here I'm trying to get the only groups I've added in above step instead of all groups
- debug:
msg: "{{ groups['{{ item }}'] }}"
with_items: "{{ vm.stdout_lines }}"
Error is
{"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute '{{ item }}'
Appreciate help on this!
Fix the syntax
msg: "{{ groups[item] }}"
I am trying to shutdown databases in a loop, the catch is some databases run as a different user and others just run as oracle. I login as oracle user and run the playbook and if the database is run as oracle user it goes through fine. If it is running as a different user I would like to become that user (oracle user has permissions to do that).
Here is my main playbook:
[oracle#ansctrlsrv.localdomain epd3]$ cat test.yml
---
- hosts: testdrive
tasks:
- set_fact:
db_list: "{{ lookup('file', 'vars/' ~ inventory_hostname ~ '.dblist')|from_yaml }}"
- name: Shutdown running databases
include_tasks: shutdowndb.yml
loop: "{{ db_list }}"
DB list is as follows:
[oracle#ansctrlsrv.localdomain epd3]$ cat vars/dbsrv.localdomain.dblist
- ebs1
- ebs2
- ndb1
[oracle#ansctrlsrv.localdomain epd3]$ cat shutdowndb.yml
---
- debug: msg='Shutting down {{ item }}'
- name: Execute shutdown
shell: id "{{ item }}"
register: shutdown_output
become: "{{ item is search('ebs') | ternary('yes','no') }}"
become_user: "{{ item }}"
- debug: msg="{{ shutdown_output.stdout }}"
[oracle#ansctrlsrv.localdomain epd3]$ cat inventory
[testdrive]
dbsrv.localdomain
[oracle#ansctrlsrv.localdomain epd3]$ ansible-playbook -i inventory test.yml
TASK [Execute shutdown] ***
fatal: [dbsrv1.localdomain]: FAILED! => {"changed": false, "module_stderr": "Shared connection to dbsrv1.localdomain closed.\r\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1} ...ignoring
I tried this question on another thread but got closed, so trying another hand after realizing a few issues myself such as being unable to run blocks of code with a loop, etc.
Appreciate any help.
Set become user conditionally
Fix the line
shell: id "{{ item }}"
correct syntax (use shell only when necessary)
command: "id {{ item }}"
The playbook below
- hosts: testdrive
tasks:
- set_fact:
db_list: "{{ lookup('file', 'vars/' ~ inventory_hostname ~ '.dblist')|from_yaml }}"
- name: Shutdown running databases
include_tasks: shutdowndb.yml
loop: "{{ db_list }}"
with the included tasks
$ cat shutdowndb.yml
- debug:
msg:
- "shell: {{ 'shutdown.sh ' ~ item }}"
- "become: {{ item is search('ebs')|ternary('yes', 'no') }}"
- "become_user: {{ item }}"
give
"msg": [
"shell: shutdown.sh ebs1",
"become: yes",
"become_user: ebs1"
]
"msg": [
"shell: shutdown.sh ebs2",
"become: yes",
"become_user: ebs2"
]
"msg": [
"shell: shutdown.sh ndb1",
"become: no",
"become_user: ndb1"
]
Q: "Why the command whoami is still giving oracle rather than ebs1?"
A: Short answer: Because become is not set to True.
Debugging
1) Is it possible to become all of the users in db_list? Yes.
- hosts: test_01
become: no
remote_user: admin
vars:
db_list: ['ebs1', 'ebs2', 'ndb1']
tasks:
- command: whoami
become_user: "{{ item }}"
become: true
register: result
loop: "{{ db_list }}"
- debug:
msg: "{{ result.results|json_query('[].stdout') }}"
give
"msg": [
"ebs1",
"ebs2",
"ndb1"
]
2) Does search and ternary work properly? Yes.
- debug:
msg: "{{ item is search('ebs')|ternary(true, false) }}"
loop: "{{ db_list }}"
gives
"msg": true
"msg": true
"msg": false
3) Does become and become_user work properly?. Yes.
- command: whoami
become_user: "{{ item }}"
become: "{{ item is search('ebs')|ternary(true, false) }}"
register: result
loop: "{{ db_list }}"
- debug:
msg: "{{ result.results|json_query('[].stdout') }}"
give
"msg": [
"ebs1",
"ebs2",
"admin"
]
I need to pass a dynamic group name info with_items so that i can access a specific fact that is ran from another host. I cannot hard code the group name
I tried to set a generic variable that is passed as 'GroupName' a few different ways. Including
with_items: "{{ groups['{{GROUPNAME}}'] }}"
- name: Name of task
debug:
msg: "{{ hostvars[item]['ansible_check_mode'] }}"
with_items: "{{ groups['GROUPNAME'] }}"
fatal: [localhost]: FAILED! => {"msg": "'dict object' has no attribute '{{ GROUPNAME }}'"}
Get the list of the hosts in the group and loop them
vars:
my_group: GROUPNAME
tasks:
- set_fact:
my_hosts: "{{ groups|
dict2items|
selectattr('key', 'match', my_group)|
map(attribute='value')|
list|
flatten }}"
- debug:
msg: "{{ hostvars[item]['ansible_check_mode'] }}"
loop: "{{ my_hosts }}"
(not tested)