Como alternar um usuário por tarefa ou conjunto de tarefas?

159

Um tema recorrente que está nos meus playbooks ansíveis é que muitas vezes devo executar um comando com privilégios sudo ( sudo: yes) porque gostaria de fazê-lo para um determinado usuário. Idealmente, prefiro usar o sudo para alternar para esse usuário e executar os comandos normalmente. Porque então não precisarei limpar meus comandos de postagem habituais, como diretórios de chowning. Aqui está um trecho de um dos meus 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

Idealmente, eu poderia executar comandos ou conjuntos de comandos como um usuário diferente, mesmo que exija que o sudo su para esse usuário.

rgrinberg
fonte

Respostas:

241

Com Ansible 1.9 ou posterior

Usos o ansible become, become_user, e become_methoddirectivas para alcançar escalação de privilégios. Você pode aplicá-los a uma play ou playbook inteira, configurá-los em um playbook incluído ou configurá-los para uma tarefa específica.

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

Você pode usar become_withpara especificar como a escalação de privilégios é alcançada, sendo o padrão sudo.

A diretiva está em vigor para o escopo do bloco em que é usado ( exemplos ).

Consulte Hosts e Usuários para obter alguns exemplos adicionais e Tornar - se (Escalonamento de Privilégios) para obter uma documentação mais detalhada.

Além do escopo da tarefa becomeebecome_user diretivas , o Ansible 1.9 adicionou algumas novas variáveis ​​e opções de linha de comando para definir esses valores pela duração de uma reprodução na ausência de diretivas explícitas:

No Ansible 2.0.2.0, os mais antigos sudo / sudo_usersintaxe descrita abaixo ainda funciona, mas os estados Aviso depreciação, "Este recurso será removido em uma versão futura."


Sintaxe anterior, descontinuada a partir do Ansible 1.9 e agendada para remoção:

- name: checkout repo
  git: repo=https://github.com/some/repo.git version=master dest={{ dst }}
  sudo: yes
  sudo_user: some_user
Brett
fonte
4
Para especificar o sudo_user a partir de uma variável, use aspas ao redor do seu modelo de variável, como este - sudo_user: "{{ ansible_ssh_user }}"ou você receberá um erro de sintaxe yaml.
Sumeet Pareek
Boa pegada. Eu estava tentando igualar o máximo possível a formulação do problema pelo OP, mas concordo que o uso de interpolação variável será a escolha mais comum.
Brett
5
No Ansible 1.9, é o becomesistema em vez de "sudo *".
AndiDog 24/07/2015
2
A sintaxe 1.9+ para "tornar-se" está correta. Você também pode marcar "become_method", pois "su" pode ser melhor que o "sudo" padrão, dependendo da configuração do sistema.
ElementalStorm
New Ansible variables and command line options are added to set these values for the duration of a play. @Brett, isso significa que as tarefas seguintes serão executadas some_usere não o usuário original remote_userque foi usado para se conectar ao host, está correto?
JohnnyQ
42

No Ansible 2.x, você pode usar o blockgrupo de tarefas:

- 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
fonte
26

No Ansible> 1.4, você pode realmente especificar um usuário remoto no nível da tarefa, o que deve permitir que você efetue login como usuário e execute esse comando sem recorrer ao sudo. Se você não conseguir fazer o login como esse usuário, a solução sudo_user também funcionará.

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

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

trcarden
fonte
Esta é a melhor solução para situações em que você não tem privilégios sudo
Darrel Holt
7

Uma solução é usar a includeinstrução com remote_uservar (descreva lá: http://docs.ansible.com/playbooks_roles.html ), mas isso deve ser feito no playbook em vez de no nível da tarefa.

Guillaume Dedrie
fonte
Esta não é uma boa solução para o caso de uso acima. No entanto, eu não sabia dessa solução por um longo tempo. Eu pensei que só podia incluir papéis.
ArjanSchouten
1

Você pode especificar become_methodpara substituir o método padrão definido em ansible.cfg(se houver) e qual pode ser definido como um dos 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 }}'

Deve exibir

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