Как переключить пользователя для каждой задачи или набора задач?

160

Повторяющаяся тема, которая есть в моих сборниках пьес, состоит в том, что я часто должен выполнять команду с привилегиями sudo ( sudo: yes), потому что я хотел бы сделать это для определенного пользователя. В идеале я бы предпочел использовать sudo для переключения на этого пользователя и выполнения команд в обычном режиме. Потому что тогда мне не нужно будет выполнять обычные почтовые команды, такие как уничтожение каталогов. Вот фрагмент из одной из моих пьес:

- name: checkout repo
  git: repo=https://github.com/some/repo.git version=master dest={{ dst }}
  sudo: yes
- name: change perms
  file: dest={{ dst }} state=directory mode=0755 owner=some_user
  sudo: yes

В идеале я мог бы запускать команды или наборы команд от имени другого пользователя, даже если для этого пользователя требуется sudo или su.

rgrinberg
источник

Ответы:

241

С Ansible 1.9 или более поздней

Анзибль использует become, become_userи become_methodдирективы для достижения привилегий. Вы можете применить их ко всей пьесе или сборнику пьес, установить их во включенную сборник пьес или установить для конкретной задачи.

- name: checkout repo
  git: repo=https://github.com/some/repo.git version=master dest={{ dst }}
  become: yes
  become_user: some_user

Вы можете использовать, become_withчтобы указать, как достигается повышение привилегий, по умолчанию sudo.

Директива действует для области действия блока, в котором она используется ( примеры ).

См. Hosts and Users для некоторых дополнительных примеров и Become (Privilege Escalation) для более подробной документации.

В дополнение к области задач becomeи become_userдирективам, Ansible 1.9 добавил несколько новых переменных и параметров командной строки, чтобы установить эти значения на время воспроизведения при отсутствии явных директив:

Начиная с Ansible 2.0.2.0, старый sudo/ sudo_userсинтаксис, описанный ниже, все еще работает, но в уведомлении об устаревании говорится: «Эта функция будет удалена в следующем выпуске».


Предыдущий синтаксис, устаревший с Ansible 1.9 и запланированный для удаления:

- name: checkout repo
  git: repo=https://github.com/some/repo.git version=master dest={{ dst }}
  sudo: yes
  sudo_user: some_user
Brett
источник
4
Чтобы указать sudo_user из переменной, используйте кавычки вокруг шаблона переменной, например так, sudo_user: "{{ ansible_ssh_user }}"иначе вы получите синтаксическую ошибку yaml.
Сумит Парик
Хороший улов. Я пытался максимально точно согласовать постановку задачи с ОП, но я согласен с тем, что использование переменной интерполяции будет наиболее распространенным выбором.
Бретт
5
Начиная с Ansible 1.9, это becomeсистема вместо "sudo *".
AndiDog
2
1.9+ синтаксис для "стать" является правильным. Вы также можете проверить «становиться_методом», так как «su» иногда может быть лучше, чем «sudo» по умолчанию, в зависимости от настроек вашей системы.
ElementalStorm
New Ansible variables and command line options are added to set these values for the duration of a play. @ Бретт, значит ли это, что последующие задачи после этого будут выполняться, some_userа не исходный пользователь, remote_userкоторый использовался для подключения к хосту?
JohnnyQ
43

В Ansible 2.x вы можете использовать blockдля группы задач:

- block:
    - name: checkout repo
      git:
        repo: https://github.com/some/repo.git
        version: master
        dest: "{{ dst }}"
    - name: change perms
      file:
      dest: "{{ dst }}"
      state: directory
      mode: 0755
      owner: some_user
  become: yes
  become_user: some user
Арбаб Назар
источник
26

В Ansible> 1.4 вы можете указать удаленного пользователя на уровне задач, что позволит вам войти в систему под этим пользователем и выполнить эту команду, не прибегая к sudo. Если вы не можете войти в систему под этим пользователем, то решение sudo_user также будет работать.

---
- hosts: webservers
  remote_user: root
  tasks:
    - name: test connection
      ping:
      remote_user: yourname

Смотрите http://docs.ansible.com/playbooks_intro.html#hosts-and-users

trcarden
источник
Это лучшее решение для ситуаций, когда у вас нет привилегий sudo
Даррел Холт
7

Решением является использование includeоператора с remote_uservar (опишите здесь: http://docs.ansible.com/playbooks_roles.html ), но это должно быть сделано в playbook, а не на уровне задач.

Гийом Дедри
источник
Это не очень хорошее решение для приведенного выше варианта использования. Однако я не знал об этом решении в течение длительного времени. Я думал, что могу включать только роли.
Арьян Шоутен
1

Вы можете указать, become_methodчтобы переопределить метод по умолчанию, установленный в ansible.cfg(если есть), и который может быть установлен в один из sudo, su, pbrun, pfexec, doas, dzdo, ksu.

- name: I am confused
  command: 'whoami'
  become: true
  become_method: su
  become_user: some_user
  register: myidentity

- name: my secret identity
  debug:
    msg: '{{ myidentity.stdout }}'

Должен отображаться

TASK [my-task : my secret identity] ************************************************************
ok: [my_ansible_server] => {
    "msg": "some_user"
}
avi.elkharrat
источник