Install Redis from source using Ansible?

8,834 views
Skip to first unread message

Nicolas Grilly

unread,
Sep 27, 2013, 9:58:36 AM9/27/13
to ansible...@googlegroups.com
Hello,

I'm trying to install Redis from source using Ansible, and here is the resulting playbook:

- hosts: all

  vars:
    redis_version: 2.6.16

  tasks:
    - name: Download Redis
      shell: creates=/tmp/redis-$redis_version wget -O - http://download.redis.io/releases/redis-$redis_version.tar.gz | tar -xz -C /tmp

    - name: Install Redis
      command: creates=/usr/local/bin/redis-server chdir=/tmp/redis-$redis_version make install
      sudo: yes

    - name: Create user redis
      user: name=redis system=yes home=/var/lib/redis shell=/bin/false
      sudo: yes

    - name: Configure Upstart for Redis
      copy: src=files/upstart_redis.conf dest=/etc/init/redis.conf
      sudo: yes
      notify: Restart Redis

  handlers:
    - name: Restart Redis
      service: name=redis state=restarted
      sudo: yes

upstart_redis.conf content is:

start on runlevel [2345]
stop on runlevel [!2345]
console log
respawn
setuid redis
exec /usr/local/bin/redis-server --bind 127.0.0.1 --dir /var/lib/redis

Any critics? Does this looks good/bad/improvable to you?

Cheers,

Nicolas

Michael DeHaan

unread,
Sep 27, 2013, 10:39:43 AM9/27/13
to ansible...@googlegroups.com
If you're going to set sudo: yes on every task, set it on each play instead, and this will keep things shorter.

You are still using old style variables, and this is terrible, because it repeats this for other users.   {{ redis_version }}

The wget should use the "get_url" module instead, and you can use "register" and "when: othertask.changed" to decide when to extract the tarball.

Don't just configure the service in the handler, as if Redis is down and you rerun the script it won't start it.

Stick a "state=started enabled=yes" in your task section also.

Your make install step since has the directory as a "creates" won't work for upgrades.   You're probably ok with this, but making an OS package for the Redis version you are deploying may be a huge improvement.




--
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.
For more options, visit https://groups.google.com/groups/opt_out.



--
Michael DeHaan <mic...@ansibleworks.com>
CTO, AnsibleWorks, Inc.
http://www.ansibleworks.com/

Jean-Philippe Caruana

unread,
Sep 27, 2013, 11:27:28 AM9/27/13
to ansible...@googlegroups.com
Le 27/09/2013 16:39, Michael DeHaan a �crit :
> The wget should use the "get_url" module instead, and you can use
> "register" and "when: othertask.changed" to decide when to extract the
> tarball.

Hi Michael,

could you be more specific of give an example about this
register/changed behaviour ? I also have unnecessary untar in my
playbooks and I'm looking for a way to do it clean, but I don't find
information easily in the documentation.

(sorry, this is off the topic "install redis")

Thanks.

ps : my redis installation looks like this :) :
- name: Install redis
apt: pkg=redis-server state=present

- name: Start redis
service: name=redis-server state=running enabled=yes

-- Jean-Philippe Caruana

Michael DeHaan

unread,
Sep 27, 2013, 11:33:08 AM9/27/13
to ansible...@googlegroups.com
Something like this:

- get_url: url=http://example.com/tarball.tar.gz dest=/the/tarball.tar.gz 
  register: get_url_result

- shell:  tar -xvf /the/tarball.tar.gz
  when: register.changed

- shell: make install chdir=/whatever/directory
  when: register.changed

This will only download the tarball when it is not already present (saving upstream bandwidth -- always locally cache or have a copy of content and don't have a hundred nodes hit the same upstream server!  That's not fair to the upstream and it's also slow), but will only extract it when it has needed to be downloaded.

This will make your playbooks both faster and more repeatable.




On Fri, Sep 27, 2013 at 11:27 AM, Jean-Philippe Caruana <j...@target2sell.com> wrote:
--
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.
For more options, visit https://groups.google.com/groups/opt_out.

Brian Coca

unread,
Sep 27, 2013, 11:48:03 AM9/27/13
to ansible...@googlegroups.com
Normally I do a -get_url in local action and then copy to all machines (if its from external source, like redis site), this would clobber my bandwidth only and not theirs.

but ... hmm ...  -get_url:  url=torrent:....
might be nice feature for when doing mass installs (might require special deps to be added though)

--
Brian Coca
Stultorum infinitus est numerus
0110000101110010011001010110111000100111011101000010000001111001011011110111010100100000011100110110110101100001011100100111010000100001
Pedo mellon a minno

Jean-Philippe Caruana

unread,
Sep 27, 2013, 11:49:49 AM9/27/13
to ansible...@googlegroups.com
Le 27/09/2013 17:33, Michael DeHaan a �crit :
> Something like this:
>
> - get_url: url=http://example.com/tarball.tar.gz dest=/the/tarball.tar.gz
> register: get_url_result
>
> - shell: tar -xvf /the/tarball.tar.gz
> when: register.changed
>
> - shell: make install chdir=/whatever/directory
> when: register.changed
>
> This will only download the tarball when it is not already present
> (saving upstream bandwidth -- always locally cache or have a copy of
> content and don't have a hundred nodes hit the same upstream server!
> That's not fair to the upstream and it's also slow), but will only
> extract it when it has needed to be downloaded.
>
> This will make your playbooks both faster and more repeatable.

I think you meant
when: get_url_result.changed

Otherwise it fails :
TASK: [Extract Java archive]
**************************************************
fatal: [localhost] => error while evaluating conditional: {% if
register.changed %} True {% else %} False {% endif %}

FATAL: all hosts have already failed -- aborting


Thank you ! My playbook runs now faster !

-- Jean-Philippe Caruana

Michael DeHaan

unread,
Sep 27, 2013, 12:54:46 PM9/27/13
to ansible...@googlegroups.com
Yep, I did.

Glad it's working out!




On Fri, Sep 27, 2013 at 11:49 AM, Jean-Philippe Caruana <j...@target2sell.com> wrote:

-- Jean-Philippe Caruana

--
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.
For more options, visit https://groups.google.com/groups/opt_out.

Nicolas Grilly

unread,
Sep 27, 2013, 2:18:12 PM9/27/13
to ansible...@googlegroups.com
Thank you Michael for your critical review of my playbook. My comments hereunder.

On Fri, Sep 27, 2013 at 4:39 PM, Michael DeHaan <mic...@ansibleworks.com> wrote:
You are still using old style variables, and this is terrible, because it repeats this for other users.   {{ redis_version }}

Yes, my mistake. Maybe ansible-playbook could print a deprecation warning to make sure everyone is aware of this?
 
The wget should use the "get_url" module instead, and you can use "register" and "when: othertask.changed" to decide when to extract the tarball.

Yes, get_url is nicer. I still prefer to use creates= in the commands after get_url, instead of relying on the result of get_url, just in case something fails after the download and leaves the system in an incoherent state.
 
Don't just configure the service in the handler, as if Redis is down and you rerun the script it won't start it.
Stick a "state=started enabled=yes" in your task section also.

I use upstart. I think enabled=yes is unnecessary when using upstart, because the simple presence of redis.conf in /etc/init is enough to enable automatic start on reboot?

I had a look to the source of /library/system/service and it looks like it's still using the "old" update-rc.d even when running on Ubuntu and using pure upstart scripts?

Your make install step since has the directory as a "creates" won't work for upgrades.   You're probably ok with this, but making an OS package for the Redis version you are deploying may be a huge improvement.

Yes, I'm aware of this limitation. :) 

Here is the modified playbook:

- hosts: all
  sudo: yes

  vars:
    redis_version: 2.6.16

  tasks:
    - name: Download Redis

    - name: Untar Redis
      command: chdir=/tmp creates=redis-{{redis_version}} tar -xzf redis-{{redis_version}}.tar.gz

    - name: Install Redis
      command: creates=/usr/local/bin/redis-server chdir=/tmp/redis-{{redis_version}} make install

    - name: Create user redis
      user: name=redis system=yes home=/var/lib/redis shell=/bin/false

    - name: Configure Upstart for Redis
      copy: src=files/upstart_redis.conf dest=/etc/init/redis.conf
      notify: Restart Redis

    - name: Start Redis
      service: name=redis state=started

Brian Coca

unread,
Sep 27, 2013, 2:51:18 PM9/27/13
to ansible...@googlegroups.com
debian based distros all will default to starting a service when it is installed., so enabled= is not always needed on install as it is the default state, but it is prudent to add in case someone manually disables it.

Michael DeHaan

unread,
Sep 27, 2013, 11:21:33 PM9/27/13
to ansible...@googlegroups.com
re: old style variables

It's not strictly deprecated in that it doesn't have a decided date yet, it's just heavily discouraged.

It will likely generate a deprecation warning in future releases though as it's valid in bash it may not.




--
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.
For more options, visit https://groups.google.com/groups/opt_out.
Reply all
Reply to author
Forward
0 new messages