- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- 2,368 Views
I am confused what kind of beast a "vars: " block in a playbook is.
Apparently both these are legal syntax:
vars:
my_var: "my_value"
which looks like a dictionary; but also:
vars:
- my_var: "my_value"
which looks like a list.
In contrast, vars_files must be a list even with a single entry:
vars_files:
- /wherever/it/is
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- 2,343 Views
@TPeters -
I want to provide a tiny bit more information directly related to your question on VARS Block.
So there are multiple ways to provide variables to Ansible (depending on the type some of them are automatic). When providing these variables (outside of the special variables and variables defined in inventory or the command line), there are two methods for specifying or providing variables directly in a playbook. Those two methods are vars: and vars_files: both of which provide the ability to instruct the playbook that you've defined variables.
One of the things I emphasize when delivering a course (especially the intro Ansible course) everything in Ansible is a List/Dictionary and from there, you just build out and expand using a comination of Lists/Dictionaries. At the play level, I emphasize the playbook directives are key: value pairs belonging to the play at the first indentation level. Depending on the key, the value can be a single value (most likely a string), a list, or a dictionary value.
At the play level we have name, hosts, vars, vars_files, tasks, roles, pre-tasks, post-tasks, and handlers. Yes, there are some other special things we can put in there to override configuration files and users and things, but those are the top ones.The tasks and the vars_files are always expecting the items as a list of tasks or files to process and handle (again, these will be lists and possibly lists of dictionaries). If you think about a task, the indentation level in there is essentially a list of dictionaries (key: value pairs). Where a task must always have a module, but it is generally recommended it has a name prior to the module and then the next indentation is the dictionary items that go with the module (key: value pairs) needed to make the module function as intended.
So why is the vars: block confusing ...? Simply put, this is the way for Ansible to get variables for your playbook. These variables can be many things and there is a single vars: block defined for each play. That means it must accept a list of variable values. What is more, as you pointed out some variables can be dictionaries, so vars: must also accept a dictionary. Therefore, when you boil even a regular variable definition down and you think to look at it conceptually, even a basic variable can be viewed as a dictionary.
For example:
my_pkg: vim
The my_pkg is the variable name, but you could also look at it as the KEY for the dictionary. The value for the variable is vim but it could also be looked at as the dictionary value for the KEY.
So if you approach things this way, the vars: block accepts a list of dictionaries. When there is only one thing specified, you don't need the "-" for the list.
Variables are DICTIONARIES as you hopefully can see using the reference above. Keep in mind ... variable precedence the highest is the "extra variable" specified on the command line ... it is done with -e "key=value" so hoping that also helps illustrate the point on variables being treated like a dictionary.
To expand things further from your example ...
vars: my_var: - "my_value1" - "my_value2" - "my_value3"
You can take your DICTIONARY variable and now the my_var values are actually a list (think of my_var) as maybe being packages to install. So again, the vars: block in the playbook is a very powerful option of defining variables for tasks and roles.
As you work more with Ansible, you will most likely find yourself beginning to use host/group variables in inventory and having only a minimum number of variables in the playbook. This is how I work with larger teams. For my demos, I almost always put things in a vars: block or vars_files: to make it easier to figure things out and understand, but as you work with larger projects and maybe take the DO374 you will soon see the power and advantages of using inventory group/host variables.
Hope this along with @Chetan_Tiwary_ 's answer helps clear things up.
@Trevor_Chandler - I know you like interesting conversations so I thought this might be a good read for you.
https://rhtapps.redhat.com/verify?certId=111-134-086
SENIOR TECHNICAL INSTRUCTOR / CERTIFIED INSTRUCTOR AND EXAMINER
Red Hat Certification + Training
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- 2,354 Views
Hello @TPeters !
Ansible variables are like chameleons of configuration. They adapt and shift based on your needs, allowing you to customize, flex, and reuse playbooks and roles across different environments. No need of hardcoding details - variables can let you manage complex tasks with the same playbook, on any system, in multiple contexts.
Totally depends upon how you want to define it and use it.
You can have : List, dictionary, nested , string, integer, magic , connection, special, runtime, play , block, registering & extra variables .
And yes, vars_files that is a list of include variables defined in external file/s.
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- 2,344 Views
@TPeters -
I want to provide a tiny bit more information directly related to your question on VARS Block.
So there are multiple ways to provide variables to Ansible (depending on the type some of them are automatic). When providing these variables (outside of the special variables and variables defined in inventory or the command line), there are two methods for specifying or providing variables directly in a playbook. Those two methods are vars: and vars_files: both of which provide the ability to instruct the playbook that you've defined variables.
One of the things I emphasize when delivering a course (especially the intro Ansible course) everything in Ansible is a List/Dictionary and from there, you just build out and expand using a comination of Lists/Dictionaries. At the play level, I emphasize the playbook directives are key: value pairs belonging to the play at the first indentation level. Depending on the key, the value can be a single value (most likely a string), a list, or a dictionary value.
At the play level we have name, hosts, vars, vars_files, tasks, roles, pre-tasks, post-tasks, and handlers. Yes, there are some other special things we can put in there to override configuration files and users and things, but those are the top ones.The tasks and the vars_files are always expecting the items as a list of tasks or files to process and handle (again, these will be lists and possibly lists of dictionaries). If you think about a task, the indentation level in there is essentially a list of dictionaries (key: value pairs). Where a task must always have a module, but it is generally recommended it has a name prior to the module and then the next indentation is the dictionary items that go with the module (key: value pairs) needed to make the module function as intended.
So why is the vars: block confusing ...? Simply put, this is the way for Ansible to get variables for your playbook. These variables can be many things and there is a single vars: block defined for each play. That means it must accept a list of variable values. What is more, as you pointed out some variables can be dictionaries, so vars: must also accept a dictionary. Therefore, when you boil even a regular variable definition down and you think to look at it conceptually, even a basic variable can be viewed as a dictionary.
For example:
my_pkg: vim
The my_pkg is the variable name, but you could also look at it as the KEY for the dictionary. The value for the variable is vim but it could also be looked at as the dictionary value for the KEY.
So if you approach things this way, the vars: block accepts a list of dictionaries. When there is only one thing specified, you don't need the "-" for the list.
Variables are DICTIONARIES as you hopefully can see using the reference above. Keep in mind ... variable precedence the highest is the "extra variable" specified on the command line ... it is done with -e "key=value" so hoping that also helps illustrate the point on variables being treated like a dictionary.
To expand things further from your example ...
vars: my_var: - "my_value1" - "my_value2" - "my_value3"
You can take your DICTIONARY variable and now the my_var values are actually a list (think of my_var) as maybe being packages to install. So again, the vars: block in the playbook is a very powerful option of defining variables for tasks and roles.
As you work more with Ansible, you will most likely find yourself beginning to use host/group variables in inventory and having only a minimum number of variables in the playbook. This is how I work with larger teams. For my demos, I almost always put things in a vars: block or vars_files: to make it easier to figure things out and understand, but as you work with larger projects and maybe take the DO374 you will soon see the power and advantages of using inventory group/host variables.
Hope this along with @Chetan_Tiwary_ 's answer helps clear things up.
@Trevor_Chandler - I know you like interesting conversations so I thought this might be a good read for you.
https://rhtapps.redhat.com/verify?certId=111-134-086
SENIOR TECHNICAL INSTRUCTOR / CERTIFIED INSTRUCTOR AND EXAMINER
Red Hat Certification + Training
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- 2,337 Views
Thank you for the question. I went ahead and created one more item here for this post and I will cross-post to your other variables question. The playbook here shows a couple different variable definitions (single item, a list, and a dictionary). The tasks show how to extract information from these variables as well as some variables that aren't specified that @Chetan_Tiwary_ mentioned. The other thing that I am showing is how to get the variable type which can be important.
https://github.com/tmichett/AnsiblePlaybooks/tree/master/Vars
https://rhtapps.redhat.com/verify?certId=111-134-086
SENIOR TECHNICAL INSTRUCTOR / CERTIFIED INSTRUCTOR AND EXAMINER
Red Hat Certification + Training
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- 2,304 Views
@Chetan_Tiwary_ , @Travis : thank you for your extensive explanations and examples. Agreed that in Ansible everything is a list or a dictionary, or takes a list or a dictionary. What is confusing me is the dual nature of "vars: " (and possibly other keywords), that it can take both; e.g. in AnsiblePlaybooks/Vars/Var_Demo_Playbook.yml at master · tmichett/AnsiblePlaybooks · GitHub , under "vars: " there are 3 variables, but without preceding '- ' so here it is not a list but a dictionary of variables. But it can also take a list of variables. In contrast, "vars_files: " and "roles: " appear to require a list, I recall I've had error messages when I forgot the preceding '- ' for the role or file.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- 2,275 Views
@TPeters -
So I'm not sure I can help much more and yes you have a point in vars being a little bit strange in how it works. The only thing I can say is it comes with experience and to look carefully at the documentation.
I can also state that things defined as "lists" must be a list and have the "-" preceding them. I did another quick demo to show it works the same with the preceding "-" as you have mentioned to show that it is treated no differently. Again, this is how the vars directive works.
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_intro.html
https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html#yaml-syntax
https://www.redhat.com/sysadmin/ansible-pretasks-posttasks
The "vars_files" can ONLY be a LIST of files. The "tasks", pre_tasks, post_tasks, handlers, and roles are all "LISTS" of tasks so they need the preceding "-". Since the vars section can be either, there isn't an enforcement or anything one way or the other. However, it is possible to adopt a style to make it be easier and just use the preceding "-" even if you have a single variable item.
The above link should give you all the playbook keywords that are reserved. Specifically, it refers to vars as being "Dictionary/map of variables". That link provides keywords that are "reserved" for controlling Ansible behavior.
Creating variable names has the reference provided above regarding playbook keywords, but you must also know to be careful not to use Python keywords. The link provided below talks more about defining variables. One of the considerations with Python keywords is when we are referencing facts and returned values. That is what the [] notation is recommended over the "." notation for variable referencing.
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html
That's about all the insight I can provide on this as well as "official" references. At this point, you need to just know that the vars directive in the playbook acts the way it does and know that the YAML and linting rules can assist in writing the playbook. Know too you can also create your own rules when working with larger teams so that if you feel more comfortable with the preceding "-" that can be a playbook design and authoring rule you choose to implement.
https://rhtapps.redhat.com/verify?certId=111-134-086
SENIOR TECHNICAL INSTRUCTOR / CERTIFIED INSTRUCTOR AND EXAMINER
Red Hat Certification + Training
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- 2,210 Views
@Travis : again, thank you for extensive explanation and the links - I wasn't aware of the keyword overview page (in an appendix). Much more than I've had to use so far.