Version 73 (modified by, 4 years ago) (diff)


Converting the Hello GENI Install Script to Ansible

Image Map

4. Configure and Initialize

omni comes with a script, readyToLogin which finds the login information for nodes in your slice. As of omni version 2.8, readyToLogin has an --ansible-inventory flag which generates the Ansible inventory, which is a flat file which tells Ansible the name and login information for your nodes.

  1. Create your Ansible inventory file:

    On your local machine:

    $ readyToLogin MYSLICE --useSliceAggregates --ansible-inventory -o
    $ cat inventory

    Example output of running these commands:

    $ readyToLogin MYSLICE --useSliceAggregates --ansible-inventory -o
    Host info saved in inventory file: /Users/jdoe/projects/GENI/hellogeni/inventory
    $ cat inventory
    client  ansible_ssh_port=33850
    Tip If your GENI Username is different than your username on your local machine, append the following information to each line of the `inventory` file:
    ansible_ssh_user = GENIUSERNAME
    Your GENIUSERNAME is shown in the header of the GENI Portal in the upper right hand corner.
    Tip Windows users should copy their 'inventory' file onto their node running the ansible client.
  2. Be sure your private key has been added to your SSH agent:
    ssh-add /path/to/your/private/key
  3. Check to see if your nodes are up and ready.

    This command uses the ping module to ping the specified nodes (in this case all) listed in the inventory file:

    $ ansible -i inventory all -m ping 

    Example output showing all of the nodes responding to ping:

    $ ansible -i inventory all -m ping 
    client | success >> {
        "changed": false,
        "ping": "pong"
    server | success >> {
        "changed": false,
        "ping": "pong"
  4. Try using the ping module in Ansible to only ping server or client by replacing all in the above with server or client.

5. Execute Experiment

Tip The following are some example Ansible Ad Hoc commands. You can run these commands one at a time from the machine where you have Ansible installed. `-s` tells Ansible to use `sudo` when executing the command. All modules are described in the Ansible Documentation.

`apt` module is used to install packages using the apt package manager:

ansible [-i inventory] [all/server/client] -s -m apt -a "name=apache2 update_cache=yes"

`command` module is used to execute an arbitrary command on the remote node:

ansible [-i inventory] [all/server/client]  -s -m command -a "/usr/sbin/a2enmod status"

`file` module is used to set attributes of files:

ansible [-i inventory] [all/server/client] -s -m file -a "path=/var/www/html state=absent"

`synchronize` module is an implementation of rsync and is used to efficiently synchronize files between your local machine and a remote node:

ansible [-i inventory] [all/server/client] -s  -m synchronize \
    -a "src=website/index.html dest=/var/www"

`lineinfile` module is used to see if an arbitrary line exists in a file:

ansible [-i inventory] [all/server/client] -s  -m lineinfile \
     -a "line='ExtendedStatus On' dest=/etc/apache2/conf.d/extendedstatus create=yes state=present"

`service` module is used to start/stop/restart/etc services:

ansible [-i inventory] [all/server/client] -s  -m service -a "name=apache2 state=restarted"
  1. Using the above Ad Hoc Ansible commands configure the client node by doing the following:
    1. on both client and server, install apache2 and iperf
    2. copy the scripts directory into /local on the client node with permissions 755.
    3. verify the above three items have been done.

      Log into the client node and run:

      $ apache2 -v
      $ iperf -v
      $ ls /local/scripts
Tip Ansible commands can be collected into files called Playbooks. Playbooks are in a configuration file format called YAML which is very straightforward. In particular, Ansible Ad Hoc commands easily map to commands used in an Ansible Playbook.
Tip Use the `name` construct to leave a comment describing the Ansible command you are running.

The Playbook to configure the client node as in the install script is as follows:

- name: Configure client
  hosts: client
  sudo: True
   - name: install apache2
     apt: name=apache2 update_cache=yes
   - name: install iperf
     apt: name=iperf update_cache=yes
   - name: copy scripts into /local with permissions 755
     synchronize: src=scripts dest=/local mode=755

Do these commands look like the Ad Hoc commands you came up with in the previous step?

Put the above content in a file called hello-client.yml.

Run the playbook with the following command on the local machine:

ansible-playbook hello-client.yml -i inventory
  1. Using the above Ansible modules, configure the server node by reproducing the steps in the HelloGENI install script for the server node. As you find a command that works, use it to construct a hello-server.yml playbook. (See the solution or `hello-server.yml`)

    Here is a template you can fill in to create the hello-server.yml file:

    - name: Configure server
      hosts: server
      sudo: True
       - name: install apache2
         apt: name=apache2 update_cache=yes
       - name: install iperf
         apt: name=iperf update_cache=yes
       - name: /usr/sbin/a2enmod status
       - name: check /etc/apache2/mods-enabled/status.conf file is absent
       - name: copy website/index.html into /var/www
       - name: copy the website/graphics directory into /var/www
       - name: rm -rf /var/www/html
       - name: Make simlink to webfiles
       - name: restart apache2 service
       - name: Make sure /etc/apache2/conf.d/extendedstatus file contains "ExtendedStatus On"
       - name: Make sure /etc/apache2/sites-available/default contains Location information
           dest: /etc/apache2/sites-available/default  
           create: yes 
           state: present 
           insertafter: EOF 
           backup: yes
           regexp: "{{ item.regexp }}"
           line: "{{ item.line }}"
           - { regexp: '^<Location /server-status>', line: '<Location /server-status>' }
           - { regexp: '^   SetHandler server-status', line: '   SetHandler server-status' }
           - { regexp: '^   Allow from all', line: '   Allow from all' }
           - { regexp: '^</Location>', line: '</Location>' }
       - name: create directory for iperf logs in /var/www/iperflogs with permissions of 755
  2. Run both the client and server playbooks on your nodes.
  3. Start the iperf and wget traffic:

    On the local node do:

    ansible -i inventory server -s -m shell -a "iperf -s -i 10 &> /var/www/iperflogs/iperf-server.log" 

    On the local node do:

    ansible -i inventory client -s -m shell -a "/local/scripts/ &"
    ansible -i inventory client -s -m shell -a "/local/scripts/ &"
  4. Browse to the server node (as in the original HelloGENI example). Do you see the same behavior you saw when you ran the original HelloGENI exercise?

6. Analyze Experiment

  1. You may have noticed that the server playbook and the client playbook contained duplicate commands. This is because both nodes need to have apache installed so that they can act as webservers. As you might have guessed, there is a way to modularize this configuration. In Ansible this is done with "roles".
  2. Explore some of the intermediate features of Ansible such as roles, variables, and handlers.


Next: Finish