> For the complete documentation index, see [llms.txt](https://ansible.drx.tw/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ansible.drx.tw/23.how-to-setup-lnmp-webapp-with-roles-2.md).

# 怎麼用 Roles 部署 LNMP 網頁應用程式？(下)

## 23. 怎麼用 Roles 部署 LNMP 網頁應用程式？(下)

上一章「[22. 怎麼用 Roles 部署 LNMP 網頁應用程式？(上)](/22.how-to-setup-lnmp-webapp-with-roles-1.md)」我們挑選了 Nginx, MySQL 和 PHP 的 Roles，接下來就讓凍仁展示怎麼用 Roles **簡化**大型的 TestLink Playbooks 吧！

![automate\_with\_ansible\_practice-26.jpg](/files/-LpvdLF7RWnptgrS-XU6)

### 怎麼用 Roles 撰寫強化版的 Playbooks？

在這份 Playbooks 與「[19. 如何維護大型的 Playbooks？](/19.how-to-maintain-the-complex-playbooks.md)」不同的是，凍仁除了把 variables, tasks, handlers 拆開寫以外，還加入 Roles 的部份。

#### 取得範例檔

為避免版面過於混亂，凍仁已上傳範例檔，還請大家先至 [GitHub](https://github.com/chusiang/automate-with-ansible) 下載。

**Git**

1. 取得 demo code。

```
$ git clone https://github.com/chusiang/automate-with-ansible.git
```

1. 進入 testlink 目錄。

```
$ cd automate-with-ansible/lab/ch23/testlink
```

**Zip**

1. 若不想使用 Git，可改下載 zip 檔。

```
$ wget https://github.com/chusiang/automate-with-ansible/archive/main.zip
```

1. 解壓縮。

```
$ unzip main.zip
```

1. 進入 testlink 目錄。

```
$ cd automate-with-ansible-main/lab/ch23/testlink/
```

#### 從 Galaxy 下載 Roles

透過凍仁定義好的 `requirements.yml` 下載多個 Roles，詳情請參考 [Installing multiple roles from a file | Ansible Documentation](https://docs.ansible.com/ansible/latest/galaxy/user_guide.html#installing-multiple-roles-from-a-file) 一文。

> 在 Python 的世界裡，我們可藉由 `requirements.txt` 批次下載 pip 套件，而在 Ansible 的世界裡則是 `requirements.yml`。

```
$ ansible-galaxy install -f -p roles -r requirements.yml
```

#### 使用 Vagrant 建立開發環境

由於這次的 `Vagrantfile` 有設置 provision (配置) ansible 的語法，故使用 `vagrant up` 時會一併執行 playbook。詳情請參考「[04. 怎麼用 Vagrant 練習 Ansible？](/04.how-to-practive-the-ansible-with-vagrant.md)」一文。

1. 觀看 Vagrantfile 內容。

```ruby
$ cat Vagrantfile
# -*- mode: ruby -*-

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/trusty64"
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "1024"
  end
  config.vm.provision "ansible" do |ansible|
    ansible.playbook = "setup.yml"
    ansible.sudo = true
    #ansible.verbose = "vvv"
  end
end

# vi: set ft=ruby :
```

#### 執行 Playbooks

1. 啟用虛擬機並執行 Playbook。

```
$ vagrant up
```

![2016-12-23-ansible-testlink-1.gif](/files/-LpvdLFFkpB77img04BA)

1. 若過程中有問題，可使用 `provision` 重新執行 Ansible。

```
$ vagrant provision
```

1. 執行完畢後，開啟瀏覽器 (Browsers) 並進入 TestLink 網站 (<http://192.168.33.10>)，其帳號密碼皆為 `admin`。

![2016-12-23-ansible-testlink-2.gif](/files/-LpvdGgC-ZIwkmmzMxES)

#### TestLink Playbooks 架構解說

```
$ tree -L 2
.
├── README.md
├── Vagrantfile
├── defaults
│   └── main.yml            # main vars.
├── handlers
│   └── main.yml            # main handler.
├── requirements.yml        # for Roles.
├── roles
│   ├── chusiang.php7
│   ├── geerlingguy.mysql
│   └── williamyeh.nginx
├── setup.yml               # main playbook.
├── tasks
│   ├── check.yml
│   ├── main.yml            # main task.
│   ├── setting_nginx.yml
│   ├── setting_php-fpm.yml
│   ├── setting_testlink.yml
│   └── setup_testlink.yml
└── templates
    ├── config_db.inc.php.j2
    ├── nginx-testlink.conf.j2
    ├── php7-cli.ini.j2
    └── php7-fpm.ini.j2

8 directories, 16 files
```

1. `README.md`：可先從這裡取得較詳細的資訊。
2. `requirements.yml`：這裡定義了相依的 Roles。

```yaml
$ cat requirements.yml
# Nginx 1.10
- src: williamyeh.nginx
  path: roles/

# PHP 7
- src: chusiang.php7
  path: roles/

# MySQL 5.6
- src: geerlingguy.mysql
  path: roles/
```

1. `setup.yml`：前面提到 Vagrant provision 進入點是這裡，故我們可從這個 playbook 了解主要架構。

```yaml
$ cat setup.yml
01 #!/usr/bin/env ansible-playbook
02
03 ---
04 - name: play 'setup testlink'
05   hosts: all
06   become: true
07
08   vars_files:
09     - defaults/main.yml
10
11   roles:
12     - williamyeh.nginx
13     - chusiang.php7
14     - {
15         role: geerlingguy.mysql,
16         mysql_packages: ['mysql-server-5.6', 'mysql-client-5.6','python-mysqldb'],
17       }
18
19   tasks:
20     - name: include main task
21       include: tasks/main.yml
22
23     - name: include check task
24       include: tasks/check.yml
25
26   handlers:
27     - include: handlers/main.yml
28
29 # vim:ft=yaml.ansible:
```

* 在第 6 行裡，用了 `become: yes` 來取得 root 權限。
* 在第 8, 9 行裡，載入了定義好的 `defaults/main.yml` 變數檔案，這裡宣告了所有會用到的變數。
* 在第 11-17 行裡，載入了 Nginx, MySQL 和 PHP 的 Roles。
* 在第 20, 21 行裡，載入了主要的 tasks。
* 在第 23, 24 行裡，載入了檢查用的 tasks。
* 在第 26, 27 行裡，載入了主要的 handler。

1. `defaults/main.yml`：覆蓋 Roles 預設變數和 TestLink 會用到的相關變數皆宣告於此。
2. `tasks/`
3. `main.yml`：tasks 的主要進入點，並藉由它載入預設執行的 tasks。

   ```yaml
   $ cat tasks/main.yml
   ---
   # tasks file for testlink

   - name: setup testlink
     include: setup_testlink.yml

   - name: setting php-fpm
     include: setting_php-fpm.yml

   - name: setting nginx
     include: setting_nginx.yml

   - name: setting testlink
     include: setting_testlink.yml

   # vim:ft=yaml.ansible:
   ```
4. `setup_testlink.yml`：所有關於安裝 TestLink 會用到 tasks。
5. `setting_php-fpm.yml`：設定 PHP 的 tasks。
6. `setting_nginx.yml`：設定 Nginx 的 tasks。
7. `setting_testlink.yml`：設定 TestLink 的 tasks。
8. `check.yml`：檢查狀態用的 tasks。
9. `templates/`
10. `config_db.inc.php.j2`：TestLink 的 Database 設定檔模板。
11. `nginx-testlink.conf.j2`：Nginx 設定檔模板。
12. `php7-cli.ini.j2`：php7-cli 設定檔模板。
13. `php7-fpm.ini.j2`：php7-fpm 設定檔模板。
14. `handlers/main.yml`：主要的 handler，主要用來重新啟動 php-fpm 和 nginx。

```yaml
$ cat handlers/main.yml
---
# handlers file for testlink

- name: restart php-fpm
  service: name=php7.0-fpm enabled=yes state=restarted

- name: restart nginx
  service: name=nginx enabled=yes state=restarted
```

以上，當我們整合好 Roles 後，只需撰寫部署 TestLink 的 Playbooks 即可。仔細算一算這份範例的 Tasks 行數加起來還不到 220 行呢！

```
$ wc -l setup.yml tasks/*
      29 setup.yml
      42 tasks/check.yml
      16 tasks/main.yml
      25 tasks/setting_nginx.yml
      18 tasks/setting_php-fpm.yml
      11 tasks/setting_testlink.yml
      78 tasks/setup_testlink.yml
     219 total
```

### 後語

原先凍仁想從實作環境、建立 Playbooks、下載 Roles ... 等手把手一步步帶領著大家，但事後發現成效不佳，無法逐一說明，所以才會改用重點式介紹。

若您實作後無法正常執行，可於下方留言給凍仁，或至 [GitHub](https://github.com/chusiang/automate-with-ansible) 開 [issues](https://github.com/chusiang/automate-with-ansible/issues)。

### 相關連結

* [22. 怎麼用 Roles 部署 LNMP 網頁應用程式？(上)](/22.how-to-setup-lnmp-webapp-with-roles-1.md)
