generate ssh key pair

Change-Id: I9f7cbdb0ba9379eed262cc211a5eff2be5b05f8a
diff --git a/.gitignore b/.gitignore
index d77fa41..6263af1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,16 @@
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
+# Ignore the generated password storage area
+passwords
+
+# Ignore Ansible retry files
+*.retry
+
+# Ignore vim swap files
+*.swp
+
+# Ignore Gradle build files
+.gradle
+
+## Compiled Object files, Static and Dynamic libs (Shared Objects)
 *.o
 *.a
 *.so
diff --git a/ansible/roles/common/tasks/main.yml b/ansible/roles/common/tasks/main.yml
index b7d5eb2..7084802 100644
--- a/ansible/roles/common/tasks/main.yml
+++ b/ansible/roles/common/tasks/main.yml
@@ -32,7 +32,7 @@
     state: directory
     owner: "{{ ansible_user }}"
     group: "{{ ansible_user }}"
-    mode: 0700
+    mode: "0700"
   tags: [common]
 
 - name: Ensure known_hosts file is absent
@@ -47,6 +47,6 @@
     dest: /home/{{ ansible_user }}/.ssh/config
     owner: "{{ ansible_user }}"
     group: "{{ ansible_user }}"
-    mode: 0600
+    mode: "0600"
   tags: [common]
 
diff --git a/ansible/roles/consul-template/tasks/main.yml b/ansible/roles/consul-template/tasks/main.yml
index 06a5e03..2e2bc6d 100644
--- a/ansible/roles/consul-template/tasks/main.yml
+++ b/ansible/roles/consul-template/tasks/main.yml
@@ -8,12 +8,12 @@
   copy:
     src: consul-template
     dest: /usr/local/bin/consul-template
-    mode: 0755
+    mode: "0755"
   tags: [consul-template]
 
 - name: Example template is copied
   copy:
     src: example.ctmpl
     dest: /data/consul-template/example.ctmpl
-    mode: 0644
+    mode: "0644"
   tags: [consul-template]
diff --git a/ansible/roles/docker-compose/tasks/main.yml b/ansible/roles/docker-compose/tasks/main.yml
index 3845f4a..41ed8cc 100644
--- a/ansible/roles/docker-compose/tasks/main.yml
+++ b/ansible/roles/docker-compose/tasks/main.yml
@@ -2,4 +2,4 @@
   get_url:
     url: https://github.com/docker/compose/releases/download/1.6.2/docker-compose-Linux-x86_64
     dest: /usr/local/bin/docker-compose
-    mode: 0755
+    mode: "0755"
diff --git a/ansible/roles/docker/templates/docker.cfg b/ansible/roles/docker/templates/docker.cfg
index 7dfff7b..467a304 100644
--- a/ansible/roles/docker/templates/docker.cfg
+++ b/ansible/roles/docker/templates/docker.cfg
@@ -1,3 +1,3 @@
-DOCKER_OPTS="$DOCKER_OPTS --insecure-registry 10.100.198.200:5000 -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --registry-mirror=http://10.100.198.200:5001"
+DOCKER_OPTS="$DOCKER_OPTS --insecure-registry 10.100.198.200:5000 -H unix:///var/run/docker.sock --registry-mirror=http://10.100.198.200:5001"
 DOCKER_OPTS="$DOCKER_OPTS --insecure-registry 10.100.198.201:5000"
 
diff --git a/ansible/roles/fakeswitch/tasks/main.yml b/ansible/roles/fakeswitch/tasks/main.yml
index 39879e9..efddbf9 100644
--- a/ansible/roles/fakeswitch/tasks/main.yml
+++ b/ansible/roles/fakeswitch/tasks/main.yml
@@ -10,7 +10,7 @@
     path: "{{ item }}"
     owner: root
     group: root
-    mode: 0755
+    mode: "0755"
     state: directory
   with_items:
     - /mnt/flash2
@@ -23,7 +23,7 @@
     dest: /usr/bin/{{ item }}
     owner: root
     group: root
-    mode: 0755
+    mode: "0755"
   with_items:
     - persist
     - savepersist
diff --git a/build.gradle b/build.gradle
index 48ed61d..aa869e5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -336,6 +336,12 @@
             .p(config.seedServer.port, "ansible_ssh_port")
     }
 
+    if (config.passwords) {
+        extraVars = extraVars.p(config.passwords.compute_node, "password_compute_node")
+        .p(config.passwords.maas_admin, "password_maas_admin")
+        .p(config.passwords.maas_user, "password_maas_user")
+    }
+
     if (config.otherServers) {
         extraVars = extraVars.p(config.otherServers.location, "prov_location")
         .p(config.otherServers.rolesPath, "prov_role_path")
@@ -345,7 +351,10 @@
     extraVars = extraVars.p("$targetReg", "deploy_docker_registry")
         .p("$targetTag", "deploy_docker_tag")
 
-    def skipTags = [].p(config.seedServer.skipTags)
+    // the password set on the compute node is skipped because this is being run against the 
+    // head node and we don't want to change the head node password as this node was manualy 
+    // set up.
+    def skipTags = [].p(config.seedServer.skipTags).p('set_compute_node_password')
 
     args = args.p(skipTags.asParam("skip-tags", ",")).p(extraVars.asParam("extra-vars", " ")) << "prime-node.yml"
 }
@@ -389,6 +398,12 @@
             .p(config.seedServer.port, "ansible_ssh_port")
     }
 
+    if (config.passwords) {
+        extraVars = extraVars.p(config.passwords.compute_node, "password_compute_node")
+        .p(config.passwords.maas_admin, "password_maas_admin")
+        .p(config.passwords.maas_user, "password_maas_user")
+    }
+
     if (config.otherServers) {
         extraVars = extraVars.p(config.otherServers.location, "prov_location")
         .p(config.otherServers.rolesPath, "prov_role_path")
@@ -398,7 +413,10 @@
     extraVars = extraVars.p("$targetReg", "deploy_docker_registry")
         .p("$targetTag", "deploy_docker_tag")
 
-    def skipTags = [].p(config.seedServer.skipTags)
+    // the password set on the compute node is skipped because this is being run against the
+    // head node and we don't want to change the head node password as this node was manualy
+    // set up.
+    def skipTags = [].p(config.seedServer.skipTags).p('set_compute_node_password')
 
     args = args.p(skipTags.asParam("skip-tags", ",")).p(extraVars.asParam("extra-vars", " ")) << "head-node.yml"
 }
diff --git a/roles/compute-node/files/id_rsa b/roles/compute-node/files/id_rsa
deleted file mode 100644
index e4a3947..0000000
--- a/roles/compute-node/files/id_rsa
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEpQIBAAKCAQEA4ixakIQFlpSXd3NJ98btbO7Dt0o9ioDl0ZLZa2v1g0dWifn0
-W5gkqo9VSkY2fPwUtgxnyoyVFiEc1MyLNxAkd6UHl+YzFw4dDCrEpu5XDCPCkvky
-dd2P3OiuxmheDqjpklPMWddsWSIA061qSdBQ+pYm9Qq5tfekvOVcAPPkoB22ftPr
-gnOSovvTwHfnZH/gfiI+IxUcWwLkneiUenw5oO+3Jie1Gbn3yFqf3pk+VG6M+8YH
-gZKY0/TBaFBHB+acKN3/yIhnnQzfwRyLX5txnYyaDI0HjVLJQiFK0XKgTGhm4U7C
-mpWkEH6WLF/cOs9+chQDDSwOxRD/VIw6W4sXIwIDAQABAoIBABhQFkg0uPkP7hxc
-G1Z0Xu931zgr1eO+qXXW6GJgz5qWH5pjcT4rY72l/NAoLhFPc9aCDOI8LIaddqD1
-f/2iUZk+90r/5vwSe1LkghFDy721VmRAP4lmEOH5bVhMvderlrgxI+WAf9gxDI+0
-s5lNuHbHj1aGGaKTBXV83mAH18rSUxxPZ+M5xT9RE5uKJwZcRLrqnOI3dleGy7xc
-Pxrtm0v/507DVjRdQzpjcYkndGQXfOqjNLEtwMADwmYCOEF3sqaSSDeqYtg/IOIR
-hiM65ekl7R+bqMaowv82V5NCfdSXKyRLvk4Nr9E9Jji9gPA2bYkx6ASkkWduGzA3
-tYqs5kkCgYEA9y396CV/NQfxGGwRD/lLtpNG/YgzihO+IojLd5RsdTCUxvxB5BCx
-i/KGWisg5PLORBh1UGpyrSIKaoMJXbrSSpQwZri+Xnpjt/qHIT8KWUN4tuiHKluV
-DkWQFkD1aOIZujWEX9J25C/SGICtyCIWp/ylNPX6Kwf/cm8W7A7GPU0CgYEA6j53
-dHW2ia4k0ze0HI0PWaiZoi2jFhzI33le1MMBjRMIS3TW2LajWB3TjFs+AdLb831P
-gQrA76oMQ5KDZ3o2b4NrixwfRAQaBBW2cCsRLkxZEIsoVa3QthT5UihqR/t6G6FB
-u9pl+fK8IsHoc5pKFtOkCD9c/Axyu0m30BWqLi8CgYEAjbEPm8Pi58NlsVpBbaa6
-gC5sw2kQIlau550DBclPYt42atqv6sym+lJMMeQHNzb4hpB+r1pV4mlhDy2OcOxn
-H9lS5Y+BkScXgp9aVvSMOh8zU6Z31RAqocO+lQMnqrfxh4ymFUfQX34KMYGSHOdt
-lV5+VZ2rin9LL43+1dKiUQECgYEAlOCQ4ZbzJjxlMU1lDwRkbjKnOplQ3vv6e3ZT
-XFx4fuZKzlJ7Po+N77I9Qya2mUgf/Xh2cGiaSXjFhKj5FWpqcKORVX/RK1SECHaY
-VmA48jkaHlajkxj+3ssjzyDas9dUO31ZHwDm8V5iTqD5kYfNcQagaZGEEroCraBj
-0EAEwocCgYEAmQ2RumGHjYdSgkxw1MWCAXg1RPBaifZifErhe1MiVkZuHdCxYn3p
-Yv7KPaOQtYfbZEN1Ww3ScWqIRZzOmRdEakFGFh+d1V+qK1r/Bj6SBSOND1UZFm+j
-+DeGwmHuPzdNbtoW4dqyFM5OFib3N9P6r87Kfl1X3q31R8gVhK4wtOo=
------END RSA PRIVATE KEY-----
diff --git a/roles/compute-node/files/id_rsa.pub b/roles/compute-node/files/id_rsa.pub
deleted file mode 100644
index 36daa90..0000000
--- a/roles/compute-node/files/id_rsa.pub
+++ /dev/null
@@ -1 +0,0 @@
-ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDiLFqQhAWWlJd3c0n3xu1s7sO3Sj2KgOXRktlra/WDR1aJ+fRbmCSqj1VKRjZ8/BS2DGfKjJUWIRzUzIs3ECR3pQeX5jMXDh0MKsSm7lcMI8KS+TJ13Y/c6K7GaF4OqOmSU8xZ12xZIgDTrWpJ0FD6lib1Crm196S85VwA8+SgHbZ+0+uCc5Ki+9PAd+dkf+B+Ij4jFRxbAuSd6JR6fDmg77cmJ7UZuffIWp/emT5Uboz7xgeBkpjT9MFoUEcH5pwo3f/IiGedDN/BHItfm3GdjJoMjQeNUslCIUrRcqBMaGbhTsKalaQQfpYsX9w6z35yFAMNLA7FEP9UjDpbixcj cord@cord.lab
diff --git a/roles/compute-node/files/remove-maas-components b/roles/compute-node/files/remove-maas-components
index 4d85694..5adf79e 100755
--- a/roles/compute-node/files/remove-maas-components
+++ b/roles/compute-node/files/remove-maas-components
@@ -1,10 +1,31 @@
 #!/bin/bash
 
-docker kill $(docker ps -q)
-docker rm -f $(docker ps -aq)
-docker rmi -f $(docker images -aq)
+KEEP_DOCKER=0
+DOCKER_ENGINE="docker-engine"
+DOCKER_REGISTRY="/docker-registry /docker-registry-mirror"
+CONTAINER_LIST=$(docker ps -qa)
 
-sudo apt-get remove --purge -y bind9 apache2 docker-engine ansible $(dpkg --get-selections | grep maas | cut -f1)
+while [ $# -gt 0 ]; do
+    case $1 in
+        -k|--keep-docker)
+            KEEP_DOCKER=1
+            DOCKER_ENGINE=
+            DOCKER_REGISTRY=
+	    CONTAINER_LIST=$(docker ps --format '{{.ID}} {{.Names}}' | grep -v ' registry$' | grep -v ' registry-mirror$' | awk '{print $1}')
+            ;;
+    esac
+    shift
+done
+
+CONTAINER_LIST=$(docker ps --format '{{.ID}} {{.Names}}' | grep -v ' registry$' | grep -v ' registry-mirror$' | awk '{print $1}')
+
+docker kill $CONTAINER_LIST
+docker rm -f $CONTAINER_LIST
+if [ $KEEP_DOCKER -eq 0 ]; then
+    docker rmi -f $(docker images -aq)
+fi
+
+sudo apt-get remove --purge -y bind9 apache2 $DOCKER_ENGINE ansible $(dpkg --get-selections | grep maas | cut -f1)
 
 sudo rm -rf \
     /etc/maas \
@@ -20,12 +41,10 @@
     /etc/apt/sources.list.d/ppa_maas_stable_trusty.list \
     /etc/apt/sources.list.d/ppa_ansible_ansible_trusty.list \
     /etc/network/if-pre-up.d/nat \
-    /docker-registry \
-    /docker-registry-mirror
+    $DOCKER_REGISTRY
 
 sudo apt-get update -y
 
 # remove NAT rules
 sudo iptables --table nat --delete POSTROUTING --out-interface eth3 -j MASQUERADE
 sudo iptables --delete FORWARD --in-interface mgmtbr -j ACCEPT
-
diff --git a/roles/compute-node/files/remove-xos-components b/roles/compute-node/files/remove-xos-components
index 1b6fc42..2f2cf07 100755
--- a/roles/compute-node/files/remove-xos-components
+++ b/roles/compute-node/files/remove-xos-components
@@ -19,6 +19,9 @@
 UVT=$(which uvt-kvm)
 test -z $UVT || uvt-kvm list | xargs uvt-kvm destroy
 
+LXC=$(which lxc)
+test -z $LXC || lxc delete --force $(lxc list | grep "^| [^ ]" | awk '{print $2}')
+
 sudo apt-get remove --purge -y $(dpkg --get-selections | grep "nagioas\|juju\|nova\|neutron" | awk '{print $1}') &&sudo apt-get autoremove -y && sudo rm -rf /etc/juju /etc/neutron /home/ubuntu/.juju && sudo find / -name "*juju*" -exec rm -r \{\} \; && sudo rm -f /var/lib/uvtool/libvirt/images/*
 
 OVS=$(which ovs-vsctl)
diff --git a/roles/compute-node/meta/main.yml b/roles/compute-node/meta/main.yml
index 047a60f..2e50ead 100644
--- a/roles/compute-node/meta/main.yml
+++ b/roles/compute-node/meta/main.yml
@@ -12,5 +12,6 @@
   galaxy_tags:
     - cord
 dependencies:
+  - { role: prep }
   - { role: local-ubuntu-repository, when: ubuntu_apt_repo is defined }
   - { role : docker }
diff --git a/roles/compute-node/tasks/main.yml b/roles/compute-node/tasks/main.yml
index f093d17..bfafc40 100644
--- a/roles/compute-node/tasks/main.yml
+++ b/roles/compute-node/tasks/main.yml
@@ -19,6 +19,7 @@
   become: yes
   apt: name={{ item }} state=present force=yes
   with_items:
+    - whois
     - build-essential=11.6*
     - git=1:1.9.*
     - python-pip=1.5.4*
@@ -29,6 +30,31 @@
     - curl=7.35.*
     - jq=1.3*
 
+- name: Validate Encyrpted Compute Node Password
+  set_fact:
+    already_encrypted: "{{compute_node.password.startswith('enc:')}}"
+
+# If the compute_node.password begins with 'enc:' then it is an
+# encyrpted password, which is what we need so we are done. Thus
+# if it is not encrypted then we have to encrypt it
+
+- name: Encyrpt Compute Node Password
+  command: "mkpasswd --method=sha-512 {{compute_node.password}}"
+  register: encrypted
+  changed_when: false
+  when: "not already_encrypted"
+
+- name: Update Compute Node Password
+  set_fact:
+    compute_node_update:
+      password: "enc:{{encrypted.stdout}}"
+  when: "not already_encrypted"
+
+- name: Merge Compute Node Properties
+  set_fact:
+    compute_node: "{{compute_node|combine(compute_node_update,recursive=True)}}"
+  when: "not already_encrypted"
+
 - name: Ensure Docker Insecure Repository
   become: yes
   lineinfile:
@@ -61,16 +87,18 @@
 - name: Set Default Password
   become: yes
   user:
-    name={{ ansible_user }}
-    password="$6$TjhJuOgh8xp.v$z/4GwFbn5koVmkD6Ex9wY7bgP7L3uP2ujZkZSs1HNdzQdz9YclbnZH9GvqMC/M1iwC0MceL05.13HoFz/bai0/"
+    name: "{{ansible_user}}"
+    password: "{{compute_node.password.split(':',1)[1]}}"
   when: '"{{ ansible_user }}" == "ubuntu"'
+  tags:
+    - set_compute_node_password
 
 - name: Authorize SSH Key
   become: yes
   authorized_key:
-    key="{{ pub_ssh_key }}"
-    user={{ ansible_user }}
-    state=present
+    key: "{{ pub_ssh_key }}"
+    user: "{{ ansible_user }}"
+    state: present
 
 - name: Verify Private SSH Key
   become: yes
@@ -78,16 +106,26 @@
     path=/home/{{ ansible_user }}/.ssh/id_rsa
   register: private_key
 
-- name: Ensure SSH Key
+- name: Ensure SSH Key Pair
+  become: yes
+  copy:
+    src: "/etc/maas/.ssh/{{item.src}}"
+    dest: "{{ansible_env['PWD']}}/.ssh/{{item.dest}}"
+    owner: "{{ansible_user}}"
+    group: "docker"
+    mode: "0600"
+  with_items:
+    - { "src": "cord_rsa", "dest": "id_rsa" }
+    - { "src": "cord_rsa.pub", "dest": "id_rsa.pub" }
+
+- name: Ensure SSH config
   become: no
   copy:
-    src=files/{{ item }}
-    dest={{ ansible_env['PWD'] }}/.ssh/{{ item }}
-    owner={{ ansible_user }}
-    mode=0600
+    src: "files/{{item}}"
+    dest: "{{ansible_env['PWD']}}/.ssh/{{item}}"
+    owner: "{{ansible_user}}"
+    mode: "0600"
   with_items:
-    - id_rsa
-    - id_rsa.pub
     - config
 
 - name: Ensure CORD SUDO
@@ -97,7 +135,7 @@
     dest=/etc/sudoers.d/99-cord-sudoers
     owner=root
     group=root
-    mode=0600
+    mode="0600"
 
 - name: Ensure Utility Scripts
   become: yes
@@ -106,7 +144,7 @@
     dest=/usr/local/bin/{{ item }}
     owner=root
     group=root
-    mode=0755
+    mode="0755"
   with_items:
     - delete-fabric-config
     - delete-node-prov-state
diff --git a/roles/compute-node/vars/main.yml b/roles/compute-node/vars/main.yml
index 7e6ff5e..5accf44 100644
--- a/roles/compute-node/vars/main.yml
+++ b/roles/compute-node/vars/main.yml
@@ -1,6 +1,7 @@
-pub_ssh_key: "{{ lookup('file', 'files/id_rsa.pub') }}"
+pub_ssh_key: "{{ lookup('file', '/etc/maas/.ssh/cord_rsa.pub') }}"
 
 compute_node:
+    password: "{{password_compute_node | default(lookup('password', 'passwords/compute_node.txt'))}}"
     fabric:
         include:
             names: "{{ fabric_include_names | default(omit) }}"
diff --git a/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml
index d3b3622..a0383a2 100644
--- a/roles/docker/tasks/main.yml
+++ b/roles/docker/tasks/main.yml
@@ -30,7 +30,7 @@
     dest=/etc/default/docker
     state=present
     insertafter='#DOCKER_OPTS'
-    line='DOCKER_OPTS="-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock"'
+    line='DOCKER_OPTS="-H unix:///var/run/docker.sock"'
   register: docker_config
 
 - name: Docker Restart
@@ -54,4 +54,4 @@
     dest=/usr/local/bin/docker-compose
     owner=root
     group=root
-    mode=0755
+    mode="0755"
diff --git a/roles/fabric-switch/files/id_rsa.pub b/roles/fabric-switch/files/id_rsa.pub
deleted file mode 100644
index 36daa90..0000000
--- a/roles/fabric-switch/files/id_rsa.pub
+++ /dev/null
@@ -1 +0,0 @@
-ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDiLFqQhAWWlJd3c0n3xu1s7sO3Sj2KgOXRktlra/WDR1aJ+fRbmCSqj1VKRjZ8/BS2DGfKjJUWIRzUzIs3ECR3pQeX5jMXDh0MKsSm7lcMI8KS+TJ13Y/c6K7GaF4OqOmSU8xZ12xZIgDTrWpJ0FD6lib1Crm196S85VwA8+SgHbZ+0+uCc5Ki+9PAd+dkf+B+Ij4jFRxbAuSd6JR6fDmg77cmJ7UZuffIWp/emT5Uboz7xgeBkpjT9MFoUEcH5pwo3f/IiGedDN/BHItfm3GdjJoMjQeNUslCIUrRcqBMaGbhTsKalaQQfpYsX9w6z35yFAMNLA7FEP9UjDpbixcj cord@cord.lab
diff --git a/roles/fabric-switch/tasks/main.yml b/roles/fabric-switch/tasks/main.yml
index 4e718f9..afea0ed 100644
--- a/roles/fabric-switch/tasks/main.yml
+++ b/roles/fabric-switch/tasks/main.yml
@@ -30,7 +30,7 @@
     dest: /root
     owner: root
     group: root
-    mode: 0755
+    mode: "0755"
   with_items:
     - purge
     - killit
diff --git a/roles/fabric-switch/vars/main.yml b/roles/fabric-switch/vars/main.yml
index 6d1a0cd..d63e3ab 100644
--- a/roles/fabric-switch/vars/main.yml
+++ b/roles/fabric-switch/vars/main.yml
@@ -1 +1 @@
-pub_ssh_key: "{{ lookup('file', 'files/id_rsa.pub') }}"
+pub_ssh_key: "{{ lookup('file', '/etc/maas/.ssh/cord_rsa.pub') }}"
diff --git a/roles/head-node/tasks/main.yml b/roles/head-node/tasks/main.yml
index b617dbe..7d59204 100644
--- a/roles/head-node/tasks/main.yml
+++ b/roles/head-node/tasks/main.yml
@@ -19,7 +19,7 @@
     owner=maas
     group=maas
     state=directory
-    mode=0755
+    mode="0755"
 
 - name: Ensure Ansible Roles
   become: yes
@@ -47,7 +47,7 @@
     src=files/{{ item }}
     owner=maas
     group=maas
-    mode=0755
+    mode="0755"
   with_items:
     - do-ansible
     - do-switch
@@ -59,7 +59,7 @@
     state=directory
     owner=maas
     group=maas
-    mode=0755
+    mode="0755"
 
 - name: Capture MAAS API Key
   become: yes
@@ -74,7 +74,7 @@
     dest=/etc/maas/ansible/{{ item }}
     owner=maas
     group=maas
-    mode=0644
+    mode="0644"
   with_items:
     - compute-node.yml
     - switch-node.yml
@@ -85,7 +85,7 @@
     path=/etc/maas/ansible/vars
     owner=maas
     group=maas
-    mode=0755
+    mode="0755"
     state=directory
 
 - name: Ensure Compute and Switch Node Variables
@@ -95,7 +95,7 @@
     dest=/etc/maas/ansible/vars/compute-node-vars.yml
     owner=maas
     group=maas
-    mode=0644
+    mode="0644"
 
 - name: Ensure Connect Switch Ansible Playbook
   become: yes
@@ -104,7 +104,7 @@
     src=files/{{ item }}
     owner=maas
     group=maas
-    mode=0644
+    mode="0644"
   with_items:
     - connect-switch.yml
 
@@ -115,7 +115,7 @@
     dest=/etc/maas/ansible/pod-inventory
     owner=maas
     group=maas
-    mode=0755
+    mode="0755"
 
 - name: Copy CORD Utility Scripts
   become: yes
@@ -124,7 +124,7 @@
     dest=/usr/local/bin/{{ item }}
     owner=root
     group=root
-    mode=0755
+    mode="0755"
   with_items:
     - cord
     - cord-harvest
@@ -132,3 +132,24 @@
     - cord-switch
     - cord-generate
     - cord-registry
+
+- name: Ensure SSH Key Storage
+  become: yes
+  file:
+    path: /etc/maas/.ssh
+    mode: "0755"
+    owner: maas
+    group: maas
+    state: directory
+
+- name: Copy SSH Key Pair for POD
+  become: yes
+  copy:
+    src: /etc/maas/.ssh/{{item}}
+    dest: /etc/maas/.ssh/{{item}}
+    owner: maas
+    group: maas
+    mode: "0644"
+  with_items:
+    - cord_rsa
+    - cord_rsa.pub
diff --git a/roles/head-node/templates/compute-node-vars.yml.j2 b/roles/head-node/templates/compute-node-vars.yml.j2
index 10bc4e0..0ece477 100644
--- a/roles/head-node/templates/compute-node-vars.yml.j2
+++ b/roles/head-node/templates/compute-node-vars.yml.j2
@@ -1,3 +1,6 @@
+{% if compute_node.password is defined and compute_node.password != omit %}
+password_compute_node: '{{ compute_node.password }}'
+{% endif %}
 {% if compute_node.fabric.include.names is defined and compute_node.fabric.include.names != omit %}
 fabric_include_names: '{{ compute_node.fabric.include.names }}'
 {% endif %}
diff --git a/roles/local-ubuntu-repository/tasks/main.yml b/roles/local-ubuntu-repository/tasks/main.yml
index dd9be2b..92a24f8 100644
--- a/roles/local-ubuntu-repository/tasks/main.yml
+++ b/roles/local-ubuntu-repository/tasks/main.yml
@@ -7,7 +7,7 @@
     src: sources.list.j2
     group: root
     owner: root
-    mode: 0644
+    mode: "0644"
   when: ubuntu_apt_repo is defined
 
 - name: Capture Existing Respositories
diff --git a/roles/maas/files/cord_id_rsa b/roles/maas/files/cord_id_rsa
deleted file mode 100644
index e4a3947..0000000
--- a/roles/maas/files/cord_id_rsa
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEpQIBAAKCAQEA4ixakIQFlpSXd3NJ98btbO7Dt0o9ioDl0ZLZa2v1g0dWifn0
-W5gkqo9VSkY2fPwUtgxnyoyVFiEc1MyLNxAkd6UHl+YzFw4dDCrEpu5XDCPCkvky
-dd2P3OiuxmheDqjpklPMWddsWSIA061qSdBQ+pYm9Qq5tfekvOVcAPPkoB22ftPr
-gnOSovvTwHfnZH/gfiI+IxUcWwLkneiUenw5oO+3Jie1Gbn3yFqf3pk+VG6M+8YH
-gZKY0/TBaFBHB+acKN3/yIhnnQzfwRyLX5txnYyaDI0HjVLJQiFK0XKgTGhm4U7C
-mpWkEH6WLF/cOs9+chQDDSwOxRD/VIw6W4sXIwIDAQABAoIBABhQFkg0uPkP7hxc
-G1Z0Xu931zgr1eO+qXXW6GJgz5qWH5pjcT4rY72l/NAoLhFPc9aCDOI8LIaddqD1
-f/2iUZk+90r/5vwSe1LkghFDy721VmRAP4lmEOH5bVhMvderlrgxI+WAf9gxDI+0
-s5lNuHbHj1aGGaKTBXV83mAH18rSUxxPZ+M5xT9RE5uKJwZcRLrqnOI3dleGy7xc
-Pxrtm0v/507DVjRdQzpjcYkndGQXfOqjNLEtwMADwmYCOEF3sqaSSDeqYtg/IOIR
-hiM65ekl7R+bqMaowv82V5NCfdSXKyRLvk4Nr9E9Jji9gPA2bYkx6ASkkWduGzA3
-tYqs5kkCgYEA9y396CV/NQfxGGwRD/lLtpNG/YgzihO+IojLd5RsdTCUxvxB5BCx
-i/KGWisg5PLORBh1UGpyrSIKaoMJXbrSSpQwZri+Xnpjt/qHIT8KWUN4tuiHKluV
-DkWQFkD1aOIZujWEX9J25C/SGICtyCIWp/ylNPX6Kwf/cm8W7A7GPU0CgYEA6j53
-dHW2ia4k0ze0HI0PWaiZoi2jFhzI33le1MMBjRMIS3TW2LajWB3TjFs+AdLb831P
-gQrA76oMQ5KDZ3o2b4NrixwfRAQaBBW2cCsRLkxZEIsoVa3QthT5UihqR/t6G6FB
-u9pl+fK8IsHoc5pKFtOkCD9c/Axyu0m30BWqLi8CgYEAjbEPm8Pi58NlsVpBbaa6
-gC5sw2kQIlau550DBclPYt42atqv6sym+lJMMeQHNzb4hpB+r1pV4mlhDy2OcOxn
-H9lS5Y+BkScXgp9aVvSMOh8zU6Z31RAqocO+lQMnqrfxh4ymFUfQX34KMYGSHOdt
-lV5+VZ2rin9LL43+1dKiUQECgYEAlOCQ4ZbzJjxlMU1lDwRkbjKnOplQ3vv6e3ZT
-XFx4fuZKzlJ7Po+N77I9Qya2mUgf/Xh2cGiaSXjFhKj5FWpqcKORVX/RK1SECHaY
-VmA48jkaHlajkxj+3ssjzyDas9dUO31ZHwDm8V5iTqD5kYfNcQagaZGEEroCraBj
-0EAEwocCgYEAmQ2RumGHjYdSgkxw1MWCAXg1RPBaifZifErhe1MiVkZuHdCxYn3p
-Yv7KPaOQtYfbZEN1Ww3ScWqIRZzOmRdEakFGFh+d1V+qK1r/Bj6SBSOND1UZFm+j
-+DeGwmHuPzdNbtoW4dqyFM5OFib3N9P6r87Kfl1X3q31R8gVhK4wtOo=
------END RSA PRIVATE KEY-----
diff --git a/roles/maas/files/cord_id_rsa.pub b/roles/maas/files/cord_id_rsa.pub
deleted file mode 100644
index 36daa90..0000000
--- a/roles/maas/files/cord_id_rsa.pub
+++ /dev/null
@@ -1 +0,0 @@
-ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDiLFqQhAWWlJd3c0n3xu1s7sO3Sj2KgOXRktlra/WDR1aJ+fRbmCSqj1VKRjZ8/BS2DGfKjJUWIRzUzIs3ECR3pQeX5jMXDh0MKsSm7lcMI8KS+TJ13Y/c6K7GaF4OqOmSU8xZ12xZIgDTrWpJ0FD6lib1Crm196S85VwA8+SgHbZ+0+uCc5Ki+9PAd+dkf+B+Ij4jFRxbAuSd6JR6fDmg77cmJ7UZuffIWp/emT5Uboz7xgeBkpjT9MFoUEcH5pwo3f/IiGedDN/BHItfm3GdjJoMjQeNUslCIUrRcqBMaGbhTsKalaQQfpYsX9w6z35yFAMNLA7FEP9UjDpbixcj cord@cord.lab
diff --git a/roles/maas/tasks/download.yml b/roles/maas/tasks/download.yml
index 1fc73c7..49f00fe 100644
--- a/roles/maas/tasks/download.yml
+++ b/roles/maas/tasks/download.yml
@@ -33,6 +33,6 @@
     path: "/var/www/html/{{ item.dest }}"
     owner: root
     group: root
-    mode: 0644
+    mode: "0644"
   tags:
     - switch_support
diff --git a/roles/maas/tasks/main.yml b/roles/maas/tasks/main.yml
index fe05558..fd136b1 100644
--- a/roles/maas/tasks/main.yml
+++ b/roles/maas/tasks/main.yml
@@ -74,7 +74,7 @@
     path: /etc/maas
     owner: maas
     group: maas
-    mode: 0755
+    mode: "0755"
     state: directory
 
 - name: MAAS Automation Storage
@@ -83,7 +83,7 @@
     path: /etc/maas/automation/storage
     owner: maas
     group: maas
-    mode: 0777
+    mode: "0777"
     state: directory
 
 - name: Host Name Mapping File
@@ -93,7 +93,7 @@
     dest: /etc/maas/mappings.json
     owner: maas
     group: maas
-    mode: 0644
+    mode: "0644"
 
 - name: Verify MAAS admin User
   become: yes
@@ -103,7 +103,7 @@
 
 - name: MAAS admin User
   become: yes
-  command: maas-region-admin createadmin --username=admin --password=admin --email={{ maas.admin_email }}
+  command: maas-region-admin createadmin --username=admin --password={{ maas.admin_password }} --email={{ maas.admin_email }}
   when: maas_admin_user_exists.stdout == '0'
 
 - name: Verify MAAS User
@@ -140,7 +140,7 @@
     dest: /etc/network/if-pre-up.d/nat
     owner: root
     group: root
-    mode: 0755
+    mode: "0755"
 
 - name: Ensure Masquerading (NAT)
   become: yes
@@ -202,7 +202,7 @@
     dest: "{{ item.dest }}"
     owner: maas
     group: maas
-    mode: 0644
+    mode: "0644"
   with_items:
     - { src: 'dhcpd.blacklist', dest: '/etc/dhcp' }
     - { src: 'dhcpd.reservations', dest: '/etc/dhcp' }
@@ -291,7 +291,7 @@
     path: /etc/maas/ansible/id_rsa
     owner: root
     group: root
-    mode: 0400
+    mode: "0400"
 
 - name: Initialize Interface Configuration Fact
   set_fact:
@@ -324,7 +324,7 @@
     state: directory
     owner: root
     group: docker
-    mode: 0755
+    mode: "0755"
 
 - name: Ensure Automation Container Secrets
   become: yes
@@ -333,7 +333,7 @@
     dest: /etc/maas/secrets/{{ item }}
     owner: root
     group: docker
-    mode: 0440
+    mode: "0440"
   with_items:
     - automation.env
     - switchq.env
@@ -345,7 +345,7 @@
     dest: /etc/maas/{{ item }}
     owner: maas
     group: maas
-    mode: 0644
+    mode: "0644"
   with_items:
     - automation-compose.yml
 
diff --git a/roles/maas/tasks/virtualbox.yml b/roles/maas/tasks/virtualbox.yml
index 25bef6f..f46254c 100644
--- a/roles/maas/tasks/virtualbox.yml
+++ b/roles/maas/tasks/virtualbox.yml
@@ -12,7 +12,7 @@
     dest: /etc/maas/templates/power/amt.template
     owner: maas
     group: maas
-    mode: 0755
+    mode: "0755"
 
 - name: Ensure SSH Discovery Directory
   become: yes
@@ -21,16 +21,16 @@
     state: directory
     owner: maas
     group: maas
-    mode: 0755
+    mode: "0755"
 
 - name: VirtualBox Power Discovery Support
   become: yes
   copy:
-    src: files/cord_id_rsa
+    src: /etc/maas/.ssh/cord_rsa
     dest: /etc/maas/virtualbox/id_rsa
     owner: root
     group: root
-    mode: 0600
+    mode: "0600"
 
 - name: VirtualBox Power Discovery Script
   become: yes
@@ -39,7 +39,7 @@
     dest: /etc/maas/virtualbox/power_discovery
     owner: maas
     group: maas
-    mode: 0755
+    mode: "0755"
 
 - name: Ensure SSH Power Script Directory
   become: yes
@@ -48,19 +48,29 @@
     state: directory
     owner: maas
     group: maas
-    mode: 0700
+    mode: "0700"
 
-- name: VirtualBox Power Script Support
+- name: VirtualBox Power Script Key Pair Support
   become: yes
   copy:
-    src: files/{{ item.src }}
+    src: /etc/maas/.ssh/{{ item.src }}
     dest: /var/lib/maas/.ssh/{{ item.dest }}
     owner: maas
     group: maas
-    mode: 0600
+    mode: "0600"
   with_items:
-    - { src: cord_id_rsa, dest: id_rsa }
-    - { src: cord_id_rsa.pub, dest: id_rsa.pub }
+    - { src: cord_rsa, dest: id_rsa }
+    - { src: cord_rsa.pub, dest: id_rsa.pub }
+
+- name: VirtualBox Power Script SSH Config Support
+  become: yes
+  copy:
+    src: "files/{{ item.src }}"
+    dest: /var/lib/maas/.ssh/{{ item.dest }}
+    owner: maas
+    group: maas
+    mode: "0600"
+  with_items:
     - { src: ssh_config, dest: config }
 
 - name: Discover VirtualBox Host
diff --git a/roles/maas/templates/automation-compose.yml.j2 b/roles/maas/templates/automation-compose.yml.j2
index 51034bf..3fb4747 100644
--- a/roles/maas/templates/automation-compose.yml.j2
+++ b/roles/maas/templates/automation-compose.yml.j2
@@ -60,6 +60,7 @@
       - "PROVISION_LOG_FORMAT=text"
     volumes:
       - "/etc/maas/ansible:/etc/maas/ansible"
+      - "/etc/maas/.ssh:/etc/maas/.ssh"
     restart: unless-stopped
 
   switchq:
diff --git a/roles/maas/vars/main.yml b/roles/maas/vars/main.yml
index c9176ac..59bee09 100644
--- a/roles/maas/vars/main.yml
+++ b/roles/maas/vars/main.yml
@@ -12,10 +12,11 @@
 
 maas:
     admin_email: "{{ admin_email | default('admin@cord.lab') }}"
+    admin_password: "{{ password_maas_admin | default(lookup('password', 'passwords/maas_admin.txt')) }}"
     user: "{{ maas_user | default('cord') }}"
-    user_password: "{{ maas_password | default('cord') }}"
+    user_password: "{{ password_maas_user | default(lookup('password', 'passwords/maas_user.txt')) }}"
     user_email: "{{ maas_email | default('cord@cord.lab') }}"
-    user_sshkey: "{{ lookup('file', 'files/cord_id_rsa.pub') }}"
+    user_sshkey: "{{ lookup('file', '/etc/maas/.ssh/cord_rsa.pub') }}"
 
     # CHANGE:
     #   'domain' specifies the domain name configured in to MAAS
diff --git a/roles/onos-fabric/tasks/main.yml b/roles/onos-fabric/tasks/main.yml
index d633104..036593f 100644
--- a/roles/onos-fabric/tasks/main.yml
+++ b/roles/onos-fabric/tasks/main.yml
@@ -5,7 +5,7 @@
     state=directory
     owner={{ ansible_user }}
     group={{ ansible_user }}
-    mode=0755
+    mode="0755"
 
 - name: Copy Utility Commands
   copy:
@@ -13,7 +13,7 @@
     dest=/home/{{ ansible_user }}/bin
     owner={{ ansible_user }}
     group={{ ansible_user }}
-    mode=0755
+    mode="0755"
   with_items:
     - minify
     - onos-cfg-get
@@ -41,4 +41,4 @@
     dest=/home/{{ ansible_user }}/fabric-network.config.json
     owner={{ ansible_user }}
     group={{ ansible_user }}
-    mode=0644
+    mode="0644"
diff --git a/roles/prep/tasks/main.yml b/roles/prep/tasks/main.yml
new file mode 100644
index 0000000..5194230
--- /dev/null
+++ b/roles/prep/tasks/main.yml
@@ -0,0 +1,21 @@
+---
+- name: Ensure key pair storage
+  become: yes
+  local_action: file path=/etc/maas/.ssh owner=root group=root mode="0755" state=directory
+
+- name: Validate existing key pair
+  become: yes
+  local_action: stat path=/etc/maas/.ssh/cord_rsa
+  register: key_pair
+
+- name: Generate key pair
+  become: yes
+  local_action: command ssh-keygen -b 2048 -t rsa -N "" -C cord@cord.lab -f /etc/maas/.ssh/cord_rsa
+  when: not key_pair.stat.exists
+
+- name: Ensure privacy of key pair
+  become: yes
+  local_action: file path="/etc/maas/.ssh/{{item.name}}" mode="{{item.mode}}" owner=root group=root
+  with_items:
+    - { "name": "cord_rsa", "mode": "0644" }
+    - { "name": "cord_rsa.pub", "mode": "0644" }
diff --git a/roles/registry/tasks/main.yml b/roles/registry/tasks/main.yml
index a55ecad..658939c 100644
--- a/roles/registry/tasks/main.yml
+++ b/roles/registry/tasks/main.yml
@@ -5,7 +5,7 @@
     line: 127.0.0.1 docker-registry
     owner: root
     group: root
-    mode: 0644
+    mode: "0644"
 
 - name: Directories are present
   become: yes
@@ -31,7 +31,7 @@
     state: directory
     owner: root
     group: root
-    mode: 0755
+    mode: "0755"
 
 - name: Local Docker Registry
   become: yes
@@ -40,7 +40,7 @@
     dest: /etc/maas/{{ item }}
     owner: root
     group: root
-    mode: 0644
+    mode: "0644"
   with_items:
     - registry-compose.yml
   tags: [registry]