I've been using Ansible for a few years, mostly for server provisioning and configuration management. I think it's a fantastic tool. For a new project, I've also begun to attempt to use Ansible as a web application deployment tool where I would have previously used ant. However, there are a couple of snags that have me questioning whether the Ansible model is the best fit for this type of task.
For example, the first thing I want to is download the deployment artefact from Jenkins. This is only available internally, so my plan was to download locally and then upload to the production servers. I quickly realised that this was totally different to anything I'd done before as I was trying to perform a task that wasn't really associated with any remote hosts. After a bit of searching, I found this: - hosts: 127.0.0.1 connection: local Which works perfectly well, and could have been designed for exactly this type of task, but it feels a bit like trying to fit a round peg in to a square hole. I understand that since all modules assume that they are executing within the context of a host, there is really no other way it could be, but it got me thinking if Ansible is a good place to write these type of non-host specific, pre-deployment steps? The next challenge then was to have the play book prompt the user for the job and build to deploy. var_prompt seemed perfect for this, so I ended up with a playbook like so: - hosts: 127.0.0.1 connection: local vars_prompt: jenkins_job: "Job Name" jenkins_build: "Build Number" roles: - jenkinsfetch - hosts: dashboards roles: - { role: uploadapp, app_name: 'dashboard' } Which seemed to work well until I tried to reference jenkins_job and jenkins_build from within the uploadapp role and couldn't: TASK: [uploadapp | upload build tar] *************************************** fatal: [local.dev] => One or more undefined variables: 'jenkins_job' is undefined FATAL: all hosts have already failed -- aborting I spent a bit of time trying to figure out how to make these variables visible across the plays but couldn't. I tried set_fact, which didn't work as it's host specific. I tried to include both roles within the same play but couldn't (obviously as I don't want to run uploadapp on 127.0.0.1) and finally just resolved to put the variables as part of a global var file rather than prompt for them. I can workaround this works, but it feels to me like I'm trying to make Ansible do something it really doesn't want to. The variable problem also came up when I wanted to abbreviate some paths within my jenkinsfetch role: --- - name: create builds dir file: > path=/tmp/builds/{{jenkins_job}} state=directory - name: fetch build from jenkins get_url: > url={{jenkins_url}}/job/{{jenkins_job}}/{{jenkins_build}}/artifact/build/output/{{jenkins_job}}_{{jenkins_build}}.tar.gz dest=/tmp/builds/{{jenkins_job}} So rather than reference /tmp/builds/{{jenkins_job}} twice, I wanted to redefine a new variable, something along the lines of: --- - name: set build dir var: > name=build_dir value=/tmp/builds/{{jenkins_job}} - name: create builds dir file: > path=/tmp/builds/{{jenkins_job}} state=directory In this case, set_fact may happen to work, but I'm not setting a fact about a host, I'm just wanting to define a new variable (and have that visible across the rest of the plays). So I will carry on, but given these small snags, I'm curious if anyone else has had the same experience - that when trying to implement a set of deployment steps in Ansible, it sometimes feels like trying to force the tool to do something it wasn't designed for? Thanks -- 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-project+unsubscr...@googlegroups.com. To post to this group, send email to ansible-project@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/a66caad5-c6b8-4244-aa17-9b1c5d7d13d7%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.