※当サイトの記事には、広告・プロモーションが含まれます。

Ansibleのダブルクォーテーション問題で結局のところ正規表現を使うしかないのか...

gigazine.net

Wikipediaは世界最大のオンライン百科事典であり、世界中のボランティア編集者によって日々膨大な項目が編集されていますが、中には編集者が特定の政治的思想に偏った記述をしたり、事実と反する内容を記載したりして編集合戦に発展するケースもあります。海外メディアのBloombergが、「イスラエルとハマスの戦争に関するWikipediaのページで、編集者同士の争いが起きている」と報じました。

Wikipediaでイスラエルとハマスの戦争の記事を巡って激しい編集合戦が起きている - GIGAZINE

Wikipediaにおける論争について裁定を下す裁定委員会は2025年1月、イスラエルパレスチナに関するWikipediaの項目で、「ソックパペット(多重アカウント)による編集」が問題になっていると報告しました。裁定委員会によると、イスラエルパレスチナに関するトピックでは、メインスペースの編集の約7%が既知の多重アカウントによって行われており、政治的な論争の場になっているとのこと。

Wikipediaでイスラエルとハマスの戦争の記事を巡って激しい編集合戦が起きている - GIGAZINE

⇧ システムを管理するコスト的に「性善説」で考えたくなるのは分からないのでもないが、「性悪説」で考えていかないと駄目なんでしょうね...

一部の身勝手な人たちが、やったもん勝ちで台無しにしてしまう構造、どうにかして欲しい...

とりあえず、

東日本大震災(ひがしにほんだいしんさい)は、2011年平成23年)3月11日14時46分に発生した東北地方太平洋沖地震およびこれに伴う福島第一原子力発電所事故放射能汚染)による大規模な地震災害(震災)である

東日本大震災 - Wikipedia

東日本各地での大きな揺れや、大津波火災などにより、東北地方を中心に12都道府県で2万2,325名の死者・行方不明者が発生した(震災関連死を含む)。これは明治時代以降の日本地震被害としては関東大震災明治三陸地震に次ぐ被害規模である(震災関連死を除いた比較)

東日本大震災 - Wikipedia

この地震では緊急地震速報が発表された。

東日本大震災 - Wikipedia

発生した日付から、3.11(さんてんいちいち、もしくは、さんいちいちと称することもある。英称は Great East Japan Earthquake など

東日本大震災 - Wikipedia

Wikipediaの情報が正しいとすると、14年経ったんですね...

日本の未来が明るくないということだけが分かっているのだが、震災で犠牲になられた方には日本の惨状を聞かせられないよね...

Ansibleのダブルクォーテーション問題で結局のところ正規表現を使うしかないのか...

前回、

ts0818.hatenablog.com

⇧「YAMLファイル」の「value」部分のダブルクォーテーション勝手に消される問題があって、どう考えてもバグっぽいのだが、「Ansible」側で対応してくれ無さそうな気がするので、力業で何とかするしかないということで、ChatGPT氏に質問したところ、「正規表現」を提案されたので、備忘録として書き留めておく。

 

■/home/ts0818/ansible/roles/modify_yaml/tasks/main.yml

---
- name: YAMLファイルのキー値を差し替えて対象ホストに配置
  block:
    - name: ファイル1を対象ホストにコピー
      ansible.builtin.copy:
        src: '/home/ts0818/work/app/config/config.yml'  # ローカルのファイル1
        dest: '/tmp/file1.yml'  # 対象ホストに配置する場所
        owner: root
        group: root
        mode: '0644'

    - name: ファイル1を対象ホストから読み込む
      ansible.builtin.slurp:
        src: '/tmp/file1.yml'
      register: file1_slurp

    - name: ファイル1の内容をYAMLに変換
      ansible.builtin.set_fact:
        file1_content: "{{ file1_slurp.content | b64decode | from_yaml }}"

    - name: ファイル1の内容を確認する
      ansible.builtin.debug:
        msg: "file1_content {{ file1_content | to_nice_yaml(sort_keys=False) }}"

    - name: 変数展開
      ansible.builtin.template:
        src: /home/ts0818/work/ansible/inventory/host_vars/nijyo/config.yml
        dest: /tmp/file2.yml

    - name: ファイル2を対象ホストから読み込む
      ansible.builtin.slurp:
        src: '/tmp/file2.yml'
      register: file2_slurp

    - name: ファイル2の内容をYAMLに変換
      ansible.builtin.set_fact:
        file2_content: "{{ file2_slurp.content | b64decode | from_yaml }}"

    # - name: ファイル2を読み込む
    #   ansible.builtin.set_fact:
    #     file2_content: "{{ lookup('file', '/home/ts0818/work/ansible/inventory/host_vars/nijyo/expand_config.yml') | from_yaml }}"

    - name: ファイル2の内容を確認する
      ansible.builtin.debug:
        msg: "file2_content {{ file2_content | to_nice_yaml(sort_keys=False)  }}"

    - name: 共通のキーをファイル2の値で差し替え、残りはファイル1の値を使用
      ansible.builtin.set_fact:
        merged_content: >
          {{ file1_content | combine(file2_content, recursive=True) }}

    # - name: ダブルクォーテーション付与
    #   ansible.builtin.lineinfile:
    #     path: /tmp/file1.yml
    #     regexp: '^{{ item.key }}='
    #     line: "{{ item.key }}={% if item.value != 'null' %}'{{ item.value }}'{% else %}{{ item.value }}{% endif %}"
    #     create: yes
    #   loop: "{{ merged_content | dict2items }}"

    - name: 更新用のファイルの内容を確認する
      ansible.builtin.debug:
        msg: "merged_content {{ merged_content | to_nice_yaml(sort_keys=False)  }}"

    - name: 変更後の内容を対象ホストに書き戻す
      ansible.builtin.copy:
        dest: '/tmp/file1.yml'  # 変更後のファイル1を上書き
        content: "{{ merged_content | to_nice_yaml(sort_keys=False)  }}"
        owner: root
        group: root
        mode: '0644'

    - name: ダブルクォーテーション付与
      ansible.builtin.replace:
        dest: /tmp/file1.yml
        regexp: '(\S+\s*:\s*)(?!null|$)(\S+)(?=\n|$)'
        replace: '\1"\2"'

    # - name: 対象ホストに変更後のファイル1を最終的な場所に移動
    #   block:
    #     - name: ファイルの更新日時(更新前)
    #       ansible.builtin.stat:
    #         path: /home/vagrant/file1.yml
    #       register: file_stat_before

    #     - name: ファイルをコピー(リモート内)
    #       ansible.builtin.copy:
    #         remote_src: true
    #         src: /tmp/file1.yml
    #         dest: /home/vagrant/file1.yml
    #         force: true

    #     - name: ファイルの更新日時(更新後)
    #       ansible.builtin.stat:
    #         path: /home/vagrant/file1.yml
    #       register: file_stat_after

    #     - name: ファイルの更新前後の差分をテーブル形式でデバッグログに出力
    #       ansible.builtin.debug:
    #         msg: |
    #           +---------------------+---------------------+---------------------+---------------------+---------------------+
    #           |       項目          |   更新前の状態      |   更新後の状態      |   差分              |
    #           +---------------------+---------------------+---------------------+---------------------+---------------------+
    #           | atime               | {{ file_stat_before.stat.atime }} | {{ file_stat_after.stat.atime }} | {{ file_stat_after.stat.atime | int - file_stat_before.stat.atime | int }} |
    #           | ctime               | {{ file_stat_before.stat.ctime }} | {{ file_stat_after.stat.ctime }} | {{ file_stat_after.stat.ctime | int - file_stat_before.stat.ctime | int }} |
    #           | mtime               | {{ file_stat_before.stat.mtime }} | {{ file_stat_after.stat.mtime }} | {{ file_stat_after.stat.mtime | int - file_stat_before.stat.mtime | int }} |
    #           | size                | {{ file_stat_before.stat.size }}  | {{ file_stat_after.stat.size }}  | {{ file_stat_after.stat.size | int - file_stat_before.stat.size | int }}  |
    #           | uid                 | {{ file_stat_before.stat.uid }}   | {{ file_stat_after.stat.uid }}   | N/A                 |
    #           | gid                 | {{ file_stat_before.stat.gid }}   | {{ file_stat_after.stat.gid }}   | N/A                 |
    #           | mode                | {{ file_stat_before.stat.mode }}  | {{ file_stat_after.stat.mode }}  | N/A                 |
    #           +---------------------+---------------------+---------------------+---------------------+---------------------+

    #     - name: /tmpディレクトリに配置していた一時ファイルを削除
    #       ansible.builtin.file:
    #         path: /tmp/file1.yml
    #         state: absent

    - name: 対象ホストに変更後のファイル1を最終的な場所に移動
      block:
        - name: ファイルの更新日時(更新前)
          ansible.builtin.stat:
            path: /home/vagrant/file1.yml
          register: file_stat_before

        - name: ファイルの更新
          ansible.builtin.command: |
            mv /tmp/file1.yml /home/vagrant/file1.yml
    #        creates: /home/vagrant/file1.yml

        - name: ファイルの更新日時(更新後)
          ansible.builtin.stat:
            path: /home/vagrant/file1.yml
          register: file_stat_after

        - name: ファイルの更新前後の差分をテーブル形式でデバッグログに出力
          ansible.builtin.debug:
            msg: |
              +---------------------+---------------------+---------------------+---------------------+---------------------+
              |       項目          |   更新前の状態      |   更新後の状態      |   差分              |
              +---------------------+---------------------+---------------------+---------------------+---------------------+
              | atime               | {{ file_stat_before.stat.atime }} | {{ file_stat_after.stat.atime }} | {{ file_stat_after.stat.atime | int - file_stat_before.stat.atime | int }} |
              | ctime               | {{ file_stat_before.stat.ctime }} | {{ file_stat_after.stat.ctime }} | {{ file_stat_after.stat.ctime | int - file_stat_before.stat.ctime | int }} |
              | mtime               | {{ file_stat_before.stat.mtime }} | {{ file_stat_after.stat.mtime }} | {{ file_stat_after.stat.mtime | int - file_stat_before.stat.mtime | int }} |
              | size                | {{ file_stat_before.stat.size }}  | {{ file_stat_after.stat.size }}  | {{ file_stat_after.stat.size | int - file_stat_before.stat.size | int }}  |
              | uid                 | {{ file_stat_before.stat.uid }}   | {{ file_stat_after.stat.uid }}   | N/A                 |
              | gid                 | {{ file_stat_before.stat.gid }}   | {{ file_stat_after.stat.gid }}   | N/A                 |
              | mode                | {{ file_stat_before.stat.mode }}  | {{ file_stat_after.stat.mode }}  | N/A                 |
              +---------------------+---------------------+---------------------+---------------------+---------------------+

        - name: 一時ファイル削除
          ansible.builtin.file:
            path: "/tmp/file2.yml"
            state: absent    

⇧で、他は前回と変わらず。

「Ansible」の「Playbook」を実行する。

⇧ とりあえず、

  1. 何も設定していない
  2. null

以外の場合に、「ダブルクォーテーション」で囲むとしているので、数値とか関係なく全ての「value」が「ダブルクォーテーション」で囲まれることにはなってしまう...

とは言え、どう実装すれば良いか分からない...

何と言うか「Ansible」側のバグを考慮しないといけないのは理不尽過ぎるんだが...

「Ansible」の「モジュール」がイケてなさ過ぎて、辛過ぎるんだが...

毎度モヤモヤ感が半端ない…

今回はこのへんで。