Reputation: 5643
I have this play.yml
---
- hosts: localhost
tasks:
- include: apache.yml
My apache.yml file looks like this:
vars:
url: http://example.com/apache
- name: Download apache
shell: wget {{ url }}
This is giving me an error.
If I remove vars
then it works. But, I want to keep the variable inside the included tasks file, so that I can keep different variables for different tasks separate.
Upvotes: 98
Views: 223431
Reputation: 229
In Your example, apache.yml is tasklist, but not playbook
In depends on desired architecture, You can do one of:
1. Convert apache.yml to role. Then define tasks in roles/apache/tasks/mail.yml and variables in roles/apache/defaults/mail.yml (vars in defaults can be overriden when role applied)
play.yml :
---
- hosts: localhost
connection: local
sudo: false
roles:
- apache
roles/apache/defaults/main.yml :
---
url: czxcxz
roles/apache/tasks/main.yml :
---
- name: Download apache
shell: wget {{url}}
2. Set vars in play.yml playbook
play.yml :
---
- hosts: localhost
connection: local
sudo: false
vars:
url: czxcxz
tasks:
- include: apache.yml
apache.yml :
- name: Download apache
shell: wget {{url}}
3. Make apache.yml complete playbook and import it in play.yml as playbook
play.yml :
---
- name: Configure Apache
import_playbook: apache.yml
apache.yml :
---
- name: Configure Apache
hosts: localhost
connection: local
sudo: false
vars:
url: czxcxz
tasks:
- name: Download apache
shell: wget {{url}}
4. Import variables from separate file
play.yml :
---
- hosts: localhost
tasks:
- include: apache.yml
apache.yml :
---
- name: Import apache vars
# Static import var-file with single var look ugly
include_vars: apache-vars.yml
- name: Download apache
shell: wget {{ url }}
apache-vars.yml :
---
url: http://example.com/apache
5. Consider put variables to host_var or group_var
host_vars/localhost.yml : or host_vars/localhost/apache.yml :
---
url: http://example.com/apache
Upvotes: 6
Reputation: 31
If you have multiple tasks use a block instead
- name: Scope change (Kind of)
block:
- name: Download apache
shell: wget {{ url }}
- name: Debug
debug:
msg: "It ran: wget {{ url }}"
vars:
url: http://example.com/apache
In general, avoid using set_fact . If you do use it, its high precedence will override most other constructs including vars: . It can cause very difficult to debug side effects, even outside the role, or include where it was used.
Upvotes: 3
Reputation: 1183
Just move the variable definition inside inside your task:
- name: Download apache
shell: wget {{ url }}
vars:
url: http://example.com/apache
Upvotes: 95
Reputation: 21188
If you need to have local variables that only persist through specific task, you can do this:
- name: My Task
vars:
my_var: 123
This can be useful, when you want to have more reusable roles, where it expects some generic variables (arguments). For example:
my_debug_role/main.yml
:
- name: Output me
ansible.builtin.debug:
msg: "Your output was: {{ my_msg }}"
Then in your playbook, you can reuse it with more specific variable, like:
my_playbook.yml
:
- name: Output my custom log
include_role:
name: my_debug_role
vars:
my_msg: "{{ some_custom_specific_variable }}"
Upvotes: 0
Reputation: 131
Whenever you have a module followed by a variable on the same line in ansible the parser will treat the reference variable as the beginning of an in-line dictionary. For example:
- name: some example
command: {{ myapp }} -a foo
The default here is to parse the first part of {{ myapp }} -a foo
as a dictionary instead of a string and you will get an error.
So you must quote the argument like so:
- name: some example
command: "{{ myapp }} -a foo"
Upvotes: -3
Reputation: 2339
NOTE: Using set_fact
as described below sets a fact/variable onto the remote servers that the task is running against. This fact/variable will then persist across subsequent tasks for the entire duration of your playbook.
Also, these facts are immutable (for the duration of the playbook), and cannot be changed once set.
Use set_fact
before your task to set facts which seem interchangeable with variables:
- name: Set Apache URL
set_fact:
apache_url: 'http://example.com/apache'
- name: Download Apache
shell: wget {{ apache_url }}
See http://docs.ansible.com/set_fact_module.html for the official word.
Upvotes: 103
Reputation: 61689
Variable definitions are meant to be used in tasks. But if you want to include them in tasks probably use the register
directive. Like this:
- name: Define variable in task.
shell: echo "http://www.my.url.com"
register: url
- name: Download apache
shell: wget {{ item }}
with_items: url.stdout
You can also look at roles as a way of separating tasks depending on the different roles roles. This way you can have separate variables for each of one of your roles. For example you may have a url
variable for apache1
and a separate url
variable for the role apache2
.
Upvotes: 14