I am trying to Include a file which contains tasks. but it fails as below
ERROR! Unable to retrieve file contents Could not find or access
'/roles/k8s/tasks/Get_volumes.yaml' on the Ansible Controller. If you
are using a module and expect the file to exist on the remote, see the
remote_src option
Below is my ansible script. As i am going to test only few tasks ,i have included the tasks file which is inside roles folder. I am not sure whether it fails because of roles folder . But i am unable to resolve it.
---
- hosts: localhost
vars:
local_kubectl: kubectl
local_array_api_url: https://Mystoragearray:5392/v1
array_username: admin
array_password: admin
tasks:
#- import_tasks: /roles/k8s/tasks/GetVolume_token.yaml
- include_tasks: /roles/k8s/tasks/Get_volumes.yaml
Q: How to include_tasks with relative path?
A: Place the file relative to the playbook base directory playbook_dir. For example
- include_tasks: Get_volumes.yaml
is the same as
- include_tasks: "{{ playbook_dir }}/Get_volumes.yaml"
If the directory /roles is configured in DEFAULT_ROLES_PATH then include_role might be a better option
- include_role:
name: k8s
tasks_from: Get_volumes.yaml
Please verify the path again. is path "/roles/k8s/tasks/Get_volumes.yaml" correct? it should be something like "roles/k8s/tasks/Get_volumes.yaml".
if path is correct ( seems to be starting from root directory "/"), please provide necessary permission to the ansible user.
Related
I am setting up Ansible as a newbie. I would like to group a few tasks under an Nginx role.
See my folder structure
The only way I could get this to work is to use include statements in my playbooks... but that means I needed to start changing everything to relative paths since Ansible stopped being able to find things.
My playbook currently:
- name:
Install Nginx, Node, and Verdeccia
hosts:
all
remote_user:
root
tasks:
- include: ../roles/nginx/tasks/install.yml
- include: ../roles/nginx/tasks/create_node_config.yml
vars:
hostname: daz.com
How can I reference the sub task in the playbook to be something like
tasks:
- nginx.install
and still be within best practices.
Your use of roles so far is not in line with the norm or the idea of Ansible. From a purely technical point of view, it is quite possible that you have multiple task bundles in yml files that you include in the playbook.
If you want to include a specific task file from a role, you should better do this via the module include_role with the parameter tasks_from.
However, the workflow with roles usually looks different.
in the folder tasks should always be a file main.yml, this is called automatically, if simply the role is included, no matter over which way.
in this main.yml you can then add further control logic to include your yml files as required.
As it looks to me, for example, you always need to install, but depending on the use case you want to have different configurations.
create in your nginx role a file defaults/main.yml.
---
config_flavor: none
This initializes the config_flavor variable with the string none.
create in your nginx role a file tasks/main.yml.
---
- name: include installation process
include_tasks: install.yml
- name: configure node
include_tasks: create_node_config.yml
when: config_flavor == "node"
- name: configure symfony
include_tasks: create_symfony_config.yml
when: config_flavor == "symfony"
- name: configure wordpress
include_tasks: create_wordpress_config.yml
when: config_flavor == "wordpress"
The main.yml will be included by default when the role is applied.
This is where the installation is done first, then the proper configuration is done.
Which configuration should be done is defined by the variable config_flavor. In the listed example the values are node, symfony and wordpress. In all other cases the installation will be done, but no configuration (so in the default case with none).
include your role in the playbook as follows
---
- name: Install Nginx, Node, and Verdeccia
hosts: all
remote_user: root
vars:
hostname: daz.com
roles:
- role: nginx
config_flavor: node
At this point you can set the value for config_flavor. If you set wordpress instead, the tasks create_wordpress_config.yml will be included automatically, using the logic from tasks/main.yml.
You can find more about roles in the Ansible Docs.
There are many more possibilities and ways, you will get to know them in the course of your learning. Basically I would recommend you to read a lot in the Ansible docs and to use them as a reference book.
Please refer to bellow document. you can use "include_role" with "tasks_from" attribute. you don't need to provide full path of task files, Just file names.
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/include_role_module.html
Example:
- name: Run tasks/other.yaml instead of 'main'
ansible.builtin.include_role:
name: myrole
tasks_from: other
When I run the following ansible command:
$ ansible-playbook deploy/solo/wifi.yml -i inventories/solo
I got the following error message:
ERROR! the role 'solo/controller/wifi' was not found in /home/peng/git/uavops/deploy/roles:/home/peng/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:/home/peng/git/uavops/deploy
The error appears to be in '/home/peng/git/uavops/deploy/wifi.yml': line 5, column 7, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
roles:
- solo/controller/wifi
^ here
How did this happen? I invoke the ansible-playbook under the working directory /home/peng/git/uavops. Yet ansible-playbook ignores it and try to find the roles in directory /home/peng/git/uavops/deploy.
How do I tell ansible to locate the right role directory?
By default, Ansible looks for roles in two locations:
roles/ # in a directory called relative to the playbook file
/etc/ansible/roles
If you store your roles in a different location, set the roles_path configuration option so Ansible can find your roles. Checking shared roles into a single location makes them easier to use in multiple playbooks. See Configuring Ansible for details about managing settings in ansible.cfg.
Alternatively, you can call a role with a fully qualified path:
---
- hosts: webservers
roles:
- role: '/path/to/my/roles/common'
You can set role_path in your inventory file to tell ansible where to search role.
In your case,
you should move your roles inside a directory called roles at same level as the playbook.
Full path of the role or
roles:
- home/peng/git/uavops/deploy/solo/controller/wifi
use role_path to point to desired location.
I have to make delete some directory and create them on local before copy to the remote. Is there anyway to delete and create locally?
Currently I'm using 'command'
command: rm -r directory
But warning shows as
Consider using file module with state=absent rather than running rm
Is there any options we can use for local folder changes?
You can use diffrent delegation methods or use the local_action:
- local_action: file path=directory state=absent
If you're running this in a playbook, you can use a section of the playbook that uses a local connection to make changes on the command machine, then copies files to the remote:
---
- hosts: 127.0.0.1
connection: local
tasks:
- name: Delete local directory
file: path=/directory state=absent
- hosts: myhosts
tasks:
copy: src=/directory dest=/foo/directory
Update:
Current Ansible (2.10) does not like - local_action: , instead use delegate_to:
- name: Remove directory 'dir1'
file:
path: "path/to/dir1"
state: absent
delegate_to: localhost
Ansible get facts only at start. But i need check facts at each commands.
For example:
I need create a directory, after that i need put file to this directory. But ansible get fact 'dir doesn't exist' at start, create dir and at next step fact still FALSE and ansible skip this step =( And do this step only after second run.
I'll try setup after all steps to gathering facts again but it doesn't work.
I do it like this:
- stat: path=/etc/zabbix/scripts/rabbitmq
register: rmqscriptdir
- name: Create scripts dir if not exist
when: rmqscriptdir.stat.exists == False
shell: mkdir /etc/zabbix/scripts/rabbitmq
- name: Gathering facts again
setup:
- name: Set owner and permissions to rabbitmq directory
when: rmqscriptdir.stat.exists == True
file: path=/etc/zabbix/scripts/rabbitmq owner=zabbix group=root mode=0750
- stat: path=/etc/zabbix/scripts/rabbitmq/api.py
register: rmqscript_api
- name: Create api.py if not exist
when: rmqscript_api.stat.exists == False and rmqscriptdir.stat.exists == True
shell: cd /etc/zabbix/scripts/rabbitmq; wget https://raw.githubusercontent.com/jasonmcintosh/rabbitmq-zabbix/master/scripts/rabbitmq/api.py
- name: Gathering facts again
setup:
- name: Set owner and permissions to api.py
when: rmqscript_api.stat.exists == True
file: path=/etc/zabbix/scripts/rabbitmq/api.py owner=zabbix group=root mode=0755
I think you misunderstand what the setup module does. By registering a value it does not become a fact that will be reloaded by the setup module when run again. Your registered value stays the same. If you want to check again if a path exists you do not need to re-run the setup module, but the stats module and again register its output.
But anyway, the idea of Ansible is actually to not manually check if every task should be executed or not. That is something Ansible takes care for you, Ansible in general is indepotent, meaning it will have the same result no matter how many times you run the play.
Here is a cleaned up version, which creates a folder and downloads the file. If the folder already exists, the 1st task will do nothing. If the file api.py already exists, the 2nd task will do nothing.
- name: Create scripts dir if not exist
file:
path: /etc/zabbix/scripts/rabbitmq
state: directory
owner: zabbix
group: root
mode: 0750
- name: Create api.py if not exist
get_url:
url: https://raw.githubusercontent.com/jasonmcintosh/rabbitmq-zabbix/master/scripts/rabbitmq/api.py
dest: /etc/zabbix/scripts/rabbitmq/api.py
owner: zabbix
group: root
mode: 0755
PS: If you want to see which values are reloaded by the setup module, you can register its output and show it in a debug task, like so:
- setup:
register: all_server_facts
- debug:
var: all_server_facts
This only contains server facts, info about cpu, hard drives, network etc. Also see this answer for an example output.
I am putting together an Ansible Playbook designed to build webservers. However I am stuck when trying to use with_fileglob because Ansible keeps reporting that it's skipping the copy of nginx vhost files.
My script looks like this:
- name: Nginx | Copy vhost files
copy: src={{ item }} dest=/etc/nginx/sites-available owner=root group=root mode=600
with_fileglob:
- "{{ templates_dir }}/nginx/sites-available/*"
notify
- nginx-restart:
{{ templates }} has been defined elsewhere as roles/common/templates. In this directory I have a file called webserver1 that I'm hoping Ansible will copy into /etc/nginx/sites-available/
I have found other people discussing this issue but no responses have helped me solve this problem. Why would Ansible be skipping files?
Edit: I should point out that I want to use with_fileglob (rather than straight copy) as I want to iterate over other virtual hosts in the future.
Look at http://docs.ansible.com/playbooks_loops.html#looping-over-fileglobs, Note 1:
When using a relative path with with_fileglob in a role, Ansible resolves the path relative to the roles//files directory.
So to access a file in the templates directory, you can start the relative path with ../templates