web-dev-qa-db-ja.com

Ansible:ファイルの既存の行に単一の単語を挿入します

/ etc/ssh/sshd_configファイルを編集するには、Ansibleモジュールを使用する必要があります。新しいユーザーを作成するたびに、次の2行に追加します。

AllowUsers root osadmin <new_user>
AllowGroups root staff <new_group>

現時点では、シェルモジュールを使用してsedコマンドを実行していますが、可能であればlineinfileを使用したいと思います。

- Shell: "sed -i '/^Allow/ s/$/ {{ user_name }}/' /etc/ssh/sshd_config"

どんな提案でも心からいただければ幸いです。

9
Alexandra Ivan

改行を使用して1回の再生でそれを行うこともできますが、これには2つのlineinfile再生を使用する方がクリーンだと思います。

- hosts: '127.0.0.1'
  vars:
    usernames:
       - larry
       - curly
       - moe
    usergroups:
       - stooges
       - admins
  tasks:
    - lineinfile:
        dest: /etc/ssh/sshd_config
        regexp: '^AllowUsers'
        line: "AllowUsers {{usernames | join(' ')}}"
    - lineinfile:
        dest: /etc/ssh/sshd_config
        regexp: '^AllowGroups'
        line: "AllowGroups {{usergroups | join(' ')}}"

groupsは予約語であるため、変数名として使用しないでください。

8
Ben Whaley

replace module は、ファイル内の正規表現パターンのすべてのインスタンスを置き換えます。 AllowUsers行に一致するタスクを記述し、ユーザー名が追加された元の行に置き換えます。タスクがべき等であることを確認するために、正規表現での負の先読みアサーションは、ユーザー名がすでに行に表示されているかどうかを確認します。例えば:

- name: Add user to AllowUsers
  replace:
    backup: yes
    dest: /etc/ssh/sshd_config
    regexp: '^(AllowUsers(?!.*\b{{ user_name }}\b).*)$'
    replace: '\1 {{ user_name }}'
15
Chin Huang

選択された回答は、ユーザーの完全なリストが実行時に利用可能であることを前提としていますが、\bはそれを単語の境界として解釈するため、ユーザー名にダッシュがあると最も一般的な回答が失敗する可能性があります。次の解決策は、プレイブックがユーザー名の完全なリストを最初から再生成できないことを前提としており、ダッシュのコーナーケースを処理しようとします。

name: add a user to the list of AllowUsers if not present
lineinfile:
  path: /etc/ssh/sshd_config
  backrefs: yes
  backup: yes
  regexp: "^AllowUsers((?:(?:\s+\S+(?!\S))(?<!\s{{ username }}))+\s*?)(\n?)$"
  line: "AllowUsers\1 {{ username }}\2"
  validate: /usr/sbin/sshd -t -f %s

ボーナスとして、私はsshd_configのバックアップと検証を投入しました。

正規表現(の興味深い部分)がどのように機能するか:

--------------------------+----------------------------------------------------
(                         |
--------------------------+----------------------------------------------------
  (?:                     | This group is not captured
--------------------------+----------------------------------------------------
    (?:\s+\S+(?!\S))      | Matches any sequence of whitespace characters fol-
                          | lowed by any sequence of non-whitespace characters,
                          | that is to say a leading space and a username. The
                          | negative look-ahead at the end prevents a "catast-
                          | rophic backtracking". Also, this group is not cap-
                          | tured.
--------------------------+----------------------------------------------------
    (?<!\s{{ username }}) | Applies a negative look-behind on the username, so
                          | that if the username found by the previous expres-
                          | sion matches, the regular expression fails. The
                          | match on a leading whitespace character ensures
                          | that the comparison is made on the complete string.
--------------------------+----------------------------------------------------
  )+                      | Groups the detection of a username and its negative
                          | look-behind together. The "+" quantifier is used
                          | here on the assumption that the file already cont-
                          | ains at least one username, but "*" could be used
                          | for a more relaxed matching.
--------------------------+----------------------------------------------------
  \s*?                    | Matches any trailing whitespace. The match is lazy
                          | in order to detect the newline character later on.
--------------------------+----------------------------------------------------
)                         | Captures the whole text after "AllowUsers" (this
                          | will be \1).
--------------------------+----------------------------------------------------
(\n?)                     | Captures either a newline character or an empty
                          | string (this will be \2).
--------------------------+----------------------------------------------------

正規表現が一致する場合は、その行が存在し、{{ username }}が含まれていないことを意味するため、追加します。

正規表現が一致しない場合は、その行が存在しないか、{{ username }}が含まれていることを意味し、何もしません。

1
To마SE

これは私のために働いた

 - name: Add Group to AllowGroups
   lineinfile: 
     dest=/etc/ssh/sshd_config
     backup=True
     backrefs=True
     state=present
     regexp='^(AllowGroups(?!.*\b{{ groupname }}\b).*)$'
     line='\1 {{ groupname }}'
0
user3330284

私も同じ問題を抱えていました。 sudoersグループにユーザーを追加する必要がありました。たとえば、「testuser」を次の行に追加します。

_User_Alias SOMEADMIN = smoeuser1, someuser2, someuser3
_

これは私にとってうまくいきました:

_- name: add testuser to end of line
      lineinfile:
        dest: /etc/sudoers.d/somegroup
        state: present
        regexp: '^(User_Alias(.*)$)'
        backrefs: yes
        line: '\1, testuser'
_

重要なのは、正規表現に'^ User_Alias(。。)$' *があり、'^(User_Alias(。。)$)' *がない場合です。 t作業とライン全体が交換されました。 ()検索されたテキストの周りで、結果はOKでした:

_User_Alias SOMEADMIN = smoeuser1, someuser2, someuser3, testuser
_

したがって、"{{ usernames | join(', ') }}"のようなansible変数を含むline:で何でも機能します。

0
Gedrex ..