Installing a Development Server

Today I wanted to get started on writing the server code for SyncItStore so needed to set up a dev server. I started installing Ubuntu Server and was keeping notes on the steps I needed to replicated it.

I created virtual guests on my laptop using libvirt backed by LVM storage with a (Virtual Machine Manager)[http://virt-manager.org/] front end.

Installing Ubuntu is a breeze nowadays, I can nearly do it with my eyes closed, but it is the post release stuff that's a little trickier...

Deciding on how to configure the Development Server.

I realise that I should be using something like Puppet or Chef but every time I start researching what is involved they seem overly complicated for my purposes. I'm very capable of doing bits of server admin but figuring out either of those seems too much. I'm mostly a developer so I want something to support my code/configuration, I'm not looking to change profession.

Eventually in my research I came across this Wikipedia article and looked at the table deciding what I wanted... I wanted something that is still being actively maintained, of those I might as well go for one that supports "Verify Mode" as it just seemed like a good idea, so now the list of possibles is down to four! I noticed that Ansible "Manages nodes over SSH and does not require any additional remote software to be installed on them".... Wow that seems perfect, I trust SSH with my whole life, so I'm fine trusting it with my servers!

Installing Ansible

So I read through the Getting Started documentation and decided to give it a go... It's always worth looking to see if there's a package for any software you're going to install already in the Ubuntu repositories, but there wasn't.

    me@laptop:~/Projects/syncitserv $ apt-cache search ansible

No big deal... They supply a PPA for easy installation

    root@laptop:/home/me/Projects/syncitserv# add-apt-repository ppa:rquillo/ansible
root@laptop:/home/me/Projects/syncitserv# apt-get update
root@laptop:/home/me/Projects/syncitserv# apt-cache search ansible

ansible - Ansible Application root@laptop:/home/me/Projects/syncitserv# sudo apt-get install ansible

Installed... What now?

Let's see what we have

    me@laptop:~/Projects/syncitserv $ ansible[TAB][TAB]
ansible ansible-doc ansible-playbook ansible-pull

A few programs

    me@laptop:~/Projects/syncitserv $ ansible --help
Usage: ansible <host-pattern> [options]

Options:
-a MODULE_ARGS, --args=MODULE_ARGS
module arguments
-k, --ask-pass ask for SSH password
-K, --ask-sudo-pass ask for sudo password
-B SECONDS, --background=SECONDS
run asynchronously, failing after X seconds
(default=N/A)
-c CONNECTION, --connection=CONNECTION
connection type to use (default=paramiko)
-f FORKS, --forks=FORKS
specify number of parallel processes to use
(default=5)
-h, --help show this help message and exit
-i INVENTORY, --inventory-file=INVENTORY
specify inventory host file
(default=/etc/ansible/hosts)
-l SUBSET, --limit=SUBSET
further limit selected hosts to an additional pattern
--list-hosts dump out a list of hosts matching input pattern, does
not execute any modules!
-m MODULE_NAME, --module-name=MODULE_NAME
module name to execute (default=command)
-M MODULE_PATH, --module-path=MODULE_PATH
specify path(s) to module library
(default=/usr/share/ansible/)
-o, --one-line condense output
-P POLL_INTERVAL, --poll=POLL_INTERVAL
set the poll interval if using -B (default=15)
--private-key=PRIVATE_KEY_FILE
use this file to authenticate the connection
-s, --sudo run operations with sudo (nopasswd)
-U SUDO_USER, --sudo-user=SUDO_USER
desired sudo user (default=root)
-T TIMEOUT, --timeout=TIMEOUT
override the SSH timeout in seconds (default=10)
-t TREE, --tree=TREE log output to this directory
-u REMOTE_USER, --user=REMOTE_USER
connect as this user (default=me)
-v, --verbose verbose mode (-vvv for more)
--version show program's version number and exit

And it does at least run too, great :-)

The documentation wants you to setup a /etc/ansible/hosts file, which to me seems a bit overkill. I will do work for my full time job on this laptop and work on a few personal projects, so having a centralized list of servers, which require root to edit, does not seem like the right idea. I wanted an ansible/hosts file per project, thankfully it supports it with the -i INVENTORY option.

    me@laptop:~/Projects/syncitserv $ mkdir ansible
me@laptop:~/Projects/syncitserv $ cd ansible/
me@laptop:~/Projects/syncitserv/ansible $ echo '192.168.122.249' > _etc_ansible_hosts

me@laptop:~/Projects/syncitserv/ansible $ ansible all -m ping -i _etc_ansible_hosts
192.168.122.249 | FAILED => FAILED: ssh me@192.168.122.249:22 : Private key file is encrypted
To connect as a different user, use -u <username>.

But it does not yet respond to ping requests... But of course, that's the wrong username.

    me@laptop:~/Projects/syncitserv/ansible $ ansible all -m ping -i _etc_ansible_hosts  -u theadmin
192.168.122.249 | success >> {
"changed": false,
"ping": "pong"
}

Will it work with sudo for root?

    me@laptop:~/Projects/syncitserv/ansible $ ansible all -m ping -i _etc_ansible_hosts  -u theadmin --sudo
^C
ERROR: interupted

Nope, not straight away anyway.

    me@laptop:~/Projects/syncitserv/ansible $  -K
sudo password:
192.168.122.249 | success >> {
"changed": false,
"ping": "pong"
}

But passing in -K will prompt me for a password, though I don't think that's the press a button to deploy a server option that I want...

Added a sudo record on the new server to stop it asking me for passwords

    root@server:/home/theadmin# echo 'theadmin ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/theadmin_has_sudo

Try again...

    me@laptop:~/Projects/syncitserv/ansible $ ansible all -m ping -i _etc_ansible_hosts  -u theadmin --sudo
192.168.122.249 | success >> {
"changed": false,
"ping": "pong"
}

So lets see if we can actually run commands...

    me@laptop:~/Projects/syncitserv/ansible $ ansible all -i _etc_ansible_hosts -u theadmin --sudo -m command -a 'ls /'
192.168.122.249 | success | rc=0 >>
bin
boot
dev
etc
home
initrd.img
initrd.img.old
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
selinux
srv
sys
tmp
usr
var
vmlinuz
vmlinuz.old

Doing something useful

That's a lot of progress with nothing actually achieved, except learning, I think it's always important to get a real step closer to your goal when learning something new. The getting started documentation has a link to Command Line Examples And Next Steps and on there it has a trivial example of using copying a file, but it introduces the concept of modules.

    $ ansible atlanta -m copy -a "src=/etc/hosts dest=/tmp/hosts"

Modules area is really where Ansible becomes useful. I wanted to see if I could install mongodb. I visited the modules page and saw there was an apt command and it takes a few parameters, pkg looks like what I need. Looking at the copy example above it seems like src and dest are keys with /etc/hosts and /tmp/hosts being parameters so substituting my pkg in I get the command:

    me@laptop:~/Projects/syncitserv/ansible $ ansible all --sudo -i _etc_ansible_hosts  -u theadmin -m apt -a 'pkg=mongodb
192.168.122.249 | success >> {
"changed": true
}

Success!