hubertf's NetBSD Blog
Send interesting links to hubert at feyrer dot de!
 
[20130314] Ansible, EC2 and NetBSD milestone 2 reached: Instance preparation and communication
On my quest to use Ansible to get a NetBSD virtual machine into Amazon's EC2 cloud, I've previously described how I use ansible to prepare a local machine. Working from a basic NetBSD setup, the system is setup for basic operation, the configured as both a database server and a Web/PHP server to serve a small demo application.

Now the next step is to replace the VM with an Amazon EC2 instance. I have previously written about how to manage Amazon/EC2 NetBSD instances, and here are the steps that I make to first prepare an EC2 instance with NetBSD and Ansible, and then use a regular Ansible playbook to talk to all my EC2 instances. Note that the connection between the machines setup via euca2ools and ansible is in the security group names. In this case, the security group "ec2-webservers" is assumed to exist.

  1. Make sure SSH agent runs and has the EC2 SSH-key added:
    % ssh-add -l
    Could not open a connection to your authentication agent.
    % eval `ssh-agent`
    Agent pid 9304
    % ssh-add -l
    The agent has no identities.
    % ssh-add .../key-ec2HF.pem 
    Identity added: ../../euca2ools/key-ec2HF.pem (../../euca2ools/key-ec2HF.pem)
    % ssh-add -l
    2048 d5:25:19:3d:59:40:35:32:03:f7:c5:83:de:19:b6:d0 ../../euca2ools/key-ec2HF.pem (RSA)
    % 
    
  2. When using a VM to talk to EC2, pay special attention that it has the correct time, else funny things will happen:
    % date
    Sun Mar 10 14:42:33 CET 2013
    
  3. Setup the ec2-webservers security (firewall) group. This is used both when creating the EC2 instances, and when accessing them. It's the link between EC2 and Ansible's ec2.py script.
    % euca-add-group -d 'Web servers' ec2-webservers
    % euca-authorize -P tcp -p 80-80 -s 0.0.0.0/0 ec2-webservers
    % euca-authorize -P tcp -p 22-22 -s 0.0.0.0/0 ec2-webservers
    % euca-authorize -P icmp -s 0.0.0.0/0 ec2-webservers
    % 
    % euca-describe-groups
    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
    
  4. List out EC2 instances:
    % euca-describe-instances
    % 
    
    None so far.

  5. Let's use our playbook to prepare our first EC2 instance:
    % ansible-playbook -i hosts-HF config-ec2-prepare1vm.yml
    
    PLAY [localhost] ********************* 
    
    TASK: [Launch new EC2 instance] ********************* 
    changed: [127.0.0.1]
    
    TASK: [Give the system 30 seconds to boot up] ********************* 
    changed: [127.0.0.1]
    
    TASK: [Get rid of SSH "Are you sure you want to continue connecting (yes/no)?" query] ********************* 
    changed: [127.0.0.1]
    
    TASK: [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.orig >/usr/bootstrap.sh'})
    changed: [127.0.0.1] => (item={'cmd': 'chmod -w /usr/bootstrap.sh'})
    
    TASK: [Install pkgin via /usr/bootstrap.sh] ********************* 
    changed: [127.0.0.1] => (item={'cmd': u'env PATH=/usr/sbin:${PATH} /usr/bootstrap.sh binpkg'})
    
    TASK: [Copy over Ansible binary package] ********************* 
    changed: [127.0.0.1]
    
    TASK: [Install Ansible dependencies] ********************* 
    changed: [127.0.0.1]
    
    TASK: [Install Ansible package (manually)] ********************* 
    changed: [127.0.0.1]
    
    TASK: [Setup lame /usr/bin/python symlink] ********************* 
    changed: [127.0.0.1]
    
    PLAY RECAP ********************* 
    127.0.0.1                      : ok=9    changed=9    unreachable=0    failed=0    
    
    
    % 
    
  6. There we go. Let's list it:
    % euca-describe-instances
    RESERVATION     r-bb3b6ac1      749335780469    ec2-webservers
    INSTANCE        i-2cb9a45f      ami-a754dbce    ec2-54-234-59-5.compute-1.amazonaws.com \
    	ip-10-243-150-74.ec2.internal   running ec2HF  0               t1.micro        \
    	2013-03-10T13:47:32.000Z        us-east-1a      aki-825ea7eb                    \
    	monitoring-disabled     54.234.59.5     10.243.150.74                   ebs                                                                     
    % 
    
  7. That worked - excellent! Let's add a few more, just for kicks:
    % ansible-playbook -i hosts-HF config-ec2-prepare1vm.yml >&/dev/null & 
    % ansible-playbook -i hosts-HF config-ec2-prepare1vm.yml >&/dev/null & 
    % ansible-playbook -i hosts-HF config-ec2-prepare1vm.yml >&/dev/null & 
    % ansible-playbook -i hosts-HF config-ec2-prepare1vm.yml >&/dev/null & 
    % ansible-playbook -i hosts-HF config-ec2-prepare1vm.yml >&/dev/null & 
    % 
    
    <...wait...>
    
    % euca-describe-instances
    RESERVATION     r-bb3b6ac1      749335780469    ec2-webservers
    INSTANCE        i-2cb9a45f      ami-a754dbce    ec2-54-234-59-5.compute-1.amazonaws.com \
    	ip-10-243-150-74.ec2.internal   running ec2HF  0               t1.micro        \
    	2013-03-10T13:47:32.000Z        us-east-1a      aki-825ea7eb                    \
    	monitoring-disabled     54.234.59.5     10.243.150.74                   ebs                                                                     
    RESERVATION     r-8b3c6df1      749335780469    ec2-webservers
    INSTANCE        i-7cb5a80f      ami-a754dbce    ec2-23-20-42-71.compute-1.amazonaws.com \
    	ip-10-203-73-195.ec2.internal   running ec2HF  0               t1.micro        \
    	2013-03-10T13:50:48.000Z        us-east-1a      aki-825ea7eb                    \
    	monitoring-disabled     23.20.42.71     10.203.73.195                   ebs                                                                     
    RESERVATION     r-733f6e09      749335780469    ec2-webservers
    INSTANCE        i-42b5a831      ami-a754dbce    ec2-23-20-87-176.compute-1.amazonaws.com        \
    	ip-10-116-37-145.ec2.internal   running ec2HF  0               t1.micro        \
    	2013-03-10T13:50:54.000Z        us-east-1a      aki-825ea7eb                    \
    	monitoring-disabled     23.20.87.176    10.116.37.145                   ebs                                                                     
    RESERVATION     r-713f6e0b      749335780469    ec2-webservers
    INSTANCE        i-40b5a833      ami-a754dbce    ec2-54-242-254-237.compute-1.amazonaws.com      \
    	ip-10-195-47-153.ec2.internal   running ec2HF  0               t1.micro        \
    	2013-03-10T13:50:54.000Z        us-east-1a      aki-825ea7eb                    \
    	monitoring-disabled     54.242.254.237  10.195.47.153                   ebs                                                                     
    RESERVATION     r-773f6e0d      749335780469    ec2-webservers
    INSTANCE        i-46b5a835      ami-a754dbce    ec2-54-235-232-227.compute-1.amazonaws.com      \
    	ip-10-194-7-72.ec2.internal     running ec2HF  0               t1.micro        \
    	2013-03-10T13:50:54.000Z        us-east-1a      aki-825ea7eb                    \
    	monitoring-disabled     54.235.232.227  10.194.7.72                     ebs                                                                     
    RESERVATION     r-b72475cd      749335780469    ec2-webservers
    INSTANCE        i-b2adb0c1      ami-a754dbce    ec2-50-16-129-62.compute-1.amazonaws.com        \
    	domU-12-31-39-14-C6-CB.compute-1.internal       running ec2HF  0               t1.micro        \
    	2013-03-10T13:55:24.000Z        us-east-1d      aki-825ea7eb                    \
    	monitoring-disabled     50.16.129.62    10.206.197.53                   ebs                                                                     
    % 
    
  8. Let's talk to our EC2 instances now. For that, we use the ec2.py script, which enumerates all instances:
    % ./ec2.py --list
    {
      "i-2cb9a45f": [
        "ec2-54-234-59-5.compute-1.amazonaws.com"
      ], 
      "i-40b5a833": [
        "ec2-54-242-254-237.compute-1.amazonaws.com"
      ], 
      "i-42b5a831": [
        "ec2-23-20-87-176.compute-1.amazonaws.com"
      ], 
      "i-46b5a835": [
        "ec2-54-235-232-227.compute-1.amazonaws.com"
      ], 
      "i-7cb5a80f": [
        "ec2-23-20-42-71.compute-1.amazonaws.com"
      ], 
      "i-b2adb0c1": [
        "ec2-50-16-129-62.compute-1.amazonaws.com"
      ], 
      "key_ec2HF": [
        "ec2-54-234-59-5.compute-1.amazonaws.com", 
        "ec2-23-20-42-71.compute-1.amazonaws.com", 
        "ec2-23-20-87-176.compute-1.amazonaws.com", 
        "ec2-54-242-254-237.compute-1.amazonaws.com", 
        "ec2-54-235-232-227.compute-1.amazonaws.com", 
        "ec2-50-16-129-62.compute-1.amazonaws.com"
      ], 
      "security_group_ec2-webservers": [
        "ec2-54-234-59-5.compute-1.amazonaws.com", 
        "ec2-23-20-42-71.compute-1.amazonaws.com", 
        "ec2-23-20-87-176.compute-1.amazonaws.com", 
        "ec2-54-242-254-237.compute-1.amazonaws.com", 
        "ec2-54-235-232-227.compute-1.amazonaws.com", 
        "ec2-50-16-129-62.compute-1.amazonaws.com"
      ], 
      "type_t1_micro": [
        "ec2-54-234-59-5.compute-1.amazonaws.com", 
        "ec2-23-20-42-71.compute-1.amazonaws.com", 
        "ec2-23-20-87-176.compute-1.amazonaws.com", 
        "ec2-54-242-254-237.compute-1.amazonaws.com", 
        "ec2-54-235-232-227.compute-1.amazonaws.com", 
        "ec2-50-16-129-62.compute-1.amazonaws.com"
      ], 
      "us-east-1": [
        "ec2-54-234-59-5.compute-1.amazonaws.com", 
        "ec2-23-20-42-71.compute-1.amazonaws.com", 
        "ec2-23-20-87-176.compute-1.amazonaws.com", 
        "ec2-54-242-254-237.compute-1.amazonaws.com", 
        "ec2-54-235-232-227.compute-1.amazonaws.com", 
        "ec2-50-16-129-62.compute-1.amazonaws.com"
      ], 
      "us-east-1a": [
        "ec2-54-234-59-5.compute-1.amazonaws.com", 
        "ec2-23-20-42-71.compute-1.amazonaws.com", 
        "ec2-23-20-87-176.compute-1.amazonaws.com", 
        "ec2-54-242-254-237.compute-1.amazonaws.com", 
        "ec2-54-235-232-227.compute-1.amazonaws.com"
      ], 
      "us-east-1d": [
        "ec2-50-16-129-62.compute-1.amazonaws.com"
      ]
    }
    
  9. ec2.py can also give us information about one instance:
    % ./ec2.py --host ec2-54-234-59-5.compute-1.amazonaws.com
    {
      "ec2__in_monitoring_element": false, 
      "ec2_ami_launch_index": "0", 
      "ec2_architecture": "x86_64", 
      "ec2_client_token": "", 
      "ec2_dns_name": "ec2-54-234-59-5.compute-1.amazonaws.com", 
      "ec2_eventsSet": "", 
      "ec2_group_name": "", 
      "ec2_hypervisor": "xen", 
      "ec2_id": "i-2cb9a45f", 
      "ec2_image_id": "ami-a754dbce", 
      "ec2_instanceState": "", 
      "ec2_instance_type": "t1.micro", 
      "ec2_ip_address": "54.234.59.5", 
      "ec2_item": "", 
      "ec2_kernel": "aki-825ea7eb", 
      "ec2_key_name": "ec2HF", 
      "ec2_launch_time": "2013-03-10T13:47:32.000Z", 
      "ec2_monitored": false, 
      "ec2_monitoring": "", 
      "ec2_networkInterfaceSet": "", 
      "ec2_persistent": false, 
      "ec2_placement": "us-east-1a", 
      "ec2_platform": "", 
      "ec2_previous_state": "", 
      "ec2_private_dns_name": "ip-10-243-150-74.ec2.internal", 
      "ec2_private_ip_address": "10.243.150.74", 
      "ec2_public_dns_name": "ec2-54-234-59-5.compute-1.amazonaws.com", 
      "ec2_ramdisk": "", 
      "ec2_reason": "", 
      "ec2_region": "us-east-1", 
      "ec2_requester_id": "", 
      "ec2_root_device_name": "/dev/sda1", 
      "ec2_root_device_type": "ebs", 
      "ec2_security_group_ids": "sg-a854b3c3", 
      "ec2_security_group_names": "ec2-webservers", 
      "ec2_shutdown_state": "", 
      "ec2_spot_instance_request_id": "", 
      "ec2_state": "running", 
      "ec2_state_code": 16, 
      "ec2_state_reason": "", 
      "ec2_subnet_id": "", 
      "ec2_tenancy": "default", 
      "ec2_virtualization_type": "paravirtual", 
      "ec2_vpc_id": ""
    }
    
  10. Now let's use a regular playbook with the ec2.py script to get a list of all instances in the 'ec2-webservers' group and then use ansible's ping module on all of them:
    % env ANSIBLE_HOSTS=./ec2.py ansible-playbook config-ec2-basic.yml
    
    PLAY [security_group_ec2-webservers] ********************* 
    
    GATHERING FACTS ********************* 
    ok: [ec2-50-16-129-62.compute-1.amazonaws.com]
    ok: [ec2-54-235-232-227.compute-1.amazonaws.com]
    ok: [ec2-23-20-42-71.compute-1.amazonaws.com]
    ok: [ec2-23-20-87-176.compute-1.amazonaws.com]
    ok: [ec2-54-242-254-237.compute-1.amazonaws.com]
    ok: [ec2-54-234-59-5.compute-1.amazonaws.com]
    
    TASK: [ping] ********************* 
    ok: [ec2-54-235-232-227.compute-1.amazonaws.com]
    ok: [ec2-50-16-129-62.compute-1.amazonaws.com]
    ok: [ec2-23-20-87-176.compute-1.amazonaws.com]
    ok: [ec2-23-20-42-71.compute-1.amazonaws.com]
    ok: [ec2-54-234-59-5.compute-1.amazonaws.com]
    ok: [ec2-54-242-254-237.compute-1.amazonaws.com]
    
    PLAY RECAP ********************* 
    ec2-23-20-42-71.compute-1.amazonaws.com : ok=2    changed=0    unreachable=0    failed=0    
    ec2-23-20-87-176.compute-1.amazonaws.com : ok=2    changed=0    unreachable=0    failed=0    
    ec2-50-16-129-62.compute-1.amazonaws.com : ok=2    changed=0    unreachable=0    failed=0    
    ec2-54-234-59-5.compute-1.amazonaws.com : ok=2    changed=0    unreachable=0    failed=0    
    ec2-54-235-232-227.compute-1.amazonaws.com : ok=2    changed=0    unreachable=0    failed=0    
    ec2-54-242-254-237.compute-1.amazonaws.com : ok=2    changed=0    unreachable=0    failed=0    
    
    
    % 
    
  11. Finally, clean up and use euca-terminate-instance to delete all instances:
    % euca-describe-instances | grep INSTANCE | awk '{print $2}' | xargs -n 1 euca-terminate-instances
    INSTANCE        i-60829f13
    INSTANCE        i-2cb9a45f
    INSTANCE        i-7cb5a80f
    INSTANCE        i-42b5a831
    INSTANCE        i-40b5a833
    INSTANCE        i-46b5a835
    INSTANCE        i-b2adb0c1
    % euca-describe-instances
    RESERVATION     r-bb3b6ac1      749335780469    ec2-webservers
    INSTANCE        i-2cb9a45f      ami-a754dbce                    terminated      ec2HF  \
    	0               t1.micro        2013-03-10T13:47:32.000Z        us-east-1a      \
    	aki-825ea7eb                    monitoring-disabled                                     ebs                                                                     
    RESERVATION     r-8b3c6df1      749335780469    ec2-webservers
    INSTANCE        i-7cb5a80f      ami-a754dbce                    terminated      ec2HF  \
    	0               t1.micro        2013-03-10T13:50:48.000Z        us-east-1a      \
    	aki-825ea7eb                    monitoring-disabled                                     ebs                                                                     
    RESERVATION     r-733f6e09      749335780469    ec2-webservers
    INSTANCE        i-42b5a831      ami-a754dbce                    terminated      ec2HF  \
    	0               t1.micro        2013-03-10T13:50:54.000Z        us-east-1a      \
    	aki-825ea7eb                   monitoring-disabled                                     ebs                                                                     
    RESERVATION     r-713f6e0b      749335780469    ec2-webservers
    INSTANCE        i-40b5a833      ami-a754dbce                    terminated      ec2HF  \
    	0               t1.micro        2013-03-10T13:50:54.000Z        us-east-1a      \
    	aki-825ea7eb                    monitoring-disabled                                     ebs                                                                     
    RESERVATION     r-773f6e0d      749335780469    ec2-webservers
    INSTANCE        i-46b5a835      ami-a754dbce                    terminated      ec2HF  \
    	0               t1.micro        2013-03-10T13:50:54.000Z        us-east-1a      \
    	aki-825ea7eb                    monitoring-disabled                                     ebs                                                                     
    RESERVATION     r-b72475cd      749335780469    ec2-webservers
    INSTANCE        i-b2adb0c1      ami-a754dbce                    terminated      ec2HF  \
    	0               t1.micro        2013-03-10T13:55:24.000Z        us-east-1d      \
    	aki-825ea7eb                    monitoring-disabled                                     ebs                                                             
    % 
    
  12. The terminated instances will be removed by EC2 eventually, and you can start all over.
With the above steps and the previous work to use Ansible to setup a NetBSD system with basic configuration as database- and webserver the next step is to put those two things together, and get a (single) NetBSD machine into the Amazon cloud that serves as both database and webserver.

Let's stay tune for this to happen!

Shameless plug: 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!

References: CapsUnlock blog post, CentOS Wiki.

[Tags: , , ]


Disclaimer: All opinion expressed here is purely my own. No responsibility is taken for anything.

Access count: 36116061
Copyright (c) Hubert Feyrer