I'm getting an error that says 'destination /etc not writable' when I run my playbook:
fatal: [B-mmp-edge-90c9.stg01.aws.company.net]: FAILED! => {"changed": false, "checksum": "686f224b9b97fe890014e1320f48d31cae90abc2", "msg": "Destination /etc not writable"}
fatal: [B-mmp-edge-9df4.stg01.aws.company.net]: FAILED! => {"changed": false, "checksum": "23cd3c17b1f9f84d48dc67affd5d3f4e09506b48", "msg": "Destination /etc not writable"}
My playbook common.yml just has this in it:
---
- hosts: all, !ansible
roles:
- common
And in roles/common/meta/main.yml I have:
---
dependencies:
- { role: selinux_disable }
# - { role: iptables_disable }
- { role: motd }
- { role: ntp }
# - { role: epel }
# - { role: hosts }
- { role: users }
# - { role: limits }
# - { role: sysctl }
- { role: snmp }
I'm using Ansible version 2.6.4.
I think I need to have root privileges. But I don't know how to do that in an Ansible role. Can somebody help with that?
To execute Ansible tasks with root privileges, you would need to add the following:
name: YourPlaybookName
hosts: YourHosts
become: yes
Note the third line and the become: yes directive.
For more information about privilege escalation in Ansible, please take a look at: https://docs.ansible.com/ansible/latest/user_guide/become.html
Related
I have an inventory:
[dbs]
server1.intranet
[webservices]
server2.intranet
[apps]
server3.intranet
And a file with variables:
users:
- { name: user1, ssh_key: <SSH_KEY> }
- { name: user2, ssh_key: <SSH_KEY> }
(1) My first question is: How can I tell in the inventory which user is part of each server? (without having to copy and duplicate the user information at every host) Note that users can change and can belong to multiple servers.
(2) The final objective is to do some tasks at each host. For example, to create the users at each host, and add the corresponding user SSH key at each server, something like:
- name: SSH
ansible.posix.authorized_key:
user: "item.name"
state: present
key: "item.ssh_key"
with_items: "{{ users[??] }}"
Of course the users variable should only have the users for the specific host iterating.
How can I do this?
I didn't understand your second point, but this solution could be helpful.
Define destination hosts as an array:
users:
- { name: user1, ssh_key: <SSH_KEY>,hosts: ['test-001','test-002'] }
- { name: user2, ssh_key: <SSH_KEY>,hosts: ['test-002'] }
Use selectattr filter for your loop to search the running hostname in the hosts list defined in the vars:
- name: SSH
ansible.posix.authorized_key:
user: "{{ item.name }}"
state: present
key: "{{ item.ssh_key }}"
loop: "{{ users | selectattr('hosts', 'search', inventory_hostname) }}"
ok: [test-001] => (item={'name': 'user1', 'ssh_key': '<SSH_KEY1>', 'hosts': ['test-001', 'test-002']}) => {
"msg": "user1"
}
ok: [test-002] => (item={'name': 'user1', 'ssh_key': '<SSH_KEY1>', 'hosts': ['test-001', 'test-002']}) => {
"msg": "user1"
}
ok: [test-002] => (item={'name': 'user2', 'ssh_key': '<SSH_KEY2>', 'hosts': ['test-002']}) => {
"msg": "user2"
}
I'm creating playbook to install fluentbit on windows hosts. Everything is working properly but i'm getting error when creating service, it doesn’t fail the install as then everything is already in place but I would like to figure out how I could leverage conditionals. Could you help me with this? :)
My adhoc test-play where I've tried to parse results from ansible.windows.win_service_info module is as follows:
---
- name: Check Windows service status
hosts: win
gather_facts: True
tasks:
- name: Check if a service is installed
win_service:
name: fluent-bit
register: service_info
- debug: msg="{{service_info}}"
- name: Get info for a single service
ansible.windows.win_service_info:
name: fluent-bit
register: service_info
- debug: msg="{{ service_info }}"
- name: Get info for a fluent-bit service
ansible.windows.win_service_info:
name: logging
register: service_exists
- debug: msg="{{ service_exists }}"
- name: Send message if service exists
debug:
msg: "Service is installed"
when: service_exists.state is not defined or service_exists.name is not defined
- name: Send message if service exists
debug:
msg: "Service is NOT installed"
when: service_exists.state is not running
I just don’t get it how I could parse output so that I could skip task when fluent-bit -service exists = True like here:
TASK [debug] *****************************************************************************************
ok: [win-server-1] => {
"msg": {
"can_pause_and_continue": false,
"changed": false,
"depended_by": [],
"dependencies": [],
"description": "",
"desktop_interact": false,
"display_name": "fluent-bit",
**"exists": true,**
"failed": false,
"name": "fluent-bit",
"path": "C:\\fluent-bit\\bin\\fluent-bit.exe -c C:\\fluent-bit\\conf\\fluent-bit.conf",
"start_mode": "manual",
"state": "stopped",
"username": "LocalSystem"
}
}
Cheers :)
So, got it working as I wanted with service_info.exists != True, now it will skip the task if service is already present.
I have a role that is common for both mongo replicas and arbiters and hosts groups separately for each replica and arbiter because the role should support the arbiter on the same host & different host.
hosts:
[replicas]
127.0.0.1
127.0.0.2
[arbiter]
127.0.0.2
the task inside role:
- name: Run only on replicas
debug msg=" Only on replica"
when: '"replicas" in group_names'
- name: Run only on the arbiter
debug: msg="Only on the arbiter"
when: '"arbiter" in group_names'
playbook:
- hosts: replicas
roles:
- role: "common"
- role: "replica"
- hosts: arbiter
roles:
- role: "common"
- role: "arbiter'
Expected output while running on replicas:
TASK [debug] *********************************************************************************************************************************************
ok: [127.0.0.1] => {
"msg": " Only on replica"
}
ok: [127.0.0.2] => {
"msg": " Only on replica"
}
TASK [debug(arbiter)] *********************************************************************************************************************************************
skipping: [127.0.0.1]
skipping: [127.0.0.2]
But is not skipping on arbiter task as expected as the same host is part of replicas group. Below is the actual output.
Actual output:
TASK [debug] *********************************************************************************************************************************************
ok: [127.0.0.1] => {
"msg": " Only on replica"
}
ok: [127.0.0.2] => {
"msg": " Only on replica"
}
TASK [debug(arbiter)] *********************************************************************************************************************************************
skipping: [127.0.0.1]
ok: [127.0.0.2] => {
"msg": " Only on replica"
}
How to run on a specific group that playbook delegated?
hello you can use this method:
Playbook:
- hosts: replicas
roles:
- { role: common, vars: { group: "replicas" } }
- { role: replica, vars: { group: "replicas" } }
- hosts: arbiter
roles:
- { role: common, vars: { group: "arbiter" } }
- { role: arbiter, vars: { group: "arbiter" } }
and inside your role:
- name: Run only on replicas
debug msg=" Only on replica"
when: group == "replicas"
- name: Run only on the arbiter
debug: msg="Only on the arbiter"
when: group == "arbiter"
I hope that can help you to resolve your issue.
I am trying to loop variables into a playbook, but I keep getting the following error
TASK [Add policy package to model device] ********************************************************************************************************************************************************************
failed: [fmg01] (item={'device_name': 'FGT1', 'device_ip': '192.168.0.103', 'group_name': 'Branch_Office', 'policy_package': 'default', 'device_serial': 'FGVM01TM12345678'}) => {"ansible_loop_var": "item", "changed": false, "item": {"device_ip": "192.168.0.103", "device_name": "FGT1", "device_serial": "FGVM01TM12345678", "group_name": "Branch_Office", "policy_package": "default"}, "meta": {"status": {"code": -10, "message": "The data is invalid for selected url"}, "url": "/pm/pkg/adom/root"}, "unreachable": false}
Below is my YML playbook. It works just fine when I use static variables (write out a single IP address and serial number as a string)
---
- name: Add model device to FMG and install Policy Package
hosts: fmg01
# gather_facts: no
connection: httpapi
collections:
- fortinet.fortimanager
vars_files:
- inventory.yml
tasks:
- name: Add model device
fmgr_dvm_cmd_add_device:
loose_validation: true
method: exec
params:
- data:
adom: root
device:
# device action: add_model
mgmt_mode: 'fmg'
#os_ver: 6
#mr: 4
sn: '{{item.device_serial}}'
adm_pass: 'password'
adm_usr: 'admin'
ip: '{{item.device_ip}}'
loop: '{{device_list}}'
- name: Add policy package to model device
fmgr_pm_pkg_adom_obj:
loose_validation: true
method: set
url_params:
adom: root
params:
- data:
name: default
scope member:
- name: '{{item.device_serial}}'
vdom: root
type: pkg
loop: '{{device_list}}'
- name: Install policy package to model device
fmgr_securityconsole_install_package:
loose_validation: true
method: exec
params:
- data:
adom: root
pkg: default
scope:
- name: '{{item.device_serial}}'
vdom: root
loop: '{{device_list}}'
Here is my inventory.yml file. I tested this ok with the first task. It passed in the IP address in ok. I tested the other tasks with the device_serial parameter, but that did not work.
#feeds into playbook
#add_device / add_device_group
device_list:
- device_name: FGT1
device_ip: '192.168.0.103'
group_name: Branch_Office
policy_package: default
device_serial: 'FGVM01TM12345678'
Problem turned out to be an indention problem with the params portion
- name: Add policy package to model device
fmgr_pm_pkg_adom_obj:
loose_validation: true
method: set
url_params:
adom: root
params:
- data:
name: default
scope member:
- name: '{{item.device_serial}}'
vdom: root
type: pkg
loop: '{{device_list}}'
I have a bunch of playbooks where a big percentage of roles are common to all servers. So I'd like to do something like:
---
- hosts: nfs2pre2
sudo: true
gather_facts: no
roles:
- include: initial_setup.yml
- { role: role10, tags: ['role10' ] }
- { role: role11, tags: ['role11' ] }
The initial_setup.yml would be something like:
- { role: role1, tags: ['role1' ] }
- { role: role2, tags: ['role2' ] }
Is it possible?
That's not possible as far as I know, but there is a simple workaround. You can create a role which will only have dependencies on other roles. To follow your example, you can create a role initial_setup, by creating a directory roles/initial_setup and in it create a directory meta with a file main.yml:
# roles/initial_setup/meta/main.yml
---
dependencies:
- { role: 'role1', tags: 'role1' }
- { role: 'role2', tags: 'role2' }
Now you can use initial_setup as any regular role:
- hosts: nfs2pre2
sudo: true
gather_facts: no
roles:
- { role: initial_setup, tags: ['initial_setup' ] }
- { role: role10, tags: ['role10' ] }
- { role: role11, tags: ['role11' ] }