CORD-714
initial set of roles/playbooks
bug fixes
fix docker-compose logging, pull xos-base image
dynamically add docker instances to ansible inventory after onboarding
Bootstrap the onboarding synchronizer
more defaults, reload vars after adding docker inventory
move TOSCA templates to cord-profilea, random password on admin
fixes for docker compose, paths in xos.yaml in jinja
don't try to mangle XOS _config files (yet)
create xos-test image
make xos-test use locally build xosproject/xos
add docker-compose v2 format networking
fix docker-compose template
path fixes, move ssh keys
service names/paths aren't so simple
added api-tests, teardown roles
scan the onboarded docker-compose file for ansible inventory
add various tests used by test-standalone profile
fixes for API tests
save test output to /tmp/<testname>.out, bugfixes
autogenerate openstack keystone admin password, fix tests
remove nonfunctional UI tests
change location of cord_profile, use inventory to specify profile
fix YAML escaping of backslashes in regex
bugfixes after path change, add teardown playbook
backout setting of cord_dir with ansible_user_dir which differs depending on context
gradle build fixes, renaming
fix yml/yaml naming issue
null xos_images default
added rcord/mcord frontend variants, exampleservice onboarding
add missing role, help text in cord-bootstrap.sh
bugfix
create/run deployment.yaml by default
allow teardown to handle partially built pods, bugfix to deployment.yaml generation
add defaults, fix path for exampleservice
revert yaml naming to ease testing, rename mocks
debugging
exampleservice onboarding, mounting volume in XOS container
bugfix
add volume mounts when creating xos_ui, don't double add to ansible inventory
post-onboard TOSCA cnfig
typo fixes, order of loading TOSCA
config bits for cord-pod, some var renaming
update documentation, rename to rcord
doc fixes
support for building just before XOS install, docs
fix tests, refactor how compute nodes are configed, split vtn service config from adding a node
remove build process from deploy repo
inclusion/merge of PKI support
typo
bugfixes and change to use cord instead of opencord for install dir
fix pki support
fix ssh key paths
update xos ui/bs ports, fix onboarding on vagrant
have compute enlist script use same config file as other playbooks
fix ports, add MaaS version of compute node enable script
fix port and nodes.yaml loading
generate API SSL cert for all profiles
remove cord-app-build which is vestigial
remove config dir
default xos_ui_port in xos-ready role
use xostosca from service-profie/cord-pod-ansible to handle POST form-encode
fix nodes.yaml, variable name in xostosca, and include openstack properly
copy cert chain to build into XOS container
increase onboarding timeouts, don't restart docker
fix ONOS app versions and network settings
fix management_hosts network optional include
fix management/fabric settings
avoid modifying service#ONOS_CORD when adding nodes
split out compute node and vtn config, put delay between
fix template generation and fail on file not found
rename vars to profile_manifests, fix redis include
whitespace fix
increase timeout
reenable platform-check
parameterize node_key path, set defaults and fix platform-check
workaround for onboarding sync, minor fixes
pause in middle of VTN bug workaround
reload openstack config as well
disable platform-check role as a test
fixed head-diag role
reapply VTN config during compute node enable
Create exampleservice instance during test

Change-Id: I87e171bcfa429e65e1075a1ee4c97de1e90a7dd5
diff --git a/roles/cord-profile/templates/cdn-content.yaml.j2 b/roles/cord-profile/templates/cdn-content.yaml.j2
new file mode 100644
index 0000000..7b6ef00
--- /dev/null
+++ b/roles/cord-profile/templates/cdn-content.yaml.j2
@@ -0,0 +1,224 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Hypercache CDN Content
+
+imports:
+   - custom_types/xos.yaml
+   - custom_types/cdn.yaml
+
+topology_template:
+  node_templates:
+    HyperCache:
+      type: tosca.nodes.CDNService
+      properties:
+          # HyperCache service must already exist before running this recipe
+          no-create: true
+          no-delete: true
+          no-update: true
+
+    # Setup the CDN Service Provider
+
+    main_service_provider:
+        type: tosca.nodes.ServiceProvider
+        requirements:
+           - hpc_service:
+                 node: HyperCache
+                 relationship: tosca.relationships.MemberOfService
+
+    # Wall Street Journal Content Provider
+
+    wsj_content:
+        type: tosca.nodes.ContentProvider
+        requirements:
+            - service_provider:
+                  node: main_service_provider
+                  relationship: tosca.relationships.MemberOfServiceProvider
+
+    www.wsj.com:
+        type: tosca.nodes.CDNPrefix
+        requirements:
+             - content_provider:
+                   node: wsj_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+             - default_origin_server:
+                   node: http_www.wsj.com
+                   relationship: tosca.relationships.DefaultOriginServer
+
+    si.wsj.net:
+        type: tosca.nodes.CDNPrefix
+        requirements:
+             - content_provider:
+                   node: wsj_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+             - default_origin_server:
+                   node: http_si.wsj.net
+                   relationship: tosca.relationships.DefaultOriginServer
+
+    s.wsj.net:
+        type: tosca.nodes.CDNPrefix
+        requirements:
+             - content_provider:
+                   node: wsj_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+             - default_origin_server:
+                   node: http_s.wsj.net
+                   relationship: tosca.relationships.DefaultOriginServer
+
+    ore.wsj.net:
+        type: tosca.nodes.CDNPrefix
+        requirements:
+             - content_provider:
+                   node: wsj_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+             - default_origin_server:
+                   node: http_ore.wsj.net
+                   relationship: tosca.relationships.DefaultOriginServer
+
+    http_www.wsj.com:
+        type: tosca.nodes.OriginServer
+        requirements:
+             - content_provider:
+                   node: wsj_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+
+    http_si.wsj.net:
+        type: tosca.nodes.OriginServer
+        requirements:
+             - content_provider:
+                   node: wsj_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+
+    http_s.wsj.net:
+        type: tosca.nodes.OriginServer
+        requirements:
+             - content_provider:
+                   node: wsj_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+
+    http_ore.wsj.net:
+        type: tosca.nodes.OriginServer
+        requirements:
+             - content_provider:
+                   node: wsj_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+
+    # ON.Lab content provider
+
+    on_lab_content:
+        type: tosca.nodes.ContentProvider
+        requirements:
+            - service_provider:
+                  node: main_service_provider
+                  relationship: tosca.relationships.MemberOfServiceProvider
+
+    # Create CDN prefix onlab.vicci.org
+    onlab.vicci.org:
+        type: tosca.nodes.CDNPrefix
+        requirements:
+             - content_provider:
+                   node: on_lab_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+
+    http_onos-videos.s3.amazonaws.com:
+        type: tosca.nodes.OriginServer
+        requirements:
+             - content_provider:
+                   node: on_lab_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+
+    # Create origin server s3-us-west-1.amazonaws.com
+    http_s3-us-west-1.amazonaws.com:
+        type: tosca.nodes.OriginServer
+        requirements:
+             - content_provider:
+                   node: on_lab_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+
+    # Create origin server s3.amazonaws.com
+    http_s3.amazonaws.com:
+        type: tosca.nodes.OriginServer
+        requirements:
+             - content_provider:
+                   node: on_lab_content
+                   relationship: tosca.relationships.MemberOfContentProvider
+
+    # Test Content Provider
+
+    testcp2:
+        type: tosca.nodes.ContentProvider
+        requirements:
+            - service_provider:
+                  node: main_service_provider
+                  relationship: tosca.relationships.MemberOfServiceProvider
+
+    http_www.cs.arizona.edu:
+        type: tosca.nodes.OriginServer
+        requirements:
+             - content_provider:
+                   node: testcp2
+                   relationship: tosca.relationships.MemberOfContentProvider
+
+    test-cdn.opencloud.us:
+        type: tosca.nodes.CDNPrefix
+        requirements:
+             - content_provider:
+                   node: testcp2
+                   relationship: tosca.relationships.MemberOfContentProvider
+
+             - default_origin_server:
+                   node: http_www.cs.arizona.edu
+                   relationship: tosca.relationships.DefaultOriginServer
+
+    # Health Checks
+
+    healthcheck_dns_onlab.vicci.org:
+        type: tosca.nodes.HpcHealthCheck
+        requirements:
+           - hpc_service:
+                 node: HyperCache
+                 relationship: tosca.relationships.MemberOfService
+        properties:
+           kind: dns
+           resource_name: onlab.vicci.org
+
+    healthcheck_dns_test-cdn.opencloud.us:
+        type: tosca.nodes.HpcHealthCheck
+        requirements:
+           - hpc_service:
+                 node: HyperCache
+                 relationship: tosca.relationships.MemberOfService
+        properties:
+           kind: dns
+           resource_name: test-cdn.opencloud.us
+
+    healthcheck_http_test-cdn-index:
+        type: tosca.nodes.HpcHealthCheck
+        requirements:
+           - hpc_service:
+                 node: HyperCache
+                 relationship: tosca.relationships.MemberOfService
+        properties:
+           kind: http
+           resource_name: test-cdn.opencloud.us:/
+           result_contains: Lowenthal
+
+    healthcheck_http_onlab_onos_image:
+        type: tosca.nodes.HpcHealthCheck
+        requirements:
+           - hpc_service:
+                 node: HyperCache
+                 relationship: tosca.relationships.MemberOfService
+        properties:
+           kind: http
+           resource_name: onlab.vicci.org:/onos/vm/onos-tutorial-1.1.0r220-ovf.zip
+
+    healthcheck_http_onlab_mininet_image:
+        type: tosca.nodes.HpcHealthCheck
+        requirements:
+           - hpc_service:
+                 node: HyperCache
+                 relationship: tosca.relationships.MemberOfService
+        properties:
+           kind: http
+           resource_name: onlab.vicci.org:/mininet-vm/mininet-2.1.0-130919-ubuntu-13.04-server-amd64-ovf.zip
+
diff --git a/roles/cord-profile/templates/cord-services.yaml.j2 b/roles/cord-profile/templates/cord-services.yaml.j2
new file mode 100644
index 0000000..0c3c2fd
--- /dev/null
+++ b/roles/cord-profile/templates/cord-services.yaml.j2
@@ -0,0 +1,180 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Just enough Tosca to get the vSG slice running on the CORD POD, created by platform-install
+
+imports:
+   - custom_types/xos.yaml
+
+topology_template:
+  node_templates:
+
+# site, image, fully created in deployment.yaml
+    {{ site_name }}:
+      type: tosca.nodes.Site
+
+    image#vsg-1.1:
+      type: tosca.nodes.Image
+
+# management networks, fully created in management-net.yaml
+    management:
+      type: tosca.nodes.network.Network.XOS
+      properties:
+        no-create: true
+        no-delete: true
+        no-update: true
+
+{% if use_management_hosts %}
+    management_hosts:
+      type: tosca.nodes.network.Network.XOS
+      properties:
+        no-create: true
+        no-delete: true
+        no-update: true
+{% endif %}
+
+# ONOS_CORD, fully created in vtn.yaml
+    service#ONOS_CORD:
+      type: tosca.nodes.ONOSService
+      properties:
+        no-delete: true
+        no-create: true
+        no-update: true
+
+# ONOS_Fabric, fully created in fabric.yaml
+    service#ONOS_Fabric:
+      type: tosca.nodes.ONOSService
+      properties:
+        no-delete: true
+        no-create: true
+        no-update: true
+
+# CORD Services
+    service#vtr:
+      type: tosca.nodes.Service
+      properties:
+        view_url: /admin/vtr/vtrservice/$id$/
+        kind: vTR
+        replaces: service_vtr
+
+    service#volt:
+      type: tosca.nodes.VOLTService
+      requirements:
+        - vsg_tenant:
+            node: service#vsg
+            relationship: tosca.relationships.TenantOfService
+      properties:
+        view_url: /admin/volt/voltservice/$id$/
+        kind: vOLT
+        replaces: service_volt
+        public_key: { get_artifact: [ SELF, pubkey, LOCAL_FILE] }
+        private_key_fn: /opt/xos/services/volt/keys/volt_rsa
+      artifacts:
+        pubkey: /opt/xos/services/volt/keys/volt_rsa.pub
+
+    addresses_vsg:
+      type: tosca.nodes.AddressPool
+      properties:
+        addresses: 10.6.1.128/26
+        gateway_ip: 10.6.1.129
+        gateway_mac: 02:42:0a:06:01:01
+
+    addresses_public:
+      type: tosca.nodes.AddressPool
+      properties:
+        addresses: 10.6.1.192/26
+        gateway_ip: 10.6.1.193
+        gateway_mac: 02:42:0a:06:01:01
+
+    label_vsg:
+      type: tosca.nodes.NodeLabel
+
+    service#vsg:
+      type: tosca.nodes.VSGService
+      requirements:
+        - vrouter_tenant:
+            node: service#vrouter
+            relationship: tosca.relationships.TenantOfService
+      properties:
+        view_url: /admin/vsg/vsgservice/$id$/
+        backend_network_label: hpc_client
+        public_key: { get_artifact: [ SELF, pubkey, LOCAL_FILE] }
+        private_key_fn: /opt/xos/services/vsg/keys/vsg_rsa
+#       node_label: label_vsg
+        replaces: service_vsg
+      artifacts:
+        pubkey: /opt/xos/services/vsg/keys/vsg_rsa.pub
+
+    service#vrouter:
+      type: tosca.nodes.VRouterService
+      properties:
+        view_url: /admin/vrouter/vrouterservice/$id$/
+        replaces: service_vrouter
+      requirements:
+        - addresses_vsg:
+            node: addresses_vsg
+            relationship: tosca.relationships.ProvidesAddresses
+        - addresses_public:
+            node: addresses_public
+            relationship: tosca.relationships.ProvidesAddresses
+
+    vRouter_ONOS_app:
+      type: tosca.nodes.ONOSvRouterApp
+      requirements:
+        - onos_tenant:
+            node: service#ONOS_Fabric
+            relationship: tosca.relationships.TenantOfService
+        - vrouter_service:
+            node: service#vrouter
+            relationship: tosca.relationships.UsedByService
+      properties:
+        dependencies: org.onosproject.vrouter
+        autogenerate: vrouter-network-cfg
+
+    template#vsg:
+      type: tosca.nodes.NetworkTemplate
+      properties:
+        visibility: private
+        translation: none
+        vtn_kind: VSG
+
+    # Networks required by the CORD setup
+    {{ site_name }}_vsg-access:
+      type: tosca.nodes.network.Network
+      properties:
+        ip_version: 4
+      requirements:
+        - network_template:
+            node: template#vsg
+            relationship: tosca.relationships.UsesNetworkTemplate
+        - owner:
+            node: {{ site_name }}_vsg
+            relationship: tosca.relationships.MemberOfSlice
+        - connection:
+            node: {{ site_name }}_vsg
+            relationship: tosca.relationships.ConnectsToSlice
+
+    # CORD Slices
+    {{ site_name }}_vsg:
+      description: vSG Controller Slice
+      type: tosca.nodes.Slice
+      properties:
+        network: noauto
+      requirements:
+        - vsg_service:
+            node: service#vsg
+            relationship: tosca.relationships.MemberOfService
+        - site:
+            node: {{ site_name }}
+            relationship: tosca.relationships.MemberOfSite
+        - management:
+            node: management
+            relationship: tosca.relationships.ConnectsToNetwork
+{% if use_management_hosts %}
+        - management_hosts:
+            node: management_hosts
+            relationship: tosca.relationships.ConnectsToNetwork
+{% endif %}
+        - image:
+            node: image#vsg-1.1
+            relationship: tosca.relationships.DefaultImage
+
diff --git a/roles/cord-profile/templates/deployment.yaml.j2 b/roles/cord-profile/templates/deployment.yaml.j2
new file mode 100644
index 0000000..0987b7c
--- /dev/null
+++ b/roles/cord-profile/templates/deployment.yaml.j2
@@ -0,0 +1,88 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+imports:
+   - custom_types/xos.yaml
+
+description: deployment config, generated by platform-install
+
+topology_template:
+  node_templates:
+
+# Flavors
+
+{% for flavor in deployment_flavors %}
+    {{ flavor }}:
+      type: tosca.nodes.Flavor
+
+{% endfor %}
+
+# Deployment
+    {{ deployment_type }}:
+      type: tosca.nodes.Deployment
+      requirements:
+{% for flavor in deployment_flavors %}
+          - {{ flavor }}:
+              node: {{ flavor }}
+              relationship: tosca.relationships.SupportsFlavor
+
+{% endfor %}
+
+# Site
+    {{ site_name }}:
+      type: tosca.nodes.Site
+      properties:
+          display_name: {{ site_humanname }}
+          site_url: http://{{ site_name }}.opencloud.us/
+          hosts_nodes: true
+      requirements:
+        - deployment:
+            node: {{ deployment_type }}
+            relationship: tosca.relationships.MemberOfDeployment
+
+# Attach the Tenant view to the deployment
+    Tenant:
+      type: tosca.nodes.DashboardView
+      properties:
+          no-create: true
+          no-delete: true
+      requirements:
+          - deployment:
+              node: {{ deployment_type }}
+              relationship: tosca.relationships.SupportsDeployment
+
+# XOS Users
+# Default admin user account
+    {{ xos_admin_user }}:
+      type: tosca.nodes.User
+      properties:
+        password: {{ xos_admin_pass }}
+        firstname: {{ xos_admin_first }}
+        lastname: {{ xos_admin_last }}
+        is_admin: True
+      requirements:
+        - site:
+            node: {{ site_name }}
+            relationship: tosca.relationships.MemberOfSite
+        - tenant_dashboard:
+              node: Tenant
+              relationship: tosca.relationships.UsesDashboard
+
+# All other users
+{% for user in xos_users %}
+    {{ user.email }}:
+      type: tosca.nodes.User
+      properties:
+        password: {{ user.password }}
+        firstname: {{ user.first | default(user.email) }}
+        lastname: {{ user.last | default("unknown") }}
+        is_admin: {{ user.admin | default("false") }}
+      requirements:
+        - site:
+            node: {{ site_name }}
+            relationship: tosca.relationships.MemberOfSite
+        - tenant_dashboard:
+              node: Tenant
+              relationship: tosca.relationships.UsesDashboard
+
+{% endfor %}
+
diff --git a/roles/cord-profile/templates/fabric-network-cfg.json.j2 b/roles/cord-profile/templates/fabric-network-cfg.json.j2
new file mode 100644
index 0000000..8609ef8
--- /dev/null
+++ b/roles/cord-profile/templates/fabric-network-cfg.json.j2
@@ -0,0 +1,100 @@
+{
+    "ports" : {
+        "of:0000000000000001/1" : {
+            "interfaces" : [
+                {
+                    "ips" : [ "10.6.1.0/24" ]
+                }
+            ]
+        },
+        "of:0000000000000001/2" : {
+            "interfaces" : [
+                {
+                    "ips" : [ "10.6.1.0/24" ]
+                }
+            ]
+        },
+        "of:0000000000000002/3" : {
+            "interfaces" : [
+                {
+                    "ips" : [ "10.6.2.0/24" ]
+                }
+            ]
+        },
+        "of:0000000000000002/4" : {
+            "interfaces" : [
+                {
+                    "ips" : [ "10.6.2.0/24" ]
+                }
+            ]
+        }
+    },
+    "devices" : {
+        "of:0000000000000001" : {
+            "segmentrouting" : {
+                "name" : "Leaf-R1",
+                "nodeSid" : 101,
+                "routerIp" : "10.6.1.254",
+                "routerMac" : "00:00:00:00:01:80",
+                "isEdgeRouter" : true,
+                "adjacencySids" : []
+            }
+        },
+        "of:0000000000000002" : {
+            "segmentrouting" : {
+                "name" : "Leaf-R2",
+                "nodeSid" : 102,
+                "routerIp" : "10.6.2.254",
+                "routerMac" : "00:00:00:00:02:80",
+                "isEdgeRouter" : true,
+                "adjacencySids" : []
+            }
+        },
+        "of:0000000000000191" : {
+            "segmentrouting" : {
+                "name" : "Spine-R1",
+                "nodeSid" : 103,
+                "routerIp" : "192.168.0.11",
+                "routerMac" : "00:00:01:00:11:80",
+                "isEdgeRouter" : false,
+                "adjacencySids" : []
+            }
+        },
+        "of:0000000000000192" : {
+            "segmentrouting" : {
+                "name" : "Spine-R2",
+                "nodeSid" : 104,
+                "routerIp" : "192.168.0.22",
+                "routerMac" : "00:00:01:00:22:80",
+                "isEdgeRouter" : false,
+                "adjacencySids" : []
+            }
+        }
+    },
+    "hosts" : {
+        "00:00:00:00:00:01/-1" : {
+            "basic": {
+                "ips": ["10.6.1.1"],
+                "location": "of:0000000000000001/1"
+            }
+        },
+        "00:00:00:00:00:02/-1" : {
+            "basic": {
+                "ips": ["10.6.1.2"],
+                "location": "of:0000000000000001/2"
+            }
+        },
+        "00:00:00:00:00:03/-1" : {
+            "basic": {
+                "ips": ["10.6.2.1"],
+                "location": "of:0000000000000002/3"
+            }
+        },
+        "00:00:00:00:00:04/-1" : {
+            "basic": {
+                "ips": ["10.6.2.2"],
+                "location": "of:0000000000000002/4"
+            }
+        }
+    }
+}
diff --git a/roles/cord-profile/templates/fabric-service.yaml.j2 b/roles/cord-profile/templates/fabric-service.yaml.j2
new file mode 100644
index 0000000..36ad25a
--- /dev/null
+++ b/roles/cord-profile/templates/fabric-service.yaml.j2
@@ -0,0 +1,41 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+imports:
+   - custom_types/xos.yaml
+
+description: fabric services, generated by platform-install
+
+topology_template:
+  node_templates:
+
+    service#ONOS_Fabric:
+      type: tosca.nodes.ONOSService
+      requirements:
+      properties:
+          kind: onos
+          view_url: /admin/onos/onosservice/$id$/
+          no_container: true
+          rest_hostname: onos-fabric
+          replaces: service_ONOS_Fabric
+          rest_onos/v1/network/configuration/: { get_artifact: [ SELF, fabric_network_cfg_json, LOCAL_FILE ] }
+      artifacts:
+          fabric_network_cfg_json: {{ fabric_network_cfg_json }}
+
+    service#fabric:
+      type: tosca.nodes.FabricService
+      properties:
+          view_url: /admin/fabric/fabricservice/$id$/
+          replaces: service_fabric
+
+    Fabric_ONOS_app:
+      type: tosca.nodes.ONOSApp
+      requirements:
+          - onos_tenant:
+              node: service#ONOS_Fabric
+              relationship: tosca.relationships.TenantOfService
+          - fabric_service:
+              node: service#fabric
+              relationship: tosca.relationships.UsedByService
+      properties:
+          dependencies: org.onosproject.drivers, org.onosproject.openflow-base, org.onosproject.netcfghostprovider, org.onosproject.netcfglinksprovider, org.onosproject.segmentrouting, org.onosproject.vrouter, org.onosproject.hostprovider
+
diff --git a/roles/cord-profile/templates/management-net.yaml.j2 b/roles/cord-profile/templates/management-net.yaml.j2
new file mode 100644
index 0000000..781dbf3
--- /dev/null
+++ b/roles/cord-profile/templates/management-net.yaml.j2
@@ -0,0 +1,69 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+imports:
+   - custom_types/xos.yaml
+
+description: management network config, generated by platform-install
+
+topology_template:
+  node_templates:
+
+# site, fully created in deployment.yaml
+    {{ site_name }}:
+      type: tosca.nodes.Site
+
+# management network
+    management_template:
+      type: tosca.nodes.NetworkTemplate
+      properties:
+        visibility: private
+        translation: none
+        vtn_kind: MANAGEMENT_LOCAL
+
+    management:
+      type: tosca.nodes.network.Network
+      properties:
+        ip_version: 4
+        cidr: {{ management_network_cidr }}
+      requirements:
+        - network_template:
+            node: management_template
+            relationship: tosca.relationships.UsesNetworkTemplate
+        - owner:
+            node: {{ site_name }}_management
+            relationship: tosca.relationships.MemberOfSlice
+
+{% if use_management_hosts %}
+    management_hosts_template:
+      type: tosca.nodes.NetworkTemplate
+      properties:
+        visibility: private
+        translation: none
+        vtn_kind: MANAGEMENT_HOST
+
+    management_hosts:
+      type: tosca.nodes.network.Network
+      properties:
+        ip_version: 4
+        cidr: {{ management_hosts_net_cidr }}
+        start_ip: {{ management_hosts_net_range_xos_low }}
+        end_ip: {{ management_hosts_net_range_xos_high }}
+      requirements:
+        - network_template:
+            node: management_hosts_template
+            relationship: tosca.relationships.UsesNetworkTemplate
+        - owner:
+            node: {{ site_name }}_management
+            relationship: tosca.relationships.MemberOfSlice
+{% endif %}
+
+    {{ site_name }}_management:
+      description: This slice exists solely to own the management network
+      type: tosca.nodes.Slice
+      properties:
+        network: noauto
+      requirements:
+        - site:
+            node: {{ site_name }}
+            relationship: tosca.relationships.MemberOfSite
+
diff --git a/roles/cord-profile/templates/mock-mcord.yaml.j2 b/roles/cord-profile/templates/mock-mcord.yaml.j2
new file mode 100644
index 0000000..060f829
--- /dev/null
+++ b/roles/cord-profile/templates/mock-mcord.yaml.j2
@@ -0,0 +1,319 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Setup CORD-related services
+
+imports:
+   - custom_types/xos.yaml
+
+topology_template:
+  node_templates:
+    # M-CORD Services
+    
+    # RAN
+    vBBU:
+      type: tosca.nodes.Service
+      properties:
+          view_url: /mcord/?service=vBBU
+          kind: RAN
+
+    eSON:
+      type: tosca.nodes.Service
+      properties:
+          view_url: http://www.google.com
+          kind: RAN
+
+    # EPC
+    vMME:
+      type: tosca.nodes.Service
+      properties:
+          view_url: /mcord/?service=vMME
+          kind: EPC
+
+    vSGW:
+      type: tosca.nodes.Service
+      properties:
+          view_url: /mcord/?service=vSGW
+          kind: EPC
+
+    vPGW:
+      type: tosca.nodes.Service
+      properties:
+          view_url: /mcord/?service=vPGW
+          kind: EPC
+
+    # EDGE
+    Cache:
+      type: tosca.nodes.Service
+      properties:
+          view_url: /mcord/?service=Cache
+          icon_url: /static/mCordServices/service_cache.png
+          kind: EDGE
+
+    Firewall:
+      type: tosca.nodes.Service
+      properties:
+          view_url: /mcord/?service=Firewall
+          icon_url: /static/mCordServices/service_firewall.png
+          kind: EDGE
+
+    Video Optimization:
+      type: tosca.nodes.Service
+      properties:
+          view_url: /mcord/?service=Video%20Optimization
+          icon_url: /static/mCordServices/service_video.png
+          kind: EDGE
+          
+    # Images
+    trusty-server-multi-nic:
+      type: tosca.nodes.Image
+      properties:
+         disk_format: QCOW2
+         container_format: BARE
+
+    # Deployments
+    StanfordDeployment:
+      type: tosca.nodes.Deployment
+      properties:
+          flavors: m1.large, m1.medium, m1.small
+      requirements:
+          - image:
+              node: trusty-server-multi-nic
+              relationship: tosca.relationships.SupportsImage
+
+    # Site
+    stanford:
+      type: tosca.nodes.Site
+      properties:
+          display_name: Stanford University
+          site_url: https://www.stanford.edu/
+      requirements:
+          - deployment:
+               node: StanfordDeployment
+               relationship: tosca.relationships.MemberOfDeployment
+          - controller:
+               node: CloudLab
+               relationship: tosca.relationships.UsesController
+
+
+    # Nodes
+    node1.stanford.edu:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: stanford
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: StanfordDeployment
+            relationship: tosca.relationships.MemberOfDeployment
+
+    # Slices
+    stanford_slice:
+      description: Slice that contains sample instances
+      type: tosca.nodes.Slice
+      requirements:
+          - site:
+              node: stanford
+              relationship: tosca.relationships.MemberOfSite
+
+    # Instances
+    BBU_service_instance1:
+      type: tosca.nodes.Compute
+      capabilities:
+        # Host container properties
+        host:
+         properties:
+           num_cpus: 1
+           disk_size: 10 GB
+           mem_size: 4 MB
+        # Guest Operating System properties
+        os:
+          properties:
+            # host Operating System image properties
+            architecture: x86_64
+            type: linux
+            distribution: ubuntu
+            version: 14.04
+      requirements:
+          - slice:
+                node: stanford_slice
+                relationship: tosca.relationships.MemberOfSlice
+
+    BBU_service_instance2:
+      type: tosca.nodes.Compute
+      capabilities:
+        # Host container properties
+        host:
+         properties:
+           num_cpus: 1
+           disk_size: 10 GB
+           mem_size: 4 MB
+        # Guest Operating System properties
+        os:
+          properties:
+            # host Operating System image properties
+            architecture: x86_64
+            type: linux
+            distribution: ubuntu
+            version: 14.04
+      requirements:
+          - slice:
+                node: stanford_slice
+                relationship: tosca.relationships.MemberOfSlice
+
+    MME_service_instance1:
+      type: tosca.nodes.Compute
+      capabilities:
+        # Host container properties
+        host:
+         properties:
+           num_cpus: 1
+           disk_size: 10 GB
+           mem_size: 4 MB
+        # Guest Operating System properties
+        os:
+          properties:
+            # host Operating System image properties
+            architecture: x86_64
+            type: linux
+            distribution: ubuntu
+            version: 14.04
+      requirements:
+          - slice:
+                node: stanford_slice
+                relationship: tosca.relationships.MemberOfSlice
+
+    SGW_service_instance1:
+      type: tosca.nodes.Compute
+      capabilities:
+        # Host container properties
+        host:
+         properties:
+           num_cpus: 1
+           disk_size: 10 GB
+           mem_size: 4 MB
+        # Guest Operating System properties
+        os:
+          properties:
+            # host Operating System image properties
+            architecture: x86_64
+            type: linux
+            distribution: ubuntu
+            version: 14.04
+      requirements:
+          - slice:
+                node: stanford_slice
+                relationship: tosca.relationships.MemberOfSlice
+
+    PGW_service_instance1:
+      type: tosca.nodes.Compute
+      capabilities:
+        # Host container properties
+        host:
+         properties:
+           num_cpus: 1
+           disk_size: 10 GB
+           mem_size: 4 MB
+        # Guest Operating System properties
+        os:
+          properties:
+            # host Operating System image properties
+            architecture: x86_64
+            type: linux
+            distribution: ubuntu
+            version: 14.04
+      requirements:
+          - slice:
+                node: stanford_slice
+                relationship: tosca.relationships.MemberOfSlice
+
+    # Let's add a user who can be administrator of the household
+    johndoe@stanford.us:
+      type: tosca.nodes.User
+      properties:
+          password: letmein
+          firstname: john
+          lastname: doe
+      requirements:
+          - site:
+              node: stanford
+              relationship: tosca.relationships.MemberOfSite
+
+    # A subscriber
+    Stanford:
+       type: tosca.nodes.CORDSubscriber
+       properties:
+           service_specific_id: 123
+           firewall_enable: false
+           cdn_enable: false
+           url_filter_enable: false
+           url_filter_level: R
+       requirements:
+          - house_admin:
+              node: johndoe@stanford.us
+              relationship: tosca.relationships.AdminPrivilege
+
+    Barbera Lapinski:
+       type: tosca.nodes.CORDUser
+       properties:
+           mac: 01:02:03:04:05:06
+           level: PG_13
+       requirements:
+           - household:
+               node: Stanford
+               relationship: tosca.relationships.SubscriberDevice
+
+    Norbert Shumway:
+       type: tosca.nodes.CORDUser
+       properties:
+           mac: 90:E2:BA:82:F9:75
+           level: PG_13
+       requirements:
+           - household:
+               node: Stanford
+               relationship: tosca.relationships.SubscriberDevice
+
+    Fay Muldoon:
+       type: tosca.nodes.CORDUser
+       properties:
+           mac: 68:5B:35:9D:91:D5
+           level: PG_13
+       requirements:
+           - household:
+               node: Stanford
+               relationship: tosca.relationships.SubscriberDevice
+
+    Janene Earnest:
+       type: tosca.nodes.CORDUser
+       properties:
+           mac: 34:36:3B:C9:B6:A6
+           level: PG_13
+       requirements:
+           - household:
+               node: Stanford
+               relationship: tosca.relationships.SubscriberDevice
+
+
+    Topology:
+      type: tosca.nodes.DashboardView
+      properties:
+          url: template:xosMcordTopology
+
+    Ceilometer:
+      type: tosca.nodes.DashboardView
+      properties:
+          url: template:xosCeilometerDashboard
+
+    padmin@vicci.org:
+      type: tosca.nodes.User
+      properties:
+          firstname: XOS
+          lastname: admin
+          is_admin: true
+      requirements:
+          - mcord_dashboard:
+              node: Topology
+              relationship: tosca.relationships.UsesDashboard
+          - ceilometer_dashboard:
+              node: Ceilometer
+              relationship: tosca.relationships.UsesDashboard
+
diff --git a/roles/cord-profile/templates/mock-onos.yaml.j2 b/roles/cord-profile/templates/mock-onos.yaml.j2
new file mode 100644
index 0000000..1f733f9
--- /dev/null
+++ b/roles/cord-profile/templates/mock-onos.yaml.j2
@@ -0,0 +1,16 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+imports:
+   - custom_types/xos.yaml
+
+description: enough onos config to make the mock work
+
+topology_template:
+  node_templates:
+
+    service#ONOS_Fabric:
+      type: tosca.nodes.ONOSService
+
+    service#ONOS_CORD:
+      type: tosca.nodes.ONOSService
+
diff --git a/roles/cord-profile/templates/openstack.yaml.j2 b/roles/cord-profile/templates/openstack.yaml.j2
new file mode 100644
index 0000000..07882f1
--- /dev/null
+++ b/roles/cord-profile/templates/openstack.yaml.j2
@@ -0,0 +1,70 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+imports:
+   - custom_types/xos.yaml
+
+description: openstack extensions to deployment, generated by platform-install
+
+topology_template:
+  node_templates:
+
+# Images and flavors
+{% for image in xos_images %}
+    {{ image.name }}:
+      type: tosca.nodes.Image
+      properties:
+         path: /opt/xos/images/{{ image.name }}.qcow2
+         disk_format: QCOW2
+         container_format: BARE
+
+{% endfor %}
+
+{% for flavor in deployment_flavors %}
+    {{ flavor }}:
+      type: tosca.nodes.Flavor
+
+{% endfor %}
+
+# Deployment - adds images/flavors to site defined in deployment.yaml
+    {{ deployment_type }}:
+      type: tosca.nodes.Deployment
+      requirements:
+{% for flavor in deployment_flavors %}
+          - {{ flavor }}:
+              node: {{ flavor }}
+              relationship: tosca.relationships.SupportsFlavor
+{% endfor %}
+
+# OpenStack Controller
+    {{ site_name }}_{{ deployment_type }}_openstack:
+      type: tosca.nodes.Controller
+      requirements:
+        - deployment:
+            node: {{ deployment_type }}
+            relationship: tosca.relationships.ControllerDeployment
+      properties:
+          backend_type: OpenStack
+          version: Kilo
+          auth_url: { get_script_env: [ SELF, adminrc, OS_AUTH_URL, LOCAL_FILE] }
+          admin_user: { get_script_env: [ SELF, adminrc, OS_USERNAME, LOCAL_FILE] }
+          admin_password: { get_script_env: [ SELF, adminrc, OS_PASSWORD, LOCAL_FILE] }
+          admin_tenant: { get_script_env: [ SELF, adminrc, OS_TENANT_NAME, LOCAL_FILE] }
+          domain: Default
+      artifacts:
+          adminrc: /opt/cord_profile/admin-openrc.sh
+
+# Site - adds openstack controller to site defined in deployment.yaml
+    {{ site_name }}:
+      type: tosca.nodes.Site
+      properties:
+          display_name: {{ site_humanname }}
+          site_url: http://{{ site_name }}.opencloud.us/
+          hosts_nodes: true
+      requirements:
+        - deployment:
+            node: {{ deployment_type }}
+            relationship: tosca.relationships.MemberOfDeployment
+        - controller:
+            node: {{ site_name }}_{{ deployment_type }}_openstack
+            relationship: tosca.relationships.UsesController
+
diff --git a/roles/cord-profile/templates/public-net.yaml.j2 b/roles/cord-profile/templates/public-net.yaml.j2
new file mode 100644
index 0000000..cf111ca
--- /dev/null
+++ b/roles/cord-profile/templates/public-net.yaml.j2
@@ -0,0 +1,54 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+imports:
+   - custom_types/xos.yaml
+
+description: public network config, generated by platform-install
+
+topology_template:
+  node_templates:
+
+# site, fully created in deployment.yaml
+    {{ site_name }}:
+      type: tosca.nodes.Site
+
+
+# vrouter service, fully created in cord-service.yaml
+    service#vrouter:
+      type: tosca.nodes.VRouterService
+
+# public network
+
+    public_template:
+      type: tosca.nodes.NetworkTemplate
+      properties:
+          visibility: public
+          translation: none
+          vtn_kind: PUBLIC
+
+    public:
+      type: tosca.nodes.network.Network
+      properties:
+          ip_version: 4
+      requirements:
+          - network_template:
+              node: public_template
+              relationship: tosca.relationships.UsesNetworkTemplate
+          - owner:
+              node: {{ site_name }}_public
+              relationship: tosca.relationships.MemberOfSlice
+          - vrouter_tenant:
+              node: service#vrouter
+              relationship: tosca.relationships.TenantOfService
+
+
+    {{ site_name }}_public:
+      description: This slice exists solely to own the public network
+      type: tosca.nodes.Slice
+      properties:
+          network: noauto
+      requirements:
+          - site:
+              node: {{ site_name }}
+              relationship: tosca.relationships.MemberOfSite
+
diff --git a/roles/cord-profile/templates/sample.yaml.j2 b/roles/cord-profile/templates/sample.yaml.j2
new file mode 100644
index 0000000..6a3324c
--- /dev/null
+++ b/roles/cord-profile/templates/sample.yaml.j2
@@ -0,0 +1,92 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >
+    * Some sample data to populate the demo frontend
+
+imports:
+   - custom_types/xos.yaml
+
+topology_template:
+  node_templates:
+    trusty-server-multi-nic:
+      type: tosca.nodes.Image
+      properties:
+         disk_format: QCOW2
+         container_format: BARE
+
+    {{ deployment_type }}:
+      type: tosca.nodes.Deployment
+      properties:
+          flavors: m1.large, m1.medium, m1.small
+      requirements:
+          - image:
+              node: trusty-server-multi-nic
+              relationship: tosca.relationships.SupportsImage
+
+    CloudLab:
+      type: tosca.nodes.Controller
+      requirements:
+          - deployment:
+              node: {{ deployment_type }}
+              relationship: tosca.relationships.ControllerDeployment
+      properties:
+          backend_type: OpenStack
+          version: Juno
+          auth_url: http://sample/v2
+          admin_user: admin
+          admin_password: adminpassword
+          admin_tenant: admin
+          domain: Default
+
+    {{ site_name }}:
+      type: tosca.nodes.Site
+      properties:
+          display_name: {{ site_name }}
+          site_url: http://opencloud.us/
+      requirements:
+          - deployment:
+               node: {{ deployment_type }}
+               relationship: tosca.relationships.MemberOfDeployment
+          - controller:
+               node: CloudLab
+               relationship: tosca.relationships.UsesController
+
+    Public shared IPv4:
+      type: tosca.nodes.NetworkTemplate
+      properties:
+          visibility: private
+          translation: NAT
+
+    {{ xos_admin_user }}:
+      type: tosca.nodes.User
+      properties:
+        password: {{ xos_admin_pass }}
+        firstname: {{ xos_admin_first }}
+        lastname: {{ xos_admin_last }}
+        is_admin: True
+        is_active: True
+      requirements:
+        - site:
+            node: {{ site_name }}
+            relationship: tosca.relationships.MemberOfSite
+
+    node1.opencloud.us:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: {{ site_name }}
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: {{ deployment_type }}
+            relationship: tosca.relationships.MemberOfDeployment
+
+    node2.opencloud.us:
+      type: tosca.nodes.Node
+      requirements:
+        - site:
+            node: {{ site_name }}
+            relationship: tosca.relationships.MemberOfSite
+        - deployment:
+            node: {{ deployment_type }}
+            relationship: tosca.relationships.MemberOfDeployment
+
diff --git a/roles/cord-profile/templates/services.yaml.j2 b/roles/cord-profile/templates/services.yaml.j2
new file mode 100644
index 0000000..055fa57
--- /dev/null
+++ b/roles/cord-profile/templates/services.yaml.j2
@@ -0,0 +1,67 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Created by platform-install/roles/cord-profile/templates/services.yaml.j2
+
+imports:
+   - custom_types/xos.yaml
+
+topology_template:
+  node_templates:
+
+    # CORD Services
+    service#vtr:
+      type: tosca.nodes.Service
+      properties:
+          view_url: /admin/vtr/vtrservice/$id$/
+          kind: vTR
+          replaces: service_vtr
+
+    service#volt:
+      type: tosca.nodes.VOLTService
+      requirements:
+          - vsg_tenant:
+              node: service#vsg
+              relationship: tosca.relationships.TenantOfService
+      properties:
+          view_url: /admin/cord/voltservice/$id$/
+          kind: vOLT
+          replaces: service_volt
+
+    addresses_vsg:
+      type: tosca.nodes.AddressPool
+      properties:
+          addresses: 10.168.0.0/24
+          gateway_ip: 10.168.0.1
+          gateway_mac: 02:42:0a:a8:00:01
+
+    addresses_exampleservice-public:
+      type: tosca.nodes.AddressPool
+      properties:
+          addresses: 10.168.1.0/24
+          gateway_ip: 10.168.1.1
+          gateway_mac: 02:42:0a:a8:00:01
+
+    service#vsg:
+      type: tosca.nodes.VSGService
+      requirements:
+          - vrouter_tenant:
+              node: service#vrouter
+              relationship: tosca.relationships.TenantOfService
+      properties:
+          view_url: /admin/cord/vsgservice/$id$/
+          private_key_fn: /opt/xos/synchronizers/vcpe/vcpe_private_key
+          replaces: service_vsg
+
+    service#vrouter:
+      type: tosca.nodes.VRouterService
+      properties:
+          view_url: /admin/vrouter/vrouterservice/$id$/
+          replaces: service_vrouter
+      requirements:
+          - addresses_vsg:
+              node: addresses_vsg
+              relationship: tosca.relationships.ProvidesAddresses
+          - addresses_service1:
+              node: addresses_exampleservice-public
+              relationship: tosca.relationships.ProvidesAddresses
+
diff --git a/roles/cord-profile/templates/volt-devices.yaml.j2 b/roles/cord-profile/templates/volt-devices.yaml.j2
new file mode 100644
index 0000000..ec882c9
--- /dev/null
+++ b/roles/cord-profile/templates/volt-devices.yaml.j2
@@ -0,0 +1,46 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: created by platform-install/roles/cord-profile/templates/volt-devices.yaml.j2
+
+imports:
+   - custom_types/xos.yaml
+
+topology_template:
+  node_templates:
+
+# vOLT service defined in services.yaml
+    service#volt:
+      type: tosca.nodes.VOLTService
+      properties:
+          no-create: True
+          no-delete: True
+          no-update: True
+
+# vOLT devices
+{% for device in volt_devices %}
+    {{ device.name }}-{{ device.index | default(loop.index) }}:
+      type: tosca.nodes.VOLTDevice
+      properties:
+            driver: {{ device.driver | default("pmc-olt") }}
+            openflow_id: {{ device.openflow_id }}
+            access_devices: {{ device.access_devices }}
+      requirements:
+          - volt_service:
+              node: service#volt
+              relationship: tosca.relationships.MemberOfService
+          - access_agent:
+              node: {{ device.name }}-agent-{{ device.index | default(loop.index) }}
+              relationship: tosca.relationships.UsesAgent
+
+    {{ device.name }}-agent-{{ device.index | default(loop.index) }}:
+      type: tosca.nodes.AccessAgent
+      properties:
+          mac: {{ device.agent_mac }}
+          port_mappings: {{ device.agent_port_mappings }}
+      requirements:
+          - volt_service:
+              node: service#volt
+              relationship: tosca.relationships.MemberOfService
+
+{% endfor %}
+
diff --git a/roles/cord-profile/templates/vrouter.yaml.j2 b/roles/cord-profile/templates/vrouter.yaml.j2
new file mode 100644
index 0000000..cf53513
--- /dev/null
+++ b/roles/cord-profile/templates/vrouter.yaml.j2
@@ -0,0 +1,174 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Just enough Tosca to get the vSG slice running on the CORD POD
+
+imports:
+   - custom_types/xos.yaml
+   - custom_types/vrouter.yaml
+
+topology_template:
+  node_templates:
+
+    service#vrouter:
+      type: tosca.nodes.VRouterService
+      properties:
+          view_url: /admin/vrouter/
+          no-delete: true
+          no-create: true
+          rest_hostname: onos-fabric
+          rest_port: 8181
+          rest_user: onos
+          rest_pass: rocks
+    
+    device#of:00000000000000b1:
+      type: tosca.nodes.VRouterDevice
+      properties:
+        openflow_id: of:00000000000000b1
+        driver: softrouter
+        # config_key: basic
+      requirements:
+        - service#vrouter:
+            node: service#vrouter
+            relationship: tosca.relationships.MemberOfService
+
+    # Port 1
+    port#port1/1:
+      type: tosca.nodes.VRouterPort
+      properties:
+        openflow_id: of:00000000000000b1/1
+      requirements:
+        - device#of:00000000000000b1:
+            node: device#of:00000000000000b1
+            relationship: tosca.relationships.PortOfDevice
+        - service#vrouter:
+            node: service#vrouter
+            relationship: tosca.relationships.MemberOfService
+
+    interface#b1-1:
+      type: tosca.nodes.VRouterInterface
+      properties:
+        name: b1-1
+        mac: 00:00:00:00:00:01
+      requirements:
+        - port#port1/1:
+            node: port#port1/1
+            relationship: tosca.relationships.InterfaceOfPort
+
+    ips#10.0.1.2/24:
+      type: tosca.nodes.VRouterIp
+      properties:
+        ip: 10.0.1.2/24
+      requirements:
+        - interface#b1-1:
+            node: interface#b1-1
+            relationship: tosca.relationships.IpOfInterface
+
+    # Port 2
+    port#port1/2:
+      type: tosca.nodes.VRouterPort
+      properties:
+        openflow_id: of:00000000000000b1/2
+      requirements:
+        - device#of:00000000000000b1:
+            node: device#of:00000000000000b1
+            relationship: tosca.relationships.PortOfDevice
+        - service#vrouter:
+            node: service#vrouter
+            relationship: tosca.relationships.MemberOfService
+
+    interface#b1-2:
+      type: tosca.nodes.VRouterInterface
+      properties:
+        name: b1-2
+        mac: 00:00:00:00:00:01
+      requirements:
+        - port#port1/2:
+            node: port#port1/2
+            relationship: tosca.relationships.InterfaceOfPort
+
+    ips#10.0.2.2/24:
+      type: tosca.nodes.VRouterIp
+      properties:
+        ip: 10.0.2.2/24
+      requirements:
+        - interface#b1-1:
+            node: interface#b1-2
+            relationship: tosca.relationships.IpOfInterface
+
+    # Port 3
+    port#port1/3:
+      type: tosca.nodes.VRouterPort
+      properties:
+        openflow_id: of:00000000000000b1/3
+      requirements:
+        - device#of:00000000000000b1:
+            node: device#of:00000000000000b1
+            relationship: tosca.relationships.PortOfDevice
+        - service#vrouter:
+            node: service#vrouter
+            relationship: tosca.relationships.MemberOfService
+
+    interface#b1-3:
+      type: tosca.nodes.VRouterInterface
+      properties:
+        name: b1-3
+        mac: 00:00:00:00:00:01
+      requirements:
+        - port#port1/3:
+            node: port#port1/3
+            relationship: tosca.relationships.InterfaceOfPort
+
+    ips#10.0.3.2/24:
+      type: tosca.nodes.VRouterIp
+      properties:
+        ip: 10.0.3.2/24
+      requirements:
+        - interface#b1-1:
+            node: interface#b1-3
+            relationship: tosca.relationships.IpOfInterface
+
+    # Port 4
+    port#port1/4:
+      type: tosca.nodes.VRouterPort
+      properties:
+        openflow_id: of:00000000000000b1/4
+      requirements:
+        - device#of:00000000000000b1:
+            node: device#of:00000000000000b1
+            relationship: tosca.relationships.PortOfDevice
+        - service#vrouter:
+            node: service#vrouter
+            relationship: tosca.relationships.MemberOfService
+
+    interface#b1-4:
+      type: tosca.nodes.VRouterInterface
+      properties:
+        name: b1-4
+        mac: 00:00:00:00:00:01
+        vlan: 100
+      requirements:
+        - port#port1/4:
+            node: port#port1/4
+            relationship: tosca.relationships.InterfaceOfPort
+
+    ips#10.0.4.2/24:
+      type: tosca.nodes.VRouterIp
+      properties:
+        ip: 10.0.4.2/24
+      requirements:
+        - interface#b1-1:
+            node: interface#b1-4
+            relationship: tosca.relationships.IpOfInterface
+
+    app#vrouterApp:
+      type: tosca.nodes.VRouterApp
+      properties:
+        name: org.onosproject.router
+        # can we use a relation to specify the connect point port?
+        control_plane_connect_point: of:00000000000000b1/5
+        ospf_enabled: true
+      requirements:
+          - service#vrouter:
+              node: service#vrouter
+              relationship: tosca.relationships.MemberOfService
+
diff --git a/roles/cord-profile/templates/vtn-service.yaml.j2 b/roles/cord-profile/templates/vtn-service.yaml.j2
new file mode 100644
index 0000000..7dc5d30
--- /dev/null
+++ b/roles/cord-profile/templates/vtn-service.yaml.j2
@@ -0,0 +1,52 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+imports:
+   - custom_types/xos.yaml
+
+description: Configures the VTN ONOS service
+
+topology_template:
+  node_templates:
+
+    service#ONOS_CORD:
+      type: tosca.nodes.ONOSService
+      requirements:
+      properties:
+          kind: onos
+          view_url: /admin/onos/onosservice/$id$/
+          no_container: true
+          rest_hostname: onos-cord
+          rest_port: 8182
+          replaces: service_ONOS_CORD
+
+    service#vtn:
+      type: tosca.nodes.VTNService
+      properties:
+          view_url: /admin/vtn/vtnservice/$id$/
+          privateGatewayMac: 00:00:00:00:00:01
+          localManagementIp: {{ management_network_ip }}
+          ovsdbPort: 6641
+          sshUser: root
+          sshKeyFile: /root/node_key
+          sshPort: 22
+          xosEndpoint: http://xos:{{ xos_ui_port }}/
+          xosUser: {{ xos_admin_user }}
+          xosPassword: {{ xos_admin_pass }}
+          replaces: service_vtn
+          vtnAPIVersion: 2
+          controllerPort: onos-cord:6654
+
+    VTN_ONOS_app:
+      type: tosca.nodes.ONOSVTNApp
+      requirements:
+          - onos_tenant:
+              node: service#ONOS_CORD
+              relationship: tosca.relationships.TenantOfService
+          - vtn_service:
+              node: service#vtn
+              relationship: tosca.relationships.UsedByService
+      properties:
+          install_dependencies: http://mavenrepo:8080/repository/org/opencord/cord-config/{{ cord_app_version }}/cord-config-{{ cord_app_version }}.oar,http://mavenrepo:8080/repository/org/opencord/vtn/{{ cord_app_version }}/vtn-{{ cord_app_version }}.oar
+          dependencies: org.onosproject.drivers, org.onosproject.drivers.ovsdb, org.onosproject.openflow-base, org.onosproject.ovsdb-base, org.onosproject.dhcp
+          autogenerate: vtn-network-cfg
+
diff --git a/roles/cord-profile/templates/xos-bootstrap-docker-compose.yaml.j2 b/roles/cord-profile/templates/xos-bootstrap-docker-compose.yaml.j2
new file mode 100644
index 0000000..bf79d65
--- /dev/null
+++ b/roles/cord-profile/templates/xos-bootstrap-docker-compose.yaml.j2
@@ -0,0 +1,98 @@
+version: '2'
+
+# XOS bootstrap docker compose
+# generated by platform-install/roles/cord-profile
+
+networks:
+{% for network in xos_docker_networks %}
+  {{ network }}:
+    external: true
+{% endfor %}
+
+services:
+  xos_db:
+    image: xosproject/xos-postgres
+    networks:
+{% for network in xos_docker_networks %}
+      - {{ network }}
+{% endfor %}
+    expose:
+      - "5432"
+
+{% if use_redis %}
+  xos_redis:
+    image: redis
+    networks:
+{% for network in xos_docker_networks %}
+     - {{ network }}
+{% endfor %}
+    logging:
+      driver: "json-file"
+      options:
+        max-size: "1000k"
+        max-file: "5"
+{% endif %}
+
+  xos_bootstrap_ui:
+    image: xosproject/xos
+    command: python /opt/xos/manage.py runserver 0.0.0.0:{{ xos_bootstrap_ui_port }} --insecure --makemigrations
+    networks:
+{% for network in xos_docker_networks %}
+     - {{ network }}
+{% endfor %}
+    labels:
+      org.xosproject.kind: userinterface
+      org.xosproject.target: bootstrap
+    links:
+      - xos_db
+{% if use_redis %}
+      - xos_redis:redis
+{% endif %}
+    volumes:
+      - .:/opt/cord_profile:ro
+      - ./xos_common_config:/opt/xos/xos_configuration/xos_common_config:ro
+{% for service in xos_services %}
+      - {{ cord_dir }}/{{ service.path }}:/opt/xos_services/{{ service.path | basename }}:ro
+{% endfor %}
+{% for library in xos_libraries %}
+      - {{ cord_dir }}/orchestration/xos_libraries/{{ library }}:/opt/xos_libraries/{{ library }}:ro
+{% endfor %}
+{% for volume in xos_docker_volumes %}
+      - {{ volume.host }}:{{ volume.container }}{{ ":rw" if (volume.read_only is defined and not volume.read_only ) else ":ro" }}
+{% endfor %}
+    ports:
+      - "{{ xos_bootstrap_ui_port }}:{{ xos_bootstrap_ui_port }}"
+    logging:
+      driver: "json-file"
+      options:
+        max-size: "1000k"
+        max-file: "5"
+
+  xos_synchronizer_onboarding:
+    image: xosproject/xos
+    command: bash -c "cd /opt/xos/synchronizers/onboarding; ./run.sh"
+    networks:
+{% for network in xos_docker_networks %}
+     - {{ network }}
+{% endfor %}
+    labels:
+      org.xosproject.kind: synchronizer
+      org.xosproject.target: onboarding
+    links:
+      - xos_db
+    volumes:
+      - /var/run/docker.sock:/var/run/docker.sock
+      - ./key_import:/opt/xos/key_import:ro
+      - ./onboarding-docker-compose:/opt/xos/synchronizers/onboarding/docker-compose
+{% for service in xos_services %}
+      - {{ cord_dir }}/{{ service.path }}:/opt/xos_services/{{ service.path | basename }}:ro
+{% endfor %}
+{% for library in xos_libraries %}
+      - {{ cord_dir }}/orchestration/xos_libraries/{{ library }}:/opt/xos_libraries/{{ library }}:ro
+{% endfor %}
+    logging:
+      driver: "json-file"
+      options:
+        max-size: "1000k"
+        max-file: "5"
+
diff --git a/roles/cord-profile/templates/xos.yaml.j2 b/roles/cord-profile/templates/xos.yaml.j2
new file mode 100644
index 0000000..626660c
--- /dev/null
+++ b/roles/cord-profile/templates/xos.yaml.j2
@@ -0,0 +1,87 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Onboard XOS
+
+imports:
+   - custom_types/xos.yaml
+
+topology_template:
+  node_templates:
+
+    xos:
+      type: tosca.nodes.XOS
+      properties:
+        ui_port: {{ xos_ui_port }}
+        bootstrap_ui_port: {{ xos_bootstrap_ui_port }}
+        docker_project_name: {{ cord_profile | regex_replace('\W','') }}
+        db_container_name: {{ cord_profile | regex_replace('\W','') }}bs_xos_db_1
+{% if use_redis %}
+        redis_container_name: {{ cord_profile | regex_replace('\W','') }}bs_xos_redis_1
+{% endif %}
+{% if frontend_only is defined %}
+        frontend_only: {{ frontend_only }}
+{% endif %}
+{% if source_ui_image is defined %}
+        source_ui_image: {{ source_ui_image }}
+{% endif %}
+
+    /opt/xos/xos_configuration/xos_common_config:
+      type: tosca.nodes.XOSVolume
+      properties:
+          host_path: {{ cord_profile_dir }}/xos_common_config
+          read_only: True
+      requirements:
+          - xos:
+             node: xos
+             relationship: tosca.relationships.UsedByXOS
+
+    /opt/cord_profile:
+      type: tosca.nodes.XOSVolume
+      properties:
+          host_path: {{ cord_profile_dir }}
+          read_only: True
+      requirements:
+          - xos:
+             node: xos
+             relationship: tosca.relationships.UsedByXOS
+
+{% for library in xos_libraries %}
+    /opt/xos_libraries/{{ library }}:
+      type: tosca.nodes.XOSVolume
+      properties:
+          host_path: {{ cord_dir }}/orchestration/xos_libraries/{{ library }}
+          read_only: True
+      requirements:
+          - xos:
+             node: xos
+             relationship: tosca.relationships.UsedByXOS
+
+{% endfor %}
+
+
+{% for service in xos_services %}
+    /opt/xos_services/{{ service.path | basename }}:
+      type: tosca.nodes.XOSVolume
+      properties:
+          host_path: {{ cord_dir }}/{{ service.path }}
+          read_only: {{ service.read_only | default("True") }}
+      requirements:
+          - xos:
+             node: xos
+             relationship: tosca.relationships.UsedByXOS
+
+{% endfor %}
+
+{% for volume in xos_docker_volumes %}
+    {{ volume.container }}:
+      type: tosca.nodes.XOSVolume
+      properties:
+          host_path: {{ volume.host }}
+          read_only: {{ volume.read_only | default("True") }}
+      requirements:
+          - xos:
+             node: xos
+             relationship: tosca.relationships.UsedByXOS
+
+{% endfor %}
+
diff --git a/roles/cord-profile/templates/xos_common_config.j2 b/roles/cord-profile/templates/xos_common_config.j2
new file mode 100644
index 0000000..175be92
--- /dev/null
+++ b/roles/cord-profile/templates/xos_common_config.j2
@@ -0,0 +1,59 @@
+; xos_common_config
+; generated by platform-install/roles/cord-profile
+
+[plc]
+name=plc
+deployment=plc
+
+[db]
+name=xos
+user=postgres
+password=password
+host=xos_db
+port=5432
+
+[api]
+host=localhost
+port=8000
+ssl_key=None
+ssl_cert=None
+ca_ssl_cert=None
+ratelimit_enabled=0
+omf_enabled=0
+mail_support_address=support@localhost
+nova_enabled=True
+logfile=/var/log/xos.log
+
+[nova]
+admin_user=admin@domain.com
+admin_password=admin
+admin_tenant=admin
+url=http://localhost:5000/v2.0/
+default_image=None
+default_flavor=m1.small
+default_security_group=default
+ca_ssl_cert=/etc/ssl/certs/ca-certificates.crt
+
+[observer]
+pretend=False
+backoff_disabled=True
+images_directory=/opt/xos/images
+dependency_graph=/opt/xos/model-deps
+logfile=/var/log/xos_backend.log
+save_ansible_output=True
+node_key={{ cord_profile_dir }}/node_key
+
+[gui]
+disable_minidashboard={{ disable_minidashboard }}
+branding_name={{ gui_branding_name }}
+branding_icon={{ gui_branding_icon }}
+branding_favicon={{ gui_branding_favicon }}
+branding_bg={{ gui_branding_bg }}
+{% if gui_service_view_class %}
+service_view_class={{ gui_service_view_class }}
+{% endif %}
+
+{% if use_vtn %}
+[networking]
+use_vtn=True
+{% endif %}