Comment changer d'utilisateur par tâche ou par ensemble de tâches?

160

Un thème récurrent dans mes playbooks ansible est que je dois souvent exécuter une commande avec les privilèges sudo ( sudo: yes) parce que j'aimerais le faire pour un certain utilisateur. Idéalement, je préfère de loin utiliser sudo pour basculer vers cet utilisateur et exécuter les commandes normalement. Parce qu'alors je n'aurai pas à nettoyer mes commandes de publication habituelles, comme chowning des répertoires. Voici un extrait de l'un de mes playbooks:

- 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

Idéalement, je pourrais exécuter des commandes ou des ensembles de commandes en tant qu'utilisateur différent, même si cela nécessite sudo pour su à cet utilisateur.

rgrinberg
la source

Réponses:

241

Avec Ansible 1.9 ou version ultérieure

Ansible utilise les become, become_user, et les become_methoddirectives pour obtenir une escalade des privilèges. Vous pouvez les appliquer à une lecture ou un livre de lecture entier, les définir dans un livre de lecture inclus ou les définir pour une tâche particulière.

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

Vous pouvez utiliser become_withpour spécifier comment l'escalade de privilèges est réalisée, la valeur par défaut étant sudo.

La directive est en vigueur pour la portée du bloc dans lequel elle est utilisée ( exemples ).

Voir Hôtes et utilisateurs pour quelques exemples supplémentaires et Devenir (augmentation des privilèges) pour une documentation plus détaillée.

En plus de la portée des tâches becomeet des become_userdirectives, Ansible 1.9 a ajouté de nouvelles variables et options de ligne de commande pour définir ces valeurs pour la durée d'une lecture en l'absence de directives explicites:

Depuis Ansible 2.0.2.0, l'ancienne sudo/ sudo_usersyntaxe décrite ci-dessous fonctionne toujours, mais l'avis d'obsolescence indique: «Cette fonctionnalité sera supprimée dans une version ultérieure».


Syntaxe précédente, obsolète depuis Ansible 1.9 et dont la suppression est prévue:

- name: checkout repo
  git: repo=https://github.com/some/repo.git version=master dest={{ dst }}
  sudo: yes
  sudo_user: some_user
Brett
la source
4
Pour spécifier sudo_user à partir d'une variable, utilisez des guillemets autour de votre modèle de variable, comme ceci - sudo_user: "{{ ansible_ssh_user }}"ou vous obtiendrez une erreur de syntaxe yaml.
Sumeet Pareek
Bonne prise. J'essayais de faire correspondre la formulation du problème du PO aussi étroitement que possible, mais je suis d'accord que l'utilisation de l'interpolation variable sera le choix le plus courant.
Brett
5
Depuis Ansible 1.9, c'est le becomesystème au lieu de "sudo *".
AndiDog
2
La syntaxe 1.9+ pour "devenir" est correcte. Vous voudrez peut-être aussi cocher "devenir_méthode", car "su" pourrait être parfois meilleur que "sudo" par défaut, selon la configuration de votre système.
ElementalStorm
New Ansible variables and command line options are added to set these values for the duration of a play. @Brett, cela signifie-t-il que les tâches suivantes seront exécutées par some_useret non par l'utilisateur d'origine remote_userqui a été utilisé pour se connecter à l'hôte, est-ce correct?
JohnnyQ
43

Dans Ansible 2.x, vous pouvez utiliser le blockgroupe de tâches pour:

- 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
Arbab Nazar
la source
26

Dans Ansible> 1.4, vous pouvez en fait spécifier un utilisateur distant au niveau de la tâche, ce qui devrait vous permettre de vous connecter en tant que cet utilisateur et d'exécuter cette commande sans recourir à sudo. Si vous ne pouvez pas vous connecter en tant que cet utilisateur, la solution sudo_user fonctionnera également.

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

Voir http://docs.ansible.com/playbooks_intro.html#hosts-and-users

trcarden
la source
C'est la meilleure solution pour les situations où vous ne disposez pas des privilèges sudo
Darrel Holt
7

Une solution consiste à utiliser l' includeinstruction avec remote_uservar (décrivez ici: http://docs.ansible.com/playbooks_roles.html ) mais cela doit être fait au niveau du playbook au lieu du niveau de la tâche.

Guillaume Dedrie
la source
Ce n'est pas une bonne solution pour le cas d'utilisation ci-dessus. Cependant, je n'étais pas au courant de cette solution depuis longtemps. Je pensais que je ne pouvais inclure que des rôles.
ArjanSchouten
1

Vous pouvez spécifier become_methodde remplacer la méthode par défaut définie dans ansible.cfg(le cas échéant), et qui peut être définie sur l'un des 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 }}'

Devrait afficher

TASK [my-task : my secret identity] ************************************************************
ok: [my_ansible_server] => {
    "msg": "some_user"
}
avi.elkharrat
la source