Estoy desplegando una máquina con vagrant y ansible en la que use vars_promt, mi intención es hacer una serie de preguntas previas al despliegue de una máquina y llevaba un buen rato pegándome con un error, concretamente este :
Traceback (most recent call last): File "/usr/bin/ansible-playbook", line 309, in <module> sys.exit(main(sys.argv[1:])) File "/usr/bin/ansible-playbook", line 249, in main pb.run() File "/usr/lib/python2.7/dist-packages/ansible/playbook/__init__.py", line 305, in run play = Play(self, play_ds, play_basedir, vault_password=self.vault_password) File "/usr/lib/python2.7/dist-packages/ansible/playbook/play.py", line 65, in __init__ self.vars = self._get_vars() File "/usr/lib/python2.7/dist-packages/ansible/playbook/play.py", line 672, in _get_vars vname, private, prompt, encrypt, confirm, salt_size, salt, default File "/usr/lib/python2.7/dist-packages/ansible/callbacks.py", line 662, in on_vars_prompt result = prompt(msg, private) File "/usr/lib/python2.7/dist-packages/ansible/callbacks.py", line 648, in prompt msg = prompt.encode(sys.stdout.encoding) TypeError: encode() argument 1 must be string, not None Ansible failed to complete successfully. Any error output should be visible above. Please fix these errors and try again.
Leer el traceback de python al principio es un poco ruidoso, pero hay que leer detenidamente la traza y veremos claramente el problema. Yo al principio no lo he hecho y eso me ha llevado a dedicarle más tiempo 😀
Existe un problema documentado en ansible que genera este error cuando no es capaz de generar la codificación de salida, no se si es exactamente un bug de python2.x o es de ansible, por que en algunos casos recomiendan directamente migrar a python3 aunque ansible está desarrollado con python2.7.
Si queréis entreneros veréis que efectivamente sys.stdout.enconding devuelve None y de ahí la execepción que genera ansible.
Ahora bien,¿ como lo solucionamos ? forzando un tipo de codificacion con la variable de entorno PYTHONIOENCODING
export PYTHONIOENCODING='utf-8'
De esta manera ya podemos lanzar el provisionamiento de la máquina
vagrant provision
Esto está bien, pero no es práctico, ya que lo que queremos es olvidarnos de tener que hacer cosas manualmente, por eso automatizamos. Pues bien, hay una forma de agregar esto, y dejar nuestro Vagrantfile más o menos así:
VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "debian/jessie64" #Force sys.stdout.encoding to utf8 ENV['PYTHONIOENCODING'] = "utf-8" config.vm.provision "ansible" do |ansible| ansible.verbose = "v" ansible.playbook = "ansible/playbook.yml" end end
Evidentemente esto es un fichero muy sencillo, lo importante es declarar la variable de entorno
ENV['PYTHONIOENCODING'] = "utf-8"
Este fallo está documentado en una issue de github https://github.com/ansible/ansible/issues/8644 aunque su resolución está prevista en una versión ‘mayor’ con lo que supongo que estará corregido en la rama 1.8.x mientras que en Debian stable estamos en la versión 1.7.2 a diciembre de 2015. Otra alternativa sería crear un virtual environment de python e instalar la versión que queramos, no lo he probado pero seguro que es posible.
Deja una respuesta