Ansible 外掛系統是其靈活性和擴充套件性的根本,允許開發者根據自身需求定製功能。本文從環境準備開始,逐步講解如何建立過濾器和查詢外掛,並著重說明瞭測試方法和整合步驟。此外,文章還提供了提交自定義外掛到 Ansible 社群的流程,鼓勵讀者貢獻自己的程式碼。理解 Ansible 外掛機制對於提升自動化效率至關重要,能更好地管理和維護複雜的基礎架構。

建立自定義外掛

本章節將引導您建立自己的外掛。雖然範例將保持簡單,但它將幫助您瞭解外掛開發的原理和最佳實踐,並為您建立更複雜的外掛奠定基礎。我們還將展示如何將這些外掛與您的 playbook 整合,並在準備就緒時提交給官方 Ansible 專案。

開發環境準備

Ansible 是用 Python 編寫的,其外掛也不例外。因此,您需要使用 Python 編寫您的外掛。要開始開發自己的外掛,您需要確保已安裝 Python 和一些必要的工具。如果您已經在開發機器上執行 Ansible,那麼您可能已經安裝了所需的套件。

安裝必要套件

在不同作業系統上安裝所需套件的命令如下:

  • 在 Fedora 上:

    $ sudo dnf install python python-devel
    
  • 在 CentOS 上:

    $ sudo yum install python python-devel
    
  • 在 Ubuntu 上:

    $ sudo apt-get update
    $ sudo apt-get install python-pip python-dev build-essential
    
  • 在 macOS 上使用 Homebrew:

    $ brew install python
    

克隆 Ansible Git 倉函式庫

安裝完所需的套件後,您需要將 Ansible 的 Git 倉函式庫克隆到本地機器。因為在模組開發過程中,我們需要使用到其中的一些有價值的指令碼。使用以下命令將 Ansible 倉函式庫克隆到當前目錄:

$ git clone https://github.com/ansible/ansible.git
$ cd ansible

建立過濾器外掛

對於我們的簡單範例,我們將建立一個過濾器外掛,用於替換給定的字串。根據官方 Ansible 檔案,過濾器外掛可能是最容易編寫的外掛之一,因為它們對檔案的要求不像模組那樣嚴格。

編寫過濾器外掛程式碼

首先,建立一個名為 custom_filter.py 的檔案,並將其放在與 playbook 同一目錄下的 filter_plugins 目錄中。

  1. 新增檔案頭:在外掛檔案的開頭新增一個頭部,以表明外掛的作者和許可證。

    # (c) 2020, James Freeman <james.freeman@example.com>
    # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
    
  2. 定義過濾器函式:新增一個簡單的 Python 函式。在我們的例子中,使用 Python 的 replace 函式來替換字串中的某個子串。

    def improve_automation(a):
        return a.replace("Puppet", "Ansible")
    
  3. 建立 FilterModule 物件:建立一個 FilterModule 類別的物件,並定義一個 filters 方法傳回我們的過濾器函式。

    class FilterModule(object):
        '''improve_automation filters'''
        def filters(self):
            return {'improve_automation': improve_automation}
    

#### 內容解密:

  • improve_automation 函式接收一個字串 a,並使用 replace 方法將其中的 “Puppet” 替換為 “Ansible”,傳回替換後的新字串。
  • FilterModule 是 Ansible 用於識別過濾器外掛的類別。透過定義 filters 方法,我們可以告訴 Ansible 可用的過濾器有哪些。

測試過濾器外掛

由於 Ansible 中沒有特定的測試工具來測試外掛,因此我們將透過編寫一個簡單的 playbook 來測試我們的外掛。

---
- name: Play to demonstrate our custom filter
  hosts: frontends
  gather_facts: false
  vars:
    statement: "Puppet is an excellent automation tool!"
  tasks:
    - name: make a statement
      debug:
        msg: "{{ statement | improve_automation }}"

#### 內容解密:

  • 此 playbook 定義了一個名為 statement 的變數,其值為 “Puppet is an excellent automation tool!"。
  • 使用 debug 模組列印預出應用了 improve_automation 過濾器後的 statement 變數值。預期輸出應為 “Ansible is an excellent automation tool!"。

建立與使用Ansible外掛

自定義過濾器外掛的建立與應用

在前一章中,我們探討瞭如何建立和利用自定義模組於Ansible中。接下來,我們將深入瞭解如何建立和使用自定義的過濾器外掛(filter plugin)。過濾器外掛是用於處理和轉換資料的工具,它們可以在Ansible playbook中被呼叫,以實作對資料的靈活操作。

目錄結構與外掛檔案

為了使Ansible能夠識別和載入我們的自定義過濾器外掛,我們需要在專案目錄下建立一個名為filter_plugins的子目錄,並在其中放置我們的外掛檔案。假設我們要建立一個名為custom_filter.py的外掛檔案,其目錄結構應該如下所示:

.
├── filter_plugins
│   ├── custom_filter.py
├── hosts
├── myplugin.yml

建立自定義過濾器外掛

下面是一個簡單的例子,展示如何建立一個名為improve_automation的過濾器外掛,用於替換字串中的特定內容。

# custom_filter.py 中的內容
def improve_automation(statement):
    return statement.replace('Puppet', 'Ansible')

class FilterModule(object):
    def filters(self):
        return {
            'improve_automation': improve_automation
        }

在Playbook中使用自定義過濾器外掛

myplugin.yml playbook中,我們可以這樣使用剛建立的improve_automation過濾器:

---
- name: Play to demonstrate our custom filter
  hosts: frt01.example.com
  tasks:
    - name: make a statement
      debug:
        msg: "{{ 'Puppet is an excellent automation tool!' | improve_automation }}"

執行Playbook並檢視結果

執行以下命令執行我們的playbook:

$ ansible-playbook -i hosts myplugin.yml

輸出結果應該類別似於:

PLAY [Play to demonstrate our custom filter]
***********************************
TASK [make a statement]
********************************************************
ok: [frt01.example.com] => {
    "msg": "Ansible is an excellent automation tool!"
}
PLAY RECAP
*********************************************************************
frt01.example.com : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

內容解密:

  1. 我們的自定義過濾器外掛成功地將變數中的"Puppet"字串替換為"Ansible”。
  2. 這個例子展示瞭如何透過簡單的Python程式碼和適當的目錄結構,建立並使用自定義過濾器外掛。
  3. 開發更複雜和有用的過濾器外掛是完全可行的,只需遵循相關的檔案規範和錯誤處理機制。

建立查詢(Lookup)外掛

建立查詢外掛比建立過濾器外掛需要更多的步驟和考慮。查詢外掛允許你從外部源取得資料。下面,我們將以建立一個名為firstchar的查詢外掛為例,講解如何實作。

查詢外掛的結構與實作

首先,建立一個名為lookup_plugins的目錄,並在其中新增firstchar.py檔案。該外掛將讀取檔案的第一個字元。

# firstchar.py 中的內容
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

DOCUMENTATION = """
lookup: firstchar
author: James Freeman <james.freeman@example.com>
version_added: "2.9"
short_description: read the first character of file contents
description:
- This lookup returns the first character of the contents from a file on the Ansible controller's file system.
options:
  _terms:
    description: path(s) of files to read
    required: True
notes:
- if read in variable context, the file can be interpreted as YAML if the content is valid to the parser.
- this lookup does not understand 'globing', use the fileglob lookup instead.
"""

EXAMPLES = """
- debug: msg="the first character in foo.txt is {{lookup('firstchar', '/etc/foo.txt') }}"
"""

RETURN = """
_raw:
  description:
    - first character of content of file(s)
"""

from ansible.errors import AnsibleError, AnsibleParserError
from ansible.plugins.lookup import LookupBase
from ansible.utils.display import Display

display = Display()

class LookupModule(LookupBase):
    def run(self, terms, variables=None, **kwargs):
        # 實作讀取檔案第一個字元的邏輯
        pass

內容解密:

  1. DOCUMENTATIONEXAMPLESRETURN區塊對於檔案和示例至關重要,它們幫助其他使用者瞭解如何使用你的外掛。
  2. 查詢外掛需要實作LookupBase類別,並覆寫run方法來執行實際的資料取得邏輯。
  3. 正確的錯誤處理和檔案對於建立有用的查詢外掛是必不可少的。

自定義 Ansible 查詢外掛的建立與測試

在 Ansible 中,查詢外掛(lookup plugin)是一種強大的工具,能夠讓使用者從外部源取得資料並在 Playbook 中使用。本章節將指導您如何建立一個自定義的查詢外掛,並將其整合到 Ansible 中。

建立自定義查詢外掛

首先,我們需要定義一個名為 LookupModule 的類別,並實作 run 方法,這是 Ansible 查詢外掛框架所要求的。這個方法將會接收檔名作為引數,並傳回檔案內容的第一個字元。

from ansible.plugins.lookup import LookupBase
from ansible.errors import AnsibleError, AnsibleParserError

class LookupModule(LookupBase):
    def run(self, terms, variables=None, **kwargs):
        ret = []
        for term in terms:
            display.debug("File lookup term: %s" % term)
            lookupfile = self.find_file_in_search_path(variables, 'files', term)
            display.vvvv(u"File lookup using %s as file" % lookupfile)
            try:
                if lookupfile:
                    contents, show_data = self._loader._get_file_contents(lookupfile)
                    ret.append(contents.rstrip()[0])
                else:
                    raise AnsibleParserError()
            except AnsibleParserError:
                raise AnsibleError("could not locate file in lookup: %s" % term)
        return ret

程式碼解析:

  • 我們首先匯入必要的模組,包括 LookupBase 和錯誤處理類別。
  • LookupModule 類別繼承自 LookupBase,並實作 run 方法。
  • run 方法中,我們遍歷傳入的檔名列表,嘗試在指定的路徑中查詢檔案。
  • 找到檔案後,我們讀取其內容,並傳回第一個字元。

測試自定義查詢外掛

建立好查詢外掛後,我們需要測試它。為此,我們可以建立一個簡單的 Playbook,使用我們的自定義查詢外掛。

---
- name: Play to demonstrate our custom lookup plugin
  hosts: frontends
  gather_facts: false
  tasks:
    - name: make a statement
      debug:
        msg: "{{ lookup('firstchar', 'testdoc.txt')}}"

測試步驟:

  1. 將上述 Playbook 儲存為 myplugin2.yml
  2. 建立一個名為 testdoc.txt 的文字檔案,包含任意文字。
  3. 確保目錄結構正確,如下所示:
    .
    ├── hosts
    ├── lookup_plugins
    │   └── firstchar.py
    ├── myplugin2.yml
    └── testdoc.txt
    
  4. 執行 Playbook:ansible-playbook -i hosts myplugin2.yml

如果一切正常,您應該會看到輸出結果是 testdoc.txt 檔案內容的第一個字元。

將自定義外掛整合到 Ansible 原始碼中

如果您希望將自定義外掛提交到 Ansible 專案或在自己的 Ansible 分支中使用,您需要將外掛程式碼複製到適當的目錄中。

操作步驟:

  1. 克隆 Ansible 的 GitHub 倉函式庫:git clone https://github.com/ansible/ansible.git
  2. 將您的外掛程式碼複製到相應的外掛目錄,例如:cp ~/firstchar.py ./lib/ansible/plugins/lookup/
  3. 使用 ansible-doc 命令測試檔案是否正確渲染:ansible-doc -t lookup firstchar

此時,您應該能夠看到您的自定義查詢外掛的檔案。

Ansible 外掛開發與分享

外掛開發的重要性與實踐

Ansible 外掛是擴充套件 Ansible 功能的核心元件,無論是模組還是各種外掛,都能輕易地為 Ansible 新增新的功能。本章節將探討 Ansible 外掛的開發與分享,幫助讀者掌握如何建立與提交高品質的外掛。

開發外掛的基本原則

在開發 Ansible 外掛時,需特別注意錯誤處理與檔案品質。所有外掛必須傳回 Unicode 字串,以確保能正確透過 jinja2 過濾器。此外,外掛開發與模組開發有許多相似之處,例如錯誤處理和檔案標準。

建立與提交外掛的流程

若希望將自定義外掛提交至 Ansible 專案,需遵循以下步驟:

  1. Fork Ansible 官方倉函式庫:登入 GitHub 帳號並 Fork https://github.com/ansible/ansible.gitdevel 分支。
  2. 克隆倉函式庫到本地:使用 git clone 命令將 Fork 的倉函式庫克隆到本地。
    $ git clone https://github.com/<your GitHub account>/ansible.git
    
  3. 新增外掛程式碼:將外掛程式碼複製到對應的 plugins/ 目錄下,並執行 git addgit commit
    $ cd ansible
    $ cp ~/ansible-development/plugindev/firstchar.py ./lib/ansible/plugins/lookup
    $ git add lib/ansible/plugins/lookup/firstchar.py
    $ git commit -m 'Added tested version of firstchar.py for pull request creation'
    
  4. 推播程式碼並建立 PR:將程式碼推播到 Fork 的倉函式庫,並在 GitHub 上建立 Pull Request。
    $ git push
    

查詢與檔案

Ansible 提供了 ansible-doc 命令來查詢外掛的檔案。例如,列出所有 cache 外掛的名稱可以使用:

$ ansible-doc -t cache -l

常見問題與解答

  1. 如何列出所有 cache 外掛的名稱?

    • 正確答案:D) ansible-doc -t cache -l
  2. 在 lookup 外掛中,需要新增哪個類別來包含主要的外掛程式碼?

    • 正確答案:A) LookupModule
  3. 使用 Python 建立自定義外掛是否需要安裝 Python 及相關依賴?

    • 正確答案:A) True

在下一章中,我們將探討編寫高品質 Ansible Playbooks 的最佳實踐,確保自動化程式碼的可維護性和高效性。

參考資料