[20130321]
|
Ansible, EC2 and NetBSD final milestone 4 reached: Web and DB on separate VMs in the cloud
In the fourth and last step on my journey to use
Ansible
to bring a non-trivial system of a Web server and a DB server into
Amazon's EC2 cloud, this is the final step.
After starting out with a local VMware VM and making first steps
with Ansible and EC2, the
previous step was to push a single system
into the cloud. Now, the final step is to setup two distinct VMs, one
for the database and one for the webserver, and then make them known
to each other.
The single steps are:
- Prepare the two VMs
- Basic setup for all systems
- Install the database server
- Install the webserver
- Connect database and webserver
Again, here are all the steps in detail:
- As before, ensure local time is correct when talking to Amazon,
and also make sure the SSH agent has the proper key loaded.
% date
Thu Mar 21 00:45:37 CET 2013
% ssh-add -l
2048 d5:25:19:3d:59:40:35:32:03:f7:c5:83:de:19:b6:d0 ../../euca2ools/key-eucaHF.pem (RSA)
- Make sure security groups are setup properly. We use one group
for the database server, and one for the webserver. This defines the
access permissions from the internet, and also allows to identify
systems for their individual configuration and also for connecting
them in the final step:
% euca-describe-groups
...
GROUP sg-ae54b3c5 749335780469 ec2-dbservers Database servers
PERMISSION 749335780469 ec2-dbservers ALLOWS tcp 22 22 FROM CIDR 0.0.0.0/0
PERMISSION 749335780469 ec2-dbservers ALLOWS tcp 3306 3306 FROM CIDR 0.0.0.0/0
PERMISSION 749335780469 ec2-dbservers ALLOWS icmp -1 -1 FROM CIDR 0.0.0.0/0
GROUP sg-a854b3c3 749335780469 ec2-webservers Web servers
PERMISSION 749335780469 ec2-webservers ALLOWS tcp 22 22 FROM CIDR 0.0.0.0/0
PERMISSION 749335780469 ec2-webservers ALLOWS tcp 80 80 FROM CIDR 0.0.0.0/0
PERMISSION 749335780469 ec2-webservers ALLOWS icmp -1 -1 FROM CIDR 0.0.0.0/0
- Now, run our playbook to setup the two VMs. This uses the single
playbook from the previous milestone, and just runs it twice with
different security groups:
% ansible-playbook -i hosts-HF config-ec2-prepare-db+web-vm.yml
PLAY [localhost] *********************
TASK: [ec2-webservers | Launch new EC2 instance] *********************
changed: [127.0.0.1]
TASK: [ec2-webservers | Give the system 30 seconds to boot up] *********************
changed: [127.0.0.1]
TASK: [ec2-webservers | Get rid of SSH "Are you sure you want to continue connecting (yes/no)?" query] *********************
changed: [127.0.0.1]
TASK: [ec2-webservers | Fix /usr/bootstrap.sh to run pkgin with -y] *********************
changed: [127.0.0.1] => (item={'cmd': 'install /usr/bootstrap.sh /usr/bootstrap.sh.orig'})
changed: [127.0.0.1] => (item={'cmd': 'chmod +w /usr/bootstrap.sh'})
changed: [127.0.0.1] => (item={'cmd': 'sed "s,bin/pkgin update,bin/pkgin -y update," /usr/bootstrap.sh'})
changed: [127.0.0.1] => (item={'cmd': 'chmod -w /usr/bootstrap.sh'})
TASK: [ec2-webservers | Install pkgin via /usr/bootstrap.sh] *********************
changed: [127.0.0.1] => (item={'cmd': u'env PATH=/usr/sbin:${PATH} /usr/bootstrap.sh binpkg'})
TASK: [ec2-webservers | Copy over Ansible binary package] *********************
changed: [127.0.0.1]
TASK: [ec2-webservers | Install Ansible dependencies] *********************
changed: [127.0.0.1]
TASK: [ec2-webservers | Install Ansible package (manually)] *********************
changed: [127.0.0.1]
TASK: [ec2-webservers | Setup lame /usr/bin/python symlink] *********************
changed: [127.0.0.1]
TASK: [ec2-dbservers | Launch new EC2 instance] *********************
changed: [127.0.0.1]
TASK: [ec2-dbservers | Give the system 30 seconds to boot up] *********************
changed: [127.0.0.1]
TASK: [ec2-dbservers | Get rid of SSH "Are you sure you want to continue connecting (yes/no)?" query] *********************
changed: [127.0.0.1]
TASK: [ec2-dbservers | Fix /usr/bootstrap.sh to run pkgin with -y] *********************
changed: [127.0.0.1] => (item={'cmd': 'install /usr/bootstrap.sh /usr/bootstrap.sh.orig'})
changed: [127.0.0.1] => (item={'cmd': 'chmod +w /usr/bootstrap.sh'})
changed: [127.0.0.1] => (item={'cmd': 'sed "s,bin/pkgin update,bin/pkgin -y update," /usr/bootstrap.sh'})
changed: [127.0.0.1] => (item={'cmd': 'chmod -w /usr/bootstrap.sh'})
TASK: [ec2-dbservers | Install pkgin via /usr/bootstrap.sh] *********************
changed: [127.0.0.1] => (item={'cmd': u'env PATH=/usr/sbin:${PATH} /usr/bootstrap.sh binpkg'})
TASK: [ec2-dbservers | Copy over Ansible binary package] *********************
changed: [127.0.0.1]
TASK: [ec2-dbservers | Install Ansible dependencies] *********************
changed: [127.0.0.1]
TASK: [ec2-dbservers | Install Ansible package (manually)] *********************
changed: [127.0.0.1]
TASK: [ec2-dbservers | Setup lame /usr/bin/python symlink] *********************
changed: [127.0.0.1]
PLAY RECAP *********************
127.0.0.1 : ok=18 changed=18 unreachable=0 failed=0
- Just to make sure, check that the two instances run properly, and
are in the right security groups, ec2-webservers and ec2-dbservers:
% euca-describe-instances
RESERVATION r-a419f9d9 749335780469 ec2-webservers
INSTANCE i-21b7c441 ami-5d0f8034 ...
RESERVATION r-641efe19 749335780469 ec2-dbservers
INSTANCE i-54a2ab3e ami-5d0f8034 ...
- Next, bring the two freshly setup systems (which are already
capable of acting as ansible targets) up to our basic system setup:
% env ANSIBLE_HOSTS=./ec2.py ansible-playbook config-ec2-basic.yml
PLAY [security_group_ec2-webservers;security_group_ec2-dbservers] *********************
TASK: [ping] *********************
ok: [ec2-54-235-44-118.compute-1.amazonaws.com]
ok: [ec2-54-234-139-151.compute-1.amazonaws.com]
TASK: [Install tcsh] *********************
changed: [ec2-54-235-44-118.compute-1.amazonaws.com]
changed: [ec2-54-234-139-151.compute-1.amazonaws.com]
TASK: [Add user feyrer] *********************
changed: [ec2-54-234-139-151.compute-1.amazonaws.com]
changed: [ec2-54-235-44-118.compute-1.amazonaws.com]
TASK: [Create ~feyrer/.ssh directory] *********************
changed: [ec2-54-235-44-118.compute-1.amazonaws.com]
changed: [ec2-54-234-139-151.compute-1.amazonaws.com]
TASK: [Enable ssh login with ssh-key] *********************
changed: [ec2-54-235-44-118.compute-1.amazonaws.com]
changed: [ec2-54-234-139-151.compute-1.amazonaws.com]
TASK: [Install sudo] *********************
changed: [ec2-54-235-44-118.compute-1.amazonaws.com]
changed: [ec2-54-234-139-151.compute-1.amazonaws.com]
TASK: [Enable PW-less sudo-access for everyone in group 'wheel'] *********************
changed: [ec2-54-234-139-151.compute-1.amazonaws.com]
changed: [ec2-54-235-44-118.compute-1.amazonaws.com]
TASK: [Disable ssh logins as root] *********************
ok: [ec2-54-235-44-118.compute-1.amazonaws.com]
ok: [ec2-54-234-139-151.compute-1.amazonaws.com]
PLAY RECAP *********************
ec2-54-234-139-151.compute-1.amazonaws.com : ok=8 changed=6 unreachable=0 failed=0
ec2-54-235-44-118.compute-1.amazonaws.com : ok=8 changed=6 unreachable=0 failed=0
- Check:
% ssh ec2-54-234-139-151.compute-1.amazonaws.com id
uid=1000(feyrer) gid=100(users) groups=100(users),0(wheel)
%
% ssh ec2-54-235-44-118.compute-1.amazonaws.com id
uid=1000(feyrer) gid=100(users) groups=100(users),0(wheel)
- Now that the two machines run with our basline configuration,
install their individual software and settings. First the
database server:
% env ANSIBLE_HOSTS=./ec2.py ansible-playbook config-ec2-dbserver.yml
PLAY [security_group_ec2-dbservers] *********************
TASK: [Install mysql] *********************
changed: [ec2-54-235-44-118.compute-1.amazonaws.com]
TASK: [Install MySQL rc.d script] *********************
changed: [ec2-54-235-44-118.compute-1.amazonaws.com]
TASK: [Start MySQL service] *********************
changed: [ec2-54-235-44-118.compute-1.amazonaws.com]
TASK: [Install python-mysqldb (for mysql_user module)] *********************
changed: [ec2-54-235-44-118.compute-1.amazonaws.com]
TASK: [Setup DB] *********************
changed: [ec2-54-235-44-118.compute-1.amazonaws.com]
TASK: [Add db-user] *********************
changed: [ec2-54-235-44-118.compute-1.amazonaws.com]
TASK: [Copy over DB template] *********************
changed: [ec2-54-235-44-118.compute-1.amazonaws.com]
TASK: [Import DB data] *********************
changed: [ec2-54-235-44-118.compute-1.amazonaws.com]
PLAY RECAP *********************
ec2-54-235-44-118.compute-1.amazonaws.com : ok=8 changed=8 unreachable=0 failed=0
- Check and see if the database works as expected:
% ssh -t ec2-54-235-44-118.compute-1.amazonaws.com mysql -u webapp -p webapp
Enter password: ****
...
mysql> show tables;
+------------------+
| Tables_in_webapp |
+------------------+
| names |
+------------------+
1 row in set (0.01 sec)
mysql> select * from names;
+----+--------+------+
| id | first | last |
+----+--------+------+
| 1 | Donald | Duck |
| 2 | Daisy | Duck |
+----+--------+------+
2 rows in set (0.00 sec)
mysql> bye
- Excellent. Now setup the webserver, too:
% env ANSIBLE_HOSTS=./ec2.py ansible-playbook config-ec2-webserver.yml
PLAY [security_group_ec2-webservers] *********************
TASK: [Installing ap24-php53 package and dependencies] *********************
changed: [ec2-54-234-139-151.compute-1.amazonaws.com]
TASK: [Install Apache rc.d script] *********************
changed: [ec2-54-234-139-151.compute-1.amazonaws.com]
TASK: [Enable and start Apache service] *********************
changed: [ec2-54-234-139-151.compute-1.amazonaws.com]
TASK: [Enable PHP in Apache config file] *********************
changed: [ec2-54-234-139-151.compute-1.amazonaws.com] => (item={'re': 'LoadModule.*mod_php5.so', 'l': 'LoadModule php5_module lib/httpd/mod_php5.so'})
changed: [ec2-54-234-139-151.compute-1.amazonaws.com] => (item={'re': 'AddHandler.*x-httpd-php', 'l': 'AddHandler application/x-httpd-php .php'})
TASK: [Make Apache read index.php] *********************
changed: [ec2-54-234-139-151.compute-1.amazonaws.com]
TASK: [Add simple PHP test - see http://10.0.0.181/phptest.php] *********************
changed: [ec2-54-234-139-151.compute-1.amazonaws.com]
TASK: [Install phpmyadmin] *********************
changed: [ec2-54-234-139-151.compute-1.amazonaws.com]
TASK: [Enable phpmyadmin in Apache config] *********************
changed: [ec2-54-234-139-151.compute-1.amazonaws.com]
TASK: [Fix Apache access control for phpmyadmin] *********************
changed: [ec2-54-234-139-151.compute-1.amazonaws.com]
TASK: [Enable PHP modules in PHP config file] *********************
changed: [ec2-54-234-139-151.compute-1.amazonaws.com] => (item={'re': '^extension.*zlib.so', 'l': 'extension=zlib.so'})
changed: [ec2-54-234-139-151.compute-1.amazonaws.com] => (item={'re': '^extension.*zip.so', 'l': 'extension=zip.so'})
changed: [ec2-54-234-139-151.compute-1.amazonaws.com] => (item={'re': '^extension.*mysqli.so', 'l': 'extension=mysqli.so'})
changed: [ec2-54-234-139-151.compute-1.amazonaws.com] => (item={'re': '^extension.*mysql.so', 'l': 'extension=mysql.so'})
changed: [ec2-54-234-139-151.compute-1.amazonaws.com] => (item={'re': '^extension.*mcrypt.so', 'l': 'extension=mcrypt.so'})
changed: [ec2-54-234-139-151.compute-1.amazonaws.com] => (item={'re': '^extension.*mbstring.so', 'l': 'extension=mbstring.so'})
changed: [ec2-54-234-139-151.compute-1.amazonaws.com] => (item={'re': '^extension.*json.so', 'l': 'extension=json.so'})
changed: [ec2-54-234-139-151.compute-1.amazonaws.com] => (item={'re': '^extension.*gd.so', 'l': 'extension=gd.so'})
changed: [ec2-54-234-139-151.compute-1.amazonaws.com] => (item={'re': '^extension.*gettext.so', 'l': 'extension=gettext.so'})
changed: [ec2-54-234-139-151.compute-1.amazonaws.com] => (item={'re': '^extension.*bz2.so', 'l': 'extension=bz2.so'})
TASK: [Create directory for webapp] *********************
changed: [ec2-54-234-139-151.compute-1.amazonaws.com]
TASK: [Deploy example webapp] *********************
changed: [ec2-54-234-139-151.compute-1.amazonaws.com]
TASK: [Create webapp symlink for easy access] *********************
changed: [ec2-54-234-139-151.compute-1.amazonaws.com]
NOTIFIED: [restart apache] *********************
changed: [ec2-54-234-139-151.compute-1.amazonaws.com]
PLAY RECAP *********************
ec2-54-234-139-151.compute-1.amazonaws.com : ok=14 changed=14 unreachable=0 failed=0
- Again, test:
% links -dump ec2-54-234-139-151.compute-1.amazonaws.com/
It works!
%
% links -dump http://ec2-54-234-139-151.compute-1.amazonaws.com/phptest.php | head
PHP Logo
PHP Version 5.3.17
System NetBSD ip-10-80-61-33.ec2.internal 6.0.1 NetBSD 6.0.1
(XEN3PAE_DOMU) i386
Build Date Dec 14 2012 10:31:13
'./configure' '--with-config-file-path=/usr/pkg/etc'
'--with-config-file-scan-dir=/usr/pkg/etc/php.d'
'--sysconfdir=/usr/pkg/etc' '--localstatedir=/var'
%
% links -dump http://ec2-54-234-139-151.compute-1.amazonaws.com/webapp/
Showing table hf.names:
Cannot connect to database: Can't connect to local MySQL server through
socket '/tmp/mysql.sock' (2)(2002)
- Close to optimum, but the last error is actually expectet: In
order for proper operation, the Database needs to grant the
webserver access, and the web server needs to know where the
database server is. So let's connect them!
This step is done by preparing a shell script on both systems, which
will then be ran to - depending on the system's security group - perform the
proper steps:
% env ANSIBLE_HOSTS=./ec2.py ansible-playbook config-ec2-connections.yml
PLAY [security_group_ec2-webservers;security_group_ec2-dbservers] *********************
TASK: [Collect EC2 host information] *********************
ok: [ec2-54-234-139-151.compute-1.amazonaws.com]
ok: [ec2-54-235-44-118.compute-1.amazonaws.com]
TASK: [Prepare connection-script in /tmp/do-connect-vms.sh] *********************
changed: [ec2-54-234-139-151.compute-1.amazonaws.com]
changed: [ec2-54-235-44-118.compute-1.amazonaws.com]
TASK: [Run connection-script] *********************
changed: [ec2-54-234-139-151.compute-1.amazonaws.com]
changed: [ec2-54-235-44-118.compute-1.amazonaws.com]
PLAY RECAP *********************
ec2-54-234-139-151.compute-1.amazonaws.com : ok=3 changed=2 unreachable=0 failed=0
ec2-54-235-44-118.compute-1.amazonaws.com : ok=3 changed=2 unreachable=0 failed=0
- With that final step, our test web application works, and the
webserver can access the database properly:
% links -dump http://ec2-54-234-139-151.compute-1.amazonaws.com/webapp/
Showing table hf.names:
+--------------------+
| id | first | last |
|----+--------+------|
| 1 | Donald | Duck |
|----+--------+------|
| 2 | Daisy | Duck |
+--------------------+
----------------------------------------------------------------------
Enter new values:
first: _____________________
last: _____________________
[ Submit ]
So much for this exercise. I'll talk about the ansible and euca2ools
packages at
pkgsrcCon 2013 in Berlin.
Join in if you're curious about
what the actual playbooks used in the above examples look like, or
stay tuned to find my presentation and all the data after pkgsrcCon
2013.
[Tags: amazon, ansible, ec2, xen]
|
|