Running ansible from jenkins execute shell

6,724 views
Skip to first unread message

Naween Ghimire

unread,
Sep 20, 2014, 4:40:46 AM9/20/14
to ansible...@googlegroups.com
Hi All,

I am trying to run an ansible playbook from jenkins build to have jenkins trigger my ansible execution.

As part of my ansible-playbook run i need to pass extra-vars to the playbook during execution.

eg:

ansible-playbook -i $inventory-file $role-name --extra-vars"var1=$var1-value, var2=$var2-value"

when i put this line in the execute shell of jenkins the double quotes are evaluated and so aren't available to the ansible-playbook command, so i escaped them as follows:

ansible-playbook -i $inventory-file $role-name --extra-vars\"var1=$var1-value, var2=$var2-value\"

But if i do this, 

shell adds extra quotes around it as below:

ansible-playbook -i <inventory-file-name> <role-name> --extra-vars ' "var1=var1-value,' var2=var2-value, 'var3=var3-value " '

And ansible give the following error:


Traceback (most recent call last):

  File "/usr/local/bin/ansible-playbook", line 317, in <module>

    sys.exit(main(sys.argv[1:]))

  File "/usr/local/bin/ansible-playbook", line 148, in main

    extra_vars = utils.combine_vars(extra_vars, utils.parse_kv(extra_vars_opt))

  File "/Library/Python/2.7/site-packages/ansible/utils/__init__.py", line 621, in parse_kv

    vargs = split_args(args)

  File "/Library/Python/2.7/site-packages/ansible/utils/splitter.py", line 148, in split_args

    raise Exception("error while splitting arguments, either an unbalanced jinja2 block or quotes")

Exception: error while splitting arguments, either an unbalanced jinja2 block or quotes


Has anyone come across such a situation before ?

Baraa Basata

unread,
Sep 20, 2014, 1:54:31 PM9/20/14
to ansible...@googlegroups.com
I use ansible-playbook within "Execute shell" steps and I have had no issues. Here's what I have in the "Execute shell" step:

ansible-playbook -i inventory playbook.yml --extra-vars="var1=${VALUE1} var2=${VALUE2}"

Damir Suleymanov

unread,
Sep 20, 2014, 5:24:28 PM9/20/14
to ansible...@googlegroups.com
You can put all your variables in a YAML file and pass it as --extra-vars="@my_vars.yml"

Given your example, your command will look like this:
ansible-playbook -i $inventory-file $role-name --extra-vars="@my_vars.yml"

and my_vars.yml should contain:

---
# NOTE: "=" is replaced by ':'

var1
: $var1-value
var2
: $var2-value


I hope this helps.

Michael DeHaan

unread,
Sep 21, 2014, 3:34:45 PM9/21/14
to ansible...@googlegroups.com
What version of Ansible are you using?



--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/a97b244f-f05b-4c72-a95a-ad48974c853d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

jonten

unread,
Nov 15, 2014, 8:15:36 AM11/15/14
to ansible...@googlegroups.com
Hi,

Sorry for hi-jacking this old thread but I'm experiencing exactly the same problems as the original poster Naween. Have also tried Damirs workaround without success, just get the same result as when not using a vars file.

I'm running the following versions of Ansible and other related software:

OS: CentOS 6.5
Ansible verision:ansible-1.7.2-2.el6.noarch (from epel repo)
Python Jinja version: python-jinja2-2.2.1-1.el6.rf.x86_64 (think it was from rpmbone because of dependency trouble with other jinjas)
Jenkins version: jenkins-1.499-1.1.noarch

I tried this with ansible-1.7.0-1.el6.noarch also from epel repo with the same result. Everything works great with dynamic extra-vars variables from the command line but not from Jenkins.

Best regards,

//Jon

Toshio Kuratomi

unread,
Nov 15, 2014, 5:23:52 PM11/15/14
to ansible...@googlegroups.com
What does your execute shell look like with Damir's workaround? Were
you also able to see the values of the substitution has extra quotes
in that case or is it the same traceback but not necessarily the same
place that quotes are being mismatched?

-Toshio
> https://groups.google.com/d/msgid/ansible-project/ebe17377-536f-48d6-a570-1af4150ab75c%40googlegroups.com.

Michael DeHaan

unread,
Nov 17, 2014, 3:53:42 PM11/17/14
to ansible...@googlegroups.com
I'm not sure I'm following, can you clarify exactly what your issue is?

The start of this thread was about how to pass variables.



jonten

unread,
Nov 18, 2014, 8:52:57 AM11/18/14
to ansible...@googlegroups.com
Hi,

Sorry for being unclear about my problem. The issue is still about passing variables from Jenkins to Ansible as --extra-vars. I have done some more testing and biggest part of the problem was that I was trying to build up the complete ansible-playbook command from variables in Jenkins including extra-vars. Now when I just tried pasting the complete raw ansible-playbook command line in the Jenkins execute-shell box directly, it works just fine.

For example this works:
/usr/bin/python2 -u ansible-playbook manage_service.yml -l ${hosts} --extra-vars "service=${service} manage=${manage} serial=${serial} secs=${secs}"

But all the following examples causes trouble:
cmd="/usr/bin/python2 -u ansible-playbook manage_service.yml -l ${hosts} --extra-vars "service=${service} manage=${manage} serial=${serial} secs=${secs}""
cmd="/usr/bin/python2 -u ansible-playbook manage_service.yml -l ${hosts} --extra-vars \"service=${service} manage=${manage} serial=${serial} secs=${secs}\""
cmd="/usr/bin/python2 -u ansible-playbook manage_service.yml -l ${hosts} --extra-vars 'service=${service} manage=${manage} serial=${serial} secs=${secs}'"

I also tried the workaround by using --extra-vars "@manage_service_vars.yml" but that produced a failure with the following message which seems to indicate that the variable does'nt get expanded:
msg: value of state must be one of: running,started,stopped,restarted,reloaded, got: $manage

I have also tried:
cmd=$(/usr/bin/python2 -u ansible-playbook manage_service.yml -l ${hosts} --extra-vars "service=${service} manage=${manage} serial=${serial} secs=${secs}")
Which works but you get all the output from ansible in one line.

The reason for still building the complete command as a variable is to be able to add even more parameters to ansible as options to the Jenkins job without having the complete command line in several different sections of the execute-shell code.
 
For example:
if [ "${debug}" == "true" ]; then
  runcmd="${cmd} -vvvv"
else
  runcmd="${cmd}"
fi

It would be great if someone more knowledgeable than me :) could give some input on how to solve the problem with not being able to build up the complete ansible-playbook command as a variable without breaking the --extra-vars parameter?

Best regards,

//Jon

Michael Schultz

unread,
Nov 18, 2014, 11:38:31 AM11/18/14
to ansible...@googlegroups.com
It might help to split each --extra-vars into a separate args (you can have multiple --extra-vars in a single command). This should make it simpler to reason about quoting rules (in my opinion).

Our build script ends up looking something like this (hosts, site_rev, site_count) come from jenkins params:

    args="--extra-vars site_rev=$site_rev"
    args="${args} --extra-vars site_count=$site_count"
    args="${args} --limit localhost,$hosts"

    ansible-playbook deploy_site.yml ${args}

This avoids having to worry about quoting the variables for ansible itself.

--michael

Tomasz Kontusz

unread,
Nov 18, 2014, 12:42:51 PM11/18/14
to ansible...@googlegroups.com
I'd recommend using bash arrays:

args=(
--extra-vars "site=$site"
--extra-vars "service=$service"
)
args+=( -l "$hosts" )

if [ -n "$just_joking" ]; then
args+=( --check )
fi

ansible-playbook "${args[@]}" # this is magic to stop bash from mangling the args

This is much more robust, and can even survive spaces in extra vars easily :-)

Michael Schultz <mjsc...@gmail.com> napisał:

--
Wysłane za pomocą K-9 Mail.

Greg Andrews

unread,
Nov 19, 2014, 9:51:58 PM11/19/14
to ansible...@googlegroups.com
To capitalize on Tomasz's information, there's a way to get bash to prefix the boilerplate "--extra-vars" string to each extra arg for you:

extra_args=( "site=$site" "service=$service" )

ansible-playbook  "${extra_args[@]/#/--extra-args }"

(note the space character between "args" and "}")

A short example:

#!/bin/bash
site=one
service=two
extra_args=( "site=$site" "service=$service" )
echo ansible-playbook "${extra_args[@]/#/--extra-args }"

will output:

ansible-playbook --extra-args site=one --extra-args service=two

There's a similar syntax to add a suffix on each element of an array.

I haven't used this particular function on bash versions earlier than 4.2, so be sure to test that it will work on your machine.

  -Greg


jonten

unread,
Nov 24, 2014, 11:46:35 PM11/24/14
to ansible...@googlegroups.com
Many thanks to you all for the nice working solutions! You never get too old to learn new stuff and improving your Bash skills :)

//Jon

Matthew Martin

unread,
Mar 4, 2015, 12:31:19 AM3/4/15
to ansible...@googlegroups.com
Did you get a final resolution on this? I've tried several suggestions here to no avail.

Strangely, when I copy the command line output from jenkins log and run it locally, it works fine! Only when running within jenkins does it fail...

Is jenkins adding some special characters that aren't evident?
Reply all
Reply to author
Forward
0 new messages