Practice Session 4: Ansible automation tool
Make sure that you have already gone through Lab-03
Ansible is a simple automation engine that automates cloud provisioning, configuration management, application deployment, intra-service orchestration, and many other needs. It uses the YAML language that you have used in Lab-02, in the form of Ansible Playbooks, and that allows you to describe your automation jobs in a way that approaches plain English. The aim of this lab is to get acquainted with the Ansible automation tool and get to know its most commonly used commands.
Introduction to Ansible
Ansible works by connecting to your nodes and pushing out small programs, called "Ansible modules" to them. These programs are written to be resource models of the desired state of the system. Ansible then executes these modules (over SSH by default) and removes them when finished.
References
Referred documents and websites contain supportive information for the practice.
Manuals
- How Ansible works
- Demo of this lab. This may not have very exact steps.
Prerequisite: Preparing the VMs
Lets manually create 3 VMs:
- VM1: (Centos7, m3.tiny, allow-all security group, Assign floating IP)
- VM2: (Centos7, m3.xsmall, allow-all security group, Assign floating IP)
- VM3: (Centos7, m3.xsmall, allow-all security group, Assign floating IP)
- imp: Configure the VMs so that you can login (using
ssh) to VM2 and VM3 from VM1- If you have private key with extension .ppk, than convert from .ppk to .pem(openssh base64 format). Manual here
- Windows users (using gitbashm) and Linux users (bash), can use scp to copy the key file
scp -i <SSH_KEY_FILE> <SSH_KEY_FILE_TO_COPY> centos@<VM1_IP>:/home/centos/.ssh/ - Make sure that the key file is in
.pemformat.
- Install git
sudo yum install git - Install
python3.6on VM1 you may refer this manualpython --version
- Install
pip v21.2.4on VM1pip --version
Usage
VM1: Used for installing Ansible and managing other VMs.
VM2 & VM3: Used for Kubernetes cluster deployed using Ansible.
Exercise 1. Installation and basic configuration of Ansible v2.9.
The goal of this task is to get aquinted with installation of Ansible using pip and configure the ansibel to manage other virtual machines remotely.
Note: you can use your local machine, but we recommend creating the virtual machine instead.
Installing Ansible on VM1
Here we will install Ansible on Centos using pip
- Make sure that you have
pip v21.2.4andpython3.6 - Install Ansible
pip install ansible
- Check ansible verison
ansible --version
- Make sure that you have
Exercise 2. Basic Ansible commands
The aim of this task is to make you to learn basic ansible commands.
Make sure that your in VM1
2.1. Basic ansible commands to check hosts and version
- Check for ansible version using
ansible --version
Sample Output:
- List all the ansible hosts
ansible --list-hosts all
Sample Output:
- List localhost hosts
ansible --list-hosts localhost
Sample Output:
- Check for ansible version using
2.2. Ansible Hosts/inventories file
Inventories: Ansible works against multiple managed nodes or “hosts” in your infrastructure at the same time, using a list or group of lists know as inventory. The default location for inventory is a file called /etc/ansible/hosts. You can specify a different inventory file at the command line using the -i <path> option. For more information on inventory follow here....
From ansible --list-hosts all and ansible --list-hosts localhost commands, all and localhost are some group of machines with related information, that are expected to be present in default /etc/ansible/hosts file.
Note!!! Since you the ansible using pip, you cannot see the default hosts file at /etc/ansible/hosts
- So, Now lets create hosts.yaml file
vi hosts.yamland copy the following content.
[iotusecase] VM2 ansible_host=172.17.90.248 ansible_port=22 ansible_user=centos ansible_ssh_private_key_file=/home/centos/.ssh/chinmayadehury VM3 ansible_host=172.17.91.168 ansible_port=22 ansible_user=centos ansible_ssh_private_key_file=/home/centos/.ssh/chinmayadehury
- Modify with your key name instead of chinmayadehury
- Change the IPs of iot-cluster-master and iot-cluster-worker with VM2 and VM3
- [iotusecase] is the custom tag used to group your VMs and it can be changed.
- Here, hosts.yaml file contains with the required information to connect to the other VMs (i.e. VM1 and VM2 and VM3) such as username or private_key or port are used for ssh connection etc,.
note: Writing $HOME instead of /home/centos may not work.
- The hosts.yaml can also have hostname or the IP address of other VMs. Use can use either of one. Hence the minimal version would be:
[iotusecase] 172.17.90.248 172.17.91.168 172.17.89.193
2.3. Basic tasks using Ansible
The ansible command defines and run a single task playbook against a set of hosts. The ansible-doc <module-name> is a handy command to know more about a specific module.
- Now lets ping all servers in
iotusecasegroupansible -m ping iotusecase -i hosts.yaml
Sample Output:
NOTE:pingmodule is useful from/usr/bin/ansibleto verify the ability to login and that a usable Python is configured. This is NOT ICMP ping, this is just a trivial test module that requires Python on the remote-node. - Execute
pwdcommand in all servers iniotusecasegroupansible -m command -a "pwd" iotusecase -i hosts.yaml
Sample Output:
NOTE: The given command with-a "command name"option will be executed on all selected nodes. - Execute
lscommand in all servers iniotusecasegroupansible -m command -a "ls" iotusecase -i hosts.yaml
Sample Output:
- Execute
lscommand in all servers iniotusecasegroup with a private key. Change the private key name according to your ssh_key_name with chinmayadehury
- Now lets ping all servers in
ansible -m command --private-key .ssh/chinmayadehury -a "ls" iotusecase -i hosts.yaml
Sample Output:
- Execute
lscommand in all servers iniotusecasegroup insidemyinven_listinventory list with a private key.myinven_listis present in my present directory (this is similar to/etc/ansible/hostsinventory file.)ansible -m command --private-key .ssh/chinmayadehury -a "ls" -i myinven_list iotusecase
Sample Output
- Create a directiry in the remote VM using
commandmodule:ansible remote -m command -a "mkdir /home/centos/mydir1" -i hosts.yaml
NOTE: hereremoteis a host group (similar toiotusecase).
Sample Output:
- Create a directiry in the remote VM using
filemodule:ansible remote -m file -a "path=/home/centos/mydir2 state=directory" -i hosts.yaml
NOTE: Here again I am usingremotehost group (similar toiotusecase).
Sample Output:
- Transfer a file from local VM to the remote VM using
copymodule:ansible remote -m copy -a "src=/home/centos/my_ansible_dir/playbooks/mydummyfile dest=/home/centos/" -i hosts.yaml
- Execute
Exercise 3. Working with Ansible Playbook
Ansible command line is great for executing a single task. But playbooks are more useful for multiple tasks. Playbooks are text files written in the YAML format. You can check http://www.yamllint.com/ or other alternatives to validate your YAML file.
The basic command to invoke any playbook is:ansible-playbook <path to your playbook>
Make sure that your in VM1
3.1. Playbook for file/directory operation
Following playbook will let you execute above Ansible commands, e.g create new directory, new files, copy file from local machine to remote machine, print the message, etc.
Create your first playbok with following content.
vi play-1.yaml
---
- hosts: remote
tasks:
- name: what is the present working directory
command: pwd
register: out
- debug:
var: out.stdout_lines
- debug:
msg: "present working directory is: {{out.stdout_lines}}"
- name: See what is in the current directory
command: ls
register: lsout
- debug:
msg: "output of ls command: {{lsout.stdout_lines}}"
- name: create a new directory
file:
path: /home/centos/mydir3
state: directory
- name: Create an empty file inside new directory
file:
path: /home/centos/mydir3/emptyfile.txt
state: touch
- name: copy the file from local vm to the remote vm
copy:
src: /home/centos/my_ansible_dir/playbooks/lists
dest: "/home/centos/mydir3/"
- name: "list of files inside that new directory"
shell: "ls /home/centos/mydir3/"
register: lsout
- debug:
msg: "list of files inside that new directory: {{lsout.stdout_lines}}"
NOTE: Update the remote group name in the second line of above content ( hosts: remote ) based on your inventory file and host group name.
Ansible playbook command:
ansible-playbook play-1.yaml -i hosts.yaml
Sample Output:
You may visit below source for more information
3.2. Package install/remove/reinstall/download operation
Below is a playbook example for working with package management (using yum module).
Note: Follwing things will work only on the centos Operating sytem.
vi install-packages.yaml
---
- hosts: remote
gather_facts: true
become: true
become_method: sudo
tasks:
- name: Install the latest version of vim editor
yum:
name: vim
state: latest
- name: Download the nano editor package but do not install it
yum:
name:
- nano
state: latest
download_only: true
download_dir: "/home/centos/"
- name: Install the latest version of Apache
yum:
name: httpd
state: latest
- name: Start apache service
service:
name: httpd
state: started
NOTE: Update the remote group name in the second line of above content ( hosts: remote ) based on your inventory file and host group name.
Command:
ansible-playbook install-packages.yaml -i hosts.yaml
Sample Output:
Now go to the browser and test if apache web server is accessible, like below:
Figure out if you are unable to access the apache test page.
Hint:
- login to the remote VM and check if the httpd server is running
- Check the security group of the remote VM.
3.3. Playbook to stop and remove a package
Below playbook will stop the previously started apache server and remove/uninstall from the system
Note: Following playbook will work only on the centos Operating sytem.
vi remove_package.yaml
================================
--- - hosts: remote gather_facts: true become: true become_method: sudo tasks: - name: Stop service httpd, if started service: name: httpd state: stopped - name: Remove the Apache package yum: name: httpd state: absent
NOTE: Update the remote group name in the second line of above content ( hosts: remote ) based on your inventory file and host group name.
Command:
ansible-playbook remove_package.yaml -i hosts.yaml
Sample Output:
Exercise 4. Install Docker
Now you will install Docker using Ansible playbook.
vi install-docker.yaml
================================
---
- hosts: iotusecase
gather_facts: true
become: true
become_method: sudo
tasks:
- name: Create target directory
file:
path=/etc/docker/
state=directory
mode=0755
- name: configure docker network address, ahead of time, to solve issues with docker default network collision with UT VPN
lineinfile:
path: /etc/docker/daemon.json
line: |
{
"default-address-pools": [{"base":"172.80.0.0/16","size":24}]
}
owner: root
group: root
mode: '0644'
create: yes
- name: add the official Docker repository, download the latest version of Docker, and install it
shell: "curl -fsSL https://get.docker.com/ | sh"
- name: Start and enable docker service
service:
name: docker
enabled: true
state: started
NOTE: Update the remote group name in the second line of above content ( hosts: remote ) based on your inventory file and host group name.
Command:
ansible-playbook install-docker.yaml -i hosts.yaml
Sample Output:
Exercise 5. Creating a K8 cluster using Ansible
You will use Kubespray, that uses ansible script to install and configure kubernetes cluster.
Now make sure that you have following:
- One VM for Master (i.e. VM2)
- Centos7, m3.xsmall, allow-all security group, Assign floating IP
- One VM for Worker (i.e. VM3)
- Centos7, m3.xsmall, allow-all security group, Assign floating IP
Kubespray src:
- Official resources for Kubespray GitHub Repo
- Production environment using kubespray : https://kubernetes.io/docs/setup/production-environment/tools/kubespray/
The following commands need to be run on VM1
- Download the kubespray package by cloning the github repo and install all the kubespray requirements using python pip3.
git clone https://github.com/kubernetes-sigs/kubespray.gitcd kubespray
- Just have a quick look at the files present in
kubespraydirectory. - Now either you can install all the packages present in
requirements.txtfile usingpip install -r requirements.txtOR selectively install following packages:pip install ansible-basepip install ruamel.yamlpip install ruamel.yaml.clib- Please use
pip show <package name>command to see if the package is already installed.
- Copy the kubespray files to your own folder.
cp -rfp inventory/sample inventory/mycluster
- Folloing commands will prepare
hosts.ymlfile (It's not same as earlier host.yaml file) specifying the hosts and their roles in the cluster.Declare a variable IPs specifying internal IPs of both the servers.- The command to declare is
declare -a IPS=(<internal_ip_of_node1> <internal_ip_of_node2>) - Use the variable IPS to build up a config file
hosts.ymlusing the below command- Configure hosts.yaml using this command
CONFIG_FILE=inventory/mycluster/hosts.yaml python3 contrib/inventory_builder/inventory.py ${IPS[@]}
- Configure hosts.yaml using this command
- Now have a look at the following file,
cat inventory/mycluster/hosts.yaml
- The command to declare is
- Deploy with
ansible-playbookcommand- Deploy Kubespray with Ansible Playbook - run the playbook as root. The option
--becomeis required, as for example writing SSL keys in/etc/, installing packages and interacting with various systemd daemons. Without--becomethe playbook will fail to run! - Run the command by changing the <SSH_KEY>
ansible-playbook -i inventory/mycluster/hosts.yaml --become --become-user=root cluster.yml --private-key ~/.ssh/<SSH_KEY>
- Deploy Kubespray with Ansible Playbook - run the playbook as root. The option
The final Sample output should look like below:
- Login to the master node (should be either VM2 or VM3) and enter following command:
kubectl get nodes
If you see below error run the following commands:
Possible Error:
mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/config
- Now you should see following sample output of the
kubectl get nodescommand:
[ src: https://github.com/kubernetes-sigs/kubespray ]
5.1. Deploy your service on k8 cluster
Create a playbook with following content.
vi install-app.yaml
================================
--- - name: create hosts: master gather_facts: true become: true become_user: centos tasks: - name: Create target directory file: path=$HOME/deploy_nginx/ state=directory - name: create the deployment file lineinfile: path: $HOME/deploy_nginx/deploy1.yaml create: yes line: | apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.0 ports: - containerPort: 80 - name: create the deployment by running the kubectl command command: "kubectl create -f $HOME/deploy_nginx/deploy1.yaml" - name: create the service file lineinfile: path: $HOME/deploy_nginx/service1.yaml create: yes line: | apiVersion: v1 kind: Service metadata: name: nginx-service labels: run: nginx-service spec: type: NodePort ports: - port: 80 protocol: TCP selector: app: nginx - name: create the service command: "kubectl create -f $HOME/deploy_nginx/service1.yaml"
Note: Make sure that the alignment is correct.
NOTE: Update the master group in the third line of above content ( hosts: master ) based on your inventory file and host group name. This should refer to the master node (either VM2 or VM3)
- Now execute the playbook:
ansible-playbook install-app.yaml
After Nginx app deployment, go to the master node and execute kubectl get services command to know the port number.
Get the port number (as shown in below figure)
Now in the browser hit master node's external_ip with the obtained port number(as shown in above fig). Output looks like below.

Take a screenshot of a webpage where your IP address are clearly seen.
5.2. Homework: Deploy your flask application
In this task, your are going deploy the flask application from Practice Session 3 and Exercise 5. This task need to be completed by yourself with minimum instructions noted below. The following are the changes need to make to install-app.yaml from above exercise.
- Create directory
deploy_flask, and update first task, i.e.Create target directorytask. - Update second task, i.e.
create the deployment filetask, with following hints.- Update the
pathargument inlineinfilemodule (from $HOME/deploy_nginx/deploy1.yaml to $HOME/deploy_flask/deploy1.yaml) - Update the deployment name from
nginx-deploymenttoflask-deployment - Update the
labels:withapp: flask - Update the container information;
name,image,ports. Also addhostPort: 5000to theportslist.
- Update the
- Update third task, i.e.
create the deployment by running the kubectl commandtask.- Update the path to the yaml. The path should be same to the path of previous (or second) task.
- Update forth task, i.e.
create the service filetask.- Update
pathvlaue, - Update service
nameandlabels, as per your choice. - Update port number from 80 to 5000
- Update
selectoras well
- Update
- Update the kubectl command accordingly, in the fifth task, i.e.
create the servicetask.
Finally, when the playbook is executed (on VM1) you should see the sensor data on the web page, similar to above Exercise 5.1
Take a screenshot of a webpage where your name and IP address are clearly seen.
Deliverables
- Upload the screenshot taken wherever mentioned
- Pack the screenshots into a single zip file and upload them through the following submission form.
- Attach the playbooks from 5.1 and 5.2 in text file
- Your instance must be terminated!
Deadline: 15th Oct 2021
4. Lab 4Bonus Task:
What to do
- Create first VM manually
- Prepare the Ansible playbook to:
- Create VM2 and VM3
- Install K8 and clreat the cluster using kubespray
- Deploy your application atop cluster
Hint:
- To create VMs using Ansible, you need to install Waldur
sudo pip install six, setuptools_rusts, pip install cryptography pip install dataclasses pip install waldur_core pip install waldur_ansible pip install ansible-waldur-module
- Playbook to create VM. (Update
access_tokenandmykey)
---
- hosts: local
vars:
access_token: "0f4afa15bdc1923015"
api_url: "https://api.etais.ee/api/"
instance_name: "ansible-vm2"
mykey: "chinmayadehury"
tasks:
- name: Create an instance
waldur_marketplace_os_instance:
access_token: " {{ access_token }} "
api_url: "{{ api_url }}"
flavor: m3.tiny
floating_ip: auto
image: "centos7"
name: "{{ instance_name }}"
project: "DevOpscourse-internal"
offering: "Virtual machine in devops-cloud"
ssh_key: "{{ mykey }}"
subnet: devops-pi-sub-net
system_volume_size: 10
state: "present"
Deliverable (possibly in zip format):
- Don't terminate the VM
- give the Ansible playbooks
- Give output of
ansible --versioncommand (the screenshot) - Give ansible configuration file