てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] CSV ファイルを YAML ファイルに変換する

はじめに

以前の記事で、CSV ファイルをリストやディクショナリとして読み込む read_csv モジュールをご紹介しました。

tekunabe.hatenablog.jp

to_nice_yaml フィルターと組み合わせると、CSV ファイルを YAML ファイルに変換できます。

この記事では、簡単なサンプルでご紹介します。

  • 動作確認環境
    • Ansible 2.9.6

利用する CSV ファイル

今回はこんな CSV ファイルを利用します。1行目がヘッダーで、read_csv モジュールで読み込むと、ディクショナリのキーになります。

name,age,hobby
taro,50,baseball
jiro,40,swimming
saburo,30,ansible


Playbook サンプル

その1: ディクショナリのリストとして出力

CSV 1行を1つリストとして出力します。(説明が難しいのでサンプルをご参照ください・・)

- hosts: testsv
  gather_facts: no

  tasks:
    - name: read users.csv
      read_csv:
        path: users.csv   # CSV ファイル名
      register: users
      delegate_to: localhost  # ここを省略するとリモートのファイルを参照

    - name: convert to yaml
      copy:
        content: "{{ users.list | to_nice_yaml(indent=2) }}" # ポイント
        dest: users.yml   # 出力先 YAML ファイル名

こうなります。

- age: '50'
  hobby: baseball
  name: taro
- age: '40'
  hobby: swimming
  name: jiro
- age: '30'
  hobby: ansible
  name: saburo

その2 ディクショナリのディクショナリとして出力

リストではなく、指定したキーのディクショナリのディクショナリを出力します。

- hosts: testsv
  gather_facts: no

  tasks:
    - name: read users.csv
      read_csv:
        path: users.csv   # CSV ファイル名
        key: name         # ポイント1 
      register: users
      delegate_to: localhost  # ここを省略するとリモートのファイルを参照

    - name: debug csv
      copy:
        content: "{{ users.dict | to_nice_yaml(indent=2) }}"  # ポイント2 users.list ではなく users.dict
        dest: users.yml

read_csvkey で指定したフィールドをキーとした、ネストされたディクショナリになります。

jiro:
  age: '40'
  hobby: swimming
  name: jiro
saburo:
  age: '30'
  hobby: ansible
  name: saburo
taro:
  age: '50'
  hobby: baseball
  name: taro

その3 ディクショナリのディクショナリとして出力

その2をベースに、トップになにかルート要素的なキーを入れたいときの方法です。

- hosts: testsv
  gather_facts: no

  tasks:
    - name: read users.csv
      read_csv:
        path: users.csv   # CSV ファイル名
        key: name         # ポイント1 
      register: users
      delegate_to: localhost  # ここを省略するとリモートのファイルを参照

    - name: debug csv
      copy:
        content: "{{ root | to_nice_yaml(indent=2) }}" # ポイント2 users.list ではなく users.dict
        dest: users.yml
      vars:
        root:     
          users: "{{ users.list }}"   # ポイント3 トップのキーを仕込む

トップに users が入った形になります。

users:
  jiro:
    age: '40'
    hobby: swimming
    name: jiro
  saburo:
    age: '30'
    hobby: ansible
    name: saburo
  taro:
    age: '50'
    hobby: baseball
    name: taro


おわりに

read_csv モジュールも、to_nice_yaml フィルター も便利ですね。

もっと柔軟にするには、 read_csv で読み込んだ後に、template モジュールで整えるのもいいかもしれません。