web-dev-qa-db-ja.com

Ansibleで任意のリモートユーザーのホームディレクトリを取得する方法は?

次のようにgetentawkの組み合わせを使用してシェルでそれを行うことができます。

getent passwd $user | awk -F: '{ print $6 }'

参考のために、Puppetでは、次のようなカスタムファクトを使用できます。

require 'etc'

Etc.passwd { |user|

   Facter.add("home_#{user.name}") do
      setcode do
         user.dir
      end
   end

}

これにより、ユーザーのホームディレクトリがhome_<user name>ファクトとして利用可能になります。

任意リモートユーザーのホームディレクトリを取得するにはどうすればよいですか?

60
Adam Ryczkowski

Ansible(1.4以降)は、 ansible_env 変数の下でユーザーの環境変数を既に明らかにしています。

- hosts: all
  tasks:
    - name: debug through ansible.env
      debug: var=ansible_env.HOME

または、envlookup を使用して環境変数にアクセスできます。

- hosts: all
  tasks:
    - name: debug through lookup on env
      debug: var=lookup('env','HOME')

残念ながら、このプレイブックと出力が示すように、接続ユーザーの環境変数を取得するためにのみこれを使用することができます:

- hosts: all
  tasks:
    - name: debug specified user's home dir through ansible.env
      debug: var=ansible_env.HOME
      become: true
      become_user: "{{ user }}"

    - name: debug specified user's home dir through lookup on env
      debug: var=lookup('env','HOME')
      become: true
      become_user: "{{ user }}"

出力

vagrant@Test-01:~$ ansible-playbook -i "inventory/vagrant" env_vars.yml -e "user=testuser"

PLAY [all] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.0.30]

TASK: [debug specified user's home dir through ansible.env] *******************
ok: [192.168.0.30] => {
    "var": {
        "/home/vagrant": "/home/vagrant"
    }
}

TASK: [debug specified user's home dir through lookup on env] *****************
ok: [192.168.0.30] => {
    "var": {
        "/home/vagrant": "/home/vagrant"
    }
}

PLAY RECAP ********************************************************************
192.168.0.30               : ok=3    changed=0    unreachable=0    failed=0

Ansibleのすべての場合と同様に、必要なものを提供するモジュールを取得できない場合は、常に自由に Shell outにできます(ただし、これは脆弱である可能性があるため、慎重に使用する必要があります)より記述的ではない)このようなものを使用して:

- hosts: all
  tasks:
    - name: grep and register
      Shell: >
              egrep "^{{ user }}:" /etc/passwd | awk -F: '{ print $6 }'
      changed_when: false
      register: user_home

    - name: debug output
      debug: var=user_home.stdout

よりクリーンな方法があるかもしれませんが、 become_user を使用して指定されたユーザーに切り替えてもenvルックアップには影響しないように思えますが、これは与えるはずですあなたが欲しいもの。

56
ydaetskcoR

Ansible 1.8では getentモジュール が導入されました。 getentの結果をホストファクトとして登録します。この場合、getent_passwdです。

例:

指定されたuserのホームフォルダーを印刷します。

---

- getent:
    database: passwd
    key: "{{ user }}"
    split: ":"

- debug:
    msg: "{{ getent_passwd[user][4] }}"

user_homes とJinja2 combine() filter を利用して、ルックアップテーブル(set_fact)を蓄積します。

---

- assert:
    that:
      - user_name is defined

- when: user_homes is undefined or user_name not in user_homes
  block:
    - name: getent
      become: yes
      getent:
        database: passwd
        key: "{{ user_name }}"
        split: ":"

    - name: set fact
      set_fact:
        "user_homes": "{{ user_homes | d({}) | combine({user_name: getent_passwd[user_name][4]}) }}"

ただし、カスタムファクトモジュールの方が良いでしょう。

19
masu

問題

任意のユーザーの家を見つけるためのlookup()またはENV varメソッドは、--user=REMOTE_USERで指定されたユーザーとして実行され、オプションでSudo(if Sudo: yesプレイブック内または--Sudoが渡されました)。これらの2つの実行モード(Sudoまたはno Sudo)は、Ansibleが実行されているシェル環境を変更し、それでも-u REMOTE_USERまたはrootとして指定されたユーザーに制限されます。

Sudo: yesSudo_user: myarbitraryuserを一緒に使用してみることもできますが、 Ansibleの特定のバージョン のバグのため、正常に動作しないことがあります。 Ansible> = 1.9を使用している場合は、代わりにbecome: truebecome_user: myarbitraryuserを使用できます。ただし、これは、作成したプレイブックとロールがAnsibleの以前のバージョンでは機能しないことを意味します。

LDAPまたは他のディレクトリサービスでも機能するユーザーのホームディレクトリを取得するポータブルな方法を探している場合は、getentを使用します。

Ansible getentの例

playbooks/ad-hoc/get-user-homedir.ymlという名前の簡単なプレイブックを作成します

- hosts: all
  tasks:
    - name:
      Shell: >
        getent passwd {{ user }} | cut -d: -f6
      changed_when: false
      register: user_home

    - name: debug output
      debug: var=user_home.stdout

以下で実行します:

ansible-playbook -i inventory/racktables.py playbooks/ad-hoc/get-user-homedir.yml -e "user=someuser"
15
TrinitronX

ここにはいくつかの答えがあると思いますが、変数として登録することで ansible user モジュールからこれを取得できることを示すと思いました。

- user:
    name: www-data
    state: present
  register: webserver_user_registered

注:存在しない場合はユーザーを作成します...

したがって、デバッグを使用して、パスを含むその変数の値を表示できます...

- debug:
    var: webserver_user_registered

TASK [wordpress : debug] ******************
ok: [wordpresssite.org] => {
    "webserver_user_registered": {
        "append": false,
        "changed": false,
        "comment": "www-data",
        "failed": false,
        "group": 33,
        "home": "/var/www",      <<------ this is the user home dir
        "move_home": false,
        "name": "www-data",
        "Shell": "/usr/sbin/nologin",
        "state": "present",
        "uid": 33
    }
}

そして、このような他のモジュールでこれらのプロパティを使用できます。

- file:
    name: "{{ webserver_user_registered.home }}/.wp-cli"
    state: directory
14
Tom H

私はこれがかなり古いスレッドであることを知っていますが、これはユーザーのホームディレクトリを取得するための少し簡単な方法だと思います

- name: Get users homedir
  local_action: command echo ~
  register: homedir

Linux(またはUnix)システムでは、チルダ記号はユーザーのホームディレクトリを指します。

3
Matti

すべての回答は、デバッグとvarを使用してプレイブックを実行し、画面に表示するときにホームディレクトリの詳細を印刷する方法について言及しています。

@TrinitronXへの適応 answer

この情報を新しいタスクに使用するための追加情報。

ホームディレクトリを抽出する必要があるユーザーのリストがあります。だから私はリストにユーザーの詳細を追加しました

- name: Get home directory
  Shell: >
         getent passwd {{ item.user }} | cut -d: -f6
  changed_when: false
  with_items:
   - "{{Java}}"
  register: user_home

ここで、このステップはすべてのユーザーリストをループし、その詳細をuser_homeに登録します。そして、これは配列の形になります。

次のステップは、この情報を新しいタスクに使用することです。たとえば、たとえば、ファイルをbashプロファイルにソースします。これは単なる例であり、どのようなシナリオでも可能ですが、方法は変わりません。

- name: Set Java home in .bash_profile
  lineinfile: path="{{ item.stdout }}/.bash_profile" regexp='^source "{{ Java_dir }}/.bash_profile_Java"' line='source "{{ Java_dir }}/.bash_profile_Java"' state=present
  with_items:
   - "{{ user_home.results }}"
  loop_control:
    label: "{{ item.stdout }}"

同じプレイブックでJava_dirのファクトを/ usr/Java/latestに設定しました。

配列user_home.resultsには、ホームディレクトリの取得タスクの詳細が含まれます。次に、この配列をループして、ホームディレクトリパスを含むstdout値を取り出します。

Loop_controlをホームディレクトリのみを印刷するために配置しました。それ以外の場合は、配列全体を印刷します。

このプロセスにより、n人のユーザーがいる場合、この方法に従うことができ、すべての面倒を見ることができます。

注:使用した用語が間違っている場合に備えて、私はAnsibleを学び始めました。私はこれを行う方法を理解するためにいくつかの時間を費やし、同じことを共有することを考えました。

2
nirmalraj17

expanduserを使用できます。

たとえば、ユーザーリストをループしている間:

- name: Deploys .bashrc
  template:
    src: bashrc.j2
    dest: "{{ '~' + item | expanduser }}/.bashrc"
    mode: 0640
    owner: "{{ item }}"
    group: "{{ item }}"
  with_items: user_list
2
leucos

現時点ではこれをAnsibleで行う簡単な方法はないため、この問題に投票を追加する必要があります。

https://github.com/ansible/ansible/issues/15901

この回避策を使用できますが、 https://stackoverflow.com/a/33343455/99834 使いやすくしたいというフィードバックを送信することを忘れないでください。

1
sorin