By Ankit Mehta, Alibaba Cloud Tech Share Author. Tech Share is Alibaba Cloud's incentive program to encourage the sharing of technical knowledge and best practices within the cloud community.
This blog post will cover parameterization and use of the Ansible Galaxy to configure the servers. If you are new to Ansible, read the previous blog post on how Ansible works and some basic configuration.
Parameterization is one of the most important segments of automation. Parameterization can help you reuse the script and file without rewriting the complete solution again.
People frequently ask, "I have only one VPS, will I get any benefits using Ansible?" the answer is yes, whether one VPS or multiple VPS servers. Ansible scripts can be used to manage all servers. This will not only retain the configuration but also help in configuring new servers, applying changes to the SSL, and also can help to configure and deploy websites on new cloud hosting provider.
For this blog post we will implement the following solution with Ansible where:
To achieve above, the blog is divided into two segments
Make sure that the server is ready and accessible by Ansible host. To configure Ansible host, refer to the Ansible Basics blog post.
There are multiple Ansible Galaxy scripts available to install NGINX. However, from my own experience, it is better to use the APT to install Nginx. A complete list of Ansible Galaxy can be found on https://galaxy.ansible.com/
The following block will install the NGINX on the server and make sure that the services are enabled
---
- hosts: all
tasks:
- name: ensure nginx is at the latest version
apt: name=nginx state=latest
become: yes
- name: start nginx
service:
name: nginx
state: started
become: yes
Save the above block as install-nginx.yml and run it with the following command.
ansible-playbook -i hosts.yml install-nginx.yml -b -v
Different Ubuntu version comes with different PHP version support. During the time of this post PHP version 7.2
Ansible galaxy helps in reducing the tasks install the required dependencies quickly. "Ansible Galaxy refers to the Galaxy website where users can share roles, and to a command line tool for installing, creating and managing roles."
To install the PHP, two ansible galaxy roles are needed: PHP version and PHP (installation sequence can be of any order).
To install PHP version, enter the following command
ansible-galaxy install geerlingguy.php-versions
To install PHP version, enter the following command
ansible-galaxy install geerlingguy.php
Once the Ansible Galaxy roles are installed, prepare the installation yaml file. The Ansible roles require a variable file. For the demonstration purpose, the variable files are stored in vars/main.yml file. In this case, we added PHP version, PHP settings (settings for php.ini file) and required PHP extensions in the vars file.
The following are the contents of the main.yml file
#PHP version
php_version: '7.2'
php_enable_webserver: true
php_webserver_daemon: "nginx"
php_packages_state: "present"
php_install_recommends: true
php_executable: "php"
php_enable_php_fpm: true
php_fpm_listen: "127.0.0.1:9000"
php_fpm_listen_allowed_clients: "127.0.0.1"
php_fpm_pm_max_children: 50
php_fpm_pm_start_servers: 5
php_fpm_pm_min_spare_servers: 5
php_fpm_pm_max_spare_servers: 5
php_use_managed_ini: true
php_fpm_pool_user: "www-data" # default varies by OS
php_fpm_pool_group: "www-data" # default varies by OS
php_memory_limit: "256M"
php_max_execution_time: "60"
php_max_input_time: "60"
php_max_input_vars: "1000"
php_realpath_cache_size: "32K"
php_file_uploads: "On"
php_upload_max_filesize: "64M"
php_max_file_uploads: "20"
php_post_max_size: "32M"
php_date_timezone: "Asia/Bangkok"
php_allow_url_fopen: "On"
php_sendmail_path: "/usr/sbin/sendmail -t -i"
php_output_buffering: "4096"
php_short_open_tag: false
php_error_reporting: "E_ALL & ~E_DEPRECATED & ~E_STRICT"
php_display_errors: "Off"
php_display_startup_errors: "On"
php_expose_php: "Off"
php_session_cookie_lifetime: 0
php_session_gc_probability: 1
php_session_gc_divisor: 1000
php_session_gc_maxlifetime: 1440
php_session_save_handler: files
php_opcache_zend_extension: "opcache.so"
php_opcache_enable: "1"
php_opcache_enable_cli: "0"
php_opcache_memory_consumption: "96"
php_opcache_interned_strings_buffer: "16"
php_opcache_max_accelerated_files: "4096"
php_opcache_max_wasted_percentage: "5"
php_opcache_validate_timestamps: "1"
php_opcache_revalidate_path: "0"
php_opcache_revalidate_freq: "2"
php_opcache_max_file_size: "0"
php_memory_limit: "128M"
php_max_execution_time: "90"
php_upload_max_filesize: "256M"
php_packages:
- php
- php-cli
- php-common
- php-devel
- php-gd
- php-mbstring
- php-pdo
- php-pecl-apcu
- php-xml
- php-fpm
The code snippet below is the installation yaml file (php-install.yml)
- hosts: all
vars_files:
- vars/main.yml
roles:
- geerlingguy.php-versions
- geerlingguy.php
To install the php following command needs to be entered
ansible-playbook -i hosts.yml php-install.yml -b -v
Likewise many packages available to install MySQL/MariaDB. However, the best option is to use the direct install package. MariaDB / MySQL requires Python-py MySQL on the server. The following installation block will install dependencies and MySQL.
---
- hosts: all
tasks:
- name: "Install Python MySQL Dependency"
apt:
name: ['python-mysqldb',
'python3-pip',
'python3-dev',
'libmysqlclient-dev',
'mysql-server',
'php7.2-mysql']
- name: select default locale
debconf:
name: locales
question: locales/default_environment_locale
value: en_US.UTF-8
vtype: select
- name: set timezone to Asia/Bangkok
timezone:
name: Asia/Bangkok
- name: "Install Python MySQL Module"
pip:
name: mysqlclient
extra_args: -i https://pypi.python.org/pypi/
executable: pip3
Save the above block as mysql-install.yml and run the following command to install.
ansible-playbook -i hosts.yml mysql-install.yml -b -v
Linux uses swap space to increase the amount of virtual memory available to a host. It can use one or more dedicated swap partitions or a swap file on a regular filesystem or logical volume. Ansible galaxy role will help to configure the swap space easily.
Install the swap ansible role with the following command
ansible-galaxy install geerlingguy.swap
Set the expected swap space and pressure details in vars/main.yml
swap_file_path: /swapfile
swap_file_size: '1024'
swap_swappiness: 60
swap_file_state: present
swap_file_create_command: "dd if=/dev/zero of={{ swap_file_path }} bs=1M count={{ swap_file_size }}"
Save the following code block as swap-install.yml
- hosts: all
vars_files:
- vars/main.yml
roles:
- geerlingguy.swap
To install the swap run the following command
ansible-playbook -i hosts.yml swap-install.yml -b -v
Update the parameter swap_file_size if more swap file size is needed. With current configuration it will create a swap file partition of 1GB
Web server security is the most integral part of any server (ECS) configuration. To improve the security it is recommended to disable the root login, disable the password login, change the SSH port and activate the fail2ban. (Please note that there are many more features and services to improve the Linux server security.)
To install the Linux security ansible role run the following command
ansible-galaxy install geerlingguy.security
Add following variables to vars/main.yml
# Security Settings
security_ssh_port: 65239
security_ssh_password_authentication: "no"
security_ssh_permit_root_login: "no"
security_ssh_usedns: "no"
security_autoupdate_enabled: true
security_fail2ban_enabled: true
Save the following code block as install-security.yml
- hosts: all
vars_files:
- vars/main.yml
roles:
- geerlingguy.security
To install the security run,
ansible-galaxy -i hosts.yml install-security.yml -b -v
For the example above, the SSH port will be changed to 65239 after the successful run of the test.
By applying the firewall configuration the server can be prevented from known network attacks. As the application is going to use the port HTTP, HTTPS, and SSH, it is recommended to block access to all other ports. To install the firewall Ansible galaxy role, run the following command.
ansible-galaxy install geerlingguy.firewall
Provide the port details in vars/main.yml file
#Firewall Settings
firewall_state: started
firewall_enabled_at_boot: true
firewall_allowed_tcp_ports:
- "443"
- "65239"
- "80"
Save the following code block as install-firewall.yml
- hosts: all
vars_files:
- vars/main.yml
roles:
- geerlingguy.firewall
To apply the firewall changes run the following command
ansible-playbook -i hosts.yml install-firewall.yml -b -v
Note: Make sure to apply the firewall changes for the ECS instance as well. To apply the changes navigate to ECS > Security Group > Add Rule
Sample LEMP installation script can be found at https://github.com/ankyit/ansible-lemp-wordpress/tree/master/LEMP
In the segment above, we discussed in detail regarding the preparation of the LEMP server. This segment will help in installing a WordPress website using Ansible.
Following is the high level structure for the site deployment configuration. Note that the format can be defined and configured as per the needs.
Here, the certs directory will contain the SSL certificate and Key file. The sites-config folder will contain NGINX configuration. The sites will contain the files and folder structure of the website. The vars folder will contain the site variables.
The hosts.yml file will contain the host information and deploy-site.yml will contain the steps/tasks for the site deployment.
The deploy-site.yml file extends the functionalities covered in the blog posts.
Tasks from deploy-site.yml
The following block will copy the certificate and key file from the certs folder to /etc/nginx/ssl folder. Here {{site_url}} is a dynamic parameter and it's values are replaced on the fly from vars/main.yml
### {{site_url}} SSL Copy
- name: copy {{site_url}} SSL files
copy:
src: ./certs/{{site_url}}.csr
dest: /etc/nginx/ssl/{{site_url}}.csr
become: yes
- name: copy {{site_url}} SSL key files
copy:
src: ./certs/{{site_url}}.key
dest: /etc/nginx/ssl/{{site_url}}.key
become: yes
The following code block will copy the NGINX configuration file for the website and will be stored in /etc/nginx/sites-available
### {{site_url}} Nginx configuration
- name: copy the nginx config file
copy:
src: ./site-config/{{site_url}}.cfg
dest: /etc/nginx/sites-available/{{site_url}}.cfg
become: yes
The following code block will create symbolic link for the URL from sites-available to sites-enabled.
- name: create symlink
file:
src: /etc/nginx/sites-available/{{site_url}}.cfg
dest: /etc/nginx/sites-enabled/{{site_url}}.cfg
state: link
become: yes
The following code block will create a website folder on /var/www/ location
### Create a directory for the website
- file:
path: /var/www/{{site_url}}
state: directory
mode: 0755
The following code block will copy the files from sites folder to /var/www/ using rsync. Here the delete yes will delete the files at destination location if the files are deleted from the source location.
##{{site_url}} Website Copy
- name: copy the content of the website
synchronize:
src: ./sites/
dest: /var/www/{{site_url}}
delete: yes
The following code block will create a database.
###{{site_url}} Database Creation
- name: Create a {{site_url}} database
mysql_db:
name: "{{site_db}}"
state: present
The following code block will create a user and assign the DB privileges.
- name: "Create a new user for {{site_url}}"
mysql_user:
name: "{{site_db_user}}"
password: "{{site_db_password}}"
priv: '{{site_db}}.*:ALL'
state: present
The following code block will import the database
# ###Import database
- name: import the database
mysql_db:
name: "{{site_db}}"
state: import
target: /var/www/{{site_url}}/{{db_file}}
login_user: "{{site_db_user}}"
login_password: "{{site_db_password}}"
The following code block will set the directory permission and set it to www-data with 0755 rights.
###Set Directory permissions
- name: Set Directory permissions
file: path=/var/www/ owner=www-data group=www-data mode=0755 state=directory recurse=yes
The following code block will restart NGINX and PHP-FPM
## Restart NginX and PHP-fpm
- name: restart nginx
service:
name: nginx
state: restarted
become: yes
- name: restart PHP FPM
service:
name: php7.2-fpm
state: restarted
become: yes
Note: All the scripts discussed here can be accessed from https://github.com/ankyit/ansible-lemp-wordpress
Automating Your PHP Application Deployment with PHP Deployer
2,599 posts | 762 followers
FollowAlibaba Clouder - June 3, 2020
Alibaba Clouder - September 20, 2019
Alibaba Clouder - July 8, 2020
Alibaba Clouder - December 5, 2017
- November 14, 2017
Alibaba Clouder - May 20, 2019
2,599 posts | 762 followers
FollowAn encrypted and secure cloud storage service which stores, processes and accesses massive amounts of data from anywhere in the world
Learn MoreMarketplace is an online market for users to search and quickly use the software as image for Alibaba Cloud products.
Learn MoreLearn More
More Posts by Alibaba Clouder