Ansible: exception handling ...
1. Lets create a simple playbook and run
[root@master wk_dec15]# cat error.yaml
- hosts: w1
tasks:
- package:
name: "httpd"
state: present
- debug:
msg: "This is a test run .."
[root@master wk_dec15]# ansible-playbook error.yaml
2. Lets make a mistake on one of the variable.
say pkg name is nane
# cat error.yaml
- hosts: w1
tasks:
- package:
nane: "httpd"
state: present
- debug:
msg: "This is just a test run ..."
[root@master wk_dec15]# alias 'ap=ansible-playbook'
[root@master wk_dec15]# ap error.yaml
we saw fatal error. we know its because the keyword we wrote, ansible does not that that keyword defined.
in fact it didn't recognize the parameter e=we supply.
say pkg name is nane
# cat error.yaml
- hosts: w1
tasks:
- package:
nane: "httpd"
state: present
- debug:
msg: "This is just a test run ..."
[root@master wk_dec15]# alias 'ap=ansible-playbook'
[root@master wk_dec15]# ap error.yaml
we saw fatal error. we know its because the keyword we wrote, ansible does not that that keyword defined.
in fact it didn't recognize the parameter e=we supply.
3. What we can do is tell ansible to ignore if you find error. do not just throw error, continue.
# cat error.yaml
- hosts: w1
tasks:
- package:
nane: "httpd"
state: present
ignore_errors: yes # ignore this error and go to next task
- debug:
msg: "This is just a test run ..."
[root@master wk_dec15]# ap error.yaml
You see, error is ignored this time.
# cat error.yaml
- hosts: w1
tasks:
- package:
nane: "httpd"
state: present
ignore_errors: yes # ignore this error and go to next task
- debug:
msg: "This is just a test run ..."
[root@master wk_dec15]# ap error.yaml
You see, error is ignored this time.
4. Now, lets try something else, lets download a file from internet..
[root@master wk_dec15]# ansible-doc -l uri
# cat errors.yaml
- hosts: w1
tasks:
- package:
name: "httpd"
state: present
debug:
msg: "This is just testing msg"
Before running the playbook to download a file from internet, lets look into some docs
or google for ansible uri or get-uri
look for example
Image source: https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/quotes-about-change-1580499303.jpg
[root@master wk_dec15]# ansible-doc -l uri
# cat errors.yaml
- hosts: w1
tasks:
- package:
name: "httpd"
state: present
debug:
msg: "This is just testing msg"
Before running the playbook to download a file from internet, lets look into some docs
or google for ansible uri or get-uri
look for example
Image source: https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/quotes-about-change-1580499303.jpg
[root@master wk_dec15]# cat error.yaml
- hosts: w1
tasks:
- package:
nane: "httpd"
state: present
ignore_errors: yes
#- get_uri:
- uri:
url: https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/quotes-about-change-1580499303.jpg
dest: "/var/www/html/life_l.jpg"
- debug:
msg: "This is a test run .."
[root@master wk_dec15]#
[root@master wk_dec15]# ap error.yaml
[root@worker1 ~]# ls -l /var/www/html/life_l.jpg
-rw-r--r--. 1 root root 206868 Dec 8 05:10 /var/www/html/life_l.jpg
The result above shows that its successful.
- hosts: w1
tasks:
- package:
nane: "httpd"
state: present
ignore_errors: yes
#- get_uri:
- uri:
url: https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/quotes-about-change-1580499303.jpg
dest: "/var/www/html/life_l.jpg"
- debug:
msg: "This is a test run .."
[root@master wk_dec15]#
[root@master wk_dec15]# ap error.yaml
[root@worker1 ~]# ls -l /var/www/html/life_l.jpg
-rw-r--r--. 1 root root 206868 Dec 8 05:10 /var/www/html/life_l.jpg
The result above shows that its successful.
5. Now, say we have a problem with internet connection, and if you run this playbook,, it will fail.
It will throw error, so how do you handle the error?
The best thing you can do is ignore the error. How? look at the yaml file below..
[root@master wk_dec15]# netstat -rn
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 192.168.10.1 0.0.0.0 UG 0 0 0 enp0s3
for lab purpose, you can remove the 0.0.0.0
[root@master wk_dec15]# cat error.yaml
- hosts: w1
tasks:
- package:
nane: "httpd"
state: present
ignore_errors: yes
#- get_uri:
- uri:
url: https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/quotes-about-change-1580499303.jpg
dest: "/var/www/html/life_l.jpg"
ignore_errors: yes
- debug:
msg: "This is a test run .."
[root@master wk_dec15]# ap error.yaml
If you are disconnected from internet, it will fail with error unreachable network.
so, you can use ignore_errors keyword to ignore the error.
it will continue to run it. But it might be an important piece of information, that you can't ignore it.
so, you have to be very careful while dealing with ignore_errors.
6. Using block.
On block, your code in block and at the end, include rescue.
[root@master wk_dec15]# ap error.yaml
/usr/lib/python3.6/site-packages/requests/__init__.py:91: RequestsDependencyWarning: urllib3 (1.26.2) or chardet (3.0.4) doesn't match a supported version!
RequestsDependencyWarning)
PLAY [w1] *********************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************
ok: [w1]
TASK [package] ****************************************************************************************************************
ok: [w1]
TASK [uri] ********************************************************************************************************************
changed: [w1]
TASK [service] ****************************************************************************************************************
changed: [w1]
TASK [debug] ******************************************************************************************************************
ok: [w1] => {
"msg": "This is a test run .."
}
TASK [debug] ******************************************************************************************************************
ok: [w1] => {
"msg": "This is a test run .."
}
PLAY RECAP ********************************************************************************************************************
w1 : ok=6 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@worker1 ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: active (running) since Tue 2020-12-08 06:01:59 EST; 42s ago
Docs: man:httpd.service(8)
Main PID: 59114 (httpd)
[root@worker1 html]# ls -ltr
total 212
-rw-r--r--. 1 root root 8 Dec 7 03:19 index.html
-rw-r--r--. 1 root root 12 Dec 8 05:51 webap.htm
-rw-r--r--. 1 root root 206868 Dec 8 05:53 life_l.jpg
[root@worker1 html]# cat webap.htm
This is cool
===================================
Notes
exception handling
- error handling
Ansible is a Framework...
- Declarative language
- Code - playbook - error - exception
- YAML
How we can handle error or exceptions
yaml code for package [ DL]
- package: # keywork - a module
nane: "httpd" # what is nane? I don't understand, its not on my voculabulary...
state: present
You ask me to perform something that I don't know.. I will terminate everything... - default behavior
but we don't want to do that. Run this task, if there is minor mistake, keep trying it. if you don't understand
something, just ignore and keep executing it... execute other tasks, skip the one with error..
how ansible handle this kind of situation?
block
try
-----
-----
----
catch .. except ... rescue
app does not crash - good programmer...
check your inventory file
# cat /root/myhosts
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- debug:
msg: "This is a test ..."
Run it
# ap error.yaml
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- package:
name: "httpd"
state: present
- debug:
msg: "This is a test ..."
# ap error.yaml
running fine now...
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- package:
nane: "httpd"
state: present
- debug:
msg: "This is a test ..."
it throws error since the keywork is bad
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- package:
name: "httpd"
state: present
ignore_errors: yes # ignore the error and go to next step
- debug:
msg: "This is a test ..."
But it is not always a good practice to ignore the error.
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- package:
name: "httpd"
state: present
ignore_errors: yes # ignore the error and go to next step
url: http://mywebsite.internet # lets say this task must run, but if you ignore, whole thing will fails if there is not internet connection.
ignore_errors: yes # not always a good idea. they skip the task.
- debug:
msg: "This is a test ..."
Try and catch ..rescue
go to ansible doc and look for uri
# ansible-doc -l uri
or google for ansible uri
look through all option and go all the way down, to example.
or google for ansible get-url # download file from somewhere..
go to internet and get an URL for any picture.
https://disabledparenting.com/wp-content/uploads/2017/02/lifeisbeautiful-e1458411303728-300x162.jpg
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- package:
name: "httpd"
state: present
# - get_url: # this module is created by a developer.. and you have to follow certain property..
- uri
url: "https://disabledparenting.com/wp-content/uploads/2017/02/lifeisbeautiful-e1458411303728-300x162.jpg"
dest: "/var/www/html/life.jpg"
- service:
name: "httpd"
state: started
- debug:
msg: "This is a test ..."
run the code, and should be able to download.
Delete your default route
# route del net 0.0.0.0
now you have internal connectivity but not internet connectivity.
run run the playbook again,
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- package:
name: "httpd"
state: present
- get_url: # this module is created by a developer.. and you have to follow certain property..
url: "https://disabledparenting.com/wp-content/uploads/2017/02/lifeisbeautiful-e1458411303728-300x162.jpg"
dest: "/var/www/html/life.jpg"
- service:
name: "httpd"
state: started
- debug:
msg: "This is a test ..."
# ap error.yaml
it will fail.. and error says ..
it is trying to go to internet .. ther eis not network connectivity,, unreachable...
if something does not work, throw the error.
Now, how do we handle it?
What we can do? ignore error ..
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- package:
name: "httpd"
state: present
- get_url:
url: "https://url.com/myimage.jpg"
dest: "/var/www/html/life.jpg"
ignore_errors: yes
- service:
name: "httpd"
state: started
- debug:
msg: "This is a test ..."
# ap error.yaml
now, it skips the error part..
This is a bad practice. What we can do is block
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
block:
- package:
name: "httpd"
state: present
- get_url:
url: "https://url.com/myimage.jpg"
dest: "/var/www/html/life.jpg"
# ignore_errors: yes
- service:
name: "httpd"
state: started
- debug:
msg: "This is a test ..."
Run this play
# ap error.yaml
we see errors
when you use block, you have to use rescue at the end..
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- block:
- package:
name: "httpd"
state: present
# - get_url:
uri:
url: "https://url.com/myimage.jpg"
dest: "/var/www/html/life.jpg"
# ignore_errors: yes
- service:
name: "httpd"
state: started
- debug:
msg: "This is a test ..."
- debug:
msg: "For rescue ..."
re-run it.
but this time, as soon error comes, last time, it failed, this time, it continue running ..
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- block: # module . runs other modules..
- package:
name: "httpd"
state: present
# - get_url:
uri:
url: "https://url.com/myimage.jpg"
dest: "/var/www/html/life.jpg"
# ignore_errors: yes
- service:
name: "httpd"
state: started
reacue:
- copy:
dest: "/var/www/html/kb.jpg"
content: "Hi How are you?"
- debug:
msg: "This is a test ..."
rescue:
- debug:
msg: "For rescue ..."
run it again,
using finally for block..
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- block: # module . runs other modules..
- package:
name: "httpd"
state: present
# - get_url:
uri:
url: "https://url.com/myimage.jpg"
dest: "/var/www/html/life.jpg"
# ignore_errors: yes
- service:
name: "httpd"
state: started
reacue:
- copy:
dest: "/var/www/html/kb.jpg"
content: "Hi How are you?"
- debug:
msg: "This is a test ..."
rescue:
- debug:
msg: "For rescue ..."
always: # block, rescue, always are on sam indent
- debug: # testing message
msg: "mail to this group ..."
google for mail
# ansible-docs -l | grep mail
community.general.mail
# ansible-docs mail
look for module sending mail...
if you want to use this module, there are some sort challanges regarding security.
lets talk about vault -
how to mail?
gmail.com -> application - web or app
--- opens with https ->
where do you want to send?
to send email,
webapp collect all info such as
to
sub
body
from
google has its own mail server,
on your behalf, the gmail application written is some language (php ..) collects info and mail server
we can use
- webUI
- you can directly go to mail server from your pc..(for automation)
- authlogin - login
emialid:
google for google mail smtp server ip address ...
# cat
- hosts: 127.0.0.1
tasks:
mail:
host: smtp.gmail.com
portL 587
username: sam@gmail.com
password: your_passsword
to: hr@abc.com
subject: ansible Class
body: system {{ ansible_host }} has been successfully provisioned.
you have to type your pw, inorder to run it. But we don't want to share our pw so people can use our email pw.
but for testing purpose, use it and verify if it infact works.. do not share the code with your pw.
interrupt/exception -> Whats the difference
ctrl+C is interruption ->
=============================================================
It will throw error, so how do you handle the error?
The best thing you can do is ignore the error. How? look at the yaml file below..
[root@master wk_dec15]# netstat -rn
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 192.168.10.1 0.0.0.0 UG 0 0 0 enp0s3
for lab purpose, you can remove the 0.0.0.0
[root@master wk_dec15]# cat error.yaml
- hosts: w1
tasks:
- package:
nane: "httpd"
state: present
ignore_errors: yes
#- get_uri:
- uri:
url: https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/quotes-about-change-1580499303.jpg
dest: "/var/www/html/life_l.jpg"
ignore_errors: yes
- debug:
msg: "This is a test run .."
[root@master wk_dec15]# ap error.yaml
If you are disconnected from internet, it will fail with error unreachable network.
so, you can use ignore_errors keyword to ignore the error.
it will continue to run it. But it might be an important piece of information, that you can't ignore it.
so, you have to be very careful while dealing with ignore_errors.
6. Using block.
On block, your code in block and at the end, include rescue.
[root@master wk_dec15]# ap error.yaml
/usr/lib/python3.6/site-packages/requests/__init__.py:91: RequestsDependencyWarning: urllib3 (1.26.2) or chardet (3.0.4) doesn't match a supported version!
RequestsDependencyWarning)
PLAY [w1] *********************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************
ok: [w1]
TASK [package] ****************************************************************************************************************
ok: [w1]
TASK [uri] ********************************************************************************************************************
changed: [w1]
TASK [service] ****************************************************************************************************************
changed: [w1]
TASK [debug] ******************************************************************************************************************
ok: [w1] => {
"msg": "This is a test run .."
}
TASK [debug] ******************************************************************************************************************
ok: [w1] => {
"msg": "This is a test run .."
}
PLAY RECAP ********************************************************************************************************************
w1 : ok=6 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@worker1 ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: active (running) since Tue 2020-12-08 06:01:59 EST; 42s ago
Docs: man:httpd.service(8)
Main PID: 59114 (httpd)
[root@worker1 html]# ls -ltr
total 212
-rw-r--r--. 1 root root 8 Dec 7 03:19 index.html
-rw-r--r--. 1 root root 12 Dec 8 05:51 webap.htm
-rw-r--r--. 1 root root 206868 Dec 8 05:53 life_l.jpg
[root@worker1 html]# cat webap.htm
This is cool
===================================
Notes
exception handling
- error handling
Ansible is a Framework...
- Declarative language
- Code - playbook - error - exception
- YAML
How we can handle error or exceptions
yaml code for package [ DL]
- package: # keywork - a module
nane: "httpd" # what is nane? I don't understand, its not on my voculabulary...
state: present
You ask me to perform something that I don't know.. I will terminate everything... - default behavior
but we don't want to do that. Run this task, if there is minor mistake, keep trying it. if you don't understand
something, just ignore and keep executing it... execute other tasks, skip the one with error..
how ansible handle this kind of situation?
block
try
-----
-----
----
catch .. except ... rescue
app does not crash - good programmer...
check your inventory file
# cat /root/myhosts
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- debug:
msg: "This is a test ..."
Run it
# ap error.yaml
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- package:
name: "httpd"
state: present
- debug:
msg: "This is a test ..."
# ap error.yaml
running fine now...
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- package:
nane: "httpd"
state: present
- debug:
msg: "This is a test ..."
it throws error since the keywork is bad
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- package:
name: "httpd"
state: present
ignore_errors: yes # ignore the error and go to next step
- debug:
msg: "This is a test ..."
But it is not always a good practice to ignore the error.
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- package:
name: "httpd"
state: present
ignore_errors: yes # ignore the error and go to next step
url: http://mywebsite.internet # lets say this task must run, but if you ignore, whole thing will fails if there is not internet connection.
ignore_errors: yes # not always a good idea. they skip the task.
- debug:
msg: "This is a test ..."
Try and catch ..rescue
go to ansible doc and look for uri
# ansible-doc -l uri
or google for ansible uri
look through all option and go all the way down, to example.
or google for ansible get-url # download file from somewhere..
go to internet and get an URL for any picture.
https://disabledparenting.com/wp-content/uploads/2017/02/lifeisbeautiful-e1458411303728-300x162.jpg
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- package:
name: "httpd"
state: present
# - get_url: # this module is created by a developer.. and you have to follow certain property..
- uri
url: "https://disabledparenting.com/wp-content/uploads/2017/02/lifeisbeautiful-e1458411303728-300x162.jpg"
dest: "/var/www/html/life.jpg"
- service:
name: "httpd"
state: started
- debug:
msg: "This is a test ..."
run the code, and should be able to download.
Delete your default route
# route del net 0.0.0.0
now you have internal connectivity but not internet connectivity.
run run the playbook again,
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- package:
name: "httpd"
state: present
- get_url: # this module is created by a developer.. and you have to follow certain property..
url: "https://disabledparenting.com/wp-content/uploads/2017/02/lifeisbeautiful-e1458411303728-300x162.jpg"
dest: "/var/www/html/life.jpg"
- service:
name: "httpd"
state: started
- debug:
msg: "This is a test ..."
# ap error.yaml
it will fail.. and error says ..
it is trying to go to internet .. ther eis not network connectivity,, unreachable...
if something does not work, throw the error.
Now, how do we handle it?
What we can do? ignore error ..
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- package:
name: "httpd"
state: present
- get_url:
url: "https://url.com/myimage.jpg"
dest: "/var/www/html/life.jpg"
ignore_errors: yes
- service:
name: "httpd"
state: started
- debug:
msg: "This is a test ..."
# ap error.yaml
now, it skips the error part..
This is a bad practice. What we can do is block
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
block:
- package:
name: "httpd"
state: present
- get_url:
url: "https://url.com/myimage.jpg"
dest: "/var/www/html/life.jpg"
# ignore_errors: yes
- service:
name: "httpd"
state: started
- debug:
msg: "This is a test ..."
Run this play
# ap error.yaml
we see errors
when you use block, you have to use rescue at the end..
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- block:
- package:
name: "httpd"
state: present
# - get_url:
uri:
url: "https://url.com/myimage.jpg"
dest: "/var/www/html/life.jpg"
# ignore_errors: yes
- service:
name: "httpd"
state: started
- debug:
msg: "This is a test ..."
- debug:
msg: "For rescue ..."
re-run it.
but this time, as soon error comes, last time, it failed, this time, it continue running ..
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- block: # module . runs other modules..
- package:
name: "httpd"
state: present
# - get_url:
uri:
url: "https://url.com/myimage.jpg"
dest: "/var/www/html/life.jpg"
# ignore_errors: yes
- service:
name: "httpd"
state: started
reacue:
- copy:
dest: "/var/www/html/kb.jpg"
content: "Hi How are you?"
- debug:
msg: "This is a test ..."
rescue:
- debug:
msg: "For rescue ..."
run it again,
using finally for block..
# cat eorrr.yml
- hosts: 192.168.10.20
tasks:
- block: # module . runs other modules..
- package:
name: "httpd"
state: present
# - get_url:
uri:
url: "https://url.com/myimage.jpg"
dest: "/var/www/html/life.jpg"
# ignore_errors: yes
- service:
name: "httpd"
state: started
reacue:
- copy:
dest: "/var/www/html/kb.jpg"
content: "Hi How are you?"
- debug:
msg: "This is a test ..."
rescue:
- debug:
msg: "For rescue ..."
always: # block, rescue, always are on sam indent
- debug: # testing message
msg: "mail to this group ..."
google for mail
# ansible-docs -l | grep mail
community.general.mail
# ansible-docs mail
look for module sending mail...
if you want to use this module, there are some sort challanges regarding security.
lets talk about vault -
how to mail?
gmail.com -> application - web or app
--- opens with https ->
where do you want to send?
to send email,
webapp collect all info such as
to
sub
body
from
google has its own mail server,
on your behalf, the gmail application written is some language (php ..) collects info and mail server
we can use
- webUI
- you can directly go to mail server from your pc..(for automation)
- authlogin - login
emialid:
google for google mail smtp server ip address ...
# cat
- hosts: 127.0.0.1
tasks:
mail:
host: smtp.gmail.com
portL 587
username: sam@gmail.com
password: your_passsword
to: hr@abc.com
subject: ansible Class
body: system {{ ansible_host }} has been successfully provisioned.
you have to type your pw, inorder to run it. But we don't want to share our pw so people can use our email pw.
but for testing purpose, use it and verify if it infact works.. do not share the code with your pw.
interrupt/exception -> Whats the difference
ctrl+C is interruption ->
=============================================================
No comments:
Post a Comment