In this blog post, I will explain the server settings by parameterization and automation using ** Ansible Galaxy **.
Alibi Cloud Tech Share Author, Ankit Mehta. Tech Share is an Alibaba Cloud incentive program that encourages sharing of technical knowledge and best practices within the cloud community.
If you are new to Ansible, read the previous blog post (https://www.alibabacloud.com/blog/getting-started-with-configuration-management-and-ansible_594653?spm=a2c65.11461447.0.0.bd4e709aj0TCSK) to read how Ansible works and some basic settings.
Parameterization is one of the most important segments of automation. Parameterization allows you to reuse scripts and files without having to rewrite the complete solution again.
People often ask me, "I only have one VPS, is there any benefit to using Ansible?", But the answer is whether it's a single VPS or multiple VPS servers. Is yes. You can use Ansible scripts to manage all your servers. This not only keeps your settings, but also helps you apply changes to SSL to set up a new server, and also helps you set up and deploy a website on your new cloud hosting provider.
In this blog post, we implement the following solution in Ansible.
To achieve the above, the blog is divided into two segments.
Make sure the server is ready and accessible from the Ansible host. To set up an Ansible host, see the Ansible Basics blog post.
There are several Ansible Galaxy scripts available for installing NGINX. However, in my own experience, I think it's better to use APT to install Nginx. A complete list of Ansible Galaxy can be found at https://galaxy.ansible.com/.
The next block installs NGINX on the server and verifies that the service is 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 execute it with the following command.
ansible-playbook -i hosts.yml install-nginx.yml -b -v
Different Ubuntu versions come with support for different PHP versions. PHP version 7.2
Ansible galaxy helps reduce the task of quickly installing the required dependencies. Ansible Galaxy refers to the Galaxy website where users can share roles and command line tools for installing, creating, and managing roles.
You need two ansible galaxy roles to install PHP. PHP version and PHP (installation order can be arbitrary).
To install the PHP version, enter the following command.
ansible-galaxy install geerlingguy.php-versions
To install the PHP version, enter the following command:
ansible-galaxy install geerlingguy.php
After installing the Ansible Galaxy role, prepare the yaml file for installation. The Ansible role requires a variable file. For demonstration purposes, store the variable file in the vars/main.yml file. This time, I added the PHP version, PHP settings (php.ini file settings), and the required PHP extension to the vars file.
The contents of the main.yml file are as follows.
#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 a yaml file (php-install.yml) for installation.
- hosts: all
vars_files:
- vars/main.yml
roles:
- geerlingguy.php-versions
- geerlingguy.php
To install php, you need to enter the following command.
ansible-playbook -i hosts.yml php-install.yml -b -v
Similarly, there are many packages available for installing MySQL / MariaDB. However, the best option is to use the direct installation package. MariaDB / MySQL requires Python-py MySQL on the server. The following installation blocks install the 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 it.
ansible-playbook -i hosts.yml mysql-install.yml -b -v
Linux uses swap space to increase the amount of virtual memory available on the host. You can use one or more dedicated swap partitions, or you can use swap files on a regular file system or logical volume. Ansible's galaxy role helps you easily configure swap space.
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 block of code as swap-install.yml.
- hosts: all
vars_files:
- vars/main.yml
roles:
- geerlingguy.swap
To install swap, run the following command:
ansible-playbook -i hosts.yml swap-install.yml -b -v
If you need a larger swap file size, update the swap_file_size parameter. The current setting creates a 1GB swap file partition.
Web server security is the most important part of any server (ECS) configuration. For better security, we recommend disabling root login, disabling password login, changing SSH port, and enabling fail2ban. (Note that there are many other features and services to improve the security of your Linux server)
To install the Linux security ansible role, run the following command.
ansible-galaxy install geerlingguy.security
Add the 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 block of code 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
In the above example, the SSH port is changed to 65239 after a successful test run.
By applying firewall settings, the server can be protected from known network attacks. Your application is trying to use HTTP, HTTPS, and SSH ports, so it's a good idea to block access to other ports. To install the Ansible galaxy role for your firewall, run the following command:
ansible-galaxy install geerlingguy.firewall
Provide the port details in the vars/main.yml file.
#Firewall Settings
firewall_state: started
firewall_enabled_at_boot: true
firewall_allowed_tcp_ports:
- "443"
- "65239"
- “80"
Save the following block of code 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: Apply the firewall changes to your ECS instance as well. To apply the changes, go to ECS> Security Groups> Add Rule.
A sample LEMP installation script can be found at https://github.com/ankyit/ansible-lemp-wordpress/tree/master/LEMP.
--The Prepare-client.sh file contains the basic installation script to prepare the ansible system with all the dependencies and required roles. --Update the server IP and ansible_user in hosts.yml (https://github.com/ankyit/ansible-lemp-wordpress/blob/master/LEMP/hosts.yml). --Use the prepare-lemp.yml (https://github.com/ankyit/ansible-lemp-wordpress/blob/master/LEMP/prepare-lemp.yml) file to install LEMP. please. --vars/main.yml (https://github.com/ankyit/ansible-lemp-wordpress/blob/master/LEMP/vars/main.yml) Update the required parameters in the file.
1, LEMP server 2. Domain name using DNS in Cloudflare 3, SSL certificate 4, Website with database (This time for WordPress demo web
The above segment has detailed the preparation of the LEMP server. In this segment, I would like you to use it as a reference when introducing a WordPress site using Ansible.
Below is a high level structure for setting up your site deployment. The format can be defined and set as needed.
Here, the certs directory contains the SSL certificate and Key file. The sites-config folder contains NGINX settings. sites stores the files and folder structure of your website. Site variables are stored in the vars folder.
The hosts.yml file contains host information, and deploy-site.yml contains steps/tasks for deploying the site.
The deploy-site.yml file extends the functionality covered in the blog post.
Tasks from deploy-site.yml
The next block copies the certificate and key files from the certs folder to the/etc/nginx/ssl folder. Where {{site_url}} is a dynamic parameter whose value is replaced in place 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 copies the website's Nginx configuration file and stores it 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 creates a 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 creates a website folder in the location of/var/www /.
### Create a directory for the website
- file:
path: /var/www/{{site_url}}
state: directory
mode: 0755
The following code block uses rsync to copy files from the site folder to/var/www /. Where delete yes deletes the file in the destination location if the file is 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
Create a database with the following code block.
###{{site_url}} Database Creation
- name: Create a {{site_url}} database
mysql_db:
name: "{{site_db}}"
state: present
The following code block creates a user and assigns 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 block of code imports 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 sets directory permissions and sets them to www-data with 0755 permissions.
###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 restarts 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 described here can be accessed from https://github.com/ankyit/ansible-lemp-wordpress.
Recommended Posts