Playbooks
In this lab you will run a playbook, check the syntax, and fix the syntax error.
Create Playbook¶
Copy the following playbook into your ansible playbook directory. This is normally found under your_home_directory/ansible/playbooks
.
---
hosts: localhost
tasks:
- name: "check if file1.txt exists"
stat:
path: /home/directoryA/file1.txt
register: file_exists
- name: "check if directoryB exists"
stat:
path: /home/directoryB
register: path_exists
- meta: end_play
when: file_exists.stat.exists is False and path_exists.stat.exists == False
- name: "create group userC"
group:
name: userC
state: present
- name: "create user userC"
user:
name: userC
comment: userC
group: userC
- name: "copy file1.txt from directory A to directory B, re-own to userC, give r-xr--r-- permissions"
copy:
src: /home/directoryA/file1.txt
dest: /home/directoryB
owner: userC
group: userC
mode: 0544
...
Run Your Playbook¶
$ ansible-playbook example.yaml
Expected Output:
ERROR! Syntax Error while loading YAML.
mapping values are not allowed in this context
The error appears to be in '/Users/user1/example/example.yaml': line 25, column 12, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- name: copy file1.txt from directory A to directory B, re-own to userC, give r-xr--r-- permissions
copy:
^ here
Unfortunately, the response indicates that the system found a syntax error. Continue onto the next section to find out how to catch these errors before running a playbook.
Run Syntax Check and Dry Run¶
Without running a syntax check, open the example.yaml file and try to determine which lines have errors. There are only two issues, but they are not quick to find. Extrapolate the time taken for a five-hundred plus line ansible playbook, and syntax checking becomes much more palatable.
Syntax Checks¶
In the case for the code above, the syntax checker would have caught the indentation mistake. It validates that the yaml file follows the recommended standards and is formatted in a parsable manner. At the end of the command, append --syntax-check
.
$ ansible-playbook example.yaml --syntax-check
Expected Output:
ERROR! Syntax Error while loading YAML.
did not find expected '-' indicator
The error appears to be in '/Users/user1/example/example.yaml': line 25, column 6, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- name: copy file1.txt from directory A to directory B, re-own to userC, give r-xr--r-- permissions
copy:
^ here
The syntax checker indicates a problem with the copy module. It now becomes obvious that an erroneous space interfered with the template. Open the file, and realign ‘copy’ with ‘name’.
After fixing the indentation error, run the syntax check again. It now shows no errors, but one issue remains which the syntax check is not registering. This is where a ‘dry run’ comes into play.
Dry Run¶
The next step is to go through a dry run to check and see if the playbook will execute successfully.
$ansible-playbook example.yaml --check
Expected Output:
ERROR! The conditional check 'file_exists.stat.exists is False and path_exists.stat.exists == False' failed. The error was: template error while templating string: no test named 'False'. String: {% if file_exists.stat.exists is False and path_exists.stat.exists == False %} True {% else %} False {% endif %}
The error appears to be in '/Users/user1/example/example.yaml': line 13, column 7, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
register: path_exists
- meta: end_play
^ here
The dry run indicates that the ‘when’ clause cannot interpret the ‘is’ comparison operator for a boolean object. Any number of small errors can cause the script to fail part way through. Open the yaml file and correct the mistake.
Bringing it Together¶
Before:
when: file_exists.stat.exists is False and path_exists.stat.exists == False
when: file_exists.stat.exists == False and path_exists.stat.exists == False
A final execution of the script should return the following:
TASK [Gathering Facts] *********************************************************
ok: [localhost]
TASK [check if file1.txt exists] ***********************************************
ok: [localhost]
TASK [check if directoryB exists] **********************************************
ok: [localhost]
PLAY RECAP *********************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
You have successfully created and executed your first playbook. The next logical step is to add another play into the playbook. Add another inventory item such as system2, and perform a slightly altered variation of the above play. The options are endless.
Resources