小技巧 - 處理 JSON 檔案
現在有不少服務都是使用 JSON 作為設定檔,所以常常會需要讀取 JSON 格式的設定檔,修改內容值後再寫回,那麼用 Ansible 的話,該怎麼做呢?
在 Ansible 裡,我們可以使用 filter 來處理,主要有這三個 filter :
- from_json
- to_json
- combine
from_json,是解析 JSON 格式字串,並轉換為變數。像下面這樣寫,就可以將 JSON 格式字串轉為變數,放到 server_conf 變數裡。
- set_fact:
server_conf: "{{ json_string | from_json }}"
to_json 是將變數轉換為 JSON 格式的字串。像下面這樣寫,就可以將變數轉為 JSON 格式的字串,並寫到 /tmp/foo.json
- copy:
content: "{{ server_conf | to_json }}"
dest: "/tmp/foo.json"
combine 則是跟變數做合併。
- name: Combine example
vars:
foo_data:
id: 100
name: "John Doe"
set_fact:
foo_data: '{{ foo_data | combine({"age":25,"name":"Mary Jane"}) }}'
以上面的例子來說,foo_data 的內容會變為
foo_data:
id: 100
name: "Mary Jane"
age: 25
除了多了 age 之外,name 也變為 Mary Jane 。
下面就來看看怎麼使用。
先說明一下環境:
- 連線主機上有 /etc/server.json 檔案
- /etc/server.json 裡的內容是
{
"foo": "2021-04-10T08:04:12Z",
"force": true,
"id": 1,
"name": "server.json"
}
完整的 Playbook 範例如下:
---
- name: 讀取連線主機上的 server.json,讀取指定內容值、修改後寫回
hosts: all
vars:
server_conf_file: "/etc/server.json"
tasks:
- name: Read {{ server_conf_file }}
shell: cat {{ server_conf_file }}
register: shell_result
- name: Parase JSON text to a variable
set_fact:
server_conf: "{{ shell_result.stdout | from_json }}"
- name: Display variable
debug:
var: server_conf
- name: Modify "foo" in server_conf
set_fact:
server_conf: '{{ server_conf | combine({"foo":ansible_date_time.iso8601}) }}'
- name: Display variable again
debug:
var: server_conf
- name: Write back
copy:
content: "{{ server_conf | to_json }}"
dest: "{{ server_conf_file }}"
- name: Display file content
shell: cat {{ server_conf_file }}
register: shell_result
- name: Display shell_result
debug:
var: shell_result.stdout
看完這個例子,相信你已經學會怎麼處理 JSON 格式的檔案了。
附帶一提,YAML 格式也可以用相同的方式來處理,因為有 from_yaml 跟 to_yaml 這兩個 filter,把 from_json / to_json 替換為 from_yaml / to_yaml 就可以啦。
參考資料: