Um "sudo: parse error in ..." originado de /etc/sudoers
ou qualquer um dos arquivos incluídos nas diretivas #include <filename>
ou #includedir <path>
pode ser causado por uma falta de novo Linha na última entrada desse arquivo.
Eu criei um usuário chamado kafka
para quem eu estou tentando dar acesso ao sudo para executar apenas /etc/init.d/kafka
comandos.
Adicionei a seguinte entrada a /etc/sudoers.d/kafka
via Ansible:
kafka ALL = NOPASSWD: /etc/init.d/kafka
No entanto, isso quebra completamente o sudo com o seguinte erro:
/etc/sudoers.d/kafka: syntax error near line 1
sudo: parse error in /etc/sudoers.d/kafka near line 1
sudo: no valid sudoers sources found, quitting
sudo: unable to initialize policy plugin
Aqui está o snippet Ansible completo:
- name: Create kafka user's group
group:
name: "{{ kafka_group }}"
state: present
- name: Create kafka user
user:
name: "{{ kafka_user }}"
state: present
group: "{{ kafka_group }}"
shell: /bin/bash
- name: Set up password-less sudo for kafka user
copy:
content: "{{ kafka_user }} ALL = NOPASSWD: /etc/init.d/{{ kafka_service_name }}"
dest: "/etc/sudoers.d/{{ kafka_user }}"
owner: root
group: root
mode: 0440
O que estou fazendo de errado?
Usar o módulo copy
provavelmente não é a melhor escolha para manipular /etc/sudoers
com Ansible.
O módulo lineinfile tem uma opção para validar o arquivo antes de salvá-lo. Também é mais fácil remover a linha, etc com esse módulo.
A documentação contém um exemplo de como usá-la.
- name: Set up password-less sudo for kafka user
lineinfile: dest=/etc/sudoers state=present regexp='^%{{ kafka_user }} ALL\=' line='%{{ kafka_user }} ALL= NOPASSWD: /etc/init.d/{{ kafka_service_name }}' validate='visudo -cf %s'