Ở các bài trước mình đã giới thiệu với các bạn về Ansible và cách sử dụng và viết một Ansible playbook. Nếu các bạn chưa đọc các bài viết này các bạn có thể đọc lại các bài viết đó tại đây.
Trong bài viết này mình sẽ thực hành ứng dụng của Ansible khi setup một trang web WordPress nhé.
Mô hình sử dụng trong bài.
- Server Ansible Control Node
- Web Server
- Nginx Load Balance
Quy hoạch xác định các roles cần thiết trong ansible.
Đầu tiên trước khi bắt đầu chúng ta cần xác định chúng ta sẽ cần thiết lập những gì cho mô hình này. Ở đây mình sẽ sử dụng Apache để chạy website wordpress và sử dụng Nginx để thiết lập Reverproxy và caching các file tĩnh. Vậy chúng ta sẽ thống kê như sau:
– Đầu tiên setup LAMP stack để chạy wordpress.
– Thiết lập Vhost cho domain và tiến hành cài đặt wordpress cho domain đó.
– Cài đặt Nginx làm loadblance
– Cài đặt Vhost để biến nginx thành reverse proxy và cache server,.
– Tất nhiên một trang wbe sẽ không thể thiếu được SSL để bảo mật hơn.
Sau khi thống kê thì ta sẽ có một tree map cho dự án như sau:
├── certbot
│ ├── README.md
│ ├── handlers
│ │ └── main.yml
│ └── tasks
│ └── main.yml
├── inventory.ini
├── loadbalance
│ ├── README.md
│ ├── handlers
│ │ └── main.yml
│ └── tasks
│ └── main.yml
├── nginx_config
│ ├── conf
│ │ ├── cdn.conf
│ │ ├── header.conf
│ │ ├── proxy_cache.conf
│ │ └── proxy_pass.conf
│ ├── nginx.conf
│ └── systctl.conf
├── playbook.yml
├── setup_lamp
│ ├── README.md
│ ├── handlers
│ │ └── main.yml
│ └── tasks
│ └── main.yml
├── setup_wordpress
│ ├── README.md
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ ├── apache.conf.j2
│ └── wp-config.php.j2
├── vars
│ └── default.yml
└── vhost-nginx
├── README.md
├── handlers
│ └── main.yml
├── tasks
│ └── main.yml
└── templates
└── nginx_vhost.conf.j2
Tiến hành viết playbook.
Trong bài này mình sẽ sử dụng roles để viết một ansible play book cho nên mỗi bước được đề ra trong phần 1 sẽ được setup thành 1 roles.
Một số modules mình sử dụng trong dự án này như sau:
apt: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/apt_module.html
mysql_user: https://docs.ansible.com/ansible/latest/collections/community/mysql/mysql_user_module.html
mysql_db: https://docs.ansible.com/ansible/latest/collections/community/mysql/mysql_db_module.html
files: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/file_module.html
template: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/template_module.html
shell: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/shell_module.html
ufw: https://docs.ansible.com/ansible/latest/collections/community/general/ufw_module.html
unarchive: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/unarchive_module.html
Đầu tiên chúng ta sẽ bắt đầu với bước 1 setup LAMP stack.
Cơ bản setup lamp stack chúng ta cần cài các thành phần như apache, mysql, php và php extention.
---
# tasks file for setup_lamp
- name: Install prerequisites
apt: name=aptitude update_cache=yes state=latest force_apt_get=yes
tags: [ system ]
- name: Install LAMP Packages
apt: name={{ item }} update_cache=yes state=latest
loop: [ 'apache2', 'mysql-server', 'python3-pymysql', 'php', 'php-mysql', 'libapache2-mod-php' ]
tags: [ system ]
- name: Install PHP Extensions
apt: name={{ item }} update_cache=yes state=latest
loop: "{{ php_modules }}"
tags: [ system ]
- name: Set the root password
mysql_user:
name: root
password: "{{ mysql_root}}"
login_unix_socket: /var/run/mysqld/mysqld.sock
tags: [ mysql, mysql-root ]
- name: Remove all anonymous user accounts
mysql_user:
name: ''
host_all: yes
state: absent
login_user: root
login_password: "{{ mysql_root_password }}"
tags: [ mysql ]
- name: Remove the MySQL test database
mysql_db:
name: test
state:reloaded
login_user: root
login_password: "{{ mysql_root_password }}"
tags: [ mysql ]
Bước 2 chúng ta cần setup một Vhost apache và install word press cho domain đó.
Đầu tiên chúng ta tạo file main dành cho task của roles setup_wordpress như sau.
---
# tasks file for setup_wordpress
# Apache Config vhost
- name: Create document root
file:
path: "/var/www/{{ http_host }}"
state: directory
owner: "www-data"
group: "www-data"
mode: '0755'
tags: [ apache ]
- name: Set up Apache VirtualHost
template:
src: "apache.conf.j2"
dest: "/etc/apache2/sites-available/{{ http_conf }}"
notify: Reload Apache
tags: [ apache ]
- name: Enable rewrite module
shell: /usr/sbin/a2enmod rewrite
notify: Reload Apache
tags: [ apache ]
- name: Enable new site
shell: /usr/sbin/a2ensite {{ http_conf }}
notify: Reload Apache
tags: [ apache ]
- name: Disable default Apache site
shell: /usr/sbin/a2dissite 000-default.conf
notify: Restart Apache
tags: [ apache ]
# Setup Database for WordPress
- name: Creates database for WordPress
mysql_db:
name: "{{mysql_user}}"
state: present
login_user: root
login_password: "{{ mysql_root_password }}"
tags: [ mysql ]
- name: Create MySQL user for WordPress
mysql_user:
name: "{{ mysql_user }}"
password: "{{ mysql_password }}"
priv: "{{ mysql_user }}.*:ALL"
state: present
login_user: root
login_password: "{{ mysql_root_password }}"
tags: [ mysql ]
# UFW Configuration
- name: "UFW - Allow HTTP on port {{ http_port }}"
ufw:
rule: allow
port: "{{ http_port }}"
proto: tcp
tags: [ system ]
# WordPress Configuration
- name: Download and unpack latest WordPress
unarchive:
src: https://wordpress.org/latest.tar.gz
dest: "/var/www/{{ http_host }}"
remote_src: yes
creates: "/var/www/{{ http_host }}/wordpress"
tags: [ wordpress ]
- name: Set ownership
file:
path: "/var/www/{{ http_host }}"
state: directory
recurse: yes
owner: www-data
group: www-data
tags: [ wordpress ]
- name: Set permissions for directories
shell: "/usr/bin/find /var/www/{{ http_host }}/wordpress/ -type d -exec chmod 750 {} \\;"
tags: [ wordpress ]
- name: Set permissions for files
shell: "/usr/bin/find /var/www/{{ http_host }}/wordpress/ -type f -exec chmod 640 {} \\;"
tags: [ wordpress ]
- name: Set up wp-config
template:
src: "wp-config.php.j2"
dest: "/var/www/{{ http_host }}/wordpress/wp-config.php"
tags: [ wordpress ]
Kế tiếp ta cần 2 template dành cho Vhost và wp-config.php dùng để cài đặt wordpress.
Ta tiến hành tạo hai file jira như sau.
Vhost.conf.j2
ServerAdmin webmaster@localhost
ServerName {{ http_host }}
ServerAlias www.{{ http_host }}
DocumentRoot /var/www/{{ http_host }}/wordpress
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
Options -Indexes
AllowOverride All
DirectoryIndex index.php index.html index.cgi index.pl index.xhtml index.htm
Wp-config.php.j2
Thiết lập Loadblance
Sau khi đã cài đặt web server thành công ta có thể tiếp tục cài đặt loadbalance cho nó.
Thiết lập file task cho roles loadblance như sau:
---
- name: Update repo
apt:
update_cache: yes
- name: Install Nginx
apt:
name: "{{ package }}"
state: present
notify: Start nginx
vars:
package:
- nginx
- nginx-extras
tags: [Load balance]
- name: Config server
copy:
src: /root/wordpress/nginx_config/systctl.conf
dest: /etc/sysctl.conf
notify: Apply sysctl config
tags: [Load balance]
- name: Optimize Nginx Caching Performance
copy:
src: /root/wordpress/nginx_config/nginx.conf
dest: /etc/nginx/nginx.conf
notify: Restart Nginx
tags: [Load balance]
- name: Config CDN Option
synchronize:
src: /root/wordpress/nginx_config/conf/
dest: /etc/nginx/conf
notify: Restart Nginx
tags: [Load balance]
Thiết lập Vhost Nginx
Sau khi đã cài đặt đầy đủ các package cần thiết cho Nginx ta cần thiết lập Vhost nginx để có thể cài đặt được Vhost cho một domain cụ thể .
Ta sẽ thiết lập task cho Vhost Nginx như sau:
---
# tasks file for vhost-nginx
- name: setup vhost for nginx
template:
src: nginx_vhost.conf.j2
dest: /etc/nginx/sites-enabled/{{ nginx_host}}.conf
owner: root
group: root
mode: '644'
notify: Reload Nginx
tags: [ vHost Nginx ]
Thiết lập SSL
Cuối cùng cũng quan trọng đó là thiết lập SSL cho web vừa khởi tạo.
---
# tasks file for certbot
- name: Install Certbot
apt:
name: "{{package}}"
state: present
vars:
package:
- certbot
- python3-certbot-nginx
tags: [ Certbot ]
- name: Install SSL
shell: certbot --nginx --non-interactive --agree-tos --email danht@vinahost.vn --domains {{ nginx_host }}
become: true
notify: Reload Nginx
tags: [ Certbot ]
Tạo Iventory và Playbook
Để playbook hoạt động ta cần cài đặt invetory và các biến mặc định truyền trong vars/default.
Inventory.
[lb-server]
nginx1 ansible_host=146.196.65.12
[webserver]
server1 ansible_host=146.196.65.7
[all:vars]
ansible_user=root
ansible_ssh_private_key_file=/root/.ssh/id_rsa
default.yml
---
#System Settings
php_modules: [ 'php-curl', 'php-gd', 'php-mbstring', 'php-xml', 'php-xmlrpc', 'php-soap', 'php-intl', 'php-zip' ]
#MySQL Settings
mysql_root_password: "Thanhdan1@710"
mysql_db: "wordpress"
mysql_user: "danny"
mysql_password: "Thanhdan1@710"
#HTTP Settings
http_host: "wordpress.thanhdan.name.vn"
http_conf: "wordpress.thanhdan.name.vn.conf"
http_port: "80"
backend_servers:
- name: server1
address: 146.196.65.7
port: 80
load_balancing_method: round-robin
nginx_host: "wordpress.thanhdan.name.vn"
load_balancer_port: 80
Cuối cùng ta cần tạo playbook để có thể thực hiện các quá trình trên.
- name: Install WordPress For Web Server
hosts: webserver
become: true
vars_files:
- vars/default.yml
roles:
- setup_lamp
- setup_wordpress
- name: Configuration LoadBalance
hosts: lb-server
become: true
vars_files:
- vars/default.yml
roles:
- loadbalance
- vhost-nginx
- certbot
~
Cuối cũng ta chạy play book để kiểm tra kết quả
PLAY [Install WordPress For Web Server] *************************************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************************************
ok: [server1]
TASK [setup_lamp : Install prerequisites] ***********************************************************************************************************************************************
changed: [server1]
TASK [setup_lamp : Install LAMP Packages] ***********************************************************************************************************************************************
changed: [server1] => (item=apache2)
changed: [server1] => (item=mysql-server)
changed: [server1] => (item=python3-pymysql)
changed: [server1] => (item=php)
changed: [server1] => (item=php-mysql)
changed: [server1] => (item=libapache2-mod-php)
TASK [setup_lamp : Install PHP Extensions] **********************************************************************************************************************************************
changed: [server1] => (item=php-curl)
changed: [server1] => (item=php-gd)
changed: [server1] => (item=php-mbstring)
changed: [server1] => (item=php-xml)
changed: [server1] => (item=php-xmlrpc)
changed: [server1] => (item=php-soap)
changed: [server1] => (item=php-intl)
changed: [server1] => (item=php-zip)
TASK [setup_lamp : Set the root password] ***********************************************************************************************************************************************
[WARNING]: Option column_case_sensitive is not provided. The default is now false, so the column's name will be uppercased. The default will be changed to true in community.mysql
4.0.0.
changed: [server1]
TASK [setup_lamp : Remove all anonymous user accounts] **********************************************************************************************************************************
ok: [server1]
TASK [setup_lamp : Remove the MySQL test database] **************************************************************************************************************************************
ok: [server1]
TASK [setup_wordpress : Create document root] *******************************************************************************************************************************************
changed: [server1]
TASK [setup_wordpress : Set up Apache VirtualHost] **************************************************************************************************************************************
changed: [server1]
TASK [setup_wordpress : Enable rewrite module] ******************************************************************************************************************************************
changed: [server1]
TASK [setup_wordpress : Enable new site] ************************************************************************************************************************************************
changed: [server1]
TASK [setup_wordpress : Disable default Apache site] ************************************************************************************************************************************
changed: [server1]
TASK [setup_wordpress : Creates database for WordPress] *********************************************************************************************************************************
changed: [server1]
TASK [setup_wordpress : Create MySQL user for WordPress] ********************************************************************************************************************************
changed: [server1]
TASK [setup_wordpress : UFW - Allow HTTP on port 80] ************************************************************************************************************************************
changed: [server1]
TASK [setup_wordpress : Download and unpack latest WordPress] ***************************************************************************************************************************
changed: [server1]
TASK [setup_wordpress : Set ownership] **************************************************************************************************************************************************
changed: [server1]
TASK [setup_wordpress : Set permissions for directories] ********************************************************************************************************************************
changed: [server1]
TASK [setup_wordpress : Set permissions for files] **************************************************************************************************************************************
changed: [server1]
TASK [setup_wordpress : Set up wp-config] ***********************************************************************************************************************************************
changed: [server1]
RUNNING HANDLER [setup_wordpress : Reload Apache] ***************************************************************************************************************************************
changed: [server1]
RUNNING HANDLER [setup_wordpress : Restart Apache] **************************************************************************************************************************************
changed: [server1]
PLAY [Configuration LoadBalance] ********************************************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************************************
ok: [nginx1]
TASK [loadbalance : Update repo] ********************************************************************************************************************************************************
changed: [nginx1]
TASK [loadbalance : Install Nginx] ******************************************************************************************************************************************************
changed: [nginx1]
TASK [loadbalance : Config server] ******************************************************************************************************************************************************
changed: [nginx1]
TASK [loadbalance : Optimize Nginx Caching Performance] *********************************************************************************************************************************
changed: [nginx1]
TASK [loadbalance : Config CDN Option] **************************************************************************************************************************************************
[DEPRECATION WARNING]: The connection's stdin object is deprecated. Call display.prompt_until(msg) instead. This feature will be removed in version 2.19. Deprecation warnings can be
disabled by setting deprecation_warnings=False in ansible.cfg.
changed: [nginx1]
TASK [vhost-nginx : setup vhost for nginx] **********************************************************************************************************************************************
changed: [nginx1]
TASK [certbot : Install Certbot] ********************************************************************************************************************************************************
changed: [nginx1]
TASK [certbot : Install SSL] ************************************************************************************************************************************************************
changed: [nginx1]
RUNNING HANDLER [loadbalance : Start nginx] *********************************************************************************************************************************************
ok: [nginx1]
RUNNING HANDLER [loadbalance : Restart Nginx] *******************************************************************************************************************************************
changed: [nginx1]
RUNNING HANDLER [loadbalance : Apply sysctl config] *************************************************************************************************************************************
changed: [nginx1]
RUNNING HANDLER [certbot : Reload Nginx] ************************************************************************************************************************************************
changed: [nginx1]
PLAY RECAP ******************************************************************************************************************************************************************************
nginx1 : ok=13 changed=11 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
server1 : ok=22 changed=19 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Sau khi chạy thành công ta truy cập vào trang web wordpress.thanhdan.name.vn để kiểm tra sẽ thấy giao diện để cài đặt wordpress.
Trên đây là quá trình cài đặt một website wordpress và thiết lập caching cùng load balance từ A-Z. Các file câu hình chi tiết các bạn có thể tải về tại đây.
Vậy là chúng ta đã đi gần hết chặn đường của Series này. Ở bài sau sẽ là bài cuối cũng khi mình sử dụng Ansible để cấu hình nhiều Docker Contrainer với nhau. Các bạn có thể đón xem tại Series Ansible này nhé.
Chúc các bạn thực hiện thành công !
Tài liệu tham khảo:
- https://github.com/aleks/ansible-multi-wordpress/tree/master
- https://jinja.palletsprojects.com/en/2.10.x/
- https://blog.vinahost.vn/ansible-la-gi/
- https://elroydevops.tech/cach-su-dung-ansible-infrastructure-as-code/