= [http://groups.geni.net/geni/wiki/GENIExperimenter/Tutorials/AnsibleHelloGENI Converting the Hello GENI Install Script to Ansible] = {{{ #!html
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. a. Create your Ansible inventory file: {{{ #!div style="background: #ffd; border: 3px ridge; width: 800px;" On your local machine: {{{ #!sh $ readyToLogin MYSLICE --useSliceAggregates --ansible-inventory -o $ cat inventory }}} Example output of running these commands: {{{ #!sh $ readyToLogin MYSLICE --useSliceAggregates --ansible-inventory -o Host info saved in inventory file: /Users/jdoe/projects/GENI/hellogeni/inventory $ cat inventory client ansible_ssh_host=pc3.instageni.clemson.edu ansible_ssh_port=33850 server ansible_ssh_host=pcvm3-6.instageni.clemson.edu }}} {{{ #!html
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.
}}} }}} {{{ #!div style="background: #fdd; border: 3px ridge; width: 800px;" {{{ #!html
Tip Windows users should copy their 'inventory' file onto their node running the ansible client.
}}} }}} b. Be sure your private key has been added to your SSH agent: {{{ #!div style="background: #ffd; border: 3px ridge; width: 800px;" {{{ ssh-add /path/to/your/private/key }}} }}} c. Check to see if your nodes are up and ready. {{{ #!div style="background: #ffd; border: 3px ridge; width: 800px;" This command uses the `ping` module to ping the specified nodes (in this case `all`) listed in the inventory file: {{{ #!sh $ ansible -i inventory all -m ping }}} Example output showing all of the nodes responding to ping: {{{ #!sh $ ansible -i inventory all -m ping client | success >> { "changed": false, "ping": "pong" } server | success >> { "changed": false, "ping": "pong" } }}} }}} c. 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 == {{{ #!div style="background: #ffd; border: 3px ridge; width: 800px;" {{{ #!html
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.
}}} [http://docs.ansible.com/apt_module.html `apt`] module is used to install packages using the `apt` package manager: {{{ #!sh ansible [-i inventory] [all/server/client] -s -m apt -a "name=apache2 update_cache=yes" }}} [http://docs.ansible.com/command_module.html `command`] module is used to execute an arbitrary command on the remote node: {{{ #!sh ansible [-i inventory] [all/server/client] -s -m command -a "/usr/sbin/a2enmod status" }}} [http://docs.ansible.com/file_module.html `file`] module is used to set attributes of files: {{{ #!sh ansible [-i inventory] [all/server/client] -s -m file -a "path=/var/www/html state=absent" }}} [http://docs.ansible.com/synchronize_module.html `synchronize`] module is an implementation of `rsync` and is used to efficiently synchronize files between your local machine and a remote node: {{{ #!sh ansible [-i inventory] [all/server/client] -s -m synchronize \ -a "src=website/index.html dest=/var/www" }}} [http://docs.ansible.com/lineinfile_module.html `lineinfile`] module is used to see if an arbitrary line exists in a file: {{{ #!sh ansible [-i inventory] [all/server/client] -s -m lineinfile \ -a "line='ExtendedStatus On' dest=/etc/apache2/conf.d/extendedstatus create=yes state=present" }}} [http://docs.ansible.com/service_module.html `service`] module is used to start/stop/restart/etc services: {{{ #!sh ansible [-i inventory] [all/server/client] -s -m service -a "name=apache2 state=restarted" }}} }}} a. Using the above Ad Hoc Ansible commands configure the `client` node by doing the following: i. on both `client` and `server`, install `apache2` and `iperf` i. copy the `scripts` directory into `/local` on the `client` node with permissions `755`. i. verify the above three items have been done. {{{ #!div style="background: #ffd; border: 3px ridge; width: 800px;" Log into the `client` node and run: {{{ #!sh $ apache2 -v $ iperf -v $ ls /local/scripts }}} }}} {{{ #!div style="background: #ffd; border: 3px ridge; width: 800px;" {{{ #!html
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.
}}} {{{ #!html
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: {{{ #!python --- - name: Configure client hosts: client sudo: True tasks: - 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: {{{ #!python ansible-playbook hello-client.yml -i inventory }}} }}} a. 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 [http://groups.geni.net/geni/attachment/wiki/GENIExperimenter/Tutorials/AnsibleHelloGENI/Execute/hello-server.yml solution] or [http://groups.geni.net/geni/raw-attachment/wiki/GENIExperimenter/Tutorials/AnsibleHelloGENI/Execute/hello-server.yml `hello-server.yml`]) {{{ #!div style="background: #ffd; border: 3px ridge; width: 800px;" Here is a template you can fill in to create the `hello-server.yml` file: {{{ #!python --- - name: Configure server hosts: server sudo: True tasks: - name: install apache2 apt: name=apache2 update_cache=yes - name: install iperf apt: name=iperf update_cache=yes - name: /usr/sbin/a2enmod status # INSERT COMMAND HERE - name: check /etc/apache2/mods-enabled/status.conf file is absent # INSERT COMMAND HERE - name: copy website/index.html into /var/www # INSERT COMMAND HERE - name: copy the website/graphics directory into /var/www # INSERT COMMAND HERE - name: rm -rf /var/www/html # INSERT COMMAND HERE - name: Make simlink to webfiles # INSERT COMMAND HERE - name: restart apache2 service # INSERT COMMAND HERE - name: Make sure /etc/apache2/conf.d/extendedstatus file contains "ExtendedStatus On" # INSERT COMMAND HERE - name: Make sure /etc/apache2/sites-available/default contains Location information # INSERT COMMAND HERE - name: create directory for iperf logs in /var/www/iperflogs with permissions of 755 # INSERT COMMAND HERE }}} }}} {{{ #!comment lineinfile: dest: /etc/apache2/sites-available/default create: yes state: present insertafter: EOF backup: yes regexp: "{{ item.regexp }}" line: "{{ item.line }}" with_items: - { regexp: '^', line: '' } - { regexp: '^ SetHandler server-status', line: ' SetHandler server-status' } - { regexp: '^ Allow from all', line: ' Allow from all' } - { regexp: '^', line: '' } }}} a. Run both the `client` and `server` playbooks on your nodes. a. Start the `iperf` and `wget` traffic: {{{ #!div style="background: #ffd; border: 3px ridge; width: 1000px;" On the local node do: {{{ #!sh ansible -i inventory server -s -m shell -a "iperf -s -i 10 &> /var/www/iperflogs/iperf-server.log" }}} On the local node do: {{{ #!sh ansible -i inventory client -s -m shell -a "/local/scripts/client-wget.sh &" ansible -i inventory client -s -m shell -a "/local/scripts/client-iperf.sh &" }}} }}} a. 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 == a. 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". b. Explore some of the intermediate features of Ansible such as roles, variables, and handlers. ---- = [wiki:GENIExperimenter/Tutorials/AnsibleHelloGENI Introduction/DesignSetup] = = [wiki:GENIExperimenter/Tutorials/AnsibleHelloGENI/Finish Next: Finish] =