Good afternoon, Habr.
Not so long ago, I started to deal with a great tool for any DevOps - Ansible. Today I want to submit to your exacting court a small introductory article on the use of this, in many respects excellent, tools. So, let's begin.
What is Ansible
Ansible is a tool for automating the tasks of a system administrator and not only. If in your own words - this is the thing that allows you to automatically configure the server in batches.
')
Someone will say that he is not needed, because There is Chef, Puppet, etc. I absolutely agree with these people. If you can use these tools, great. I am writing this article for those who want to understand a little how Ansible works and how much can be automated with its help.
If you have not encountered Ansible at all, I advise you to read the
article of the company
Selektel . Great article.
Maximum automation
Let's define what we need to run Wordpress on a VPS server with Ubuntu installed:
- Nginx
- Mysql
- PHP5
- Memcached to use the W3Total Cache plugin
- Wordpress
In this order, we will write roles to configure the server.
The directory structure for our task will be as follows:

Nginx
In the roles / nginx / tasks directory, create a main.yml with the following contents:
- name: Add nginx repository apt_repository: repo='ppa:nginx/stable' - name: Install nginx action: apt pkg=nginx-extras state=installed update_cache=true - name: Disable default site file: path: /etc/nginx/sites-enabled/default state: absent
Everything that starts with a new line like "- name" is a separate task for Ansible. Parse what is written in steps:
- Add the nginx repository (ppa: nginx / stable)
- Install nginx-extras (If necessary, it contains an SPDY module and it can be enabled in the config file)
- We delete simlink on config by default
Create the main.yml file with the following contents in the roles / nginx / handlers directory:
- name: restart nginx service: name: nginx state: restarted
This is a service description for rebooting Nginx. We will need it after installing the config for our Wordpress.
That's it with Nginx. Two simple files will allow us to install the repository into the system, install the web server, remove its default settings and define the service for restarting it.
We go further.
Mysql
I used to set up a Percona MySQL server. Better or worse - you can argue long. I used to and use it.
The principle is the same. The roles / percona-mysql / tasks / main.yml file:
- name: Add GPG key for repository command: apt-key adv --keyserver keyserver.ubuntu.com --recv CD2EFD2A - name: Add Percona repository shell: echo "deb http://repo.percona.com/apt {{ ansible_lsb['codename'] }} main" | tee /etc/apt/sources.list.d/percona.list creates=/etc/apt/sources.list.d/percona.list - name: Install Percona MySQL server apt: pkg: "{{ item }}" update_cache: true with_items: - percona-server-server-5.5 - percona-server-client-5.5 - python-mysqldb - name: Change root password (fail is not a problem) mysql_user: name: root password: "{{ mysql_root_password}}" ignore_errors: yes
Now step by step:
- Add repository key
- Add the repository itself, checking that the /etc/apt/sources.list.d/percona.list file has been created
- Install three packages:
- percona-server-server-5.5
- percona-server-client-5.5
- python-mysqldb (needed to manage mysql server from ansible)
- Change the password of the root to the specified in the variables (see below)
Variables we will specify in the main yml file below. The name of the database, a user with a password, etc. will also be indicated there.
PHP5
Since we do not use Apache, we will use php with php-fpm. To do this, in the roles / php5 / handlers / main.yml file, we describe the php5-fpm service:
- name: restart php5-fpm service: name: php5-fpm state: restarted
We will call him after configuring php5-fpm to restart the daemon.
Roles / php5 / tasks / main.yml content:
- name: install php5 apt: pkg={{ item }} with_items: - php5 - php5-cgi - php5-fpm - php5-memcache - php5-memcached - php5-mcrypt - php5-mysql - php5-gd - php5-curl - php5-xmlrpc - name: change listen socket lineinfile: dest: '/etc/php5/fpm/pool.d/www.conf' insertafter: 'listen = 127.0.0.1:9000' line: 'listen = /var/run/fpm.socket' notify: restart php5-fpm
The first step is to install the necessary packages. Everything is simple here.
But the second step is more interesting. We will understand in more detail. In Nginx we will use chat with php5-fmp via unix-socket. To do this, we need to specify in the www daemon php5-fpm configuration pool that he should listen to the socket on the path we need. The lineinfile module allows us to do this:
- “Dest” is the path where changes should be made.
- "Insertafter" - find the line in the specified file "listen = 127.0.0.1:9000" and insert after it specified in the "line"
- "Notify" - send notification to the "restart php5-fpm" service (this is why the description of the php5-fpm service was necessary)
Memcached
With this service, everything is very simple. You need to install it and that's it. The roles / memcached / tasks / main.yml contents:
- name: install memcached server apt: pkg: memcached
Wordpress
This is where we will install Wordpress automatically, create a database and nginx configuration for it. Why exactly here? It's simple. You can take any role and use it in your other ansible projects. Or create another role and deploy not wordpress, but your own project next to wordpress. Those. it is made for banal convenience.
So, roles / wordpress / tasks / main.yml:
- name: creating database mysql_db: name: "{{ db_name }}" state: "present" login_user: "root" login_password: "{{ mysql_root_password }}" - name: creating database user mysql_user: name: "{{ db_user }}" password: "{{ db_password }}" priv: "{{ db_name }}.*:ALL" state: "present" login_user: "root" login_password: "{{ mysql_root_password }}" - name: install nginx configuration template: src: wordpress.conf dest: /etc/nginx/sites-available/wordpress.conf notify: restart nginx - name: activate site configuration file: src: '/etc/nginx/sites-available/wordpress.conf' dest: '/etc/nginx/sites-enabled/wordpress.conf' state: 'link' - name: download WordPress get_url: url: "{{ download_url }}" dest: "/tmp/latest.tar.gz" - name: creating directory for WordPress file: path: "{{ wpdirectory }}" state: "directory" owner: "www-data" group: "www-data" - name: unpack WordPress installation shell: "tar xvfz /tmp/latest.tar.gz -C {{ wpdirectory }} && chown -R www-data:www-data {{ wpdirectory }}"
Now let's go through each item:
- Create a database by specifying connection parameters (root login and password)
- Create a database user with a password, while indicating his rights to the newly created database
- Create a server configuration in Nginx using a pre-prepared template (see below) and send a signal to restart the Nginx service.
- We activate the server in Nginx, creating a simlink
- Download the variable specified Wordpress version
- Create a directory for wordpress
- Extract the downloaded archive and set the necessary permissions on files and directories.
Now the Nginx roles / wordpress / templates / wordpress.conf server configuration template:
server { listen 80 default_server; root {{ wpdirectory }}/wordpress; index index.php index.html index.htm; server_name {{ domain }}; location / { try_files $uri $uri/ /index.php?q=$uri&$args; } error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/www; }
Describing the principles of Nginx configuration is a topic for a separate article and not even one. Leave this thing for homework.
Build together and start installation
In order for Ansible to know what to run and how, we need to write a playbook wordpress.yml:
- hosts: appservers-php sudo: yes vars: - mysql_root_password: "SuperP@S$w0rd" - domain: "example.com" - download_url: "http://wordpress.org/latest.tar.gz" - wpdirectory: "/var/www" - db_name: "wordpress" - db_user: "wordpress" - db_password: "wordpress" roles: - { role: nginx } - { role: percona-mysql } - { role: memcached } - { role: php5 } - { role: wordpress }
This file indicates Ansible what servers are on which, in what sequence and with what rights to execute.
- hosts is a list of hosts from the hosts file (see below) on which all actions must be performed;
- sudo - whether to perform all actions from under sudo;
- vars - variables that are used in roles:
- mysql_root_password - which password to set to root user in MySQL
- domain - the domain of the site, which is specified in the nginx configuration
- wpdirectory - in which directory to install Wordpress
- db_ * - the corresponding parameters for MySQL
- roles - performed tasks (roles)
And we just have to describe the list of servers for installing everything in the hosts file:
[appservers-php] example.com ansible_ssh_host=10.0.0.2 ansible_ssh_user=ubuntu
The block in the first line denotes a list of hosts that is listed in wordress.yml. Next, in fact, each server with a new line.
The first is the domain of the server.
The second indicates the IP address of the server, where Ansible should go over ssh. This parameter is not required if your domain is already configured on the correct server.
The third parameter is the username with which Ansible will log into the server via ssh.
Now you can run the installation:
ansible-playbook -i hosts wordpress.yml -kK
- k - request ssh password.
- K - request sudo password
After work is finished, you can log in to the server via HTTP and configure Wordpress to work.
The ready recipe can be taken on
github .
Hope this helps you a little to automate the routine at work (and at home). Thanks for reading.