Ansible에서 임의의 원격 사용자의 홈 디렉토리를 얻는 방법은 무엇입니까?
다음 getent
과 awk
같은 조합을 사용하여 쉘로 할 수 있습니다 .
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>
사실 로 사용할 수 있습니다 .
임의의 원격 사용자 의 홈 디렉토리를 어떻게 얻 습니까?
Ansible (1.4 이상)은 이미 사용자를위한 환경 변수를 ansible_env
변수 아래에 표시 합니다.
- hosts: all
tasks:
- name: debug through ansible.env
debug: var=ansible_env.HOME
또는에 대한 조회 를 사용하여 환경 변수에 액세스 할 수 있습니다 env
.
- 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의 모든 것과 마찬가지로 원하는 것을 제공하는 모듈을 얻을 수없는 경우 다음과 같은 것을 사용하여 항상 자유롭게 셸 아웃 할 수 있습니다 (이는 깨지기 쉽고 설명이 적을 수 있으므로 드물게 사용해야 함). :
- 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
조회 에 영향을 미치지 않는 것처럼 보이지만 원하는 것을 제공 한다는 점에 약간 놀랐습니다 .
Ansible 1.8은 getent
모듈 . getent 결과를 호스트 사실로 등록합니다 getent_passwd
. 이 경우에는 .
예 :
주어진 홈 폴더를 인쇄합니다 user
.
---
- getent:
database: passwd
key: "{{ user }}"
split: ":"
- debug:
msg: "{{ getent_passwd[user][4] }}"
조회 테이블 ( user_homes
)을 누적 set_fact
하고 Jinja2 combine()
필터를 활용 합니다 .
---
- 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]}) }}"
하지만 커스텀 팩트 모듈을 사용하면 더 좋을 것입니다.
문제
lookup()
이 지정된 사용자로 실행되기 때문에 슬프게도 임의의 사용자의 홈을 찾는 또는 ENV var에 방법은 Ansible 안정적으로 작동하지 않습니다 --user=REMOTE_USER
, 그리고 선택적으로 sudo
(만약 sudo: yes
작전 또는 --sudo
전달). 이 두 가지 실행 모드 (sudo 또는 no sudo)는 Ansible이 실행중인 셸 환경을 변경하며, 그 후에도 -u REMOTE_USER
또는로 지정된 사용자로 제한됩니다 root
.
sudo: yes
, 및 sudo_user: myarbitraryuser
함께 사용을 시도 할 수 있습니다. 그러나 특정 버전의 Ansible 의 버그로 인해 제대로 작동하지 않는 것을 확인할 수 있습니다. Ansible> = 1.9
에있는 경우 become: true
, become_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"
나는 여기에 몇 가지 대답이 작동한다고 생각하지만 변수로 등록 하면 ansible 사용자 모듈 에서 얻을 수 있음을 보여줄 것이라고 생각 했습니다.
- user:
name: www-data
state: present
register: webserver_user_registered
Note: it will create the user if it doesn't exist...
So we can use debug to show the values of that var, including the path...
- 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
}
}
And you can use those properties in other modules like this;
- file:
name: "{{ webserver_user_registered.home }}/.wp-cli"
state: directory
I know this is quite old thread, but I think this is a bit simpler way for getting the users home directory
- name: Get users homedir
local_action: command echo ~
register: homedir
On Linux (or Unix) systems the tilde-sign points to the users home directory.
You can use expanduser
.
For instance, while looping over a user list:
- name: Deploys .bashrc
template:
src: bashrc.j2
dest: "{{ '~' + item | expanduser }}/.bashrc"
mode: 0640
owner: "{{ item }}"
group: "{{ item }}"
with_items: user_list
Every answer mentions about how to print the home directory details while running the playbook and displaying it on screen using debug and var.
Adapting to @TrinitronX answer
An additional information on using this information to a new task.
I have a list of users whose home directory needs to be extracted. So I have added the user details to a list
- name: Get home directory
shell: >
getent passwd {{ item.user }} | cut -d: -f6
changed_when: false
with_items:
- "{{java}}"
register: user_home
Here this step will loop through all user list and will register that details to user_home. And this will be in the form of an array.
Then next step is to use this information to a new task, which is say for example sourcing a file into bash profile. This is just an example and can be any scenario, but method will remain the same.
- 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 }}"
I have set a fact for java_dir to /usr/java/latest in the same playbook.
Array user_home.results will contain the details of the Get home directory task. Now we loop through this array and take out the stdout value which contains the home directory path.
I have put loop_control for printing the home directory only, else it will print the entire array.
By this process, we can ensure that if n number of users are there, we can follow this method and all will be taken care.
Note: I have started to learn the Ansible, in case if any terminology I have used is wrong, please excuse. I have spend some time for figuring out on how to do this and thought of sharing the same.
There is no easy way to do this in Ansible at this moment and that's why you should add your votes to this issue
https://github.com/ansible/ansible/issues/15901
While you can use this workaround: https://stackoverflow.com/a/33343455/99834 you should not forget to send the feedback that you want this to be easy to be used.
I came to this thread because i needed to print the PGDATA env variable from the postgres user, i have not found how to do it more "natively" in ansible, but i ended having this that works:
- name: Find postgresql data directory
shell: 'echo $PGDATA'
become: yes
become_user: postgres
become_flags: "-i "
register: pgdata_dir
Then i can reference that in another job using "{{ pgdata_dir.stdout }}"
'Development Tip' 카테고리의 다른 글
JQuery는 내부 텍스트를 변경하지만 HTML은 유지합니다. (0) | 2020.11.27 |
---|---|
Xcode 4는 리팩토링에서 스냅 샷 생성을 비활성화합니다. (0) | 2020.11.27 |
오류 : 'style-loader'모듈을 해결할 수 없습니다. (0) | 2020.11.27 |
PowerShell Copy-Item의 제외 목록이 작동하지 않는 것 같습니다. (0) | 2020.11.27 |
추가 된 요소에서 CSS 전환 트리거 (0) | 2020.11.26 |