Starting Ansible - Easy Guide Fo - Nathan Hull

August 17, 2021 | Author: Anonymous | Category: N/A
Share Embed Donate


Short Description

Download Starting Ansible - Easy Guide Fo - Nathan Hull...

Description

Starting Ansible Easy guide for beginners

By Nathan Hull Copyright©2016 by Nathan Hull All Rights Reserved

Copyright © 2016 by Nathan Hull All rights reserved. No part of this publication may be reproduced, distributed, or transmitted in any form or by any means, including photocopying, recording, or other electronic or mechanical methods, without the prior written permission of the author, except in the case of brief quotations embodied in critical reviews and certain other noncommercial uses permitted by copyright law.

Table of Contents Introduction Chapter 1- A Brief Overview of Ansible Chapter 2- Installation Chapter 3- Running Commands Chapter 5- Roles Chapter 6- Tempates Chapter 7- Tasks Chapter 8- Templates Chapter 9- Developer Information Conclusion

Disclaimer

While all attempts have been made to verify the information provided in this book, the author does assume any responsibility for errors, omissions, or contrary interpretations of the subject matter contained within. The information provided in this book is for educational and entertainment purposes only. The reader is responsible for his or her own actions and the author does not accept any responsibilities for any liabilities or damages, real or perceived, resulting from the use of this information.

The trademarks that are used are without any consent, and the publication of the trademark is without permission or backing by the trademark owner. All trademarks and brands within this book are for clarifying purposes only and are the owned by the owners themselves, not affiliated with this document.

Introduction Ansible is a very useful IT automation tool. It makes things easy to be done even by beginners. This is why you should learn how to use this IT tool. In this guide, this tool is discussed with no detail left out. Enjoy reading!

Chapter 1- A Brief Overview of Ansible Ansible is an IT automation platform that makes it easy for us to deploy applications and systems. The platform is very easy for anyone to use, including beginners. Note that the platform makes use of SSH (Secure Shell) so as to establish a connection with servers and then run the configuration tasks. This is what makes the platform easy to use. With Ansible, bash scripts can easily be converted into Ansible tasks. Note that bash scripts are a very common way to accomplish configuration tasks. Since this is SSH based, we will end up executing the same commands. It is easy for us to script the provisioners, but with Ansible, the process of obtaining the “context” before the execution of the task is automated. With the context, it is easy for Ansible to handle most edge cases. In Ansible, tasks are idempotent. Without additional coding, it is not safe for us to run bash scripts again and again. It relies on facts, which includes the system and the environment information which it gathers before it can execute tasks. Ansible makes use of such facts so as to check the state and determine whether anything needs to be changed so that it can get the outcome which it expects. This is what makes it secure for us to run Ansible against a particular server again and again.

Chapter 2- Installation Of course, the first step for us should be installation of Ansible. This will make it possible for us to run tasks on the machine which has been installed with Ansible. There usually exists a central server tasked with the responsibility of running Ansible commands, but there exists nothing special about the server in which the Ansible has been installed. You have to note that Ansible is “agentless,” and it can be run from any server, even a laptop. For Ubuntu 14.04 users, we use the repository “ppa:ansible/ansible” which is easy to remember. The following commands can be used: sudo apt-add-repository -y ppa:ansible/ansible sudo apt-get update sudo apt-get install -y ansible

Management of servers In Ansible, there is a default inventory file which is used for the purpose of management of the servers which will be managed. Once the installation has been completed, the referencing can be done at “/etc/ansible/hosts.” In most cases, it is recommended that you copy and move the default one so that you can reference it later. This is shown in the command given below: sudo mv /etc/ansible/hosts /etc/ansible/hosts.orig After that, one can create their own inventory file right from scratch. Once the example inventory file has been moved, one can create a new file “/etc/ansible/hosts,” and then perform a definition of the servers which are to be managed. In our case, we want to define two servers under the label “web”: [web] 192.168.22.11 192.168.22.12 That is good at this point. If we need, it is possible for us to define multiple groups, a range of hosts, and reusable variables.

Chapter 3- Running Commands Once our inventory has been configured, we can begin to run tasks against the servers which have been defined. With Ansible, it is assumed that your servers can be accessed using SSH, and this is always based on an SSH-key. Since we are using SSH in Ansible, there is a need for your server to be in a position to SSH into the inventory server. If it is possible for Ansible to SSH into the servers which are being managed, the commands can easily be run as shown below: $ ansible all -m ping 127.0.0.1 | success >> { “changed”: false, “ping”: “pong” } As shown above, we are getting a JSON result from the Ansible, and this will tell us if any changes had been made, even the result. If there is a need for us to define the user, and maybe any other services which are

necessary for us to connect to the server, then it is possible. When the process of testing is done locally from the vagrant, the following command can be used: ansible all -m ping -s -k -u vagrant The following are the commands: all – will use all the servers which have been defined from the inventory file. -m ping - uses the module “ping” which will run the ping command and then return the results. -s - Use “sudo” for running the commands. -k - asks for the password rather than using the key-based authentication. -u vagrant – Logs into the servers by use of the user vagrant.

Modules Ansible makes use of modules for the purpose of accomplishing a number of its tasks. These modules can be used for the accomplishment of tasks such as installation of software, copying files, using templates, and for some more other tasks.

Modules define the way in which we use Ansible, as they make use of the available context so as to determine the type of actions which need to be done so as to accomplish our tasks. If modules were not available, then we would have to run shell commands in an arbitrary manner as shown below: ansible all -s -m shell -a ‘apt-get install nginx’ In this case, the command “sudo apt-get install nginx” will be executed by use of the shell module. The flag “-a” is used for the purpose of passing arguments to a module. However, this is not powerful. Although it is good and possible for us to run a command on all our servers, we will just have accomplished what can be done by use of any bash script. In case we used a very appropriate module, the commands can be executed with an assurance that we will get the best results. With modules in Ansible, we ensure that there is indempotence, meaning that the same result will be executed over and over and the result will not be affected. When we are installing software on Ubuntu/Debian servers, the module “apt” will run the same command, but it will ensure that there is indempotence. This is shown in the code

given below: ansible all -s -m apt -a ‘pkg=nginx state=installed update_cache=true’ 127.0.0.1 | success >> { “changed”: false } With the above code, the apt module will be used for the purpose of updating the repository cache and then installing the Nginx if it has not been installed. The result of execution of the task was “’changed’: false.” This is an indication that there was no change, as the Nginx had already been installed. The command can be executed over and over again, and you do not have to worry that the result will change in any way. The following are the various parts of the command: all – will run on all the defined hosts from our inventory file. -s – will run using sudo. -m apt – will make use of the apt module. -a ‘pkg=nginx state=installed update_cache=true- this is where the arguments of the apt module are provided. These include the state of the package, the end result which we desire, and whether there is a need to update the repository cache or not

to do it.

Playbook With playbooks, one can run multiple tasks and then perform some functionality which is more advanced which one will not be in a position to perform by use of ad-hoc commands. Let us demonstrate how the above task can be moved into a playbook. Create the file “nginx.yml” with the following code: – - hosts: local tasks: - name: Install Nginx apt: pkg=nginx state=installed update_cache=true The above task when used will just do the same thing which was done by the ad-hoc command, however, I need to specify a local group of my servers other than using all of the available servers. The “ansible-playbook” command can be used for doing this as shown below: $ ansible-playbook -s nginx.yml PLAY [local] ******************************************************************

GATHERING FACTS *************************************************************** ok: [127.0.0.1] TASK: [Install Nginx] ********************************************************* ok: [127.0.0.1] PLAY RECAP ******************************************************************** 127.0.0.1 : ok=2 changed=0 unreachable=0 failed=0 The –s option can be used for the purpose of telling the Ansible to use the sudo. It is after that that you can pass your playbook file. When this is running, you will realize that you will get very useful feedback, including the tasks which are being run by Ansible, and the expected result. In our case, it is very clear that we ran OK, but it is very clear that nothing was changed. The Nginx had already been installed into the system. To run the playbook, the command “$ ansible-playbook -s -k -u vagrant nginx.yml” can be used and this will run it locally within the installation of vagrant.

Chapter 4- Handlers A handler can be seen as being the same as a task, but it only runs once it has been called by another task. It can be thought to be part of an event system, and it will act when it is called by an event it has been listening to. This technique is important when it comes to secondary actions, as they are required even after the task has been executed, such as when we need to start a new service after installation or the reloading of a service after a service change has happened. This is shown in the code given below: – - hosts: local tasks: - name: Install Nginx apt: pkg=nginx state=installed update_cache=true notify: - Start Nginx handlers: - name: Start Nginx service: name=nginx state=started

The “nitify” directive can be added to the installation task. This will notify any task having the name “Start Nginx” once the task has been run. It is after this that the handler with the name “Start Nginx” can be started. In this handler, we have used the “Service” module which one can use so as to start, stop, restart, and reload system services. In our case, we have just told the Nginx that we need to start our Nginx. Let us run the playbook again: $ ansible-playbook -s nginx.yml PLAY [local] ****************************************************************** GATHERING FACTS *************************************************************** ok: [127.0.0.1] TASK: [Install Nginx] ********************************************************* ok: [127.0.0.1] NOTIFIED: [nginx | Start Nginx] *********************************************** ok: [127.0.0.1] PLAY RECAP ******************************************************************** 127.0.0.1 : ok=2 changed=0 unreachable=0 failed=0 With the above, we will just obtain a similar output, but in this case, we have run the handler. Note that we only run notifiers once the task has been run. In case you had

already installed the Nginx, the task for installing Nginx will not be run and the calling of the notifier will not be done. Note that playbooks can be used for running multiple tasks.

More Tasks Consider the playbook given below. A few more tasks can be added to it, and then explore some other functionalities. Here is the playbook: – - hosts: local vars: - docroot: /var/www/myservers.com/public tasks: - name: Add Nginx Repository apt_repository: repo=‘ppa:nginx/stable’ state=present register: ppastable - name: Install Nginx apt: pkg=nginx state=installed update_cache=true when: ppastable|success

register: nginxinstalled notify: - Start Nginx - name: Create Web Root when: nginxinstalled|success file: dest={{ ‘{{‘ }} docroot {{ ‘}}’ }} mode=775 state=directory owner=www-data group=www-data notify: - Reload Nginx handlers: - name: Start Nginx service: name=nginx state=started - name: Reload Nginx service: name=nginx state=reloaded We have the tasks given below: Add Nginx Repository – will add a Nginx stable PPA for getting the latest stable version of the Nginx, by use of the apt_repository module.

Install Nginx – will install the Nginx by use of the Apt module. Create Web Root – this is creates a web root directory. We have also used new directives, namely “register” and “many,” and they will tell Ansible to run the task whenever something happens. We can use the usual command so as to run the playbook. This is shown below: ansible-playbook -s nginx.yml # Or, just as I did on my Vagrant machine ansible-playbook -s -k -u vagrant nginx.yml Next, we want to explore Ansible further and explore other functionalities associated with it.

Chapter 5- Roles Roles are very good when we are in need of organizing multiple and related tasks and for the purpose of the encapsulation of data which is necessary for the accomplishment of such tasks. An example of this is the installation of Nginx, which may involve the addition of a package repository, installation of the package, and setting up any necessary configuration. The configuration option will always need extra data such as the variables, dynamic templates, files, and others. The directory structure for roles is as shown below: rolename - files - handlers - meta - templates - tasks - vars In each directory, the Ansible will search and read the present Yaml file with the name

“main.yaml,” and this will be done automatically. We are in need of breaking up the file “nginx.yml” and then putting each component in the corresponding directory for creation of a cleaner and a toolset which is more provisioning.

Files First, within the directory for files, we can add the files which need to be copied into our servers. In Nginx, this can be done as shown below: nginx - files - - h5bp The above configurations should be added by us of the copy module.

Handlers Inside the directory “handlers,” all our handlers can be put which were once contained in the playbook “nginx.yaml.” The following is the code for the “handlers/main.yml”: – - name: Start Nginx service: name=nginx state=started - name: Reload Nginx service: name=nginx state=reloaded When we have all of the above, it is easy for us to reference them from other files.

Meta The file “main.yml” of our meta directory has the role meta data, even the dependencies. If this role was depending on another role, it could have been defined there. For example, in my case, the Nginx role is dependent on the SSL role, and this will be tasked with installation of SSL certificates. This is shown in the code given below: – dependencies: - { role: ssl } - If I call the Nginx role, it will first attempt to call the SSL role. The file can also be omitted or define the role with the dependencies. This is shown below: – dependencies: [] We have not defined any dependencies, but the brackets have been left blank. This means that our role will have no dependencies.

Chapter 6- Tempates Template files can have template variables, and this will be determined by the Jinja2 template engine of Python. These types of files should end with a “.j2” extension, but any name can be used. Similar to the files, it will be impossible for us to find the file “main.yml” in our templates directory. The example given below shows virtual host configuration in nginx. The file defines the variables which will later be used in the file “vars/main.yml.” The virtual host file for nginx can be found in “templates/serversforhackers.com.conf.” This is shown below: server { # Enforce the use of HTTPS listen 80 default_server; server_name *.{{ ‘{{‘ }} domain {{ ‘}}’ }}; return 301 https://{{ ‘{{‘ }} domain {{ ‘}}’ }}$request_uri; } server { listen 443 default_server ssl; root /var/www/{{ ‘{{‘ }} domain {{ ‘}}’ }}/public;

index index.html index.htm index.php; access_log /var/log/nginx/{{ ‘{{‘ }} domain {{ ‘}}’ }}.log; error_log /var/log/nginx/{{ ‘{{‘ }} domain {{ ‘}}’ }}-error.log error; server_name {{ ‘{{‘ }} domain {{ ‘}}’ }}; charset utf-8; include h5bp/basic.conf; ssl_certificate {{ ‘{{‘ }} ssl_crt {{ ‘}}’ }}; ssl_certificate_key {{ ‘{{‘ }} ssl_key {{ ‘}}’ }}; include h5bp/directive-only/ssl.conf; location /book { return 301 http://book.{{ ‘{{‘ }} domain {{ ‘}}’ }}; } location / { try_files $uri $uri/ /index.php$is_args$args; } location = /favicon.ico { log_not_found off; access_log off; }

location = /robots.txt { log_not_found off; access_log off; } location ~ .php$ { fastcgi_split_path_info ^(.+.php)(/.+)$; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; include fastcgi_params; # fastcgi.conf for version 1.6.1+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param ENV production; } # The Nginx status # The Nginx Plus only #location /status { # status; # status_format json; # allow 127.0.0.1; # deny all; #}

location ~ ^/(fpmstatus|fpmping)$ { access_log off; allow 127.0.0.1; deny all; include fastcgi_params; # fastcgi.conf for version 1.6.1+ fastcgi_pass unix:/var/run/php5-fpm.sock; } } The above Nginx configuration is very standard for a PHP app. We have defined three variables in the above case: Domain ssl_crt ssl_key The above variables will be defined in the section for variables.

Variables Before exploring tasks, it is good for us to explore variables. The directory “vars” has the file “main.yml,” and this has the list of variables which we are going to use. With that, we will have a very convenient place in which we can change our variable-wide settings. The file “vars/main.yml” should be as shown below: – domain: serversforhackers.com ssl_key: /etc/ssl/sfh/sfh.key ssl_crt: /etc/ssl/sfh/sfh.crt Above are the three variables which can be used elsewhere in our code. We saw them being defined in our above template, but they will also be visible in our defined template.

Chapter 7- Tasks All of the above can be put together to get a series of tasks. This should be the code for the file “tasks/main.yml.” – - name: Add Nginx Repository apt_repository: repo=‘ppa:nginx/stable’ state=present register: ppastable - name: Install Nginx apt: pkg=nginx state=installed update_cache=true when: ppastable|success register: nginxinstalled notify: - Start Nginx - name: Add H5BP Config when: nginxinstalled|success copy: src=h5bp dest=/etc/nginx owner=root group=root

- name: Disable Default Site when: nginxinstalled|success file: dest=/etc/nginx/sites-enabled/default state=absent - name: Add SFH Site Config when: nginxinstalled|success register: sfhconfig template: src=serversforhackers.com.j2 dest=/etc/nginx/sites-available/{{ ‘{{‘ }} domain {{ ‘}}’ }}.conf owner=root group=root - name: Enable SFH Site Config when: sfhconfig|success file: src=/etc/nginx/sites-available/{{ ‘{{‘ }} domain {{ ‘}}’ }}.conf dest=/etc/nginx/sites-enabled/{{ ‘{{‘ }} domain {{ ‘}}’ }}.conf state=link - name: Create Web root when: nginxinstalled|success file: dest=/var/www/{{ ‘{{‘ }} domain {{ ‘}}’ }}/public mode=775 state=directory owner=www-data group=www-data notify: - Reload Nginx - name: Web Root Permissions when: nginxinstalled|success file: dest=/var/www/{{ ‘{{‘ }} domain {{ ‘}}’ }} mode=775 state=directory owner=www-data group=www-data recurse=yes

notify: - Reload Nginx The above file shows a long series of tasks, and they define a complete installation of the Nginx file. The above tasks, in the order in which they have been written, will accomplish the following tasks: 1. Add the repository nginx/stable. 2. Install and launch Nginx, and then register a successful installation so that the remaining tasks can be triggered. 3. Add the configuration for H5BP. 4. Disabling our default virtual host by removal of the simlink to our default file from the directory “sites-enabled.” 5. Copy the virtual host template “serversforhackers.com.conf.j2” into our Nginx configuration. 6. Enable the configuration of the virtual host by simlinking it to the directory “sitesenabled.”

7. Create our web root. 8. Change of permission for our project root directory, and this is just one level above our web root which was created previously. We now have some new modules, such as copy, template, and file. When we set the arguments for each of four modules, something interesting can be done such as making sure that the files are “absent” via the “state=absent.” In this case, if they exist, they will be deleted. We can also use a “state=link” so as to create a simlink. It is good for you to check the docs for your module, and see the important things which you are able to accomplish.

Running the Role Before we can be able to run our role, it is important for us to first tell Ansible where the role is located. In my case, since I am using vagrant, I have stored them in the directory “/vagrant/ansible/roles.” This path has to be added to the file “/etc/ansible/ansible.cfg” as shown below: roles_path = /vagrant/ansible/roles Let us assume that your role for Nginx is located at “/vagrant/ansible/roles/nginx.” We are now ready to run such a role. If you have been following along, just remove the role “ssl” from the file “meta/main.yml.”

Let us now see how we can create a master yaml file which helps us define the roles to use and the hosts on which we will run them. The following should be the file “server.yml”: – - hosts: all roles: - nginx - The roles can then be run as shown below: ansible-playbook -s server.yml # Or as I usually do with the Vagrant VM: ansible-playbook -s -k -u vagrant server.yml When we run the Nginx role, we get the following output: PLAY [all] ******************************************************************** GATHERING FACTS *************************************************************** ok: [127.0.0.1]

TASK: [nginx | Add Nginx Repository] ****************************************** changed: [127.0.0.1] TASK: [nginx | Install Nginx] ************************************************* changed: [127.0.0.1] TASK: [nginx | Add H5BP Config] *********************************************** changed: [127.0.0.1] TASK: [nginx | Disable Default Site] ****************************************** changed: [127.0.0.1] TASK: [nginx | Add SFH Site Config] ******************************************* changed: [127.0.0.1] TASK: [nginx | Enable SFH Site Config] **************************************** changed: [127.0.0.1] TASK: [nginx | Create Web root] *********************************************** changed: [127.0.0.1] TASK: [nginx | Web Root Permissions] ****************************************** ok: [127.0.0.1]

NOTIFIED: [nginx | Start Nginx] *********************************************** ok: [127.0.0.1] NOTIFIED: [nginx | Reload Nginx] ********************************************** changed: [127.0.0.1] PLAY RECAP ******************************************************************** 127.0.0.1 : ok=8 changed=7 unreachable=0 failed=0 In the above case, all of our components have been put together to get a coherent role, and the Nginx has been installed and well configured.

Facts Before any tasks can be run in Ansible, it always first gathers all the information about the system which is being provisioned. These are always referred to as facts, and it is an array having wide information about our system such as the available IPV4 or IPV6 networks, number of CPU cores, Linux distribution, mounted disks, and much more. Facts are very useful when dealing with Template or Tasks configuration. An example of this is the Ngtinx, as this has been set to use any of the worker processors since there are CPU cores. When you are aware of this, the template for the configuration file “nginx.conf” can be set as shown below: user www-data www-data; worker_processes {% verbatim %}{{ ansible_processor_cores }}{% endverbatim %}; pid /var/run/nginx.pid; # And the other configurations… For a server having multiple CPUs, this can be done as follows: user www-data www-data; worker_processes {% verbatim %}{{ ansible_processor_cores * ansible_processor_count }}{% endverbatim %}; pid /var/run/nginx.pid;

# And the other configurations… In Ansible, all facts have to start with “_ansible” and can be used globally in any place the variables can be used such as in Tasks, variable files, and even templates. Consider the NodeJS example given below: – - name: Ensure Ubuntu Distribution is Supported get_url: url=‘https://deb.nodesource.com/node/dists/{% verbatim %}{{ ansible_distribution_release }}{% endverbatim %}/Release’ dest=/dev/null register: distrosupported - name: Remove the Old PPA apt_repository: repo=‘ppa:rep-ubuntu/node.js’ state=absent when: distrosupported|success - name: Remove Old Sources

file: path=’/etc/apt/sources.list.d/repo-ubuntu-node_js-{% verbatim %}{{ ansible_distribution_release }}{% endverbatim %}.list’ state=absent when: distrosupported|success - name: Add Nodesource Keys apt_key: url=https://deb.nodesource.com/gpgkey/nodesource.gpg.key state=present - name: Add Nodesource Apt Sources List Deb apt_repository: repo=‘deb https://deb.nodesource.com/node {% verbatim %}{{ ansible_distribution_release }}{% endverbatim %} main’ state=present when: distrosupported|success - name: Add Nodesource Apt Sources List Deb Src apt_repository: repo=‘deb-src https://deb.nodesource.com/node {% verbatim %}{{ ansible_distribution_release }}{% endverbatim %} main’ state=present when: distrosupported|success

- name: Install NodeJS apt: pkg=nodejs state=latest update_cache=true when: distrosupported|success We need to convert the role from Node. A few tricks are happening in the code. The code just represents the bash script which Node provides us with. First, we have created the task “Ensure Ubuntu Distro is Supported,” which uses the fact “ansible_distribution_release.” This then gives us the right release of Ubuntu. If we find that the URL is available, then we will know that the version of Ubuntu we are using is supported, and we can then continue. It is after that that we have registered the “distrosupported” so as to perform a test on the step and see whether it was successful on subsequent tasks. We can then run a series of tasks so as to remove the reposirtories for NodeJS if in any case the system already has the “ppa:repo-ubuntu/node.js” already installed. Note that these will run if and only if the distribution you are using is supported. In most cases, only the fact “ansible_distribution_release” will be used. Finally, we have obtained the Debian source packages and then installed the NodeJS once the repository cache has been updated. With that, the latest stable of NPM or NodeJS will be installed.

Vault

When we have sensible data, we always need to keep it in Ansible files, templates, or variable files, and it is hard for us to avoid this. The Ansible vault provides us with a solution to this. With the vault, we are able to encrypt yaml files so as to get variable files. However, it doesn’t encrypt files and templates. Whenever one is creating an encrypted file, they are always asked to provide a password which they can use so as to edit the file later, and when we are calling Playbooks or roles. Consider the example given below, which shows how a new variable file can be created in Ansible: ansible-vault create vars/main.yml Vault Password: Once you have entered the above password, your file will then be opened in your default editor, and in most cases, this is the Vim editor. The editor which is to be defined should be defined in the environmental variable “EDITOR.” Note that this is usually set to the Vim editor, but if you don’t like using this, it will be good for you to change this and all will be okay. This is shown below: export EDITOR=nano

ansible-vault edit vars/main.yml The editor can also be set on the bash for the configuration “profile/bash,” and this is ususlly found at ~/.profile, ~/.bashrc, ~/.zshrc, or maybe depending on the Linux distribution that you are using. The following are some of the commands which can be used for the Ansible vault: $ ansible-vault -h Usage: ansible-vault [create|decrypt|edit|encrypt|rekey] \ [—help] [options] file_name Options: -h, —help will show the help message and exit For most parts, we will make use of “ansible-vault create|edit /path/to/file.yml.” All of the available commands are given below: create - Creates a new file and then encrypts it. decrypt - Creates a plaintext file from the encrypted file. edit - Edits an already-existing file which is encrypted.

encrypt - Encrypts an existing plain-text file. rekey - Sets a new password for an encrypted file.

Example I normally use vault whenever I am creating new users. In a particular user role, one can set a password file with the passwords for users and a public key which will be added to the authorized_key file of the users. Public SSH keys are very safe, and the public can be allowed to view them. They allow an individual to access their own servers. If you need to access a system by use of a public key, then this will be useless if you don’t have a paired private key. However, this has not been put in our role. Below is an example file which we can create and then encrypt it using vault. It has be edited while in plain text. This is shown below: admin_password: $6$lpQ1DqjZQ25gq9YW$mYMAmGhFpPVVv0JBCUFaDovu8u5JqvWi.Ih deploy_password: $6$edOqVumZrYW9$d5zj1Ok/T80DrncjixhjQDpXlffACDfNx2DHnC common_public_key: ssh-rsa ALongSSHPublicKeyHere You have to note that the passwords for the users have also been hashed. You can research how to generate encrypted files in Ansible from its documentation. The user will always need this so as to set the password. It should look as shown below: # The package whois will make the mkpasswd # command is available on Ubuntu

$ sudo apt-get install -y whois # Creating a password hash $ mkpasswd —method=SHA-512 Password: With the above, you will get a hashed password which one can be able to use in the user module. Once the user passwords have been set and the public key has been added to the variable file, a task can be made which will be used for making the encrypted passwords. This is shown below: – - name: Create Admin User user: name=admin password={% verbatim %}{{ admin_password }}{% endverbatim %} groups=sudo append=yes shell=/bin/bash - name: Add Admin Authorized Key authorized_key:

user=admin key=”{% verbatim %}{{ common_public_key }}{% endverbatim %}” state=present - name: Create Deploy User user: name=deploy password={% verbatim %}{{ deploy_password }}{% endverbatim %} groups=www-data append=yes shell=/bin/bash - name: Add Deployer Authorized Key authorized_key: user=deploy key=”{% verbatim %}{{ common_public_key }}{% endverbatim %}” state=present These tasks will make use of the user module so as to create new users, and it will pass the passwords which have been set in the variable file. It will also use the module “authorized_key” for the purpose of adding the SSH public key as the authorized SSH key in our server for each user. To use variables, we do it as usual with our task file. However, in order for the role to be run, Ansible should be told to ask for the vault password which

will be used for the work of unencrypting the variables. We can then setup the Playbook file “provision.yml” and then call the user role: – - hosts: all sudo: yes roles: - user For the Playbook to be run, Ansible has to be told to ask for the vault password since we are running a role having an encrypted file. This is shown below: ansible-playbook —ask-vault-pass provision.yml

Chapter 8- Templates We need to copy our virtual host to the server, and a template can be used for accomplishing this. A file could have been used for that purpose, and then hard code the “DocumentRoot” but this process is the same for the templates, and a template has much flexibility. Ansible has been written in Python, and the template it uses is the Python Jinja2 library. You do not have to worry, as the syntax used in this case is very similar to the one used in modern template languages. For us to get started, you have to create a new directory and give it the name “templates,” and this should be done at the root of your project. You can then create the file with the name “virtual-hosts.conf.j2” in the new directory. It is customary for us to call a template with its name, the extension of the file, and then append it to the “.j2” at the end. I can at this point SSH into the provisioned vagrant box and then grab the contents of our already existing Virtual Host. The contents of the file can then be pushed into the “templates/virtual-hosts.conf.j2.” This is shown below: ServerAdmin webmaster@localhost DocumentRoot /var/www/html

ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined The line: DocumentRoot /var/www/html Should be replaced with: DocumentRoot {{ document_root }} The above procedure shows how one can echo a variable in jinja2. In our case, the variable is called “document_root.” Since Apache works in a unique way, we should add a new section for config for the directory “/vagrant,” but failure to do this will give you 403 Forbidden errors. This is why you should add the following code below the DocumentRoot: Require all granted

All together, the code should be as shown below: ServerAdmin webmaster@localhost DocumentRoot {{ document_root }} Require all granted ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined You can then save the file and open the “tasks/apache.yml” and then a new task can be added to this for the purpose of copying the template to the server. This is shown below: - name: Copy across new virtual host template: src=virtual-hosts.conf.j2 dest=/etc/apache2/sites-available/vagrant.conf

The directory “templates” doesn’t have to be included in the value “src” since Ansible will always assume that the template is located in the “Templates” directory, and if it fails to get it there, it will look into the root directory before it can give up. The whole file at this point should be as follows: – - name: install apache apt: name=apache2 state=present - name: Copy across new virtual host template: src=virtual-hosts.conf.j2 dest=/etc/apache2/sites-available/vagrant.conf The lines may seem to be somehow long. The good thing is that with Ansible, one can break up the key-value pairs each into their own lines. Let us demonstrate how this can be done: – - name: install apache apt: name=apache2 state=present - name: Copy across new virtual host template: src=virtual-hosts.conf.j2 dest=/etc/apache2/sites-available/vagrant.conf

It will make it easy for us to read, but note that the behavior will not be affected in any way. For us to copy the template across, we also need to tell Ansible the value which is needed for using the “document_root” during the process of copying the template. There are a number of ways how to do this, but the simplest way to do this is to add the key “vars”” to the file “playbook.yml,” and that is what we are going to do. Update the file “playbook.yml” to be as follows: – - hosts: all sudo: true vars: document_root: /vagrant tasks: - name: update apt cache apt: update_cache=yes - include: tasks/apache.yml - name: include mysql include: tasks/mysql.yml - include: tasks/php.yml The key “vars:” can be used in any position, but it is recommended that it should come somewhere before the “tasks:” in the Playbook. Open the terminal, and then run the

command “vagrant provision.” This is just a demonstration of idempotency in Ansible. The server can be provisioned the number of times that we want, and only things which deserve a change will be changed by Ansible. In our case, a new Virtual Host file will be created. For us to check whether this is working well, we just have to SSH into our server, and then check the contents of our new file: vagrant ssh cat /etc/apache2/sites-available/vagrant.conf After that, you should see something which looks as shown below: ServerAdmin webmaster@localhost DocumentRoot /vagrant Require all granted ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined



The File Module The configuration convention in Ubuntu for Apache Virtual Hosts involves putting the contents of the possible Hosts in “/etc/apache2/sites-available” and then making use of a2dissite and a2ansite for creation and removal of symlinks for any active virtual host for the directory “/etc/apache2/sites-enabled.” Whenever we are using Ansible, we bypass such tools and then create and remove our symlink using the file module. We now need to add two tasks to the file “tasks/apache.yml,” one for removal of the existing symlink and one for creation of a new one. They should be as shown below: - file: path=/etc/apache2/sites-enabled/000-default.conf state=absent - file: src=/etc/apache2/sites-available/vagrant.conf dest=/etc/apache2/sitesenabled/vagrant.conf state=link The long line can be broken, and then some names added so that the whole file will look as shown below: — - name: install apache apt: name=apache2 state=present - name: Copy across the new virtual host

template: src=virtual-hosts.conf.j2 dest=/etc/apache2/sites-available/vagrant.conf - name: Remove default virtual host file: path=/etc/apache2/sites-enabled/000-default.conf state=absent - name: Enable new vagrant virtual host file: src=/etc/apache2/sites-available/vagrant.conf dest=/etc/apache2/sites-enabled/vagrant.conf state=link Run back to your terminal, then run the command “vagrant provision,” and the normal Ansible output will be shown in the output including the new tasks. Once done, just SSH into the vagrant box, and then execute the command “run ls /etc/apache2/sites-enabled.” You should then observe that you are missing “000-default.conf,” but the “vagrant.conf” should be missing in place.

The Service Module At this point, Apache should be reloaded so that the new changes can take effect. For us

to do this, we can make use of the service module and then add another task. This is shown below: - name: reload apache service: name=apache2 state=reloaded You can then run the command “vagrant provision” and then add a new file to the root of your project and give it the name “info.php” and then add the simple line “
View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF