# 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 ![AnsibleArchitecture](https://i.imgur.com/NBgAvlC.png) #### 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) :::