Difference between revisions of "Ops535 ansible lab"

From CDOT Wiki
Jump to: navigation, search
m (Protected "Ops535 ansible lab": OER transfer ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite)))
 
(24 intermediate revisions by one other user not shown)
Line 1: Line 1:
[[Category:OPS435]][[Category:rchan]][[Category:OPS435 Lab]]
+
[[Category:rchan]]
 
= Objective =
 
= Objective =
 
:# Install and configure Ansible on a controller Linux machine
 
:# Install and configure Ansible on a controller Linux machine
Line 11: Line 11:
  
 
= Reference =
 
= Reference =
:* For more detail information about ansible, check out the ansible web site at [http://www.ansible.com. www.ansible.com]
+
:* For more detail information about ansible, check out the ansible web site at [https://www.ansible.com. www.ansible.com]
 
:* [https://www.ansible.com/overview/how-ansible-works Overview]
 
:* [https://www.ansible.com/overview/how-ansible-works Overview]
 
:* [https://docs.ansible.com/ansible/latest/user_guide/index.html Ansible Latest User Guide]
 
:* [https://docs.ansible.com/ansible/latest/user_guide/index.html Ansible Latest User Guide]
Line 20: Line 20:
  
 
= System requirements =
 
= System requirements =
 +
The instruction in this lab has been tested for CentOS 8.3.2011, and
 
* You must have at lease two networked machines
 
* You must have at lease two networked machines
** control machine - run ansible to configure remote node - need Ansible 2.x (latest version 2.7)
+
** control machine - run ansible to configure remote node - need Ansible 2.9.16 (The IP address of control machine used in the example in this lab is 192.168.49.1)
** managed machine(s) - to be managed by the control node
+
** managed machine(s) - to be managed by the control node (The IP address of the managed machine used in the examples in this lab is 192.168.49.3)
 
* You should be able to ssh from your control machine as a regular user to any of your remote machines as regular user without supplying a login password.
 
* You should be able to ssh from your control machine as a regular user to any of your remote machines as regular user without supplying a login password.
 
* You account on the remote machine should be a sudoer and can run sudo without password.
 
* You account on the remote machine should be a sudoer and can run sudo without password.
* You should also be to ssh from your control machine as a regular user to any of your remote machines as root without supplying a login password
+
* You should also be able to ssh from your control machine as a regular user to any of your remote machines as root without supplying a login password
* Python 2.7+ on all nodes
+
* Python 3.6+ on all nodes
 
 
  
 
= Investigation I: Introduction to Ansible =
 
= Investigation I: Introduction to Ansible =
: In this introduction, we explore the main components of the Ansible configuration management system and its operating environment. we also study a simple playbook for managing the configuration of a CentOS 7.x VM.  
+
: In this introduction, we explore the main components of the Ansible configuration management system and its operating environment. we also study a simple playbook for managing the configuration of a CentOS 8.x VM.  
 
: You need at least two VMs for this lab: one VM to be used as the control machine and one or more VMs to be used as the managed machines. You only need to install Ansible on the control machine.  
 
: You need at least two VMs for this lab: one VM to be used as the control machine and one or more VMs to be used as the managed machines. You only need to install Ansible on the control machine.  
  
Line 40: Line 40:
 
* Ad hoc commands - a simple one-off task:
 
* Ad hoc commands - a simple one-off task:
 
** <u><b>shell commands</b></u>
 
** <u><b>shell commands</b></u>
*** ansible 192.168.99.153 -a 'date'
+
*** ansible 192.168.49.3 -a 'date'
*** ansible 192.168.99.153 -a 'df'  
+
*** ansible 192.168.49.3 -a 'df'  
*** ansible 192.168.99.153 -a 'iptables -L -n -v' -u root
+
*** ansible 192.168.49.3 -a 'iptables -L -n -v' -u root
 
* Built-in modules - code that performs a particular task such as copy a file, installing a package, etc:
 
* Built-in modules - code that performs a particular task such as copy a file, installing a package, etc:
 
** <u><b>copy module</b></u>
 
** <u><b>copy module</b></u>
*** ansible 192.168.99.153 -m copy -a "src=/ops435/ansible.txt dest=/tmp/ansible.txt"
+
*** ansible 192.168.49.3 -m copy -a "src=/home/rchan/ops535/ansible.txt dest=/tmp/ansible.txt"
 
** <u><b>Package management</b></u>
 
** <u><b>Package management</b></u>
*** ansible 192.168.99.153 -m yum -a "name=epel-release state=latest"
+
*** ansible 192.168.49.3 -m dnf -a "name=bind state=latest"
 
* Playbooks - contains one or multiple plays, each play defines a set of repeatable tasks on one or more managed machines. Playbooks are written in YAML. Every play in the playbook is created with environment-specific parameters for the target machines:   
 
* Playbooks - contains one or multiple plays, each play defines a set of repeatable tasks on one or more managed machines. Playbooks are written in YAML. Every play in the playbook is created with environment-specific parameters for the target machines:   
** ansible-playbook -i 192.168.99.153, setup_webserver.yaml
+
** ansible-playbook -i 192.168.49.3, setup_webserver.yaml
 
** ansible-playbook firstrun.yaml
 
** ansible-playbook firstrun.yaml
== Hardware and software required
+
 
== Part 1: Installing Ansible on CentOS 7 ==
+
== Part 1: Installing Ansible on CentOS 8 ==
 
: You only need to install the "ansible" package on your control VM.  
 
: You only need to install the "ansible" package on your control VM.  
:* Login as a regular user, change to the directory ~/ops435/lab9
 
 
:* Issue the following command to install the "ansible" package: <source lang="bash">  
 
:* Issue the following command to install the "ansible" package: <source lang="bash">  
 
sudo yum install ansible -y
 
sudo yum install ansible -y
Line 60: Line 59:
  
 
:* You may have to install the following dependent packages:<source lang="bash">
 
:* You may have to install the following dependent packages:<source lang="bash">
Dependencies Resolved
+
Dependencies resolved.
 
+
==========================================================================================
=====================================================================================================================
+
  Package                   Architecture  Version               Repository         Size
  Package                             Arch                  Version                       Repository             Size
+
==========================================================================================
=====================================================================================================================
 
 
Installing:
 
Installing:
  ansible                             noarch               2.9.1-1.el7                  epel                   17 M
+
  ansible                   noarch         2.9.17-1.el8          epel               17 M
Installing for dependencies:
+
Installing dependencies:
  python-babel                        noarch                0.9.6-8.el7                  base                 1.4 M
+
  libsodium                 x86_64         1.0.18-2.el8          epel              162 k
python-cffi                        x86_64               1.6.0-5.el7                  base                  218 k
+
  python3-babel              noarch         2.5.1-5.el8            appstream        4.8 M
  python-enum34                      noarch               1.0.4-1.el7                  base                  52 k
+
  python3-bcrypt            x86_64        3.1.6-2.el8.1         epel              44 k
  python-httplib2                    noarch                0.9.2-1.el7                  extras                115 k
+
  python3-jinja2            noarch         2.10.1-2.el8_0        appstream        538 k
  python-idna                        noarch               2.4-1.el7                    base                  94 k
+
  python3-jmespath          noarch         0.9.0-11.el8          appstream          45 k
  python-jinja2                      noarch               2.7.2-4.el7                  base                  519 k
+
  python3-markupsafe         x86_64         0.23-19.el8            appstream          39 k
  python-markupsafe                   x86_64               0.11-10.el7                  base                  25 k
+
  python3-pyasn1            noarch         0.3.7-6.el8            appstream        126 k
  python-paramiko                    noarch               2.1.1-9.el7                  base                  269 k
+
  python3-pynacl            x86_64        1.3.0-5.el8            epel              100 k
  python-ply                          noarch                3.4-11.el7                    base                  123 k
+
  sshpass                   x86_64         1.06-9.el8            epel              27 k
  python-pycparser                   noarch                2.14-1.el7                    base                  104 k
+
Installing weak dependencies:
python2-cryptography                x86_64               1.7.2-2.el7                  base                  502 k
+
  python3-paramiko          noarch         2.4.3-1.el8            epel              289 k
  python2-jmespath                    noarch               0.9.0-3.el7                  extras                39 k
 
python2-pyasn1                      noarch                0.1.9-7.el7                  base                  100 k
 
sshpass                            x86_64                1.06-2.el7                    extras                21 k
 
  
 
Transaction Summary
 
Transaction Summary
=====================================================================================================================
+
==========================================================================================
Install  1 Package (+14 Dependent packages)
+
Install  11 Packages
  
Total download size: 21 M
+
Total download size: 23 M
Installed size: 120 M
+
Installed size: 123 M
Is this ok [y/d/N]:  
+
Is this ok [y/N]:  
 
</source>
 
</source>
  
 
: To confirm that you have Ansible installed, try the following command:<source lang="python">
 
: To confirm that you have Ansible installed, try the following command:<source lang="python">
[rchan@c7-rchan ~]$ ansible --help
+
[rchan@c8 ~]$ ansible --help
 
usage: ansible [-h] [--version] [-v] [-b] [--become-method BECOME_METHOD]
 
usage: ansible [-h] [--version] [-v] [-b] [--become-method BECOME_METHOD]
 
               [--become-user BECOME_USER] [-K] [-i INVENTORY] [--list-hosts]
 
               [--become-user BECOME_USER] [-K] [-i INVENTORY] [--list-hosts]
Line 111: Line 106:
 
</source>
 
</source>
 
: Take a look of all the available command line options for the "ansible" command. There are a lots of options when running Ansible. Let's move on to try a few simple ones.
 
: Take a look of all the available command line options for the "ansible" command. There are a lots of options when running Ansible. Let's move on to try a few simple ones.
 +
 +
: To get more detail information about the version of ansible installed on your system, try to following command:<source lang="python">
 +
[rchan@host ~]$ ansible --version
 +
ansible 2.9.17
 +
  config file = /etc/ansible/ansible.cfg
 +
  configured module search path = ['/home/rchan/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
 +
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
 +
  executable location = /usr/bin/ansible
 +
  python version = 3.6.8 (default, Aug 24 2020, 17:57:11) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]
 +
</source>
  
 
== Part 2: Sample runs for some of the Ad hoc commands ==
 
== Part 2: Sample runs for some of the Ad hoc commands ==
 
<pre>
 
<pre>
[rchan@centos7 ansible]$ ansible 192.168.99.153 -m copy -a "src=/home/rchan/ops435/ansible/ansible.txt dest=/tmp/ansible.txt"
+
[rchan@host ~]$ ansible 192.168.49.3 -m copy -a "src=/home/rchan/ops535/ansible/ansible.txt dest=/tmp/ansible.txt"
192.168.99.153 | SUCCESS => {
+
192.168.49.3 | CHANGED => {
     "changed": true,  
+
    "ansible_facts": {
     "checksum": "837affc90674fb92cdb0ebac6e49ad31a586b37e",  
+
        "discovered_interpreter_python": "/usr/libexec/platform-python"
     "dest": "/tmp/ansible.txt",  
+
    },
     "gid": 1001,  
+
     "changed": true,
     "group": "rchan",  
+
     "checksum": "82548876259158d4ba80a56ff311664353e49271",
     "md5sum": "78ae49d77d28d06173cf2194a3909732",  
+
     "dest": "/tmp/ansible.txt",
     "mode": "0664",  
+
     "gid": 1000,
     "owner": "rchan",  
+
     "group": "rchan",
     "secontext": "unconfined_u:object_r:user_home_t:s0",  
+
     "md5sum": "0bcc4d27cff6cd55138dd615a09669ab",
     "size": 106,  
+
     "mode": "0664",
     "src": "/home/rchan/.ansible/tmp/ansible-tmp-1542902119.15-117618539513309/source",  
+
     "owner": "rchan",
     "state": "file",  
+
     "secontext": "unconfined_u:object_r:user_home_t:s0",
     "uid": 1001
+
     "size": 132,
 +
     "src": "/home/rchan/.ansible/tmp/ansible-tmp-1611895800.9722285-30336-117758560038295/source",
 +
     "state": "file",
 +
     "uid": 1000
 
}
 
}
 
</pre>
 
</pre>
: 192.168.99.153 is the remote machine's IP address.
+
: 192.168.49.3 is the remote machine's IP address.
: "-m copy" tells ansible to use the copy module
+
: "-m copy" tells ansible to use the copy module (type ansible-doc copy for module documentation)
 
: after '-a' is the arguments to the copy module, which specify the source file and the destination for the copy action.
 
: after '-a' is the arguments to the copy module, which specify the source file and the destination for the copy action.
: If you got the same "SUCCESS" message, login to the remote machine (in this example, it is 192.168.99.153) and check the directory "/tmp" for the file ansible.txt.
+
: If you got the same "CHANGED" status message, login to the remote machine (in this example, 192.168.49.3) and check the directory "/tmp" for the file ansible.txt.
  
 
== Part 3: Sample runs for using some Ansible's built-in modules ==
 
== Part 3: Sample runs for using some Ansible's built-in modules ==
Line 143: Line 151:
 
     ansible-doc module_name
 
     ansible-doc module_name
  
     e.g. ansible_doc yum
+
     e.g. ansible_doc copy
 +
    e.g. ansible_doc dnf
 
</source>
 
</source>
: The following command demonstrates how to install the "epel-release" package with the "yum" module:
+
: The following command demonstrates how to install the "bind" package with the "yum" module and the response message under different conditions:
 
<pre>
 
<pre>
[rchan@centos7 ansible]$ ansible 192.168.99.153 -m yum -a "name=epel-release state=present"
+
[rchan@host ~]$ ansible 192.168.49.3 -m dnf -a "name=bind state=present" -b
192.168.99.153 | SUCCESS => {
+
192.168.49.3 | CHANGED => {
     "changed": false,  
+
    "ansible_facts": {
     "msg": "",  
+
        "discovered_interpreter_python": "/usr/libexec/platform-python"
     "rc": 0,  
+
    },
 +
     "changed": true,
 +
     "msg": "",
 +
     "rc": 0,
 
     "results": [
 
     "results": [
         "epel-release-7-11.noarch providing epel-release is already installed"
+
         "Installed: bind-32:9.11.20-5.el8.x86_64"
 
     ]
 
     ]
 
}
 
}
 
+
</pre>
[rchan@centos7 ansible]$ ansible 192.168.99.153 -m yum -a "name=epel-release state=present" -u root
+
: Try the same ansible ad-hoc command again:
192.168.99.153 | SUCCESS => {
+
<pre>
     "changed": false,  
+
[rchan@host ~]$ ansible 192.168.49.3 -m dnf -a "name=bind state=present" -b
     "msg": "",  
+
192.168.49.3 | SUCCESS => {
     "rc": 0,  
+
    "ansible_facts": {
     "results": [
+
        "discovered_interpreter_python": "/usr/libexec/platform-python"
        "epel-release-7-11.noarch providing epel-release is already installed"
+
    },
    ]
+
     "changed": false,
 +
     "msg": "Nothing to do",
 +
     "rc": 0,
 +
     "results": []
 
}
 
}
 
+
</pre>
[rchan@centos7 ansible]$ ansible 192.168.99.153 -m yum -a "name=epel-release state=latest" -u root
+
: Try to install the latest version of the bind package:
192.168.99.153 | SUCCESS => {
+
<pre>
     "changed": false,  
+
[rchan@host ~]$ ansible 192.168.49.3 -m dnf -a "name=bind state=latest" -b
     "msg": "",  
+
192.168.49.3 | SUCCESS => {
     "rc": 0,  
+
    "ansible_facts": {
     "results": [
+
        "discovered_interpreter_python": "/usr/libexec/platform-python"
        "All packages providing epel-release are up to date",
+
    },
        ""
+
     "changed": false,
    ]
+
     "msg": "Nothing to do",
 +
     "rc": 0,
 +
     "results": []
 
}
 
}
 
</pre>
 
</pre>
Line 182: Line 199:
 
: One of the main ansible module is called "setup", it is automatically called by ansible playbook to gather useful "facts" about remote hosts that can be used in ansible playbooks. It can also be executed directly by the ansible command (/usr/bin/ansible) to check what "facts" are available to a host.  
 
: One of the main ansible module is called "setup", it is automatically called by ansible playbook to gather useful "facts" about remote hosts that can be used in ansible playbooks. It can also be executed directly by the ansible command (/usr/bin/ansible) to check what "facts" are available to a host.  
 
<pre>
 
<pre>
[rchan@centos7 ansible]$ ansible 192.168.99.153 -m setup
+
[rchan@host ~]$ ansible 192.168.49.3 -m setup
192.168.99.153 | SUCCESS => {
+
192.168.49.3 | SUCCESS => {
 
     "ansible_facts": {
 
     "ansible_facts": {
 
         "ansible_all_ipv4_addresses": [
 
         "ansible_all_ipv4_addresses": [
             "192.168.122.99",  
+
             "192.168.149.3",
             "192.168.99.153"
+
            "192.168.49.3",
         ],  
+
             "192.168.99.162"
         "ansible_all_ipv6_addresses": [
+
         ],
            "fe80::5054:ff:fe11:6767",
+
         "ansible_all_ipv6_addresses": [],
             "fe80::5054:ff:fe8c:b67c"
+
        "ansible_apparmor": {
         ],  
+
             "status": "disabled"
         "ansible_architecture": "x86_64",  
+
         },
         "ansible_bios_date": "04/01/2014",  
+
         "ansible_architecture": "x86_64",
         "ansible_bios_version": "1.9.1-5.el7_3.2",  
+
         "ansible_bios_date": "04/01/2014",
 +
         "ansible_bios_version": "1.13.0-2.module_el8.3.0+555+a55c8938",
 
         "ansible_cmdline": {
 
         "ansible_cmdline": {
             "BOOT_IMAGE": "/vmlinuz-3.10.0-862.14.4.el7.x86_64",  
+
             "BOOT_IMAGE": "(hd0,msdos1)/vmlinuz-4.18.0-240.1.1.el8_3.x86_64",
             "LANG": "en_CA.UTF-8",  
+
             "crashkernel": "auto",
             "console": "ttyS0",  
+
            "quiet": true,
 +
            "rd.lvm.lv": "cl/swap",
 +
            "resume": "/dev/mapper/cl-swap",
 +
            "rhgb": true,
 +
            "ro": true,
 +
            "root": "/dev/mapper/cl-root"
 +
        },
 +
        "ansible_date_time": {
 +
             "date": "2021-01-29",
 +
            "day": "29",
 +
            "epoch": "1611896933",
 +
            "hour": "00",
 +
            "iso8601": "2021-01-29T05:08:53Z",
 +
            "iso8601_basic": "20210129T000853810313",
 +
 
 
...
 
...
         "ansible_userspace_bits": "64",  
+
 
         "ansible_virtualization_role": "guest",  
+
        "ansible_swapfree_mb": 2047,
         "ansible_virtualization_type": "kvm",  
+
        "ansible_swaptotal_mb": 2047,
 +
        "ansible_system": "Linux",
 +
        "ansible_system_capabilities": [
 +
            ""
 +
        ],
 +
        "ansible_system_capabilities_enforced": "True",
 +
        "ansible_system_vendor": "Red Hat",
 +
        "ansible_uptime_seconds": 21711,
 +
        "ansible_user_dir": "/home/rchan",
 +
        "ansible_user_gecos": "Raymond Chan",
 +
        "ansible_user_gid": 1000,
 +
        "ansible_user_id": "rchan",
 +
        "ansible_user_shell": "/bin/bash",
 +
        "ansible_user_uid": 1000,
 +
        "ansible_userspace_architecture": "x86_64",
 +
         "ansible_userspace_bits": "64",
 +
         "ansible_virtualization_role": "guest",
 +
         "ansible_virtualization_type": "kvm",
 +
        "discovered_interpreter_python": "/usr/libexec/platform-python",
 +
        "gather_subset": [
 +
            "all"
 +
        ],
 
         "module_setup": true
 
         "module_setup": true
     },  
+
     },
 
     "changed": false
 
     "changed": false
 
}
 
}
 
</pre>
 
</pre>
[[OPS435_Ansible_setup|Click here for complete contents of the above]]
+
[[OPS535_Ansible_setup|Click here for complete contents of the above]]
  
 
= Investigation II: Ansible Playbook =
 
= Investigation II: Ansible Playbook =
Line 223: Line 276:
 
<pre>
 
<pre>
 
---
 
---
- hosts: 192.168.99.153
+
- hosts: 192.168.49.3
   user: root
+
   user: rchan
 +
  become: yes
 
   vars:
 
   vars:
 
     apache_version: 2.6
 
     apache_version: 2.6
     motd_warning: 'WARNING: use by ICT faculty/students only.'
+
     motd_warning: 'WARNING: use by ITAS faculty/students only.'
 
     testserver: yes
 
     testserver: yes
 
   tasks:
 
   tasks:
Line 238: Line 292:
 
Sample Run:
 
Sample Run:
 
<pre>
 
<pre>
[rchan@centos7 playbooks]$ ansible-playbook motd-play.yml
+
[rchan@host ansible]$ ansible-playbook motd-play.yml
  
PLAY [192.168.99.153] **********************************************************
+
PLAY [192.168.49.3] **********************************************************************
  
TASK [Gathering Facts] *********************************************************
+
TASK [Gathering Facts] *******************************************************************
ok: [192.168.99.153]
+
ok: [192.168.49.3]
  
TASK [setup a MOTD] ************************************************************
+
TASK [setup a MOTD] **********************************************************************
changed: [192.168.99.153]
+
changed: [192.168.49.3]
 +
 
 +
PLAY RECAP *******************************************************************************
 +
192.168.49.3              : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
  
PLAY RECAP *********************************************************************
 
192.168.99.153            : ok=2    changed=1    unreachable=0    failed=0 
 
  
 
</pre>
 
</pre>
Line 257: Line 312:
 
<pre>
 
<pre>
 
---
 
---
- hosts: 192.168.99.153
+
- hosts: 192.168.49.3
   user: root
+
   user: rchan
 +
  become: yes
 
   vars:
 
   vars:
 
     apache_version: 2.6
 
     apache_version: 2.6
     motd_warning: 'WARNING: use by ICT faculty/students only.'
+
     motd_warning: 'WARNING: use by ITAS faculty/students only.'
 
     testserver: yes
 
     testserver: yes
 
   tasks:
 
   tasks:
Line 274: Line 330:
 
Sample Run:
 
Sample Run:
 
<pre>
 
<pre>
[rchan@centos7 playbooks]$ ansible-playbook httpd-play.yml
+
[rchan@host ansible]$ ansible-playbook httpd-play.yml
  
PLAY [192.168.99.153] **********************************************************
+
PLAY [192.168.49.3] **********************************************************************
  
TASK [Gathering Facts] *********************************************************
+
TASK [Gathering Facts] *******************************************************************
ok: [192.168.99.153]
+
ok: [192.168.49.3]
  
TASK [install apache] **********************************************************
+
TASK [install apache] ********************************************************************
changed: [192.168.99.153]
+
changed: [192.168.49.3]
  
TASK [restart apache] **********************************************************
+
TASK [restart apache] ********************************************************************
changed: [192.168.99.153]
+
changed: [192.168.49.3]
  
PLAY RECAP *********************************************************************
+
PLAY RECAP *******************************************************************************
192.168.99.153            : ok=3    changed=2    unreachable=0    failed=0   
+
192.168.49.3              : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
 +
  
 
</pre>
 
</pre>
= Investigation III: Using Playbook to config a OPS435 Linux machine =
+
: Login to 192.168.49.3 and verify that apache web server has been installed and is up and running.
: You have just installed the latest version of CentOS 7.x on a VM with GNOME Desktop. You need to configure it so that you can use it for doing the Labs for OPS435. The following configuration need to be done on that VM:
+
 
:* update all the packages installed on the VM
+
= Investigation III: Using Playbook to config a CentOS 8.x VM for OPS535 =
:* install extra packages repository for enterprise Linux
+
: You have just installed the latest version of CentOS 8.x on a VM with minimal packages. You need to configure it for doing OPS535 labs. The following configuration need to be done on that VM:
:* install python3 if it is not already installed
+
:* update all the packages installed on the VM to their latest version using the dnf module.
:* set the host name to your Seneca user name
+
:* install extra packages repository for enterprise Linux using the dnf module
:* install the git package
+
:* install the git package using the dnf module
:* create a new user with your Seneca_id with sudo access
+
:* create a new user with your Seneca_id (i.e. your Seneca user name) with sudo access
:* configure the new user account so that you can ssh to it without password
+
:* configure the new user account created in the previous step so that you can ssh to it without password
 
:* setup a directory structs for completing and organizing labs as shown below:<source lang="bash">
 
:* setup a directory structs for completing and organizing labs as shown below:<source lang="bash">
       /home/[seneca_id]/ops435/lab0
+
       /home/[seneca_id]/ops535/lab1
       /home/[seneca_id]/ops435/lab1
+
       /home/[seneca_id]/ops535/lab2
       /home/[seneca_id]/ops435/lab2
+
       /home/[seneca_id]/ops535/lab3
       /home/[seneca_id]/ops435/lab3
+
       /home/[seneca_id]/ops535/lab4
       /home/[seneca_id]/ops435/lab4
+
       /home/[seneca_id]/ops535/lab5
       /home/[seneca_id]/ops435/lab5
+
       /home/[seneca_id]/ops535/lab6
       /home/[seneca_id]/ops435/lab6
+
       /home/[seneca_id]/ops535/lab7
       /home/[seneca_id]/ops435/lab7
+
       /home/[seneca_id]/ops535/lab8
       /home/[seneca_id]/ops435/lab8
+
       /home/[seneca_id]/ops535/a1
       /home/[seneca_id]/ops435/lab9
+
       /home/[seneca_id]/ope535/a2
 +
     
 
</source>
 
</source>
:* create a playbook named "config_ops435.yml" to perform the tasks mentioned above.
+
:* create a playbook named "ops535_vm_config.yml" to perform all the tasks mentioned above.
:* test your playbook and capture its output when it complete without error.
+
:* test your playbook with the ansible-playbook command and capture its output to a text file named "ops535_ansible_lab.txt"
  
= Lab 9 Sign-off (Show Instructor) =
+
= Ansible Lab Sign-off (Show Instructor) =
 
== Have the following items ready to show your instructor: ==
 
== Have the following items ready to show your instructor: ==
: * The Ansible playbook called "config_ops435.yml" for configuring the VM mentioned in Lab 1.
+
: * The Ansible playbook called "ops535_vm_config.yml" for configuring the VM.
: * The result of running the playbook "config_ops435.yml". Save the result in a file called "lab9_[seneca_id].txt"
+
: * The result of running the playbook "ops535_vm_config.yml". Save the result in a file called "ops535_ansible_lab.txt"
 
== Upload the following files to blackboard ==
 
== Upload the following files to blackboard ==
: * config_ops435.yml
+
: * ops535_vm_config.yml
: * lab9_[seneca_id].txt
+
: * ops535_ansible_lab.txt

Latest revision as of 15:50, 21 July 2023

Objective

  1. Install and configure Ansible on a controller Linux machine
  2. Explore Ansible's ad hoc commands
  3. Explore Ansible's built-in modules
  4. Explore and create Ansible playbooks

Overview

Ansible is an agentless IT automation engine for automating cloud provisioning, configuration management, application deployment, intra-service orchestration, and many other IT system administration tasks.
Ansible uses no additional custom security infrastructure, and it uses a very simple human readable language called 'YAML', to compose an Ansible Playbook which allow you to describes the tasks you want to automate.

Reference

  • By: Daniel Hall, Publisher: Packt Publishing Pub.
  • Date: April 27, 2015,ISBN-13: 978-1-78528-230-0
  • Pages in Print Edition: 122

System requirements

The instruction in this lab has been tested for CentOS 8.3.2011, and

  • You must have at lease two networked machines
    • control machine - run ansible to configure remote node - need Ansible 2.9.16 (The IP address of control machine used in the example in this lab is 192.168.49.1)
    • managed machine(s) - to be managed by the control node (The IP address of the managed machine used in the examples in this lab is 192.168.49.3)
  • You should be able to ssh from your control machine as a regular user to any of your remote machines as regular user without supplying a login password.
  • You account on the remote machine should be a sudoer and can run sudo without password.
  • You should also be able to ssh from your control machine as a regular user to any of your remote machines as root without supplying a login password
  • Python 3.6+ on all nodes

Investigation I: Introduction to Ansible

In this introduction, we explore the main components of the Ansible configuration management system and its operating environment. we also study a simple playbook for managing the configuration of a CentOS 8.x VM.
You need at least two VMs for this lab: one VM to be used as the control machine and one or more VMs to be used as the managed machines. You only need to install Ansible on the control machine.

Key Concepts when using Ansible

  • YAML - a human-readable data serialization language use by Ansible's playbooks. To know more, your can check out the wikipedia page here
  • Control machine - the host on which you use Ansible to execute tasks on the managed machines
  • Managed machine - a host that is configured by the control machine
  • Hosts file - contains information about machines to be managed - click here for sample hosts file
  • Ad hoc commands - a simple one-off task:
    • shell commands
      • ansible 192.168.49.3 -a 'date'
      • ansible 192.168.49.3 -a 'df'
      • ansible 192.168.49.3 -a 'iptables -L -n -v' -u root
  • Built-in modules - code that performs a particular task such as copy a file, installing a package, etc:
    • copy module
      • ansible 192.168.49.3 -m copy -a "src=/home/rchan/ops535/ansible.txt dest=/tmp/ansible.txt"
    • Package management
      • ansible 192.168.49.3 -m dnf -a "name=bind state=latest"
  • Playbooks - contains one or multiple plays, each play defines a set of repeatable tasks on one or more managed machines. Playbooks are written in YAML. Every play in the playbook is created with environment-specific parameters for the target machines:
    • ansible-playbook -i 192.168.49.3, setup_webserver.yaml
    • ansible-playbook firstrun.yaml

Part 1: Installing Ansible on CentOS 8

You only need to install the "ansible" package on your control VM.
  • Issue the following command to install the "ansible" package:
     
    sudo yum install ansible -y
  • You may have to install the following dependent packages:
    Dependencies resolved.
    ==========================================================================================
     Package                    Architecture   Version                Repository         Size
    ==========================================================================================
    Installing:
     ansible                    noarch         2.9.17-1.el8           epel               17 M
    Installing dependencies:
     libsodium                  x86_64         1.0.18-2.el8           epel              162 k
     python3-babel              noarch         2.5.1-5.el8            appstream         4.8 M
     python3-bcrypt             x86_64         3.1.6-2.el8.1          epel               44 k
     python3-jinja2             noarch         2.10.1-2.el8_0         appstream         538 k
     python3-jmespath           noarch         0.9.0-11.el8           appstream          45 k
     python3-markupsafe         x86_64         0.23-19.el8            appstream          39 k
     python3-pyasn1             noarch         0.3.7-6.el8            appstream         126 k
     python3-pynacl             x86_64         1.3.0-5.el8            epel              100 k
     sshpass                    x86_64         1.06-9.el8             epel               27 k
    Installing weak dependencies:
     python3-paramiko           noarch         2.4.3-1.el8            epel              289 k
    
    Transaction Summary
    ==========================================================================================
    Install  11 Packages
    
    Total download size: 23 M
    Installed size: 123 M
    Is this ok [y/N]:
To confirm that you have Ansible installed, try the following command:
[rchan@c8 ~]$ ansible --help
usage: ansible [-h] [--version] [-v] [-b] [--become-method BECOME_METHOD]
               [--become-user BECOME_USER] [-K] [-i INVENTORY] [--list-hosts]
               [-l SUBSET] [-P POLL_INTERVAL] [-B SECONDS] [-o] [-t TREE] [-k]
               [--private-key PRIVATE_KEY_FILE] [-u REMOTE_USER]
               [-c CONNECTION] [-T TIMEOUT]
               [--ssh-common-args SSH_COMMON_ARGS]
               [--sftp-extra-args SFTP_EXTRA_ARGS]
               [--scp-extra-args SCP_EXTRA_ARGS]
               [--ssh-extra-args SSH_EXTRA_ARGS] [-C] [--syntax-check] [-D]
               [-e EXTRA_VARS] [--vault-id VAULT_IDS]
               [--ask-vault-pass | --vault-password-file VAULT_PASSWORD_FILES]
               [-f FORKS] [-M MODULE_PATH] [--playbook-dir BASEDIR]
               [-a MODULE_ARGS] [-m MODULE_NAME]
               pattern
...
Take a look of all the available command line options for the "ansible" command. There are a lots of options when running Ansible. Let's move on to try a few simple ones.
To get more detail information about the version of ansible installed on your system, try to following command:
[rchan@host ~]$ ansible --version
ansible 2.9.17
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/rchan/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Aug 24 2020, 17:57:11) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]

Part 2: Sample runs for some of the Ad hoc commands

[rchan@host ~]$ ansible 192.168.49.3 -m copy -a "src=/home/rchan/ops535/ansible/ansible.txt dest=/tmp/ansible.txt"
192.168.49.3 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "checksum": "82548876259158d4ba80a56ff311664353e49271",
    "dest": "/tmp/ansible.txt",
    "gid": 1000,
    "group": "rchan",
    "md5sum": "0bcc4d27cff6cd55138dd615a09669ab",
    "mode": "0664",
    "owner": "rchan",
    "secontext": "unconfined_u:object_r:user_home_t:s0",
    "size": 132,
    "src": "/home/rchan/.ansible/tmp/ansible-tmp-1611895800.9722285-30336-117758560038295/source",
    "state": "file",
    "uid": 1000
}
192.168.49.3 is the remote machine's IP address.
"-m copy" tells ansible to use the copy module (type ansible-doc copy for module documentation)
after '-a' is the arguments to the copy module, which specify the source file and the destination for the copy action.
If you got the same "CHANGED" status message, login to the remote machine (in this example, 192.168.49.3) and check the directory "/tmp" for the file ansible.txt.

Part 3: Sample runs for using some Ansible's built-in modules

"yum" is a built-in ansible module. You can get a complete list of all the ansible modules installed on you system with the following command:
    ansisble-doc --list_files
You can also get the detail information about any ansible module with the following command:
    ansible-doc module_name

    e.g. ansible_doc copy
    e.g. ansible_doc dnf
The following command demonstrates how to install the "bind" package with the "yum" module and the response message under different conditions:
[rchan@host ~]$ ansible 192.168.49.3 -m dnf -a "name=bind state=present" -b
192.168.49.3 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "msg": "",
    "rc": 0,
    "results": [
        "Installed: bind-32:9.11.20-5.el8.x86_64"
    ]
}
Try the same ansible ad-hoc command again:
[rchan@host ~]$ ansible 192.168.49.3 -m dnf -a "name=bind state=present" -b
192.168.49.3 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "msg": "Nothing to do",
    "rc": 0,
    "results": []
}
Try to install the latest version of the bind package:
[rchan@host ~]$ ansible 192.168.49.3 -m dnf -a "name=bind state=latest" -b
192.168.49.3 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "msg": "Nothing to do",
    "rc": 0,
    "results": []
}

Part 4: Gather software and hardware information available on remote machine

One of the main ansible module is called "setup", it is automatically called by ansible playbook to gather useful "facts" about remote hosts that can be used in ansible playbooks. It can also be executed directly by the ansible command (/usr/bin/ansible) to check what "facts" are available to a host.
[rchan@host ~]$ ansible 192.168.49.3 -m setup
192.168.49.3 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.149.3",
            "192.168.49.3",
            "192.168.99.162"
        ],
        "ansible_all_ipv6_addresses": [],
        "ansible_apparmor": {
            "status": "disabled"
        },
        "ansible_architecture": "x86_64",
        "ansible_bios_date": "04/01/2014",
        "ansible_bios_version": "1.13.0-2.module_el8.3.0+555+a55c8938",
        "ansible_cmdline": {
            "BOOT_IMAGE": "(hd0,msdos1)/vmlinuz-4.18.0-240.1.1.el8_3.x86_64",
            "crashkernel": "auto",
            "quiet": true,
            "rd.lvm.lv": "cl/swap",
            "resume": "/dev/mapper/cl-swap",
            "rhgb": true,
            "ro": true,
            "root": "/dev/mapper/cl-root"
        },
        "ansible_date_time": {
            "date": "2021-01-29",
            "day": "29",
            "epoch": "1611896933",
            "hour": "00",
            "iso8601": "2021-01-29T05:08:53Z",
            "iso8601_basic": "20210129T000853810313",

...

        "ansible_swapfree_mb": 2047,
        "ansible_swaptotal_mb": 2047,
        "ansible_system": "Linux",
        "ansible_system_capabilities": [
            ""
        ],
        "ansible_system_capabilities_enforced": "True",
        "ansible_system_vendor": "Red Hat",
        "ansible_uptime_seconds": 21711,
        "ansible_user_dir": "/home/rchan",
        "ansible_user_gecos": "Raymond Chan",
        "ansible_user_gid": 1000,
        "ansible_user_id": "rchan",
        "ansible_user_shell": "/bin/bash",
        "ansible_user_uid": 1000,
        "ansible_userspace_architecture": "x86_64",
        "ansible_userspace_bits": "64",
        "ansible_virtualization_role": "guest",
        "ansible_virtualization_type": "kvm",
        "discovered_interpreter_python": "/usr/libexec/platform-python",
        "gather_subset": [
            "all"
        ],
        "module_setup": true
    },
    "changed": false
}

Click here for complete contents of the above

Investigation II: Ansible Playbook

What is a playbook?

* Playbook is one of the core features of Ansible.
* Playbook tells Ansible what to execute by which user on the remote machine.
* Playbook is like a to-do list for Ansible
* Playbook is written "YAML".
* Playbook links a task to an ansible module and provide needed arguments to the module which requires them.

Part 1: A playbook to update the /etc/motd file

Name: motd-play.yml

---
- hosts: 192.168.49.3
  user: rchan
  become: yes
  vars:
    apache_version: 2.6
    motd_warning: 'WARNING: use by ITAS faculty/students only.'
    testserver: yes
  tasks:
    - name: setup a MOTD
      copy: 
        dest: /etc/motd
        content: "{{ motd_warning }}"

Sample Run:

[rchan@host ansible]$ ansible-playbook motd-play.yml

PLAY [192.168.49.3] **********************************************************************

TASK [Gathering Facts] *******************************************************************
ok: [192.168.49.3]

TASK [setup a MOTD] **********************************************************************
changed: [192.168.49.3]

PLAY RECAP *******************************************************************************
192.168.49.3               : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   


Part 2: A playbook to install and start Apache Server

Name: httpd-play.yml

---
- hosts: 192.168.49.3
  user: rchan
  become: yes
  vars:
    apache_version: 2.6
    motd_warning: 'WARNING: use by ITAS faculty/students only.'
    testserver: yes
  tasks:
    - name: install apache
      action: yum name=httpd state=installed
    
    - name: restart apache
      service: 
        name: httpd
        state: restarted

Sample Run:

[rchan@host ansible]$ ansible-playbook httpd-play.yml

PLAY [192.168.49.3] **********************************************************************

TASK [Gathering Facts] *******************************************************************
ok: [192.168.49.3]

TASK [install apache] ********************************************************************
changed: [192.168.49.3]

TASK [restart apache] ********************************************************************
changed: [192.168.49.3]

PLAY RECAP *******************************************************************************
192.168.49.3               : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
 

Login to 192.168.49.3 and verify that apache web server has been installed and is up and running.

Investigation III: Using Playbook to config a CentOS 8.x VM for OPS535

You have just installed the latest version of CentOS 8.x on a VM with minimal packages. You need to configure it for doing OPS535 labs. The following configuration need to be done on that VM:
  • update all the packages installed on the VM to their latest version using the dnf module.
  • install extra packages repository for enterprise Linux using the dnf module
  • install the git package using the dnf module
  • create a new user with your Seneca_id (i.e. your Seneca user name) with sudo access
  • configure the new user account created in the previous step so that you can ssh to it without password
  • setup a directory structs for completing and organizing labs as shown below:
          /home/[seneca_id]/ops535/lab1
          /home/[seneca_id]/ops535/lab2
          /home/[seneca_id]/ops535/lab3
          /home/[seneca_id]/ops535/lab4
          /home/[seneca_id]/ops535/lab5
          /home/[seneca_id]/ops535/lab6
          /home/[seneca_id]/ops535/lab7
          /home/[seneca_id]/ops535/lab8
          /home/[seneca_id]/ops535/a1
          /home/[seneca_id]/ope535/a2
  • create a playbook named "ops535_vm_config.yml" to perform all the tasks mentioned above.
  • test your playbook with the ansible-playbook command and capture its output to a text file named "ops535_ansible_lab.txt"

Ansible Lab Sign-off (Show Instructor)

Have the following items ready to show your instructor:

* The Ansible playbook called "ops535_vm_config.yml" for configuring the VM.
* The result of running the playbook "ops535_vm_config.yml". Save the result in a file called "ops535_ansible_lab.txt"

Upload the following files to blackboard

* ops535_vm_config.yml
* ops535_ansible_lab.txt