Introduction
Nowadays, servers need to be created and destroyed very frequently. That’s because, at times, servers get a lot of execution load while at other times the load reduces, hence wasting the system resources. A common example is eCommerce websites during the holiday seasons attracting a lot of traffic. When the nature of the application is to be scalable, there is always a need to have configuration management tools to make the overall process of creating servers easier. Ansible is a great configuration management tool that automates server creation using standard procedures reducing human errors.
Ansible does not require special software to be installed on the nodes of the servers. It has all the tools necessary to write, build and facilitate the automation of scripts. This tutorial elaborates on how to use Ansible to automate the steps contained in our How to set up your Ubuntu server tutorial.
Prerequisites
To complete this guide we will be using Ubuntu 20.04. Further, you will also need:
-
An Ansible Control Node: An Ubuntu machine running the latest Ubuntu version. The master binary of Ansible must be installed and running on this machine. This machine should be able to connect to the Ansible nodes. For these connections, you need to use SSH keys. To avoid problems when connecting, make sure that your Ansible control node has a firewall enabled. If you require assistance, check out our Installing and Configuring Ansible on Ubuntu 20.04 blog.
-
Ansible Hosts: One or more hosts are needed to connect to. The hosts are essentially the managed nodes in Ansible. These must be Ubuntu servers.
Functions of the Ansible Playbook
You can manually set up all the below-mentioned steps. However, we will automate this execution. When you run this playbook, it will perform the below operations on your machine:
-
It will install aptitude, which is preferred by Ansible as its package manager.
-
It will create an administrative group wheel with passwordless sudo permissions.
-
It will create a new sudo user.
-
It will copy a local SSH key in the authorized_keys. This is to be used for a new administrative user on a remote host.
-
It will disable the password-based authentication for the root user.
-
It will install necessary packages.
-
It will configure UFW firewall to allow only SSH connections. Any other connections would be stopped.
Once the Playbook finishes executing, a new user would be available. You can use this user to login into the system.
Using the Ansible Playbook
To set up the server, you will need the initial server setup playbook and its dependencies. If you are using it for the first time then you will need to clone the repository using the link below:
1 |
cd ~ |
1 |
git clone https://github.com/do-community/ansible-playbooks.git |
1 |
cd ansible-playbooks |
If the repository is already existing in your system, run the below command to get the latest updates:
1 |
cd ~/ansible-playbooks |
1 |
git pull |
You will get the below structure of files on your machine:
1 2 3 4 |
setup |-- playbook.yml |__vars |-- default,yml |
Below is the description of the files:
-
vars/default.yml: This file contains the variables to configure the Ansible node.
-
playbook.yml: This file contains the jobs that are to be executed on the server.
The file vars/default.yml looks something like this:
1 2 3 4 |
--- create_user: my_user copy_local_key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}" sys_packages: [ 'curl', 'vim', 'git', 'ufw'] |
Below is the description of these variables. If you wish to edit them, you can replace their values with your own:
-
create_user: This is the user that is created. This user has sudo privileges.
-
copy_local_key: This contains the path to the local SSH public key. It would be copied to the remote server as authorized_key.
-
sys_packages: If you want to install one or more packages to your server, mention them here as an array.
Once you have edited this file, save the contents. After that, on nano, press CTRL+X , Y. Then, ENTER to save the contents of the file.
Now you are ready to run this playbook on multiple servers. By default, Playbooks are ready to be executed on the servers in your inventory. If you want to use the Playbook on some specific servers, you can use the -l flag. Now suppose that the remote server has multiple users, you can use -u flag to mention which user to connect to.
If your server name is my_server and the user name is my_user, then run the below command to execute on the Ansible nodes:
1 |
ansible-playbook playbook.yml -l my_server -u my_user |
You will get the output something like:
1 2 3 4 5 6 7 8 9 |
PLAY [all] ***************************************************************************************************************************** TASK [Gathering Facts] ***************************************************************************************************************** ok: [my_server] TASK [Install Prerequisites] *********************************************************************************************************** changed: [my_server] TASK [Make sure we have a 'wheel' group] *********************************************************************************************** changed: [my_server] TASK [Allow 'wheel' group to have passwordless sudo] *********************************************************************************** changed: [my_server] |
Once this execution has been finished, you can connect using the below command:
1 |
ssh my_user@server_host_or_IP |
Remember my_user was the name we had used in the vars/default.yml file. You will need to change the server IP to the IP of your server in the above command as well. If you had provided copy_local_key variable to point to some custom SSH key, specify the location with -i switch:
1 |
ssh my_user@server_host_or_IP -i ~/.ssh/ansible_controller_key |
Next, login to your server to check the UFW firewall’s rules:
1 |
sudo ufw status |
You will get the output as below:
1 2 3 4 5 |
Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) |
The above output confirms that the UFW firewall has been successfully finalized. This was the last step in our playbook. If this is performed correctly it means that the execution has been successful.
The Ansible Playbook Contents
The Playbook files we used in this tutorial are hosted on ansible-playbooks/setup_ubuntu1804 at master · do-community/ansible-playbooks · GitHub. If you wish to see the contents of each file to use or edit, click the Raw button on top of each script.
For quick reference, we will share the full contents of the Playbook along with the relevant files:
-
vars/default.yml
This file contains the values that will be used by the playbook tasks. These include values such as the name of the user, privileges, SSH keys, packages to be installed as part of the initial setup, and so on:
1 2 3 4 |
--- create_user: my_user copy_local_key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}" sys_packages: [ 'curl', 'vim', 'git', 'ufw'] |
-
playbook.yml
The playbook.yml file contains the jobs that are to be executed. First, the file lists all the hosts which are to be targeted. If you want to specify all the servers, make the value of this key to all. Next, if you want to specify the tasks to be executed using sudo privileges, you set the value of the variable become: true. Finally, this file needs to include the contents of the above vars/default.yml file. We include these next to load the settings from this file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
--- - hosts: all become: true vars_files: - vars/default.yml tasks: - name: Install Prerequisites apt: name=aptitude update_cache=yes state=latest force_apt_get=yes # Sudo Group Setup - name: Make sure we have a 'wheel' group group: name: wheel state: present - name: Allow 'wheel' group to have passwordless sudo lineinfile: path: /etc/sudoers state: present regexp: '^%wheel' line: '%wheel ALL=(ALL) NOPASSWD: ALL' validate: '/usr/sbin/visudo -cf %s' # User + Key Setup - name: Create a new regular user with sudo privileges user: name: "{{ create_user }}" state: present groups: wheel append: true create_home: true shell: /bin/bash - name: Set authorized key for remote user authorized_key: user: "{{ create_user }}" state: present key: "{{ copy_local_key }}" - name: Disable password authentication for root lineinfile: path: /etc/ssh/sshd_config state: present regexp: '^#?PermitRootLogin' line: 'PermitRootLogin prohibit-password' # Install Packages - name: Update apt apt: update_cache=yes - name: Install required system packages apt: name={{ sys_packages }} state=latest # UFW Setup - name: UFW - Allow SSH connections ufw: rule: allow name: OpenSSH - name: UFW - Deny all other incoming traffic by default ufw: state: enabled policy: deny direction: incoming |
Conclusion
Automation is key in IT, ensuring that all processes are error-free and are following standard practices and procedures. Since most software today is delivered over the web having distributed nature, it has become an everyday task to create new servers, e.g for different environments such as staging or production, or even demo environments.
In this tutorial, we demonstrated how to achieve automation of servers using Ansible, a powerful and easy-to-use tool that can save you a lot of time.
Happy Computing!
- How To Set Up GitHub Continuous Integration Pipelines With Self-Hosted Runners on Ubuntu 22.04. - March 20, 2023
- Managing CSV in Node.js using Node-CSV - March 15, 2023
- Containerize A Python App using Docker - March 7, 2023
- Using GitLab for Managing Projects - September 15, 2022
- Creating Drag and Drop Elements with Pure, Vanilla JavaScript - August 4, 2022