Variable does not seem to be defined in Ansible playbook - yaml

The following Ansible playbook for setting up a server for a Laravel app works fine:
---
- name: Set up a standard Laravel install
hosts: localhost
vars_prompt:
- name: "domain"
prompt: "Domain name"
private: no
- name: "dbname"
prompt: "Database name"
private: no
- name: "dbuser"
prompt: "Database username"
private: no
- name: "dbpassword"
prompt: "Database password"
private: yes
roles:
- create_droplet
- create_domain
- name: Install dependencies
hosts: launched
roles:
- upgrade
- utilities
- users
- nginx-php
- composer
- nginx_firewall
- redis
- postgres
- git
The following similar one for setting up a Wordpress install doesn't:
---
- name: Set up Wordpress with Apache, Memcached and Varnish
hosts: localhost
vars_prompt:
- name: "domain"
prompt: "Domain name"
private: no
- name: "title"
prompt: "Wordpress title"
private: no
- name: "email"
prompt: "Wordpress email"
private: no
- name: "user"
prompt: "Admin username"
private: no
- name: "pass"
prompt: "Admin password"
private: yes
roles:
- create_droplet
- create_domain
- name: Install dependencies
hosts: launched
roles:
- upgrade
- utilities
- users
- apache
- varnish
- memcached
- mysql
- wordpress
Both playbooks set up a new droplet on Digital Ocean using the create_droplet and create_domain roles, and add it to the launched group. However, the variables prompted for in the second playbook don't appear to be defined, as in this error message:
TASK [wordpress : Add user "wordpress", belonging to group "wordpress" and having a home dir of /var/www] ***
fatal: [<IP_ADDRESS_REDACTED>]: FAILED! => {"failed": true, "msg": "the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'pass' is undefined\n\nThe error appears to have been in '/home/matthew/Projects/ansible-setup/playbooks/roles/wordpress/tasks/main.yml': line 28, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Add user \"wordpress\", belonging to group \"wordpress\" and having a home dir of /var/www\n ^ here\nWe could be wrong, but this one looks like it might be an issue with\nunbalanced quotes. If starting a value with a quote, make sure the\nline ends with the same set of quotes. For instance this arbitrary\nexample:\n\n foo: \"bad\" \"wolf\"\n\nCould be written as:\n\n foo: '\"bad\" \"wolf\"'\n"}
Use of debug statements has confirmed that in none of the roles called in the second playbook does the domain variable appear to be defined. I'm not sure why that is. However, if I remove the part that creates the droplet and run it against an existing droplet, it seems to work OK.
Can anyone see why this is showing up as undefined? Is it something to do with the scope of these variables?

Is it something to do with the scope of these variables?
Yes, your variables are play-bound, so they are available for the first play (where you prompt them) and unavailable for the second one.
If you need variable to survive between plays, you need to convert it to host fact.
For example add post_tasks to your first play:
post_tasks:
- set_fact:
domain: '{{ domain }}'
delegate_to: '{{ item }}'
delegate_facts: true
with_inventory_hostnames: launched
This will add domain fact to every host in launched group.

Related

Ansible can't run when vars are used in include_tasks

I have two playbooks driver.yaml invoking another play after converting from template called main_driver.yml
Main playbook driver.yml
---
- name: Setup Services
hosts: all
gather_facts: no
vars_files:
- var_input_driver.yaml
tasks:
- name: Converting template to playbook
template:
src: template_for_driver.yaml.j2
dest: main_driver.yaml
delegate_to: localhost
- name: run roles
include_tasks: main_driver.yaml
Content of main_driver.yaml
---
- name: Setup Services
vars:
java_package: java-11-openjdk
dock_version: 18.09.0
- name: Setup services
include_role:
name: configure-java
Receiving error as below:
FAILED! => {"reason": "no module/action detected in task.\n\nThe error appears to be in 'main_driver.yaml': line 2, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n---\n- name: Setup Services\n ^ here\n"}
vars is not a module name but a task option. You should fix your included file like so:
---
- name: Setup services
include_role:
name: configure-java
vars:
java_package: java-11-openjdk
dock_version: 18.09.0
An other possible way would be:
---
- name: Set variables
set_fact:
java_package: java-11-openjdk
dock_version: 18.09.0
- name: Setup services
include_role:
name: configure-java
couple of things:
main_driver.yaml seems to include itself (main_driver) - that probably won't work.
the task file used with "include_tasks" should be a "pure" task file, not a playbook. In other words, it should not contain a playbook header (hosts, name, etc), but simply a list of tasks.
Im struggling to understand the logic in your example, maybe double-check that the file contents are correct?

Ansible playbook example code fail to run

I'm started to try Ansible, and using example code from Ansible Documentation. After I try several examples, I get error at the beginning of the code. It says
- name: Change the hostname to Windows_Ansible
^ here(Point at name)"
Any advice would be appreciate.
I tried this one
https://docs.ansible.com/ansible/latest/modules/win_hostname_module.html#win-hostname-module
---
- name: Change the hostname to Windows_Ansible
win_hostname:
name: "Windows_Ansible"
register: res
- name: Reboot
win_reboot:
when: res.reboot_required
The below task will change the hostname of the server. Make sure you run on a test server so that it wont create issues. If you just wanted to test some playbook, use the second playbook with win_command
---
- hosts: <remote server name which needs to be added in the inventory>
tasks:
- name: Change the hostname to Windows_Ansible
win_hostname:
name: "Windows_Ansible"
register: res
- name: Reboot
win_reboot:
when: res.reboot_required
---
- hosts: <remote server name which needs to be added in the inventory>
tasks:
- name: Test
win_command: whoami
register: res

Undefined variable when trying to pass username and password through Ansible Git Module

I have a follow up question to the thread in here:
How do I pass username and password while using Ansible Git module?
I am trying to achieve a similar task where I am passing a username and password to GitHub through Ansible. Here is what I am using for my playbook:
- name: ANSIBLE - Shop Installation
hosts: host_list
vars_prompt:
- name: "githubuser"
prompt: "Enter your github username"
private: no
- name: "githubpassword"
prompt: "Enter your github password"
private: yes
- hosts: host_list
tasks:
- name: Get the latest version through Git
git:
repo: 'https://{{ githubuser }}:{{ githubpassword }}#github.com/foo/bar.git'
dest: /tmp
After running through this, I get the following error message:
fatal: []: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'githubuser' is undefined\n\nThe error appears to have been in 'playbook.yml'
Any ideas where I may have gone wrong here?
I am running Ansible 2.7.1
I think the structure of your playbook is wrong. Try this:
---
- hosts: host_list
vars_prompt:
- name: "githubuser"
prompt: "Enter your github username"
private: no
- name: "githubpassword"
prompt: "Enter your github password"
private: yes
tasks:
- name: Get the latest version through Git
git:
repo: 'https://{{ githubuser }}:{{ githubpassword }}#github.com/foo/bar.git'
dest: /tmp
Scope of vars_prompt is a playbook.
Variable githubuser is defined in the first play. Second play knows nothing about it.
Would I have to pass the variable value from the first play to the second? What's the correct way of doing that in this context?
An option would be to configure fact_caching. For example with Redis
[defaults]
fact_caching=redis
In the first play store the variables with set_fact cacheable: yes
In the second play fetch data from Redis

Passing Git credentials to Ansible throwing an error

I am following this page, Clone a private git repository with Ansible (using password prompt) to solve my requirement. Re-used the same template in my playbook main.yml whose contents are as
---
- name: move CentOS repo definitions outside temp
copy:
src: "{{ item }}"
dest: /etc/yum.repos.d/
owner: "root"
mode: 0600
with_fileglob:
- /etc/yum.repos.d/temp/*
become: true
- name: passing git credentials for cloning the repos
vars_prompt:
- name: "githubuser"
prompt: "Enter your github username"
private: no
- name: "githubpassword"
prompt: "Enter your github password"
private: yes
and some more below. Am facing an error
The error appears to have been in '/tmp/.../tasks/main.yml': line 12, column 3, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- name: passing git credentials for cloning the repos
^ here
The error appears to have been in '/tmp/.../tasks/main.yml': line 12, column 3, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- name: passing git credentials for cloning the repos
^ here
I validated the yml using the syntax check option available
ansible-playbook main.yml --syntax-check
and also on the YAML lint, but can't seem to find the reason why the error is seen.
You can't use vars_prompt at task level, only at playbook level.
If your main.yml is a part of role, you should move prompt block to upper level playbook that includes your role.

Ansible error: "ERROR: hosts is not a legal parameter in an Ansible task or handler"

I have just add spark_master and spark_workers to the site.yml file. However, when I ran the ansible-playbook with my inventory file, I keep getting this error: ERROR: hosts is not a legal parameter in an Ansible task or handler. If I remove the spark_master and spark_workers, it will run fine. My ansible version is 1.9.4, python version 2.7.10
site.yml:
---
# The main playbook to deploy the site
- hosts: hadoop_all
sudo: yes
roles:
- hadoop_common
- hosts: hadoop_master_primary
roles:
- { role: hadoop_primary }
- hosts: hadoop_slaves
roles:
- { role: hadoop_slaves }
- hosts: spark_master
roles:
- { role: spark_master }
- hosts: spark_workers
roles:
- { role: spark_workers }
inventory_file:
[hadoop_all:children]
hadoop_masters
hadoop_slaves
hadoop_clients
[hadoop_master_primary]
hadoopmaster ansible_ssh_host=192.168.50.11
[hadoop_master_secondary]
[hadoop_masters:children]
hadoop_master_primary
hadoop_master_secondary
[hadoop_slaves]
hadoopslave1 ansible_ssh_host=192.168.50.12
hadoopslave2 ansible_ssh_host=192.168.50.13
hadoopslave3 ansible_ssh_host=192.168.50.14
[hadoop_clients]
hadoopclient1 ansible_ssh_host=192.168.50.15
[spark_master]
hadoopmaster
[spark_workers]
hadoopslave1
hadoopslave2
hadoopslave3
There is nothing wrong with your site.yml file. However, I definitely think that you may have placed "- hosts:" parameter in one of the roles' "tasks/main.yml" file. Since you are saying that your play runs fine without spark_master and spark_workers, I suspect that the culprit is "tasks/main.yml" file in one of those two roles.
I was able to reproduce your problem by running your site.yml, but adding the unnecessary "- Hosts:" parameter in a local role.
Let me know how it goes.

Resources