uuutee.log

Ansibleでテキスト置換を行ういくつかの方法

copy

  • destcontent を指定することでプレーンテキストを書き込むことができる
  • content の内容に変更がない場合は changed にならない。
- name: create a file
  copy:
    dest: /tmp/hello
    content: hello world

replace

This module will replace all instances of a pattern within a file. It is up to the user to maintain idempotence by ensuring that the same pattern would never match any replacements made.

パターンにマッチしたすべてのテキストを置換する。 regexp のパターンにマッチするテキストが存在するかによって冪等性が担保されている。

- replace:
  path: "/etc/httpd/vhosts.d/{{ item.website.user.name }}/{{ item.migration_src.domain }}.conf"
  regexp: '\<virtualhost \*\:80\="">'
  replace: '<virtualhost *:8080="">'
  backup: yes # backupする

regexp 内のエスケープする文字

(, ), [, ], ', /, .

regexp 自体のエスケープ

  • なし, '', ""
  • 基本なしで OK。クォートが含まれる場合はクォートをエスケープする
- replace:
  path: "/path/to/dest"
  regexp: dirname\(dirname\(\$_SERVER\[\'DOCUMENT_ROOT\'\]\)\)\.\'\/private\/config\.php\'
  replace: "$_SERVER['DOCUMENT_ROOT'] . '/module/config/database.php'"

- replace:
  path: "/path/to/dest"
  regexp: \(\'DB_USER\', SERVER_USER\)
  replace: ('DB_USER', PGSQL_USER)

- replace:
  path: "/path/to/dest"
  regexp: \(\'DB_PASSWORD\', SERVER_PASS\)
  replace: ('DB_PASSWORD', PGSQL_PASS)

- replace:
  path: "/path/to/dest"
  regexp: \(\'DB_SERVER\', SERVER_HOST\)
  replace: ('DB_SERVER', PGSQL_HOST)

# パターンマッチする
- replace:
  path: "/path/to/dest"
  regexp: \(\'DB_NAME\', .+?\)
  replace: ('DB_NAME', PGSQL_DBNAME)

正規表現内で変数展開する

lineinfile

This module will search a file for a line, and ensure that it is present or absent. This is primarily useful when you want to change a single line in a file only. See the replace module if you want to change multiple, similar lines or check blockinfile if you want to insert/update/remove a block of lines in a file. For other cases, see the copy or template modules. ドキュメントより

  • 単一行を置換する。複数行は置換できない
  • 複数箇所にマッチした場合最後にマッチしたもののみ書き換える。
  • regexp でマッチしたものを line に書き換える
- name: timezone を日本語に変更
  lineinfile:
  dest: /etc/php.ini
  regexp: '^;?date.timezone ='
  line: 'date.timezone = Asia/Tokyo'
  state: present # 行が存在する

  # 所有者やパーミッションも指定可
  owner: root
  group: root
  mode: 0644

blockinfile

  • 複数行の置換が可能
  • マーカーによって変更が管理される
# BEGIN ANSIBLE MANAGED BLOCK
# END ANSIBLE MANAGED BLOCK
- name: .soファイルを読み込み
  blockinfile:
  dest: /etc/httpd/conf.d/process_security.conf
  content: |
    LoadModule process_security_module   modules/mod_process_security.so
  create: yes
  # 所有者やパーミッションも指定可
  owner: root
  group: root
  mode: 0644

shell

replace, lineinfile で対応できない場合に使用する

# replaceだとsql置換時に UnicodeDecodeError: 'utf8' codec can't decode byte エラーが起きるのでsedで置換する
- name: replace mysql value
  shell: sed -i -e 's:/home/.*/public_html/:/home/{{ website.profile.user.name }}/public_html/:g' /tmp/{{ website.migration_src.mysql.dbname }}.sql

参考

Ansible ファイルを書き換える方法 - Qiita Ansible でファイルを書き換える時の 5 パターン | TANKSUZUKI.COM