Ansible 自動化部署工具

Ansible

前言:

Ansible 是和先前介紹的 Chef 一樣, DevOps 中用來快速部署 Server,實現 Infrastructure as Code 管控與設定 Server 的一套工具。

為什麼要介紹 Ansible 呢?

目前在 DevOps 管控設定的工具中,以 Puppe、ChefSaltAnsible 四者最有名,而 Puppe 跟 Chef 兩者概念上接近(基於 Ruby ), Salt 則與 Ansible 相近(基於 Python),在 2016 DevOps 的統計中,Ansible 是使用率相對是上升較快的一個工具,並且以簡單的特色為人喜愛。

基本上 Ansible 很多哲學上就是 python,Chef 就很像 ruby。

主要的優點如下:

  • 以 YML 格式編寫,容易上手與維護。
  • 完全使用 SSH 與遠端 Server 溝通。
  • 不需要中間代理。
  • 在 Client 端不需要安裝。

缺點如下:

  • 執行速度較慢。
  • 官方沒有一套簡易的教學(但也許是很簡單?)。

Ansible 使用教學:

1. 安裝 Ansible

  • 透過 apt(ubuntu):
sudo apt-get install -y ansible
  • 透過 yum:
sudo yum install ansible
  • Mac
brew install ansible

2. Ansible 基本檔案與概念介紹:

以下先簡單列出 Ansible 的一些用詞,後面會再用範例詳述。

  • ansible.cfg:Ansible 主要的設定檔。
  • Inventory:遠端 Server 的資訊。
  • Playbooks:我們會需要自動化的東西都會寫在裡面。(類似 Chef 中的 Recipe)
  • Task:單個需要自動化執行的程序。(類似 Chef Recipe中的一個 function )
  • Handler:用來觸發服務的狀態,例如:重啟,停止服務。
  • Role:用來把 Playbooks 跟其他相依檔案一起整合起來當成 module 使用。(類似 Chef 中的 Cookbooks)

3. 如何用 Ansible —— 以部署 Apache 為例(概略)

設定

首先,我們需要先建立一個 Ansible 的專案新目錄:

mkdir ansible-apache

然後到在目錄下

cd ~/ansible-apache/

初始化一個 Ansible 設定檔 ansible.cfg

[defaults]
hostfile = hosts # 設定 hostfile 為目錄下名稱為 hosts 檔案。

用來設定一些 Ansible 專案的一些檔案位置、參數或變數預設值。

Host 資訊

接著,我們創建一個 hosts 檔案來管理我們需要部署的 Server 資訊,這個檔案可以用中括號表示群組名稱,之後可以在 playbook 設定我們只要在哪一個群組執行就好。

[apache] # Group Name
server_ip ansible_ssh_user=username
ansible_ssh_private_key_file=key

上面例子需要填入實際的:

  • server_ip
  • username
  • key(如果是用 pem 認證 server 的話。)

再來,你可以用以下指令先測試是否可以與設定的主機連結:

ansible apache -m ping

若可以看到 success 訊息,就表示連線成功,ansible 可以 ssh 部署。

我們就可以開始建立一個 Playbook,安裝 apache

編寫 playbook 安裝 apache

在同樣目錄下,新增一個 apache.yml

---
- hosts: apache # 需要執行的主機
become: true # use sudo
tasks:
- name: install apache2
apt: name=apache2 update_cache=yes state=latest

其中,apt 參數裡的 update_cache yes 表示執行前確保有 apt-get update ,

然後,我們就可以透過以下指令安裝 apache 到 server:

ansible-playbook apache.yml

再來我們可以新增 task 和 handle,用來啟用 apache

---
- hosts: apache
sudo: yes
tasks:
- name: install apache2
apt: name=apache2 update_cache=yes state=latest

- name: enabled mod_rewrite
apache2_module: name=rewrite state=present
notify:
- restart apache2

handlers:
- name: restart apache2
service: name=apache2 state=restarted

一樣下指令

ansible-playbook apache.yml

就會更新遠端的 Server 狀態。

Ansible 內建提供 apt、copy、yum、git 等指令可以簡易描述我們希望 task 要做什麼事,同時也有 shell,可以直接輸入 shell script。

使用變數、模板

在 playbook 中,我們還可以使用 var、template 拆解與彈性化我們的 yml 檔案:

例如,apache 中我們會需要設定virtualhost.conf 這個檔案,我們可以就可以先建立一個 virtualhost.conf 在我們的目錄下

virtualhost.conf

<VirtualHost *:{{ http_port }}>
ServerAdmin webmaster@{{ domain }}
ServerName {{ domain }}
ServerAlias www.{{ domain }}
DocumentRoot /var/www/{{ domain }}
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

然後在 playbook 使用 var、template 將它 include,並用 src, dest 描述要複製到遠端哪一個檔案。

---
- hosts: apache
sudo: yes
vars:
http_port: 80
domain: example.com
tasks:
- name: install apache2
...
    - name: create virtual host file
template: src=virtualhost.conf dest=/etc/apache2/sites-available/{{ domain }}.conf

只要使用以上的東西,

我們就已經可以用 Ansible 部署一些簡單的環境設定流程了 :)

模組化

而當你需要部署更複雜的設定時,最好的方法是使用 Role 來模組化你的 Ansible 專案,例如需要部署 wordpress 我們需要先有 server、php、mysql、wordpress,我們就可以將你的 Ansible 專案變成以下結構:

[.]
|_ playbook.yml
|_ hosts
|_ [roles]
|_ [server]
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
|_ [php]
|_ ...
|_ [mysql]
|_ ...
|_ [wordpress]
|_ ...

這裡的每個 role 就是一個 app 的部分,裡面的檔案是上面 playbook 的細項(tasks、handler、vars…等),Ansible 會自動 include 對應的檔案,而你只需要在根目錄的 playbook.yml 中 include 需要的 roles 就可以。

- hosts: wordpress

roles:
- server
- php
- mysql
- wordpress

這樣我們就已經可以寫出部署大型應用的專案了!

From Chef to Ansible & Docker 補充:

補充幾個在 Chef 中對應到 Ansible 的東西

另外Ansible 官方似乎並沒有提供類似 kitchen 的東西,但有提供 check (Dry Run)機制,可以告訴你 playbook 執行後對遠端 Server 的變化,而不會真的改變遠端的 Server。

而關於 Docker官方在 playbook 有提供可以使用的指令,讓我們可以結合 Ansible 快速部署 Docker 在 Server 上(可以看參考資源)。

參考資源:

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.