天天看點

Ansible11:使用lookup生成變量

目錄

  • 簡單說明
  • 1. file
  • 2. pipe
  • 3. env
  • 4. template
  • 5. csvfile
  • 6. redis_kv
  • 7. etcd
  • 8. password
  • 9. dnstxt

在通常情況下,所有的配置資訊都會被作為ansible的變量儲存了,而且可以儲存在ansible允許定義變量的各種地方,諸如vars區段,

vars_files

加載的檔案中,以及host_vars和group_vars目錄中。

但在有些時候,我們希望從諸如文本檔案或者.csv檔案中收集資料作為ansible的變量,或者直接擷取某些指令的輸出作為ansible的變量,甚至從redis或者etcd這樣的鍵值存儲中取得相應的值作為ansible的變量。這個時候,我們就需要通過ansible的lookup插件來從這些資料源中讀取配置資料,傳遞給ansbile變量,并在playbook或者模闆中使用這些資料。

ansible支援一套從不同資料源擷取資料的lookup,包括file, password, pipe, env, template, csvfile, dnstxt, redis_kv, etcd等

使用file lookup可以從文本檔案中擷取資料,并在這些資料傳遞給ansible變量,在task或者jinja2模闆中進行引用。下面是一個從文本檔案中擷取ssh公鑰并複制到遠端主機的示例:

- name: copy authorized_host file
  template: 
    src: authorized_keys.j2 
    dest: /home/deploy/.ssh/authrized_keys 
    owner: deploy
    group: deploy
    mode: 0600
           

authorized_keys.j2模闆檔案示例如下:

{{ lookup('file', '/users/breeze/.ssh/id_rsa.pub')}}


           

使用pipe lookup可以直接調用外部指令,并将指令執行的結果列印到标準輸出,作為ansible變量。下面的例子通過pipe調用date指令拿到一個以時間數字組成的字串

- name: Flamingo | Get release version
  set_fact:
    flamingo_release_version: "{{ lookup('pipe', 'date +%Y%m%d%H%M%SZ') }}"
           

env lookup實際就是擷取在控制主機上的某個環境變量的值。下面是一個讀取控制機上

$JAVA_HOME

變量值的示例:

- name: get JAVA_HOME
  debug: msg="{{ lookup('env', 'JAVA_HOME')}}"
           

template lookup可以指定一個jinja2模闆,然後傳回這個模闆中的變量被替換以後的結果。

假設我們有一個message.j2模闆,内容如下:

This host runs {{ ansible_distribution }}
           

定義一個如下的task:

- name: print message from template
  debug: msg="{{ lookup('template', 'message.j2')}}"
           

輸出的msg的結果如下:

This host runs CentOS
           

csvfile可以從.csv檔案中讀取一個條目。假設我們有如下示例的名為users.csv的檔案:

username,email
lorin,[email protected]
john,[email protected]
sue,[email protected]
           

下面是一個使用csvfile lookkup提取sue的電子郵件位址的task示例:

- name: get sue's email
  debug: msg="{{ lookup('csvfile','sue file=users.csv delimiter=, col=1')}}"
           

可以看到,一共向插件傳遞了四個參數:sue, file=users.csv, delimiter=,以及col=1。說明如下:

  • 第一個參數指定一個名字,該名字必須出現在其所在行的第0列,需要說明的是,如果指定的第一個參數名字在檔案中出現多次,則比對第一次出現的結果
  • 第二個參數指定csv檔案的檔案名
  • 第三個參數指定csv檔案的中條目的分隔符,
  • 第四個參數指定要取得哪一列的值,這一列正是第一個參數所在行的那一列的值

如果我們想要查找的使用者存儲在名為username的變量中,則可以使用"+"符号來連接配接username字串和其他的參數字串,來建構完整的參數字元串:

lookup('csvfile', username+'file=users.csv' delimiter=, col=1)
           

redis_kv lookup

可以直接從redis存儲中來擷取一個key的value,key必須是一個字元串,如同Redis GET指令一樣。需要注意的是,要使用

redis_kv lookup

,需要在主要端安裝python的redis用戶端,在centos上,軟體包為python-redis。

下面是一個在playbook中調用redis lookup的task,從本地的redis中取中一個key為weather的值:

- name: lookup value in redis
  debug: msg="{{ lookup('redis_kv', 'redis://localhost:6379,weather')}}"
           

其中URL部分如果不指定,該子產品會預設連接配接到

redis://localhost:6379

,是以實際上在上面的執行個體中,調用可以直接寫成如下:

{{ lookup('redis_kv', 'weather')}}
           

etcd是一個分布式的key-value存儲,通常被用于儲存配置資訊或者被用于實作服務發現。可以使用etcd lookup來從etcd中擷取指定key的value。

我們通過如下方法往一個etcd中寫入一個key:

curl -L http://127.0.0.1:4001/v2/keys/weather -XPUT -d value=sunny
           

定義一個調用etcd插件的task:

- name: look up value in etcd
  debug: msg="{{ lookup('etcd','weather')}}"
           

預設情況下,etcd lookup會在http://127.0.0.1:4001上查找etcd伺服器。但我們在執行playbook之前可以通過設定

ANSIBLE_ETCD_URL

環境變量來修改這個設定。

password lookup會随機生成一個密碼,并将這個密碼寫入到參數指定的檔案中。如下示例,建立一個名為bob的mysql使用者,并随機生成該使用者的密碼,并将密碼寫入到主要端的bob-password.txt中:

- name: create deploy mysql user
  mysql_user: name=bob password={{ lookup('password', 'bob-password,txt')}} priv=*.*:ALL state=present
           

dnstxt lookup用于擷取指定域名的TXT記錄。需要在主要端安裝python-dns。

使用方法如下:

- name: lookup TXT record
  debug: msg="{{ lookup('dnstxt', "aliyun.com") }}"
           

如果某一個主機有多個相關聯的TXT記錄,那麼子產品會把他們連在一起,并且每次調用時的連接配接順序可能不同

繼續閱讀