Vagrant-Ansible scripts for tutorial vm

Change-Id: I0481fa9c7df897812a765973440b6b1b2bf669f8
diff --git a/tools/dev/vagrant/ansible/basic.yml b/tools/dev/vagrant/ansible/basic.yml
new file mode 100644
index 0000000..9308a0d
--- /dev/null
+++ b/tools/dev/vagrant/ansible/basic.yml
@@ -0,0 +1,14 @@
+---
+#
+# Installs a clean dev environment. Hostnames, bride, some utils
+#
+- name: Include vars
+  hosts: localhost
+  tasks:
+  - include_vars: vars/global_vars.yml
+
+- hosts: localhost
+  remote_user: vagrant
+  serial: 1
+  roles:
+    - common
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/gui.yml b/tools/dev/vagrant/ansible/gui.yml
new file mode 100644
index 0000000..6d3148e
--- /dev/null
+++ b/tools/dev/vagrant/ansible/gui.yml
@@ -0,0 +1,15 @@
+---
+#
+# Installs the GUI and does customizations, such as changing the background.
+#
+- name: Include vars
+  hosts: localhost
+  tasks:
+  - include_vars: vars/global_vars.yml
+
+- hosts: localhost
+  remote_user: vagrant
+  serial: 1
+  roles:
+    - gui
+    - gui-customization
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/ide-install.yml b/tools/dev/vagrant/ansible/ide-install.yml
new file mode 100644
index 0000000..d3af461
--- /dev/null
+++ b/tools/dev/vagrant/ansible/ide-install.yml
@@ -0,0 +1,14 @@
+---
+#
+# Installs the required IDEs
+#
+- name: Include vars
+  hosts: localhost
+  tasks:
+  - include_vars: vars/global_vars.yml
+
+- hosts: localhost
+  remote_user: vagrant
+  serial: 1
+  roles:
+    - intellij-install
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/machine-restart.yml b/tools/dev/vagrant/ansible/machine-restart.yml
new file mode 100644
index 0000000..2b58d6f
--- /dev/null
+++ b/tools/dev/vagrant/ansible/machine-restart.yml
@@ -0,0 +1,12 @@
+---
+#
+# Restarts the target machine
+#
+- name: Restarting the machine
+  hosts: localhost
+  tasks:
+  - shell: sleep 2 && shutdown -r now "Ansible updates triggered"
+    async: 1
+    poll: 0
+    sudo: true
+    ignore_errors: true
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/mn.yml b/tools/dev/vagrant/ansible/mn.yml
index d682660..10f4209 100644
--- a/tools/dev/vagrant/ansible/mn.yml
+++ b/tools/dev/vagrant/ansible/mn.yml
@@ -1,5 +1,15 @@
+---
+#
+# Installs Mininet, Wireshark and the latest openflow.lua dissector plugin (Loxi version)
+#
+- name: Include vars
+  hosts: localhost
+  tasks:
+  - include_vars: vars/global_vars.yml
+
 - hosts: localhost
   remote_user: vagrant
   serial: 1
   roles:
     - mininet
+    - wireshark-custom
diff --git a/tools/dev/vagrant/ansible/onos-dev-clean.yml b/tools/dev/vagrant/ansible/onos-dev-clean.yml
new file mode 100644
index 0000000..b134c32
--- /dev/null
+++ b/tools/dev/vagrant/ansible/onos-dev-clean.yml
@@ -0,0 +1,16 @@
+---
+#
+# Installs Java, configures ONOS bridges and LXC
+#
+- name: Include vars
+  hosts: localhost
+  tasks:
+  - include_vars: vars/global_vars.yml
+
+- hosts: localhost
+  remote_user: vagrant
+  serial: 1
+  roles:
+    - brctl
+    - java8-oracle
+    - lxc
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/onos-install.yml b/tools/dev/vagrant/ansible/onos-install.yml
new file mode 100644
index 0000000..fea4259
--- /dev/null
+++ b/tools/dev/vagrant/ansible/onos-install.yml
@@ -0,0 +1,14 @@
+---
+#
+# Installs and compiles ONOS
+#
+- name: Include vars
+  hosts: localhost
+  tasks:
+  - include_vars: vars/global_vars.yml
+
+- hosts: localhost
+  remote_user: vagrant
+  serial: 1
+  roles:
+    - onos-install
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/onos-tutorials.yml b/tools/dev/vagrant/ansible/onos-tutorials.yml
new file mode 100644
index 0000000..f81b6a0
--- /dev/null
+++ b/tools/dev/vagrant/ansible/onos-tutorials.yml
@@ -0,0 +1,17 @@
+---
+#
+# Installs the ONOS tutorials
+#
+- name: Include vars
+  hosts: localhost
+  tasks:
+  - include_vars: vars/global_vars.yml
+
+- hosts: localhost
+  remote_user: vagrant
+  serial: 1
+  roles:
+    - tutorial-common
+    - tutorial-sdnip
+    - tutorial-optical
+    - tutorial-distributed
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/onosdev.yml b/tools/dev/vagrant/ansible/onosdev.yml
deleted file mode 100644
index cd7a5a5..0000000
--- a/tools/dev/vagrant/ansible/onosdev.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-- hosts: localhost
-  remote_user: vagrant
-  serial: 1
-  roles:
-    - common
-    - brctl
-    - java8-oracle
-    - lxc
diff --git a/tools/dev/vagrant/ansible/roles/brctl/tasks/main.yml b/tools/dev/vagrant/ansible/roles/brctl/tasks/main.yml
index 002509a..346e2f3 100644
--- a/tools/dev/vagrant/ansible/roles/brctl/tasks/main.yml
+++ b/tools/dev/vagrant/ansible/roles/brctl/tasks/main.yml
@@ -1,37 +1,54 @@
-- name: Bridge onosbr0 is present
+---
+#
+# Configures networking and Linux brdiges 
+#
+- name: Creating ONOS bridge
   become: yes
   template:
     src: templates/create_bridge.j2
-    dest: /etc/network/if-pre-up.d/create_bridge_{{ networks.bridge_name }}
+    dest: "/etc/network/if-pre-up.d/create_bridge_{{ bridge.name }}"
     owner: root
     group: root
     mode: 0755
 
-- name: eth1 is in onosbr0
+- name: Adding second NIC to ONOS bridge
   become: yes
   template:
     src: templates/add_iface.j2
-    dest: /etc/network/if-pre-up.d/add_iface_{{ interfaces.hostonly }}
+    dest: "/etc/network/if-pre-up.d/add_iface_{{ bridge.phy_interface }}"
     owner: root
     group: root
     mode: 0755
 
-- name: Activate onos bridge
+- name: Activating ONOS bridge
   become: yes
-  command: /etc/network/if-pre-up.d/create_bridge_{{ networks.bridge_name }} report-changed
+  command: /etc/network/if-pre-up.d/create_bridge_{{ bridge.name }} report-changed
   register: bridge_changed
   changed_when: bridge_changed.stdout == 'true'
 
-- name: Activate eth1 in bridge
+- name: Adding physical interface to the bridge
   become: yes
-  command: /etc/network/if-pre-up.d/add_iface_{{ interfaces.hostonly }} report-changed
+  command: /etc/network/if-pre-up.d/add_iface_{{ bridge.phy_interface }} report-changed
   register: bridge_iface_changed
   changed_when: bridge_iface_changed == 'true'
 
-- name: Flush ip of eth1
+- name: Moving the IP and starting bridge automatically at startup
   become: yes
-  command: /sbin/ip addr flush {{ interfaces.hostonly }}
+  template:
+    src: templates/post_ifup.j2
+    dest: "/etc/network/if-up.d/bring_up_{{ bridge.name }}"
+    owner: root
+    group: root
+    mode: 0755
+  
+- name: Removing IP from the second NIC
+  become: yes
+  command: "/sbin/ip addr flush {{ bridge.phy_interface }}"
 
-- name: bring onosbr0 up
+- name: Configuring the IP on the bridge
   become: yes
-  command: /sbin/ifconfig onosbr0 up
+  command: "/sbin/ifconfig {{ bridge.name }} inet {{ bridge.ip }}"
+
+- name: Bringing up ONOS bridge
+  become: yes
+  command: "/sbin/ifconfig {{ bridge.name }} up"
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/roles/brctl/templates/add_iface.j2 b/tools/dev/vagrant/ansible/roles/brctl/templates/add_iface.j2
index f09bd50..b391252 100644
--- a/tools/dev/vagrant/ansible/roles/brctl/templates/add_iface.j2
+++ b/tools/dev/vagrant/ansible/roles/brctl/templates/add_iface.j2
@@ -6,12 +6,12 @@
 fi
 CHANGED='false'
 
-FOUND=$(brctl show | grep "^{{ interfaces.hostonly }}" | wc -l)
+FOUND=$(brctl show | grep "^{{ bridge.phy_interface }}" | wc -l)
 if [ $FOUND -eq 0 ]; then
     CHANGED='true'
-    brctl addif {{ networks.bridge_name }} {{ interfaces.hostonly }}
+    brctl addif {{ bridge.name }} {{ bridge.phy_interface }}
 fi
 
 if [ $REPORT_CHANGED -ne 0 ]; then
     echo -n $CHANGED
-fi
+fi
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/roles/brctl/templates/create_bridge.j2 b/tools/dev/vagrant/ansible/roles/brctl/templates/create_bridge.j2
index 5f12261..c301d11 100644
--- a/tools/dev/vagrant/ansible/roles/brctl/templates/create_bridge.j2
+++ b/tools/dev/vagrant/ansible/roles/brctl/templates/create_bridge.j2
@@ -6,12 +6,12 @@
 fi
 CHANGED='false'
 
-FOUND=$(brctl show | grep "^{{ networks.bridge_name }}" | wc -l)
+FOUND=$(brctl show | grep "^{{ bridge.name }}" | wc -l)
 if [ $FOUND -eq 0 ]; then
     CHANGED='true'
-    brctl addbr {{ networks.bridge_name }}
+    brctl addbr {{ bridge.name }}
 fi
 
 if [ $REPORT_CHANGED -ne 0 ]; then
     echo -n $CHANGED
-fi
+fi
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/roles/brctl/templates/post_ifup.j2 b/tools/dev/vagrant/ansible/roles/brctl/templates/post_ifup.j2
new file mode 100644
index 0000000..4156a2e
--- /dev/null
+++ b/tools/dev/vagrant/ansible/roles/brctl/templates/post_ifup.j2
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+ip addr flush {{ bridge.phy_interface }}
+ifconfig {{ bridge.name }} inet {{ bridge.ip }}
+ifconfig {{ bridge.name }} up
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/roles/brctl/vars/main.yml b/tools/dev/vagrant/ansible/roles/brctl/vars/main.yml
deleted file mode 100644
index 5c705ac..0000000
--- a/tools/dev/vagrant/ansible/roles/brctl/vars/main.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-interfaces:
-    hostonly: "{{ hostonly_iface | default('eth1') }}"
-
-networks:
-    # CHANGE:
-    #   'bridge' name of the bridge to create that is used when connecting
-    #            the LXC containers
-    bridge_name: "{{ bridge_name | default('onosbr0') }}"
-    bridge: "{{ bridge_network | default('10.100.198.200/24') }}"
diff --git a/tools/dev/vagrant/ansible/roles/common/defaults/main.yml b/tools/dev/vagrant/ansible/roles/common/defaults/main.yml
deleted file mode 100644
index cd8a8e3..0000000
--- a/tools/dev/vagrant/ansible/roles/common/defaults/main.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-hosts: [
-  { host_ip: "10.100.198.200", host_name: "onosdev"},
-  { host_ip: "10.100.198.201", host_name: "onos1"},
-  { host_ip: "10.100.198.202", host_name: "onos2"},
-  { host_ip: "10.100.198.203", host_name: "onos3"},
-]
diff --git a/tools/dev/vagrant/ansible/roles/common/tasks/main.yml b/tools/dev/vagrant/ansible/roles/common/tasks/main.yml
index d03f8ec..c9d4dc5 100644
--- a/tools/dev/vagrant/ansible/roles/common/tasks/main.yml
+++ b/tools/dev/vagrant/ansible/roles/common/tasks/main.yml
@@ -1,42 +1,26 @@
-- name: bridge-utils is present
-  apt:
-    name: bridge-utils
-    force: yes
+---
+#
+# Performs basic tasks to prepare the dev environment, such as managing the default user
+# credentials, installing the basic packages, assigning host names.
+#
+- name: Setting password ubuntu and ssh key for user ubuntu
+  user:
+    name: ubuntu
+    password: $6$rounds=656000$UcEQn7gcdsZCqt6m$HifWVYa6XXX5rpbAqkGj2mJfrIm9iT2AN2fbQbJNLcRr10SwhQgTQVnVqY8UGSQsD14WlFCdNCmJDay3CPlUR0
+    generate_ssh_key: yes
+    ssh_key_bits: 2048
+    ssh_key_file: .ssh/id_rsa
   tags: [common]
 
-- name: lxc is present
+- name: Installing basic packages
   apt:
-    name: lxc
+    name: "{{ item }}"
     force: yes
+  with_items: "{{ basic_packages }}"
   tags: [common]
 
-- name: python-dev is present
-  apt:
-    name: python-dev
-    force: yes
-  tags: [common]
-
-- name: lxc-dev is present
-  apt:
-    name: lxc-dev
-    force: yes
-  tags: [common]
-
-- name: python-pip is present
-  apt:
-    name: python-pip
-    force: yes
-  tags: [common]
-
-- name: python3-lxc is present
+- name: Installing python3-lxc
   pip:
     name: lxc-python2
     state: present
-  tags: [common]
-- name: Host is present
-  lineinfile:
-    dest: /etc/hosts
-    regexp: "^{{ item.host_ip }}"
-    line: "{{ item.host_ip }} {{ item.host_name }}"
-  with_items: hosts
-  tags: [common]
+  tags: [common]
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/roles/gui-customization/tasks/main.yml b/tools/dev/vagrant/ansible/roles/gui-customization/tasks/main.yml
new file mode 100644
index 0000000..7d21d79
--- /dev/null
+++ b/tools/dev/vagrant/ansible/roles/gui-customization/tasks/main.yml
@@ -0,0 +1,25 @@
+---
+#
+# Customizes the machine GUI
+#
+- name: Creating folder for background images
+  become: yes
+  file:
+    path: /usr/share/backgrounds
+    state: directory
+
+- name: Downloading ONOS background
+  become: yes
+  get_url:
+    url: "{{ onos_background_url }}"
+    dest: /usr/share/lubuntu/wallpapers/onos.png
+
+- name: Disabling user selection at login
+  blockinfile:
+    dest: "/etc/lightdm/lightdm.conf"
+    create: yes
+    block: |
+     [SeatDefaults]
+     greeter-show-manual-login = true
+     greeter-hide-users = true
+     allow-guest = false
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/roles/gui/tasks/main.yml b/tools/dev/vagrant/ansible/roles/gui/tasks/main.yml
new file mode 100644
index 0000000..232c7db
--- /dev/null
+++ b/tools/dev/vagrant/ansible/roles/gui/tasks/main.yml
@@ -0,0 +1,27 @@
+---
+#
+# Installs the Ubuntu GUI Unity and makes sure the machine doesn't start in text mode.
+# The machine is restarted at the end of the process.
+#
+- name: Installing GUI dependencies
+  become: yes
+  apt:
+    name: lubuntu-desktop
+
+- name: Editing grub GRUB_CMDLINE_LINUX_DEFAULT
+  become: yes
+  replace:
+    dest: /etc/default/grub
+    regexp: 'GRUB_CMDLINE_LINUX_DEFAULT="console=tty1 console=ttyS0"'
+    replace: 'GRUB_CMDLINE_LINUX_DEFAULT="nomodeset"'
+
+- name: Removing text mode from GRUB
+  become: yes
+  replace:
+    dest: /etc/default/grub
+    regexp: 'text'
+    replace: ''
+
+- name: Updating GRUB
+  become: yes
+  command: update-grub
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/roles/intellij-install/tasks/main.yml b/tools/dev/vagrant/ansible/roles/intellij-install/tasks/main.yml
new file mode 100644
index 0000000..63969c2
--- /dev/null
+++ b/tools/dev/vagrant/ansible/roles/intellij-install/tasks/main.yml
@@ -0,0 +1,25 @@
+---
+#
+# Installs the IntelliJ IDE
+#
+- name: Making sure Application folder is present
+  file:
+    path: "{{ app_dir }}"
+    state: directory
+    mode: 0777
+
+- name: Downloading IntelliJ
+  get_url:
+    url: "{{ intellij.url }}"
+    dest: "{{ app_dir }}/intellij.tar.gz"
+
+- name: Extracting IntelliJ
+  unarchive:
+    src: "/home/ubuntu/{{ app_dir }}/intellij.tar.gz"
+    dest: "/home/ubuntu/{{ app_dir }}"
+    mode: 0777
+
+- name: Removing IntelliJ tar.gz archive
+  file:
+    path: "{{ app_dir }}/intellij.tar.gz"
+    state: absent
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/roles/lxc/files/99-onos-sudoers b/tools/dev/vagrant/ansible/roles/lxc/files/99-onos-sudoers
deleted file mode 100644
index 2a00bee..0000000
--- a/tools/dev/vagrant/ansible/roles/lxc/files/99-onos-sudoers
+++ /dev/null
@@ -1 +0,0 @@
-ubuntu ALL=(ALL:ALL) NOPASSWD:ALL
diff --git a/tools/dev/vagrant/ansible/roles/lxc/files/default.conf b/tools/dev/vagrant/ansible/roles/lxc/files/default.conf
index b496600..367766c 100644
--- a/tools/dev/vagrant/ansible/roles/lxc/files/default.conf
+++ b/tools/dev/vagrant/ansible/roles/lxc/files/default.conf
@@ -9,3 +9,6 @@
 lxc.network.link = onosbr0
 lxc.network.flags = up
 lxc.network.name = eth1
+
+LXC_AUTO="true"
+lxc.start.auto = 1
diff --git a/tools/dev/vagrant/ansible/roles/lxc/tasks/main.yml b/tools/dev/vagrant/ansible/roles/lxc/tasks/main.yml
index 4bb253a..a62c7c4 100644
--- a/tools/dev/vagrant/ansible/roles/lxc/tasks/main.yml
+++ b/tools/dev/vagrant/ansible/roles/lxc/tasks/main.yml
@@ -1,55 +1,66 @@
-- name: Remove lxc default config
+- name: Removing lxc default config
   become: yes
-  file: path=/etc/lxc/default.conf state=absent
+  file:
+    path: /etc/lxc/default.conf
+    state: absent
 
-- name: Copy default lxc file
+- name: Copying default lxc file
   become: yes
   copy:
     src: files/default.conf
     dest: /etc/lxc/default.conf
     mode: 644
 
-- name: Create onos1 container
+- name: Creating lxc containers
   lxc_container:
-    name: onos1
+    name: "{{ item.value.name }}"
     container_log: true
     template: ubuntu
     state: started
-    template_options: --release trusty
+    template_options: --release "{{ item.value.release }}"
     container_config:
-      - "lxc.network.ipv4=10.100.198.201/24"
+      - "lxc.network.ipv4={{ item.value.ip }}/24"
     container_command: |
       ln -s /usr/lib/jvm/java/bin/java /usr/bin/java
       apt-get update
       apt-get install -y openssh-server
+      useradd -s /bin/bash -m -p sakA7pjBdhIsE sdn
+      useradd sdn sudo
+      mkdir /home/sdn/.ssh
+      chown sdn.sdn /home/sdn/.ssh
       echo "ubuntu ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers.d/99-onos-sudoers
+      echo "sdn ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers.d/99-onos-sudoers
+  with_dict: "{{ lxc }}"
 
-- name: Create onos2 container
-  lxc_container:
-    name: onos2
-    container_log: true
-    template: ubuntu
-    state: started
-    template_options: --release trusty
-    container_config:
-      - "lxc.network.ipv4=10.100.198.202/24"
-    container_command: |
-      ln -s /usr/lib/jvm/java/bin/java /usr/bin/java
-      apt-get update
-      apt-get install -y openssh-server
-      echo "ubuntu ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers.d/99-onos-sudoers
+- name: Copying public key to containers
+  become: yes
+  copy:
+    src: "/home/ubuntu/.ssh/id_rsa.pub"
+    dest: "/var/lib/lxc/{{ item.value.name }}/rootfs/home/sdn/.ssh/authorized_keys"
+    mode: 600
+  with_dict: "{{ lxc }}"
 
-- name: Create onos3 container
-  lxc_container:
-    name: onos3
-    container_log: true
-    template: ubuntu
-    state: started
-    template_options: --release trusty
-    container_config:
-      - "lxc.network.ipv4=10.100.198.203/24"
-    container_command: |
-      ln -s /usr/lib/jvm/java/bin/java /usr/bin/java
-      apt-get update
-      apt-get install -y openssh-server
-      echo "ubuntu ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers.d/99-onos-sudoers
+- name: Setting owner and group on authorized key files
+  become: yes
+  shell: "lxc-attach --name {{ item.value.name }} -- chown sdn:sdn /home/sdn/.ssh/authorized_keys"
+  with_dict: "{{ lxc }}"
+
+- name: Setting permissions on authorized key files
+  become: yes
+  shell: "lxc-attach --name {{ item.value.name }} -- chmod 600 /home/sdn/.ssh/authorized_keys"
+  with_dict: "{{ lxc }}"
+
+- name: Disabling ssh strict host key checking
+  blockinfile:
+    dest: "/etc/ssh/ssh_config"
+    block: |
+      Host *
+        StrictHostKeyChecking no
+
+- name: Adding containers hostname to hosts file
+  lineinfile:
+    dest: /etc/hosts
+    regexp: "^{{ item.value.ip }}"
+    line: "{{ item.value.ip }} {{ item.value.name }}"
+  with_dict: "{{ lxc }}"
+  tags: [common]
diff --git a/tools/dev/vagrant/ansible/roles/mininet/tasks/main.yml b/tools/dev/vagrant/ansible/roles/mininet/tasks/main.yml
index 105cbc4..0ed5b4c 100644
--- a/tools/dev/vagrant/ansible/roles/mininet/tasks/main.yml
+++ b/tools/dev/vagrant/ansible/roles/mininet/tasks/main.yml
@@ -1,11 +1,11 @@
-- name: git is present
-  apt:
-    name: git
-    force: yes
-  tags: [common]
-
-- name: Clone mininet repository
+---
+#
+# Clones the Mininet repository and does a full Mininet installation, including Wireshark
+#
+- name: Cloning the mininet repository
   git: repo=https://github.com/mininet/mininet.git dest=mininet
+  become: true
+  become_user: ubuntu
 
-- name: Install mininet
-  command: mininet/util/install.sh -a
+- name: Installing mininet
+  command: mininet/util/install.sh -a
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/roles/onos-install/tasks/main.yml b/tools/dev/vagrant/ansible/roles/onos-install/tasks/main.yml
new file mode 100644
index 0000000..b48901c
--- /dev/null
+++ b/tools/dev/vagrant/ansible/roles/onos-install/tasks/main.yml
@@ -0,0 +1,116 @@
+---
+#
+# Installs ONOS and downloads the related dependencies. It then compiles the code.
+#
+- name: Installing Maven
+  apt:
+    name: maven
+    force: yes
+  tags: [common]
+
+- name: Creating Application folder
+  file:
+    path: "{{ app_dir }}"
+    state: directory
+    mode: 0777
+
+- name: Creating Download folder
+  file:
+    path: "{{ download_dir }}"
+    state: directory
+    mode: 0777
+
+- name: Downloading Apache Karaf
+  get_url:
+    url: "http://archive.apache.org/dist/karaf/{{ karaf_version }}/apache-karaf-{{ karaf_version }}.tar.gz"
+    dest: "{{ download_dir }}"
+    mode: 0777
+
+- name: Copying Apache Karaf in the Application directory
+  copy:
+    src: "/home/ubuntu/{{ download_dir }}/apache-karaf-{{ karaf_version }}.tar.gz"
+    dest: "/home/ubuntu/{{ app_dir }}/apache-karaf-{{ karaf_version }}.tar.gz"
+    mode: 0777
+
+- name: Extracting Apache Karaf
+  unarchive:
+    src: "/home/ubuntu/{{ download_dir }}/apache-karaf-{{ karaf_version }}.tar.gz"
+    dest: "/home/ubuntu/{{ app_dir }}"
+    mode: 0777
+
+- name: Cloning ONOS repository
+  git:
+    repo: "{{ onos_repo_url }}"
+    dest: onos
+    version: onos-"{{ onos_version }}"
+  become: true
+  become_user: ubuntu
+
+- name: Changing ONOS repository permissions
+  file:
+    path: "/home/ubuntu/onos"
+    state: directory
+    owner: ubuntu
+    group: ubuntu
+    mode: 0777
+
+- name: Exporting ONOS variables
+  lineinfile:
+    dest: /home/ubuntu/.bashrc
+    line: "{{ item }}"
+  with_items: "{{ onos_variables }}"
+
+- name: Compiling ONOS
+  shell: "{{ item }}"
+  args:
+    chdir: "/home/ubuntu/onos"
+  with_items:
+    - mvn clean install
+  become: true
+  become_user: ubuntu
+
+- name: Changing .m2 repository permissions
+  file:
+    path: "/home/ubuntu/.m2"
+    state: directory
+    owner: ubuntu
+    group: ubuntu
+    mode: 0777
+
+- name: Creating 1 node ONOS cell
+  template:
+    src: templates/one_node_cell.j2
+    dest: "{{ cell_files[0] }}"
+    owner: ubuntu
+    group: ubuntu
+    mode: 0777
+
+- name: Creating 3 node ONOS cell
+  template:
+    src: templates/three_node_cell.j2
+    dest: "{{ cell_files[1] }}"
+    owner: ubuntu
+    group: ubuntu
+    mode: 0777
+
+- name: Creating ONOS deployment script
+  template:
+    src: templates/onos_deploy.j2
+    dest: "/home/ubuntu/onos_deploy.sh"
+    owner: ubuntu
+    group: ubuntu
+    mode: 0777
+
+- name: Deploying ONOS
+  shell: "/home/ubuntu/onos_deploy.sh"
+  environment:
+    ONOS_ROOT: /home/ubuntu/onos
+  args:
+    executable: /bin/bash
+  become: true
+  become_user: ubuntu
+
+- name: Adding ONOS to startup
+  become: yes
+  shell: "lxc-attach --name {{ item.value.name }} -- systemctl enable onos"
+  with_dict: "{{ lxc }}"
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/roles/onos-install/templates/one_node_cell.j2 b/tools/dev/vagrant/ansible/roles/onos-install/templates/one_node_cell.j2
new file mode 100644
index 0000000..31bb455
--- /dev/null
+++ b/tools/dev/vagrant/ansible/roles/onos-install/templates/one_node_cell.j2
@@ -0,0 +1,5 @@
+export ONOS_NIC="{{ onos_nic }}"
+export OCI="{{ lxc.lxc_one.ip }}"
+export OC1="{{ lxc.lxc_one.ip }}"
+export ONOS_APPS="drivers,openflow"
+export ONOS_USER="sdn"
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/roles/onos-install/templates/onos_deploy.j2 b/tools/dev/vagrant/ansible/roles/onos-install/templates/onos_deploy.j2
new file mode 100644
index 0000000..01d49ba
--- /dev/null
+++ b/tools/dev/vagrant/ansible/roles/onos-install/templates/onos_deploy.j2
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+source $ONOS_ROOT/tools/dev/bash_profile
+cell 3node
+
+onos-test
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/roles/onos-install/templates/three_node_cell.j2 b/tools/dev/vagrant/ansible/roles/onos-install/templates/three_node_cell.j2
new file mode 100644
index 0000000..9f5616c
--- /dev/null
+++ b/tools/dev/vagrant/ansible/roles/onos-install/templates/three_node_cell.j2
@@ -0,0 +1,7 @@
+export ONOS_NIC="{{ onos_nic }}"
+export OCI="{{ lxc.lxc_one.ip }}"
+export OC1="{{ lxc.lxc_one.ip }}"
+export OC2="{{ lxc.lxc_two.ip }}"
+export OC3="{{ lxc.lxc_three.ip }}"
+export ONOS_APPS="drivers,openflow"
+export ONOS_USER="sdn"
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/roles/tutorial-common/tasks/main.yml b/tools/dev/vagrant/ansible/roles/tutorial-common/tasks/main.yml
new file mode 100644
index 0000000..a24be78
--- /dev/null
+++ b/tools/dev/vagrant/ansible/roles/tutorial-common/tasks/main.yml
@@ -0,0 +1,285 @@
+---
+#
+# Installs basic tutorial packages and configures common tutorial settings
+#
+- name: Downloading repo key
+  apt_key:
+    url: "{{ google_chrome_key_url }}"
+    state: present
+
+- name: Installing Google Chrome repo
+  apt_repository:
+    repo: "{{ google_chrome_repo }}"
+    state: present
+    filename: "google-chrome"
+
+- name: Installing Google Chrome
+  apt:
+    name: google-chrome-stable
+    force: yes
+    update_cache: yes
+
+- name: Creating reset scripts for 1 node cell
+  template:
+    src: templates/reset_one_node.j2
+    dest: "{{ reset_files[0] }}"
+    owner: ubuntu
+    group: ubuntu
+    mode: 0777
+
+- name: Creating reset scripts for 3 node cell
+  template:
+    src: templates/reset_three_node.j2
+    dest: "{{ reset_files[1] }}"
+    owner: ubuntu
+    group: ubuntu
+    mode: 0777
+
+- name: Creating tutorial users
+  user:
+    name: "{{ item.value.user }}"
+    groups: "wireshark"
+    append: yes
+    password: "{{ item.value.pass }}"
+  with_dict: "{{ tutorials }}"
+
+- name: Adding tutorial users to sudoers
+  lineinfile:
+    dest: "/etc/sudoers.d/{{ item.value.user }}"
+    line: "{{ item.value.user }} ALL=(ALL) NOPASSWD:ALL"
+    state: present
+    create: yes
+  with_dict: "{{ tutorials }}"
+
+- name: Creating .ssh folders
+  file:
+    path: "/home/{{ item.value.user }}/.ssh"
+    state: directory
+    owner: "{{ item.value.user }}"
+    group: "{{ item.value.user }}"
+    mode: 0700
+  with_dict: "{{ tutorials }}"
+
+- name: Copying .ssh keys
+  copy:
+    src: "/home/ubuntu/.ssh/id_rsa"
+    dest: "/home/{{ item.value.user }}/.ssh/id_rsa"
+    owner: "{{ item.value.user }}"
+    group: "{{ item.value.user }}"
+    mode: 0600
+  with_dict: "{{ tutorials }}"
+
+- name: Setting ONOS variables
+  blockinfile:
+    dest: "/home/{{ item.value.user }}/.bashrc"
+    create: yes
+    block: |
+      export ONOS_ROOT=/home/ubuntu/onos
+      export KARAF_ROOT=/home/ubuntu/Applications/apache-karaf-{{ karaf_version }}
+      export KARAF_TAR=/home/ubuntu/Applications/apache-karaf-{{ karaf_version }}.tar.gz
+      export M2_REPO=/home/ubuntu/.m2/repository
+      . /home/ubuntu/onos/tools/dev/bash_profile
+      cell {{ item.value.cell }} > /dev/null
+  with_dict: "{{ tutorials }}"
+
+- name: Creating .wireshark folders
+  file:
+    path: "/home/{{ item.value.user }}/{{ wireshark.plugins_dir }}"
+    state: directory
+    owner: "{{ item.value.user }}"
+    group: "{{ item.value.user }}"
+    mode: 0755
+  with_dict: "{{ tutorials }}"
+
+- name: Copying openflow.lua Wireshark plugin
+  copy:
+    src: "/home/ubuntu/openflow.lua"
+    dest: "/home/{{ item.value.user }}/{{ wireshark.plugins_dir }}"
+    owner: "{{ item.value.user }}"
+    group: "{{ item.value.user }}"
+  with_dict: "{{ tutorials }}"
+
+- name: Creating run_onos.sh script
+  template:
+    src: templates/run_onos.j2
+    dest: /home/ubuntu/run_onos.sh
+    owner: ubuntu
+    group: ubuntu
+    mode: 0777
+
+- name: Creating config Desktop folder
+  file:
+    path: "/home/{{ item.value.user }}/.config/pcmanfm/lubuntu/"
+    state: directory
+    owner: "{{ item.value.user }}"
+    group: "{{ item.value.user }}"
+    mode: 0777
+  with_dict: "{{ tutorials }}"
+  
+- name: Loading ONOS Desktop background
+  template:
+    src: templates/gui_custom.j2
+    dest: "/home/{{ item.value.user }}/.config/pcmanfm/lubuntu/desktop-items-0.conf"
+    owner: "{{ item.value.user }}"
+    group: "{{ item.value.user }}"
+    mode: 0777
+  with_dict: "{{ tutorials }}"
+
+- name: Creating Desktop folders
+  file:
+    path: "/home/{{ item.value.user }}/Desktop"
+    state: directory
+    mode: 0755
+  with_dict: "{{ tutorials }}"
+
+- name: Creating ONOS CLI Desktop icons
+  blockinfile:
+    dest: "/home/{{ item.value.user }}/Desktop/ONOS CLI.desktop"
+    create: yes
+    owner: "{{ item.value.user }}"
+    group: "{{ item.value.user }}"
+    mode: 0777
+    block: |
+      [Desktop Entry]
+      Encoding=UTF-8
+      Type=Application
+      Name=ONOS
+      Name[en_US]=ONOS
+      Icon=konsole
+      Exec=/home/ubuntu/run_onos.sh
+      Comment[en_US]=
+      Terminal=true
+      X-KeepTerminal=true
+  with_dict: "{{ tutorials }}"
+
+- name: Creating Mininet Desktop icon
+  blockinfile:
+    dest: "/home/{{ item.value.user }}/Desktop/Mininet.desktop"
+    create: yes
+    owner: "{{ item.value.user }}"
+    group: "{{ item.value.user }}"
+    mode: 0777
+    block: |
+      [Desktop Entry]
+      Encoding=UTF-8
+      Type=Application
+      Name=Mininet
+      Name[en_US]=Mininet
+      Icon=konsole
+      Exec={{ item.value.mininet_exec  }}
+      Comment[en_US]=
+      Terminal=true
+      X-KeepTerminal=true
+  with_dict: "{{ tutorials }}"
+
+- name: Creating Tutorial Desktop icons
+  blockinfile:
+    dest: "/home/{{ item.value.user }}/Desktop/Tutorial.desktop"
+    create: yes
+    owner: "{{ item.value.user }}"
+    group: "{{ item.value.user }}"
+    mode: 0777
+    block: |
+      [Desktop Entry]
+      Encoding=UTF-8
+      Type=Application
+      Name=ONOS Tutorial
+      Name[en_US]=ONOS Tutorial
+      Icon=internet-web-browser
+      Exec=/usr/bin/google-chrome-stable {{ item.value.url }}
+      Comment[en_US]=
+  with_dict: "{{ tutorials }}"
+
+- name: Creating GUI Desktop icons
+  blockinfile:
+    dest: "/home/{{ item.value.user }}/Desktop/ONOS GUI.desktop"
+    create: yes
+    owner: "{{ item.value.user }}"
+    group: "{{ item.value.user }}"
+    mode: 0777
+    block: |
+      [Desktop Entry]
+      Encoding=UTF-8
+      Type=Application
+      Name=ONOS GUI
+      Name[en_US]=ONOS GUI
+      Icon=internet-web-browser
+      Exec=/usr/bin/google-chrome-stable http://{{ lxc.lxc_one.ip }}:8181/onos/ui/index.html#topo
+      Comment[en_US]=
+  with_dict: "{{ tutorials }}"
+
+- name: Creating IntelliJ Desktop icons
+  blockinfile:
+    dest: "/home/{{ item.value.user }}/Desktop/IntelliJ.desktop"
+    create: yes
+    owner: "{{ item.value.user }}"
+    group: "{{ item.value.user }}"
+    mode: 0777
+    block: |
+      [Desktop Entry]
+      Encoding=UTF-8
+      Type=Application
+      Name=IntelliJ
+      Name[en_US]=IntelliJ
+      Icon=/home/ubuntu/{{ app_dir }}/{{ intellij.dir_name }}/bin/idea.png
+      Exec=/home/ubuntu/{{ app_dir }}/{{ intellij.dir_name }}/bin/idea.sh
+      Comment[en_US]=
+  with_dict: "{{ tutorials }}"
+
+- name: Creating Wireshark Desktop icons
+  blockinfile:
+    dest: "/home/{{ item.value.user }}/Desktop/Wireshark.desktop"
+    create: yes
+    owner: "{{ item.value.user }}"
+    group: "{{ item.value.user }}"
+    mode: 0777
+    block: |
+      [Desktop Entry]
+      Encoding=UTF-8
+      Type=Application
+      Name=Wireshark
+      Name[en_US]=Wireshark
+      Icon=wireshark
+      Exec=/usr/bin/wireshark
+      Comment[en_US]=
+  with_dict: "{{ tutorials }}"
+
+- name: Creating Terminal Desktop icon
+  blockinfile:
+    dest: "/home/{{ item.value.user }}/Desktop/Terminal.desktop"
+    create: yes
+    owner: "{{ item.value.user }}"
+    group: "{{ item.value.user }}"
+    mode: 0777
+    block: |
+      [Desktop Entry]
+      Encoding=UTF-8
+      Type=Application
+      Name=Terminal
+      Name[en_US]=Terminal
+      Icon=konsole
+      Exec=/bin/bash
+      Comment[en_US]=
+      Terminal=true
+      X-KeepTerminal=true
+  with_dict: "{{ tutorials }}"
+
+- name: Creating Reset Desktop icon
+  blockinfile:
+    dest: "/home/{{ item.value.user }}/Desktop/Reset.desktop"
+    create: yes
+    owner: "{{ item.value.user }}"
+    group: "{{ item.value.user }}"
+    mode: 0777
+    block: |
+      [Desktop Entry]
+      Encoding=UTF-8
+      Type=Application
+      Name=Reset
+      Name[en_US]=Reset
+      Icon=konsole
+      Exec={{ item.value.reset_exec }}
+      Comment[en_US]=
+      Terminal=true
+      X-KeepTerminal=true
+  with_dict: "{{ tutorials }}"
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/roles/tutorial-common/templates/gui_custom.j2 b/tools/dev/vagrant/ansible/roles/tutorial-common/templates/gui_custom.j2
new file mode 100644
index 0000000..3e888d2
--- /dev/null
+++ b/tools/dev/vagrant/ansible/roles/tutorial-common/templates/gui_custom.j2
@@ -0,0 +1,15 @@
+[*]
+wallpaper_mode=center
+wallpaper_common=1
+wallpapers_configured=1
+wallpaper0=/usr/share/lubuntu/wallpapers/onos.png
+wallpaper=/usr/share/lubuntu/wallpapers/onos.png
+desktop_bg=#ffffff
+desktop_fg=#000000
+desktop_shadow=#000000
+desktop_font=Ubuntu 11
+show_wm_menu=0
+sort=mtime;ascending;
+show_documents=0
+show_trash=1
+show_mounts=1    
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/roles/tutorial-common/templates/reset_one_node.j2 b/tools/dev/vagrant/ansible/roles/tutorial-common/templates/reset_one_node.j2
new file mode 100644
index 0000000..1ab3b7a
--- /dev/null
+++ b/tools/dev/vagrant/ansible/roles/tutorial-common/templates/reset_one_node.j2
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+sudo rm -rf /tmp/*
+
+export ONOS_ROOT=/home/ubuntu/onos
+export M2_REPO=/home/ubuntu/.m2/repository
+export KARAF_TAR=/home/ubuntu/{{ app_dir }}/apache-karaf-{{ karaf_version }}.tar.gz
+export KARAF_ROOT=/home/ubuntu/Applications/apache-karaf-{{ karaf_version }}
+source ${ONOS_ROOT}/tools/dev/bash_profile
+
+sudo mn -c
+
+sudo chmod -R 777 /home/ubuntu/onos
+sudo chmod -R 777 /home/ubuntu/.m2
+
+cell 3node
+onos-service --cell stop
+
+cell 1node
+
+if [ -n "$1" ]; then
+    export ONOS_APPS=$ONOS_APPS,$1
+fi
+
+onos-test
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/roles/tutorial-common/templates/reset_three_node.j2 b/tools/dev/vagrant/ansible/roles/tutorial-common/templates/reset_three_node.j2
new file mode 100644
index 0000000..b6c5de5
--- /dev/null
+++ b/tools/dev/vagrant/ansible/roles/tutorial-common/templates/reset_three_node.j2
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+sudo rm -rf /tmp/*
+
+export ONOS_ROOT=/home/ubuntu/onos
+export M2_REPO=/home/ubuntu/.m2/repository
+export KARAF_TAR=/home/ubuntu/{{ app_dir }}/apache-karaf-{{ karaf_version }}.tar.gz
+export KARAF_ROOT=/home/ubuntu/{{ app_dir }}/apache-karaf-{{ karaf_version }}
+source ${ONOS_ROOT}/tools/dev/bash_profile
+
+sudo mn -c
+
+sudo chmod -R 777 /home/ubuntu/onos
+sudo chmod -R 777 /home/ubuntu/.m2
+
+cell 3node
+
+if [ -n "$1" ]; then
+    export ONOS_APPS=$ONOS_APPS,$1
+fi
+
+onos-test
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/roles/tutorial-common/templates/run_onos.j2 b/tools/dev/vagrant/ansible/roles/tutorial-common/templates/run_onos.j2
new file mode 100755
index 0000000..01265ae
--- /dev/null
+++ b/tools/dev/vagrant/ansible/roles/tutorial-common/templates/run_onos.j2
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+export ONOS_ROOT=/home/ubuntu/onos
+export M2_REPO=/home/ubuntu/.m2/repository
+export KARAF_TAR=/home/ubuntu/"{{ app_dir }}"/apache-karaf-"{{ karaf_version }}".tar.gz
+export KARAF_ROOT=/home/ubuntu/"{{ app_dir }}"/apache-karaf-"{{ karaf_version }}"
+source ${ONOS_ROOT}/tools/dev/bash_profile
+
+cell 1node
+
+onos
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/roles/tutorial-distributed/tasks/main.yml b/tools/dev/vagrant/ansible/roles/tutorial-distributed/tasks/main.yml
new file mode 100644
index 0000000..db25426
--- /dev/null
+++ b/tools/dev/vagrant/ansible/roles/tutorial-distributed/tasks/main.yml
@@ -0,0 +1,9 @@
+---
+#
+# Adds distributed tutorial specific configurations
+#
+- name: Cloning byon app repo
+  git:
+    repo: "{{ tutorials.distributed.byon_app_repo_url }}"
+    dest: "/home/{{ tutorials.distributed.user }}/onos-byon"
+    version: "{{ tutorials.distributed.byon_app_version }}"
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/roles/tutorial-optical/tasks/main.yml b/tools/dev/vagrant/ansible/roles/tutorial-optical/tasks/main.yml
new file mode 100644
index 0000000..3f5a116
--- /dev/null
+++ b/tools/dev/vagrant/ansible/roles/tutorial-optical/tasks/main.yml
@@ -0,0 +1,107 @@
+---
+#
+# Adds optical tutorial specific configurations
+#
+- name: Installing Prerequisites
+  apt:
+    name: "{{ item }}"
+    force: yes
+    update_cache: yes
+  with_items: "{{ tutorials.optical.packages }}"
+
+- name: Downloading ERLANG package
+  get_url:
+    url: "{{ tutorials.optical.erlang.package_url }}"
+    dest: "{{ app_dir }}"
+
+- name: Extracting ERLANG package
+  unarchive:
+    src: "/home/ubuntu/{{ app_dir }}/otp_src_{{ tutorials.optical.erlang.version }}.tar.gz"
+    dest: "/home/ubuntu/{{ app_dir }}"
+    mode: 0777
+
+- name: Configuring ERLANG installation
+  shell: "{{ item }}"
+  args:
+    chdir: "/home/ubuntu/{{ app_dir }}/otp_src_{{ tutorials.optical.erlang.version }}"
+  with_items:
+    - ./configure
+
+- name: Installing ERLANG
+  become: yes
+  make:
+    chdir: "/home/ubuntu/{{ app_dir }}/otp_src_{{ tutorials.optical.erlang.version }}"
+    target: install
+
+- name: Removing ERLANG tar.gz
+  file:
+    path: "/home/ubuntu/{{ app_dir }}/otp_src_{{ tutorials.optical.erlang.version }}.tar.gz"
+    state: absent
+
+- name: Removing ERLANG directory
+  file:
+    path: "/home/ubuntu/{{ app_dir }}/otp_src_{{ tutorials.optical.erlang.version }}"
+    state: absent
+
+- name: Cloning LINC-OE repositories
+  git:
+    repo: "{{ item.value.url }}"
+    dest: "{{ item.value.dest }}"
+  with_dict: "{{ tutorials.optical.linc_oe }}"
+
+- name: Setting LINC-OE directory permissions
+  file:
+    path: "/home/ubuntu/{{ item.value.dest }}"
+    state: directory
+    mode: 0777
+  with_dict: "{{ tutorials.optical.linc_oe }}"
+
+- name: Configuring LINC-OE traffic generator
+  copy:
+    src: "/home/ubuntu/{{ tutorials.optical.linc_oe.config_generator.dest }}/priv/{{ item }}"
+    dest: "/home/ubuntu/{{ tutorials.optical.linc_oe.config_generator.dest }}/"
+    mode: 0777
+  with_items:
+    - "json_example.json"
+    - "sys.config.template"
+
+- name: Configuring LINC-OE switch
+  replace:
+    dest: "/home/ubuntu/{{ tutorials.optical.linc_oe.switch.dest }}/rel/files/vm.args"
+    regexp: 'ERL_MAX_ETS_TABLES 3000'
+    replace: 'ERL_MAX_ETS_TABLES 300000'
+
+- name: Applying LINC-OE switch config
+  copy:
+    src: "/home/ubuntu/{{ tutorials.optical.linc_oe.switch.dest }}/rel/files/sys.config.orig"
+    dest: "/home/ubuntu/{{ tutorials.optical.linc_oe.switch.dest }}/rel/files/sys.config"
+    mode: 0777
+
+- name: Compiling LINC-OE
+  make:
+    chdir: "/home/ubuntu/{{ item.value.dest }}"
+  with_dict: "{{ tutorials.optical.linc_oe }}"
+
+- name: Setting LINC-OE directory permissions
+  file:
+    path: "/home/ubuntu/{{ item.value.dest }}"
+    state: directory
+    mode: 0777
+  with_dict: "{{ tutorials.optical.linc_oe }}"
+
+- name: Creating LINC-OE Desktop icons
+  blockinfile:
+    dest: "/home/{{ tutorials.optical.user }}/Desktop/LINC-OE.desktop"
+    create: yes
+    owner: "{{ tutorials.optical.user }}"
+    group: "{{ tutorials.optical.user }}"
+    mode: 0777
+    block: |
+      [Desktop Entry]
+      Encoding=UTF-8
+      Type=Application
+      Name=LINC-OE
+      Name[en_US]=LINC-OE
+      Icon=konsole
+      Exec=gnome-terminal -x bash -c "{{ tutorials.optical.lincoe_exec  }}; exec $SHELL"
+      Comment[en_US]=
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/roles/tutorial-sdnip/tasks/main.yml b/tools/dev/vagrant/ansible/roles/tutorial-sdnip/tasks/main.yml
new file mode 100644
index 0000000..a0ebb76
--- /dev/null
+++ b/tools/dev/vagrant/ansible/roles/tutorial-sdnip/tasks/main.yml
@@ -0,0 +1,31 @@
+---
+#
+# Adds sdn-ip tutorial specific configurations
+#
+- name: Installing Prerequisites
+  apt:
+    name: "{{ item }}"
+    force: yes
+    update_cache: yes
+  with_items: "{{ tutorials.sdnip.packages }}"
+
+- name: Copying sdnip tutorial files
+  copy:
+    src: "/home/ubuntu/onos/tools/tutorials/sdnip"
+    dest: "/home/{{ tutorials.sdnip.user }}"
+    owner: "{{ tutorials.sdnip.user }}"
+    group: "{{ tutorials.sdnip.user }}"
+
+- name: Copying sdnip config files
+  copy:
+    src: "/home/{{ tutorials.sdnip.user }}/sdnip/configs"
+    dest: "/home/{{ tutorials.sdnip.user }}"
+    owner: "{{ tutorials.sdnip.user }}"
+    group: "{{ tutorials.sdnip.user }}"
+
+- name: Adding iptables rule for BGP-ONOS communication
+  lineinfile:
+    dest: "/home/{{ tutorials.sdnip.user }}/.xprofile"
+    line: "sudo iptables -A PREROUTING -t nat -i root-eth0 -p tcp --dport 2000 -j DNAT --to {{ lxc.lxc_one.ip }}:2000"
+    state: present
+    create: yes
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/roles/wireshark-custom/tasks/main.yml b/tools/dev/vagrant/ansible/roles/wireshark-custom/tasks/main.yml
new file mode 100644
index 0000000..d6aa38b
--- /dev/null
+++ b/tools/dev/vagrant/ansible/roles/wireshark-custom/tasks/main.yml
@@ -0,0 +1,13 @@
+- name: Enabling non-root wireshark 1/2 (Set debconf)
+  become: yes
+  debconf: name='wireshark-common' question='wireshark-common/install-setuid' value='true' vtype='boolean'
+
+- name: Enabling non-root wireshark 2/2 (reconfiguring wireshark-common package)
+  become: yes
+  command: dpkg-reconfigure -f noninteractive wireshark-common
+
+- name: Downloading most recent openflow.lua wireshark plugin
+  get_url:
+    url: "{{ wireshark.of_lua_url }}"
+    dest: /home/ubuntu
+    mode: 0777
\ No newline at end of file
diff --git a/tools/dev/vagrant/ansible/vars/global_vars.yml b/tools/dev/vagrant/ansible/vars/global_vars.yml
new file mode 100644
index 0000000..f189d0d
--- /dev/null
+++ b/tools/dev/vagrant/ansible/vars/global_vars.yml
@@ -0,0 +1,133 @@
+---
+###########################################################################
+# This file contains the global vars used to configured VM and containers #
+###########################################################################
+#
+# IP Addresses and host names
+dev_host:
+  ip: "10.100.198.200"
+  name: "onos-dev"
+  release: "xenial"
+
+lxc:
+  lxc_one:
+    ip: "10.100.198.201"
+    name: "onos1"
+    release: "xenial"
+
+  lxc_two:
+    ip: "10.100.198.202"
+    name: "onos2"
+    release: "xenial"
+
+  lxc_three:
+    ip: "10.100.198.203"
+    name: "onos3"
+    release: "xenial"
+
+# Networking and bridge configuration
+bridge:
+  phy_interface: "enp0s8"
+  name: "onosbr0"
+  ip: "{{ dev_host.ip }}/24"
+
+# ONOS Applications and Downloads folders
+app_dir: "Applications"
+download_dir: "Downloads"
+
+# Basic packages to be installed
+basic_packages:
+  - "bridge-utils"
+  - "git"
+  - "git-review"
+  - "lxc"
+  - "lxc-dev"
+  - "python-dev"
+  - "python-pip"
+
+# ONOS
+onos_repo_url: "https://gerrit.onosproject.org/onos"
+onos_version: "1.6"
+onos_nic: "10.100.198.*"
+onos_variables:
+  - "export ONOS_ROOT=~/onos"
+  - "source $ONOS_ROOT/tools/dev/bash_profile"
+
+# Karaf
+karaf_version: "3.0.5"
+
+# Tutorial reset files
+reset_files:
+  - "/home/ubuntu/reset-to-1.sh"
+  - "/home/ubuntu/reset-to-3.sh"
+
+# Tutorial cell files
+cell_files:
+  - "/home/ubuntu/onos/tools/test/cells/1node"
+  - "/home/ubuntu/onos/tools/test/cells/3node"
+
+# URL where the ONOS Desktop background is downloaded from
+onos_background_url: "https://gerrit.onosproject.org/gitweb?p=onos-vm.git;a=blob_plain;f=onos.png;hb=refs/heads/master"
+
+# Wireshark
+wireshark:
+  plugins_dir: ".config/wireshark/plugins"
+  of_lua_url: "https://raw.githubusercontent.com/floodlight/loxigen-artifacts/master/wireshark/openflow.lua"
+
+# Google Chrome repo
+google_chrome_key_url: "https://ftp-master.debian.org/keys/archive-key-6.0.asc"
+google_chrome_repo: "deb http://dl.google.com/linux/chrome/deb/ stable main"
+
+# IDEs configuration
+intellij:
+  dir_name: "idea-IC-162.1628.40"
+  url: "https://download.jetbrains.com/idea/ideaIC-2016.2.2.tar.gz"
+
+# Tutorials configuration
+tutorials:
+  basic:
+    user: "tutorial1"
+    pass: $6$rounds=656000$LB/idnMb2Yy9UqSj$28Tb6R.JU3E3O.IHNWp1cQCDlWO.niFjdInKkZz0hck7eAUII.2TywPL.3PVAIPnlSjTEcUz/qjPGas4vnS56/
+    mininet_exec: sudo mn --custom /home/ubuntu/onos/tools/test/topos/tower.py --topo tower --controller remote,{{ lxc.lxc_one.ip }} --mac
+    cell: "1node"
+    reset_exec: /home/ubuntu/reset-to-1.sh
+    url: "https://wiki.onosproject.org/display/ONOS/Basic+ONOS+Tutorial"
+
+  sdnip:
+    user: "sdnip"
+    pass: $6$rounds=656000$PFDQnzQR8r0zusoI$kM.LQFdDkAMLm7rHRh94K.VqtmTVj9fb8jwaFm2jZsF9SUGJTuMxt6IUdPp445seAOcmnVpzwk3v85bPHZtLL/
+    cell: "1node"
+    mininet_exec: sudo mn --custom /home/sdnip/sdnip/tutorial.py --topo sdnip --controller remote,{{ lxc.lxc_one.ip }} --nolistenport
+    reset_exec: /home/ubuntu/reset-to-1.sh
+    url: "https://wiki.onosproject.org/display/ONOS/SDN-IP+Tutorial"
+    packages: [ "quagga" ]
+
+  optical:
+    user: "optical"
+    pass: $6$rounds=656000$Fdw89xOiuYlJAKpi$dK6wqIVaJpn96XBxZbcwZbg2mAuPdGbNEUfJaLV1dqC/SFtdrNIWXjxCobIefy3AVMdgobZl9D3OACtt8LkTz/
+    cell: "1node"
+    mininet_exec: sudo -E python /home/ubuntu/onos/tools/test/topos/opticalTest.py {{ lxc.lxc_one.ip }}
+    lincoe_exec: sudo /home/ubuntu/linc-oe/rel/linc/bin/linc attach
+    reset_exec: /home/ubuntu/reset-to-1.sh proxyarp,optical
+    url: "https://wiki.onosproject.org/display/ONOS/Packet+Optical+Tutorial"
+    packages: [ "make", "libncurses5-dev" ]
+    erlang:
+      version: "17.5"
+      package_url: "http://erlang.org/download/otp_src_17.5.tar.gz"
+    linc_oe:
+      config_generator:
+        url: "https://github.com/FlowForwarding/LINC-config-generator.git"
+        dest: "LINC-config-generator"
+      switch:
+        url: "https://github.com/FlowForwarding/LINC-Switch.git"
+        dest: "linc-oe"
+
+  distributed:
+    user: "distributed"
+    pass: $6$rounds=656000$OR9O9v15WVPqoXyu$eaBtzH9xhqi9E10U2kSlT2ltFzgpPU81yRBE6mCY.Ln9YzIYDnNys5gnPtflw1OJqa8L.8h6mPB.sIETd.oTm0
+    cell: "3node"
+    mininet_exec: cd /home/distributed/onos-byon/ && ./startmn.sh
+    reset_exec: /home/ubuntu/reset-to-3.sh
+    url: "https://wiki.onosproject.org/display/ONOS/Distributed+ONOS+Tutorial"
+    byon_app_repo_url: "https://github.com/bocon13/onos-byon.git"
+    byon_app_version: "starter-{{ onos_version }}.0"
\ No newline at end of file