# 7. Configuration Management using Ansible
[toc]
### Topics
:::warning
- [ ] Introduction to Configuration Management
- [ ] Introduction to Ansible
- [ ] Installation and Configuration
- [ ] Ansible Inventory
- [ ] Ansible Ad-hoc commands
- [ ] Ansible Playbooks
- [ ] Ansible Roles
:::
### Keywords
:::success
- Configuration Management
- Desired State Configuration (DSC)
- idempotence
- Domain Specific Language (DSL)
- Declarative (Chef DSL, YAML, HCL)(What do you need) vs Imperative Languages (Java, C, Python) (What as well as How)
- Agent-based (Pull-based)
- Agentless (Push-based)
:::
### Introduction to Configuration Management
#### Why CM / Automation
:::warning
- Reduce Human errors
- Increase Consistency
- Reduce time and effort
- Reuseability
- Improve productivity
- Ease of Maintenance
:::
#### Popular CM Tools
:::warning
**On-prem**
- Ansible
- Chef
- Puppet
- SaltStack
- CFEngine
- Powershell DSC
**Cloud-based**
- AWS OpsWorks
- AWS Systems Manager
:::
#### IaC vs Config Management
:::warning
- Infrastructure-as-Code --> (Provisioning of the Infrastructure)
- Terraform
- AWS CloudFormation
- Azure ARM templates
- Configuration Management --> (Management and maintenance of the State of the Infrastructure)
- Chef
- Ansible
- Puppet
:::
### Introduction to Ansible
#### Benefits / Features of Ansible
:::warning
- Lower learning curve
- Playbooks are written in YAML
- Works on SSH (no need to open a special port)
- Agentless (Push based)
- Written in Python
:::
#### Ansible Architecture

#### Ansible Terminologies
:::warning
- Ansible Controller
- Ansible Modules
- Ansible Playbooks
- Ansible Tasks
- Ansible Roles
:::
#### Ansible CLI
:::warning
ansible --> Ad-hoc commands
ansible-playbook --> command line tool to work with Ansible Playbooks
ansible-doc --> to check the documentation (similar to man pages)
ansible-inventory --> to check and work with your hosts and host groups
ansible-galaxy --> to work with Ansible roles
:::
### Installation and Configuration
#### Step 1: Ansible Installation (On Controller Node)
````go=1
sudo apt update
sudo apt install software-properties-common
sudo apt-add-repository --yes --update ppa:ansible/ansible
sudo apt install ansible
**Validation**
ansible --version
````
#### Step 2a: Setup password-less authentication for localhost (Simplilearn Lab)
````yaml=1
cd ~
ssh-keygen -t rsa ## Press Enter when asked for File and Paraphrase details
cat .ssh/id_rsa.pub >> .ssh/authorized_keys
Validation:
ssh localhost -p 42006
Expected result:
Above ssh command should take you directly to the target node without the need to put in the password.
````
#### Step 2b: Setup password-less authentication for localhost (DigitalOcean Lab)
````yaml=1
cd ~
ssh-keygen -t rsa ## Press Enter when asked for File and Paraphrase details
cat .ssh/id_rsa.pub >> .ssh/authorized_keys
Validation:
ssh localhost
Expected result:
Above ssh command should take you directly to the target node without the need to put in the password.
````
#### Step3: Validate Ansible configuration
````yaml=
ansible localhost -m ping
or
ansible -m ping localhost
Expected output:
localhost | SUCCESS => {
"changed": false,
"ping": "pong"
}
````
### Working with Ansible Inventory
:::warning
Edit the default Ansible inventory file as follows:
````yaml
sudo vi /etc/ansible/hosts
````
**On simplilearn lab**
````yaml
[nodes]
localhost:42006
[webservers]
localhost:42006
````
**On digitalocean lab**
````yaml
[nodes]
localhost
[webservers]
localhost
````
**Save the file**
````yaml
esc + :wq!
````
**Validate the configuration**
````yaml
ansible -m ping all
or
ansible -m ping nodes
or
ansible -m ping webservers
````
:::
### Ansible Ad-hoc commands
````yaml=
Syntax:
ansible <inventory-host-group> -m <modulename> -a <arguments> --<additionalparameters>
Examples:
ansible all -m ping
ansible --list-hosts all
ansible --list-hosts <groupname>
ansible all -m shell -a 'hostname'
ansible all -m shell -a 'uptime'
ansible all -m shell -a 'ip r'
ansible all -m shell -a 'fdisk -l' --become ## To get elevated privileges on target nodes
````
#### Classroom activity:
:::warning
Q:
Install elinks using ansible:
Sol:
ansible nodes -m apt -a "name=elinks" --become
ansible nodes -m apt -a "name=elinks state=present" --become
ansible nodes -m apt -a "name=elinks state=latest" --become
Q:
Uninstall elinks using ansible:
Sol:
ansible nodes -m apt -a "name=elinks state=absent" --become
Q:
Create a user "ansibleadm" using ansible
Sol:
ansible nodes -m user -a "name=ansibleadm" --become
Q:
Create a file named "ansible.txt" in /tmp directory
Sol:
ansible nodes -m file -a "path=/tmp/ansible.txt state=touch"
:::
#### Ansible Fundamental Modules
:::warning
- ping
- user
- service
- file
- copy
- apt/yum/package
- template
:::
### Ansible Playbooks
#### Playbook to ping the nodes for health check
:::warning
Ad-hoc command:
````yaml=
ansible all -m ping
````
Equivalent Playbook:
````yaml=
## vi ping.yaml
--- ## Using playbook to run ping on all nodes
- hosts: nodes
tasks:
- name: Ping all nodes
action: ping
````
Run the Playbook:
````yaml=
ansible-playbook ping.yaml
````
:::
YAML files will have the extension as .yaml or .yml
#### Playbook to install package on target nodes
:::warning
Ad-hoc command:
````yaml=
ansible nodes -m apt -a "name=elinks state=present" --become
````
Equivalent playbook:
````yaml=
## vi elinks.yaml
--- ## Basic playbook to install a package via apt module
- hosts: nodes
become: yes
tasks:
- name: install elinks
apt:
name: elinks
state: present
````
Run the Playbook:
````yaml=
ansible-playbook elinks.yaml
````
:::
#### Playbook to create user(s) on target nodes
:::warning
Ad-hoc command:
````yaml=
ansible nodes -m user -a "name=playuser password=mysupersecurepassword" --become
````
Equivalent playbook:
````yaml=
## vi user.yaml
--- ## basic play
- hosts: nodes
become: yes
tasks:
- name: create user
user:
name: userplay
password: mysupersecurepass
````
Run the Playbook:
````yaml=
ansible-playbook user.yaml
````
:::
#### Variables in Ansible Playbooks
:::warning
````yaml=
## vi vars.yaml
--- ## playbook to install a specified package
- hosts: '{{ myhosts }}'
become: yes
tasks:
- name: install specified software package
apt:
name: '{{ pkg }}'
state: present
````
Run the Playbook:
````yaml=
ansible-playbook vars.yaml --extra-vars "pkg=telnet myhosts=webservers"
or
ansible-playbook vars.yaml -e "pkg=telnet myhosts=webservers"
````
:::
### Ansible Roles
#### Working with Ansible Roles
````yaml=
Check local roles:
ansible-galaxy role list
Create a local role:
ansible-galaxy init <role-name>
Explore Ansible Galaxy:
galaxy.ansible.com
Go to (one of) default location for ansible roles:
cd ~/.ansible
mkdir roles && cd roles
Install a role from Ansible Galaxy:
ansible-galaxy install <authorname.rolename>
Validate the role installation:
ansible-galaxy role list
````
#### Write a playbook to call the role
````yaml=
## vi role-play.yaml
--- ## Playbook to call nginx role
- hosts: nodes
become: yes
tasks:
- name: install and manage nginx
include_role:
name: geerlingguy.nginx
````
#### Run the Playbook
````yaml=
ansible-playbook role-play.yaml
````
#### Validate the changes
````yaml=
curl localhost
or
elinks http://localhost
or
which nginx
or
sudo systemctl status nginx
````
### Assignments
:::success
**27/28 May 2023**
- Lesson 07 Demo 2
- Lesson 07 Demo 3
- Lesson 07 Demo 4
- Lesson 07 Demo 6
:::
### References
:::info
- [Ansible Inventory Documentation](https://docs.ansible.com/ansible/latest/inventory_guide/intro_inventory.html)
- [Ansible Playbook Documentation](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_intro.html)
:::