diff --git a/README-dev1.md b/README-dev1.md
new file mode 100644
index 0000000000000000000000000000000000000000..a65ecaba74f49036972b4c5ae7877c84c0a70d7d
--- /dev/null
+++ b/README-dev1.md
@@ -0,0 +1,42 @@
+SOCTools
+=========
+
+SOCTools is a set of tools that can be used by a SOC for collecting and analyzing security data, incident handling and threat intelligence.
+
+Installation
+------------
+
+Edit soctools-inventory and add the desired docker containers to be deployed. The playbook has been tested on CentOS 7.
+
+Run the ansible playbook:
+
+
+`ansible-playbook -i soctools-inventory soctools.yml -t start` to start the cluster.
+`ansible-playbook -i soctools-inventory soctools.yml -t stop` to stop the cluster.
+
+The NiFi interface should now be available on port 443 on the server.
+
+This will install the following docker images:
+ * zookeeper:latest
+ * nginx:latest
+ * apache/nifi:latest
+
+
+Building images
+---------------
+
+Images that are not offical Docker images can be built from scratch by running:
+
+`ansible-playbook -i inventories/build/hosts.yml build_images.yml`
+
+Edit the files under inventories/deploy/group_vars to specify that built images should be used. Currently only NiFi is built from scratch.
+
+License
+-------
+
+BSD
+
+Author Information
+------------------
+
+GEANT WP8
diff --git a/group_vars/all/main.yml b/group_vars/all/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f4d24e3ef95886e920e827f00547e4061caad0be
--- /dev/null
+++ b/group_vars/all/main.yml
@@ -0,0 +1,15 @@
+---
+
+soctools_netname: "dslxnifinet"
+
+zookeeper_name: "dsoclab-zookeeper"
+zookeeper_img: "gn43-dsl/zookeeper:latest"
+
+nifi_img: "gn43-dsl/nifi:1.9.2-2s"
+
+nginx_name: "dsoclab-nginx"
+nginx_img: "gn43-dsl/nginx:latest"
+
+dslproxy: "dsldev.gn4-3-wp8-soc.sunet.se"
+kspass: "Testiranje"
+tspass: "Testiranje"
diff --git a/roles/docker-deploy/README.md b/roles/docker-deploy/README.md
deleted file mode 100644
index 225dd44b9fc5b3abff7e9c68ff9e91d505cdd5f0..0000000000000000000000000000000000000000
--- a/roles/docker-deploy/README.md
+++ /dev/null
@@ -1,38 +0,0 @@
-Role Name
-=========
-
-A brief description of the role goes here.
-
-Requirements
-------------
-
-Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
-
-Role Variables
---------------
-
-A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
-
-Dependencies
-------------
-
-A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
-
-Example Playbook
-----------------
-
-Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
-
-    - hosts: servers
-      roles:
-         - { role: username.rolename, x: 42 }
-
-License
--------
-
-BSD
-
-Author Information
-------------------
-
-An optional section for the role authors to include contact information, or a website (HTML is not allowed).
diff --git a/roles/docker-deploy/defaults/main.yml b/roles/docker-deploy/defaults/main.yml
deleted file mode 100644
index 4ababba5f70a632be8bdcd776165bd5610906e2c..0000000000000000000000000000000000000000
--- a/roles/docker-deploy/defaults/main.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-# defaults file for docker-host
-
-image_location: /tmp
\ No newline at end of file
diff --git a/roles/docker-deploy/handlers/main.yml b/roles/docker-deploy/handlers/main.yml
deleted file mode 100644
index 5c2ecccee7e260751588af0321bb7bc081e7a0ca..0000000000000000000000000000000000000000
--- a/roles/docker-deploy/handlers/main.yml
+++ /dev/null
@@ -1,2 +0,0 @@
----
-# handlers file for docker-deploy
\ No newline at end of file
diff --git a/roles/docker-deploy/meta/main.yml b/roles/docker-deploy/meta/main.yml
deleted file mode 100644
index 3a212a9364cdcb2e9f1f2841cd12b091e3f6e3a0..0000000000000000000000000000000000000000
--- a/roles/docker-deploy/meta/main.yml
+++ /dev/null
@@ -1,53 +0,0 @@
-galaxy_info:
-  author: your name
-  description: your description
-  company: your company (optional)
-
-  # If the issue tracker for your role is not on github, uncomment the
-  # next line and provide a value
-  # issue_tracker_url: http://example.com/issue/tracker
-
-  # Choose a valid license ID from https://spdx.org - some suggested licenses:
-  # - BSD-3-Clause (default)
-  # - MIT
-  # - GPL-2.0-or-later
-  # - GPL-3.0-only
-  # - Apache-2.0
-  # - CC-BY-4.0
-  license: license (GPL-2.0-or-later, MIT, etc)
-
-  min_ansible_version: 2.4
-
-  # If this a Container Enabled role, provide the minimum Ansible Container version.
-  # min_ansible_container_version:
-
-  #
-  # Provide a list of supported platforms, and for each platform a list of versions.
-  # If you don't wish to enumerate all versions for a particular platform, use 'all'.
-  # To view available platforms and versions (or releases), visit:
-  # https://galaxy.ansible.com/api/v1/platforms/
-  #
-  # platforms:
-  # - name: Fedora
-  #   versions:
-  #   - all
-  #   - 25
-  # - name: SomePlatform
-  #   versions:
-  #   - all
-  #   - 1.0
-  #   - 7
-  #   - 99.99
-
-  galaxy_tags: []
-    # List tags for your role here, one per line. A tag is a keyword that describes
-    # and categorizes the role. Users find roles by searching for tags. Be sure to
-    # remove the '[]' above, if you add tags to this list.
-    #
-    # NOTE: A tag is limited to a single word comprised of alphanumeric characters.
-    #       Maximum 20 tags per role.
-
-dependencies: []
-  # List your role dependencies here, one per line. Be sure to remove the '[]' above,
-  # if you add dependencies to this list.
-  
\ No newline at end of file
diff --git a/roles/docker-deploy/tasks/main.yml b/roles/docker-deploy/tasks/main.yml
deleted file mode 100644
index a8e33e2a11b218cc0b4a10029dc517801f66749f..0000000000000000000000000000000000000000
--- a/roles/docker-deploy/tasks/main.yml
+++ /dev/null
@@ -1,34 +0,0 @@
----
-# tasks file for docker deployment
-
-- name: Copy docker image
-  copy:
-    src: "images/{{ docker[index].image }}.tar"
-    dest: "{{ image_location  }}/{{ docker[index].image  }}.tar"
-  when: docker[index].source == "load"
-
-- name: Load docker image
-  docker_image:
-    name: "{{ docker[index].image }}"
-    load_path: "{{ docker[index].load_path | default(omit) }}"
-    source: "{{ docker[index].source }}"
-    timeout: 120
-
-- name: Create docker network
-  docker_network:
-    name: soctools
-
-- name: Start docker containers {{ docker[index].image }}
-  docker_container:
-    name: "{{ index }}_{{ item  }}"
-    image: "{{ docker[index].image }}"
-    command: "{{ docker[index].command | default(omit) }}"
-    env: "{{ docker[index].env | default(omit) }}"
-    working_dir: "{{  docker[index].workdir | default(omit) }}"
-    volumes: "{{ docker[index].volumes | default(omit) }}"
-    ports: "{{ docker[index].ports | default(omit) }}"
-    networks:
-      - name: soctools
-    networks_cli_compatible: yes
-    state: started
-  with_sequence: count={{ scale }}
\ No newline at end of file
diff --git a/roles/docker-deploy/tests/inventory b/roles/docker-deploy/tests/inventory
deleted file mode 100644
index 878877b0776c44f55fc4e458f70840f31da5bb01..0000000000000000000000000000000000000000
--- a/roles/docker-deploy/tests/inventory
+++ /dev/null
@@ -1,2 +0,0 @@
-localhost
-
diff --git a/roles/docker-deploy/tests/test.yml b/roles/docker-deploy/tests/test.yml
deleted file mode 100644
index ecb44d59d41c6791c0b90be4e79c7b98756e6c77..0000000000000000000000000000000000000000
--- a/roles/docker-deploy/tests/test.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-- hosts: localhost
-  remote_user: root
-  roles:
-    - docker-deploy
\ No newline at end of file
diff --git a/roles/docker-deploy/vars/main.yml b/roles/docker-deploy/vars/main.yml
deleted file mode 100644
index 64e3849a404bea6ef03a04345d4726d13c298ac5..0000000000000000000000000000000000000000
--- a/roles/docker-deploy/vars/main.yml
+++ /dev/null
@@ -1,2 +0,0 @@
----
-# vars file for docker-deploy
\ No newline at end of file
diff --git a/roles/docker/defaults/main.yml b/roles/docker/defaults/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/roles/docker/handlers/main.yml b/roles/docker/handlers/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/roles/docker/meta/main.yml b/roles/docker/meta/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..fd2400e0ff5bbe66918e71939d02422de2df6e1f
--- /dev/null
+++ b/roles/docker/tasks/main.yml
@@ -0,0 +1,8 @@
+---
+
+- include: networkcreate.yml
+- include: zookeeper.yml
+- include: nifi.yml
+- include: nginx.yml
+- include: networkremove.yml
+
diff --git a/roles/docker/tasks/networkcreate.yml b/roles/docker/tasks/networkcreate.yml
new file mode 100644
index 0000000000000000000000000000000000000000..90343141e7de0e934bb8b199e9bd19101f90804c
--- /dev/null
+++ b/roles/docker/tasks/networkcreate.yml
@@ -0,0 +1,9 @@
+---
+
+- name: Create SOCTools cluster network
+  docker_network:
+    name: "{{ soctools_netname }}"
+    enable_ipv6: no
+  tags:
+    - start
+
diff --git a/roles/docker/tasks/networkremove.yml b/roles/docker/tasks/networkremove.yml
new file mode 100644
index 0000000000000000000000000000000000000000..caec5bc0311dadc3c77a463e33219d7455e1d25c
--- /dev/null
+++ b/roles/docker/tasks/networkremove.yml
@@ -0,0 +1,9 @@
+---
+
+- name: Remove SOCTools cluster network
+  docker_network:
+    name: "{{ soctools_netname }}"
+    state: absent
+  tags:
+    - stop
+
diff --git a/roles/docker/tasks/nginx.yml b/roles/docker/tasks/nginx.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3a45bfaa8c97ea377e182571f8ed061d1e98b186
--- /dev/null
+++ b/roles/docker/tasks/nginx.yml
@@ -0,0 +1,22 @@
+---
+
+- name: Create nginx proxy
+  docker_container:
+    name: "{{ nginx_name }}"
+    hostname: "{{ nginx_name }}"
+    image: "{{ nginx_img }}"
+    networks:
+      - name: "{{ soctools_netname}}"
+    networks_cli_compatible: yes
+    published_ports:
+      - "443:443"
+      - "7750:7750"
+  tags:
+    - start
+
+- name: Destroy nginx proxy
+  docker_container:
+    name: "{{ nginx_name }}"
+    state: absent
+  tags:
+    - stop
diff --git a/roles/docker/tasks/nifi.yml b/roles/docker/tasks/nifi.yml
new file mode 100644
index 0000000000000000000000000000000000000000..19ad16c03ccda44993c347f123cff718bf16efbd
--- /dev/null
+++ b/roles/docker/tasks/nifi.yml
@@ -0,0 +1,24 @@
+---
+
+- name: Create Nifi containers and connect to network
+  docker_container:
+    name: "{{ item }}"
+    hostname: "{{ item }}"
+    image: "{{ nifi_img }}"
+    networks:
+      - name: "{{ soctools_netname }}"
+    networks_cli_compatible: yes
+    entrypoint: "/bin/bash"
+    interactive: "yes"
+  with_items: "{{ groups['nificontainers'] }}"
+  tags:
+    - start
+
+- name: Disconnect Nifi containers from network and remove
+  docker_container:
+    name: "{{ item }}"
+    state: absent
+  with_items: "{{ groups['nificontainers'] }}"
+  tags:
+    - stop
+
diff --git a/roles/docker/tasks/zookeeper.yml b/roles/docker/tasks/zookeeper.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d8cc7f305d94e233a78ae7f9a7e54bbc59081e15
--- /dev/null
+++ b/roles/docker/tasks/zookeeper.yml
@@ -0,0 +1,22 @@
+---
+
+- name: Create zookeeper
+  docker_container:
+    name: "{{ zookeeper_name }}"
+    hostname: "{{ zookeeper_name }}"
+    image: "{{ zookeeper_img }}"
+    networks:
+      - name: "{{ soctools_netname }}"
+    networks_cli_compatible: yes
+    env:
+      ALLOW_ANONYMOUS_LOGIN: "yes"
+  tags:
+    - start
+
+- name: Remove zookeeper
+  docker_container:
+    name: "{{ zookeeper_name }}"
+    state: absent
+  tags:
+    - stop
+
diff --git a/roles/docker/vars/main.yml b/roles/docker/vars/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/roles/nginx/defaults/main.yml b/roles/nginx/defaults/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/roles/nginx/handlers/main.yml b/roles/nginx/handlers/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/roles/nginx/meta/main.yml b/roles/nginx/meta/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/roles/nginx/tasks/main.yml b/roles/nginx/tasks/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..1d158637b4f432e9833075b2ef95154a2f182074
--- /dev/null
+++ b/roles/nginx/tasks/main.yml
@@ -0,0 +1,15 @@
+---
+
+- name: Configure nginx for proxying
+  template:
+    src: nginx.conf.j2
+    dest: /etc/nginx/nginx.conf
+  tags:
+    - start
+    - reconf
+
+- name: Restart nginx service
+  command: nginx -s reload
+  tags:
+    - start
+    - reconf
diff --git a/roles/nginx/templates/nginx.conf.j2 b/roles/nginx/templates/nginx.conf.j2
new file mode 100644
index 0000000000000000000000000000000000000000..25a191866c96bfc839b5fe724dc064599caa6da5
--- /dev/null
+++ b/roles/nginx/templates/nginx.conf.j2
@@ -0,0 +1,44 @@
+user  nginx;
+include /usr/share/nginx/modules/*.conf;
+worker_processes  1;
+
+error_log  /var/log/nginx/error.log info;
+pid        /run/nginx.pid;
+events {
+    worker_connections  1024;
+}
+
+stream {
+  resolver 127.0.0.11;
+
+  upstream nifiserv {
+  {% for nifihost in groups['nificontainers'] %}
+     server {{nifihost}}:9443;
+  {% endfor %}
+  }
+  server {
+    listen 443;
+    proxy_pass nifiserv;
+  }
+
+  upstream nifiservtcp7750 {
+  {% for nifihost in groups['nificontainers'] %}
+     server {{nifihost}}:7750;
+  {% endfor %}
+  }
+  server {
+    listen 7750;
+    proxy_pass nifiservtcp7750;
+  }
+
+  upstream nifiservtcp7751 {
+  {% for nifihost in groups['nificontainers'] %}
+     server {{nifihost}}:7751;
+  {% endfor %}
+  }
+  server {
+    listen 7751;
+    proxy_pass nifiservtcp7751;
+  }
+}
+
diff --git a/roles/nginx/vars/main.yml b/roles/nginx/vars/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/roles/nifi/README.md b/roles/nifi/README.md
deleted file mode 100644
index 225dd44b9fc5b3abff7e9c68ff9e91d505cdd5f0..0000000000000000000000000000000000000000
--- a/roles/nifi/README.md
+++ /dev/null
@@ -1,38 +0,0 @@
-Role Name
-=========
-
-A brief description of the role goes here.
-
-Requirements
-------------
-
-Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
-
-Role Variables
---------------
-
-A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
-
-Dependencies
-------------
-
-A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
-
-Example Playbook
-----------------
-
-Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
-
-    - hosts: servers
-      roles:
-         - { role: username.rolename, x: 42 }
-
-License
--------
-
-BSD
-
-Author Information
-------------------
-
-An optional section for the role authors to include contact information, or a website (HTML is not allowed).
diff --git a/roles/nifi/defaults/main.yml b/roles/nifi/defaults/main.yml
index a7cb856f60c5058d6e0e01b62356782b58f32c1f..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644
--- a/roles/nifi/defaults/main.yml
+++ b/roles/nifi/defaults/main.yml
@@ -1,14 +0,0 @@
----
-# defaults file for nifi
-
-nifi_version: 1.9.2
-nifi_toolkit_version: 1.9.2
-
-nifi_base_dir: /opt/nifi
-nifi_home: "{{ nifi_base_dir }}/nifi-current"
-nifi_toolkit_home: "{{ nifi_base_dir }}/nifi-toolkit"
-nifi_pid_dir: "{{ nifi_home }}/run"
-nifi_log_dir: "{{ nifi_home }}/logs"
-
-nifi_uid: 1000
-nifi_gid: 1000
diff --git a/roles/nifi/files/cacerts.jks b/roles/nifi/files/cacerts.jks
new file mode 100644
index 0000000000000000000000000000000000000000..dfb92a5907916710460d0eae2eb40a9f955bf153
Binary files /dev/null and b/roles/nifi/files/cacerts.jks differ
diff --git a/roles/nifi/files/common.sh b/roles/nifi/files/common.sh
deleted file mode 100755
index f3ea43580edea1a71d938467a9ddcb7410172235..0000000000000000000000000000000000000000
--- a/roles/nifi/files/common.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/sh -e
-#    Licensed to the Apache Software Foundation (ASF) under one or more
-#    contributor license agreements.  See the NOTICE file distributed with
-#    this work for additional information regarding copyright ownership.
-#    The ASF licenses this file to You under the Apache License, Version 2.0
-#    (the "License"); you may not use this file except in compliance with
-#    the License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS,
-#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#    See the License for the specific language governing permissions and
-#    limitations under the License.
-
-# 1 - value to search for
-# 2 - value to replace
-# 3 - file to perform replacement inline
-prop_replace () {
-  target_file=${3:-${nifi_props_file}}
-  echo 'replacing target file ' ${target_file}
-  sed -i -e "s|^$1=.*$|$1=$2|"  ${target_file}
-}
-
-uncomment() {
-	target_file=${2}
-	echo "Uncommenting ${target_file}"
-	sed -i -e "s|^\#$1|$1|" ${target_file}
-}
-
-# NIFI_HOME is defined by an ENV command in the backing Dockerfile
-export nifi_bootstrap_file=${NIFI_HOME}/conf/bootstrap.conf
-export nifi_props_file=${NIFI_HOME}/conf/nifi.properties
-export nifi_toolkit_props_file=${HOME}/.nifi-cli.nifi.properties
-export hostname=$(hostname)
diff --git a/roles/nifi/files/docker-entrypoint.sh b/roles/nifi/files/docker-entrypoint.sh
deleted file mode 100644
index 5a2d39f582d9191073015db0b6b892a74a170956..0000000000000000000000000000000000000000
--- a/roles/nifi/files/docker-entrypoint.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-../scripts/start.sh
diff --git a/roles/nifi/files/dsoclab-nifi-1.p12 b/roles/nifi/files/dsoclab-nifi-1.p12
new file mode 100644
index 0000000000000000000000000000000000000000..9a7f342959bb02b2dcadc7fa54c8442ccdde8f1f
Binary files /dev/null and b/roles/nifi/files/dsoclab-nifi-1.p12 differ
diff --git a/roles/nifi/files/dsoclab-nifi-2.p12 b/roles/nifi/files/dsoclab-nifi-2.p12
new file mode 100644
index 0000000000000000000000000000000000000000..4f49a68103b434d45df8b05ba7188f8c0bf01274
Binary files /dev/null and b/roles/nifi/files/dsoclab-nifi-2.p12 differ
diff --git a/roles/nifi/files/dsoclab-nifi-3.p12 b/roles/nifi/files/dsoclab-nifi-3.p12
new file mode 100644
index 0000000000000000000000000000000000000000..934b318117c4ed12695d20f98a62d16c02f07bc1
Binary files /dev/null and b/roles/nifi/files/dsoclab-nifi-3.p12 differ
diff --git a/roles/nifi/files/flow-dsoclab-nifi-1.xml.gz b/roles/nifi/files/flow-dsoclab-nifi-1.xml.gz
new file mode 100644
index 0000000000000000000000000000000000000000..8837382d99acb4fc3a9ea87e2a508ac56a1f0e2d
Binary files /dev/null and b/roles/nifi/files/flow-dsoclab-nifi-1.xml.gz differ
diff --git a/roles/nifi/files/flow-dsoclab-nifi-2.xml.gz b/roles/nifi/files/flow-dsoclab-nifi-2.xml.gz
new file mode 100644
index 0000000000000000000000000000000000000000..8837382d99acb4fc3a9ea87e2a508ac56a1f0e2d
Binary files /dev/null and b/roles/nifi/files/flow-dsoclab-nifi-2.xml.gz differ
diff --git a/roles/nifi/files/flow-dsoclab-nifi-3.xml.gz b/roles/nifi/files/flow-dsoclab-nifi-3.xml.gz
new file mode 100644
index 0000000000000000000000000000000000000000..8837382d99acb4fc3a9ea87e2a508ac56a1f0e2d
Binary files /dev/null and b/roles/nifi/files/flow-dsoclab-nifi-3.xml.gz differ
diff --git a/roles/nifi/files/nifi-env.sh b/roles/nifi/files/nifi-env.sh
deleted file mode 100755
index b2b349fe7ddcbcc73b12fc4bfb2cb1f96b42d02e..0000000000000000000000000000000000000000
--- a/roles/nifi/files/nifi-env.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-
-
-
diff --git a/roles/nifi/files/secure.sh b/roles/nifi/files/secure.sh
deleted file mode 100755
index 46fa09885974c51e0d8a471c23685ed614e1f09f..0000000000000000000000000000000000000000
--- a/roles/nifi/files/secure.sh
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/bin/sh -e
-
-#    Licensed to the Apache Software Foundation (ASF) under one or more
-#    contributor license agreements.  See the NOTICE file distributed with
-#    this work for additional information regarding copyright ownership.
-#    The ASF licenses this file to You under the Apache License, Version 2.0
-#    (the "License"); you may not use this file except in compliance with
-#    the License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS,
-#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#    See the License for the specific language governing permissions and
-#    limitations under the License.
-
-scripts_dir='/opt/nifi/scripts'
-
-[ -f "${scripts_dir}/common.sh" ] && . "${scripts_dir}/common.sh"
-
-# Perform idempotent changes of configuration to support secure environments
-echo 'Configuring environment with SSL settings'
-
-: ${KEYSTORE_PATH:?"Must specify an absolute path to the keystore being used."}
-if [ ! -f "${KEYSTORE_PATH}" ]; then
-    echo "Keystore file specified (${KEYSTORE_PATH}) does not exist."
-    exit 1
-fi
-: ${KEYSTORE_TYPE:?"Must specify the type of keystore (JKS, PKCS12, PEM) of the keystore being used."}
-: ${KEYSTORE_PASSWORD:?"Must specify the password of the keystore being used."}
-
-: ${TRUSTSTORE_PATH:?"Must specify an absolute path to the truststore being used."}
-if [ ! -f "${TRUSTSTORE_PATH}" ]; then
-    echo "Keystore file specified (${TRUSTSTORE_PATH}) does not exist."
-    exit 1
-fi
-: ${TRUSTSTORE_TYPE:?"Must specify the type of truststore (JKS, PKCS12, PEM) of the truststore being used."}
-: ${TRUSTSTORE_PASSWORD:?"Must specify the password of the truststore being used."}
-
-prop_replace 'nifi.security.keystore'           "${KEYSTORE_PATH}"
-prop_replace 'nifi.security.keystoreType'       "${KEYSTORE_TYPE}"
-prop_replace 'nifi.security.keystorePasswd'     "${KEYSTORE_PASSWORD}"
-prop_replace 'nifi.security.keyPasswd'          "${KEY_PASSWORD:-$KEYSTORE_PASSWORD}"
-prop_replace 'nifi.security.truststore'         "${TRUSTSTORE_PATH}"
-prop_replace 'nifi.security.truststoreType'     "${TRUSTSTORE_TYPE}"
-prop_replace 'nifi.security.truststorePasswd'   "${TRUSTSTORE_PASSWORD}"
-
-prop_replace 'keystore'           "${KEYSTORE_PATH}"                    ${nifi_toolkit_props_file}
-prop_replace 'keystoreType'       "${KEYSTORE_TYPE}"                    ${nifi_toolkit_props_file}
-prop_replace 'keystorePasswd'     "${KEYSTORE_PASSWORD}"                ${nifi_toolkit_props_file}
-prop_replace 'keyPasswd'          "${KEY_PASSWORD:-$KEYSTORE_PASSWORD}" ${nifi_toolkit_props_file}
-prop_replace 'truststore'         "${TRUSTSTORE_PATH}"                  ${nifi_toolkit_props_file}
-prop_replace 'truststoreType'     "${TRUSTSTORE_TYPE}"                  ${nifi_toolkit_props_file}
-prop_replace 'truststorePasswd'   "${TRUSTSTORE_PASSWORD}"              ${nifi_toolkit_props_file}
-
-# Disable HTTP and enable HTTPS
-prop_replace 'nifi.web.http.port'   ''
-prop_replace 'nifi.web.http.host'   ''
-prop_replace 'nifi.web.https.port'  "${NIFI_WEB_HTTPS_PORT:-8443}"
-prop_replace 'nifi.web.https.host'  "${NIFI_WEB_HTTPS_HOST:-$HOSTNAME}"
-prop_replace 'nifi.remote.input.secure' 'true'
-
-# Setup nifi-toolkit
-prop_replace 'baseUrl' "https://${NIFI_WEB_HTTPS_HOST:-$HOSTNAME}:${NIFI_WEB_HTTPS_PORT:-8443}" ${nifi_toolkit_props_file}
-
-# Check if the user has specified a nifi.web.proxy.host setting and handle appropriately
-if [ -z "${NIFI_WEB_PROXY_HOST}" ]; then
-    echo 'NIFI_WEB_PROXY_HOST was not set but NiFi is configured to run in a secure mode.  The NiFi UI may be inaccessible if using port mapping.'
-else
-    prop_replace 'nifi.web.proxy.host' "${NIFI_WEB_PROXY_HOST}"
-fi
-
-# Establish initial user and an associated admin identity
-sed -i -e 's|<property name="Initial User Identity 1"></property>|<property name="Initial User Identity 1">'"${INITIAL_ADMIN_IDENTITY}"'</property>|'  ${NIFI_HOME}/conf/authorizers.xml
-sed -i -e 's|<property name="Initial Admin Identity"></property>|<property name="Initial Admin Identity">'"${INITIAL_ADMIN_IDENTITY}"'</property>|'  ${NIFI_HOME}/conf/authorizers.xml
-
-if [ -n "${NODE_IDENTITY}" ]; then
-    sed -i -e 's|<property name="Node Identity 1"></property>|<property name="Node Identity 1">'"${NODE_IDENTITY}"'</property>|'  ${NIFI_HOME}/conf/authorizers.xml
-fi
-
-prop_replace 'proxiedEntity' "${INITIAL_ADMIN_IDENTITY}" ${nifi_toolkit_props_file}
diff --git a/roles/nifi/files/start.sh b/roles/nifi/files/start.sh
deleted file mode 100755
index 25b0347dd97ed38a849683827ce9c4eb74016c46..0000000000000000000000000000000000000000
--- a/roles/nifi/files/start.sh
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/bin/sh -e
-
-#    Licensed to the Apache Software Foundation (ASF) under one or more
-#    contributor license agreements.  See the NOTICE file distributed with
-#    this work for additional information regarding copyright ownership.
-#    The ASF licenses this file to You under the Apache License, Version 2.0
-#    (the "License"); you may not use this file except in compliance with
-#    the License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS,
-#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#    See the License for the specific language governing permissions and
-#    limitations under the License.
-
-scripts_dir='/opt/nifi/nifi-current/scripts'
-
-[ -f "${scripts_dir}/common.sh" ] && . "${scripts_dir}/common.sh"
-
-# Override JVM memory settings
-if [ ! -z "${NIFI_JVM_HEAP_INIT}" ]; then
-    prop_replace 'java.arg.2'       "-Xms${NIFI_JVM_HEAP_INIT}" ${nifi_bootstrap_file}
-fi
-
-if [ ! -z "${NIFI_JVM_HEAP_MAX}" ]; then
-    prop_replace 'java.arg.3'       "-Xmx${NIFI_JVM_HEAP_MAX}" ${nifi_bootstrap_file}
-fi
-
-if [ ! -z "${NIFI_JVM_DEBUGGER}" ]; then
-    uncomment "java.arg.debug" ${nifi_bootstrap_file}
-fi
-
-# Establish baseline properties
-prop_replace 'nifi.web.http.port'               "${NIFI_WEB_HTTP_PORT:-8080}"
-prop_replace 'nifi.web.http.host'               "${NIFI_WEB_HTTP_HOST:-$HOSTNAME}"
-prop_replace 'nifi.remote.input.host'           "${NIFI_REMOTE_INPUT_HOST:-$HOSTNAME}"
-prop_replace 'nifi.remote.input.socket.port'    "${NIFI_REMOTE_INPUT_SOCKET_PORT:-10000}"
-prop_replace 'nifi.remote.input.secure'         'false'
-
-# Set nifi-toolkit properties files and baseUrl
-"${scripts_dir}/toolkit.sh"
-prop_replace 'baseUrl' "http://${NIFI_WEB_HTTP_HOST:-$HOSTNAME}:${NIFI_WEB_HTTP_PORT:-8080}" ${nifi_toolkit_props_file}
-
-prop_replace 'nifi.variable.registry.properties'    "${NIFI_VARIABLE_REGISTRY_PROPERTIES:-}"
-prop_replace 'nifi.cluster.is.node'                         "${NIFI_CLUSTER_IS_NODE:-false}"
-prop_replace 'nifi.cluster.node.address'                    "${NIFI_CLUSTER_ADDRESS:-$HOSTNAME}"
-prop_replace 'nifi.cluster.node.protocol.port'              "${NIFI_CLUSTER_NODE_PROTOCOL_PORT:-}"
-prop_replace 'nifi.cluster.node.protocol.threads'           "${NIFI_CLUSTER_NODE_PROTOCOL_THREADS:-10}"
-prop_replace 'nifi.cluster.node.protocol.max.threads'       "${NIFI_CLUSTER_NODE_PROTOCOL_MAX_THREADS:-50}"
-prop_replace 'nifi.zookeeper.connect.string'                "${NIFI_ZK_CONNECT_STRING:-}"
-prop_replace 'nifi.zookeeper.root.node'                     "${NIFI_ZK_ROOT_NODE:-/nifi}"
-prop_replace 'nifi.cluster.flow.election.max.wait.time'     "${NIFI_ELECTION_MAX_WAIT:-5 mins}"
-prop_replace 'nifi.cluster.flow.election.max.candidates'    "${NIFI_ELECTION_MAX_CANDIDATES:-}"
-prop_replace 'nifi.web.proxy.context.path'                  "${NIFI_WEB_PROXY_CONTEXT_PATH:-}"
-
-. "${scripts_dir}/update_cluster_state_management.sh"
-
-# Check if we are secured or unsecured
-case ${AUTH} in
-    tls)
-        echo 'Enabling Two-Way SSL user authentication'
-        . "${scripts_dir}/secure.sh"
-        ;;
-    ldap)
-        echo 'Enabling LDAP user authentication'
-        # Reference ldap-provider in properties
-        prop_replace 'nifi.security.user.login.identity.provider' 'ldap-provider'
-
-        . "${scripts_dir}/secure.sh"
-        . "${scripts_dir}/update_login_providers.sh"
-        ;;
-    *)
-        if [ ! -z "${NIFI_WEB_PROXY_HOST}" ]; then
-            echo 'NIFI_WEB_PROXY_HOST was set but NiFi is not configured to run in a secure mode.  Will not update nifi.web.proxy.host.'
-        fi
-        ;;
-esac
-
-# Continuously provide logs so that 'docker logs' can    produce them
-tail -F "${NIFI_HOME}/logs/nifi-app.log" &
-"${NIFI_HOME}/bin/nifi.sh" run &
-nifi_pid="$!"
-
-trap "echo Received trapped signal, beginning shutdown...;" KILL TERM HUP INT EXIT;
-
-echo NiFi running with PID ${nifi_pid}.
-wait ${nifi_pid}
diff --git a/roles/nifi/files/toolkit.sh b/roles/nifi/files/toolkit.sh
deleted file mode 100755
index 5262c917348025723e678e0105d088f4944da9e7..0000000000000000000000000000000000000000
--- a/roles/nifi/files/toolkit.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh -e
-
-#    Licensed to the Apache Software Foundation (ASF) under one or more
-#    contributor license agreements.  See the NOTICE file distributed with
-#    this work for additional information regarding copyright ownership.
-#    The ASF licenses this file to You under the Apache License, Version 2.0
-#    (the "License"); you may not use this file except in compliance with
-#    the License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS,
-#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#    See the License for the specific language governing permissions and
-#    limitations under the License.
-
-cat <<EOT > ${nifi_toolkit_props_file}
-baseUrl=
-keystore=
-keystoreType=
-keystorePasswd=
-keyPasswd=
-truststore=
-truststoreType=
-truststorePasswd=
-proxiedEntity=
-EOT
-
-cat <<EOT > ${HOME}/.nifi-cli.config
-nifi.props=${nifi_toolkit_props_file}
-EOT
\ No newline at end of file
diff --git a/roles/nifi/files/update_cluster_state_management.sh b/roles/nifi/files/update_cluster_state_management.sh
deleted file mode 100755
index 718e52de77687908d8bc3343a457d0beacfdadf3..0000000000000000000000000000000000000000
--- a/roles/nifi/files/update_cluster_state_management.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/sh -e
-
-#    Licensed to the Apache Software Foundation (ASF) under one or more
-#    contributor license agreements.  See the NOTICE file distributed with
-#    this work for additional information regarding copyright ownership.
-#    The ASF licenses this file to You under the Apache License, Version 2.0
-#    (the "License"); you may not use this file except in compliance with
-#    the License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS,
-#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#    See the License for the specific language governing permissions and
-#    limitations under the License.
-
-state_providers_file=${NIFI_HOME}/conf/state-management.xml
-property_xpath='/stateManagement/cluster-provider/property'
-
-edit_property() {
-  property_name=$1
-  property_value=$2
-
-  if [ -n "${property_value}" ]; then
-    xmlstarlet ed --inplace -u "${property_xpath}[@name='${property_name}']" -v "${property_value}" "${state_providers_file}"
-  fi
-}
-
-edit_property 'Connect String'     "${NIFI_ZK_CONNECT_STRING}"
-edit_property "Root Node"                   "${NIFI_ZK_ROOT_NODE}"
\ No newline at end of file
diff --git a/roles/nifi/files/update_login_providers.sh b/roles/nifi/files/update_login_providers.sh
deleted file mode 100755
index e124960eec4aa316e86da668d79a7aac30b19371..0000000000000000000000000000000000000000
--- a/roles/nifi/files/update_login_providers.sh
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/sh -e
-
-#    Licensed to the Apache Software Foundation (ASF) under one or more
-#    contributor license agreements.  See the NOTICE file distributed with
-#    this work for additional information regarding copyright ownership.
-#    The ASF licenses this file to You under the Apache License, Version 2.0
-#    (the "License"); you may not use this file except in compliance with
-#    the License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS,
-#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#    See the License for the specific language governing permissions and
-#    limitations under the License.
-
-login_providers_file=${NIFI_HOME}/conf/login-identity-providers.xml
-property_xpath='//loginIdentityProviders/provider/property'
-
-# Update a given property in the login-identity-providers file if a value is specified
-edit_property() {
-  property_name=$1
-  property_value=$2
-
-  if [ -n "${property_value}" ]; then
-    xmlstarlet ed --inplace -u "${property_xpath}[@name='${property_name}']" -v "${property_value}" "${login_providers_file}"
-  fi
-}
-
-# Remove comments to enable the ldap-provider
-sed -i '/To enable the ldap-provider remove/d' "${login_providers_file}"
-
-edit_property 'Authentication Strategy'     "${LDAP_AUTHENTICATION_STRATEGY}"
-edit_property 'Manager DN'                  "${LDAP_MANAGER_DN}"
-edit_property 'Manager Password'            "${LDAP_MANAGER_PASSWORD}"
-edit_property 'TLS - Keystore'              "${LDAP_TLS_KEYSTORE}"
-edit_property 'TLS - Keystore Password'     "${LDAP_TLS_KEYSTORE_PASSWORD}"
-edit_property 'TLS - Keystore Type'         "${LDAP_TLS_KEYSTORE_TYPE}"
-edit_property 'TLS - Truststore'            "${LDAP_TLS_TRUSTSTORE}"
-edit_property 'TLS - Truststore Password'   "${LDAP_TLS_TRUSTSTORE_PASSWORD}"
-edit_property 'TLS - Truststore Type'       "${LDAP_TLS_TRUSTSTORE_TYPE}"
-edit_property 'TLS - Protocol'              "${LDAP_TLS_PROTOCOL}"
-edit_property 'Url'                         "${LDAP_URL}"
-edit_property 'User Search Base'            "${LDAP_USER_SEARCH_BASE}"
-edit_property 'User Search Filter'          "${LDAP_USER_SEARCH_FILTER}"
-edit_property 'Identity Strategy'           "${LDAP_IDENTITY_STRATEGY}"
\ No newline at end of file
diff --git a/roles/nifi/handlers/main.yml b/roles/nifi/handlers/main.yml
index 178e24bcb14b9440ad17206c6522910353476c7b..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644
--- a/roles/nifi/handlers/main.yml
+++ b/roles/nifi/handlers/main.yml
@@ -1,2 +0,0 @@
----
-# handlers file for nifi
\ No newline at end of file
diff --git a/roles/nifi/meta/main.yml b/roles/nifi/meta/main.yml
index 3a212a9364cdcb2e9f1f2841cd12b091e3f6e3a0..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644
--- a/roles/nifi/meta/main.yml
+++ b/roles/nifi/meta/main.yml
@@ -1,53 +0,0 @@
-galaxy_info:
-  author: your name
-  description: your description
-  company: your company (optional)
-
-  # If the issue tracker for your role is not on github, uncomment the
-  # next line and provide a value
-  # issue_tracker_url: http://example.com/issue/tracker
-
-  # Choose a valid license ID from https://spdx.org - some suggested licenses:
-  # - BSD-3-Clause (default)
-  # - MIT
-  # - GPL-2.0-or-later
-  # - GPL-3.0-only
-  # - Apache-2.0
-  # - CC-BY-4.0
-  license: license (GPL-2.0-or-later, MIT, etc)
-
-  min_ansible_version: 2.4
-
-  # If this a Container Enabled role, provide the minimum Ansible Container version.
-  # min_ansible_container_version:
-
-  #
-  # Provide a list of supported platforms, and for each platform a list of versions.
-  # If you don't wish to enumerate all versions for a particular platform, use 'all'.
-  # To view available platforms and versions (or releases), visit:
-  # https://galaxy.ansible.com/api/v1/platforms/
-  #
-  # platforms:
-  # - name: Fedora
-  #   versions:
-  #   - all
-  #   - 25
-  # - name: SomePlatform
-  #   versions:
-  #   - all
-  #   - 1.0
-  #   - 7
-  #   - 99.99
-
-  galaxy_tags: []
-    # List tags for your role here, one per line. A tag is a keyword that describes
-    # and categorizes the role. Users find roles by searching for tags. Be sure to
-    # remove the '[]' above, if you add tags to this list.
-    #
-    # NOTE: A tag is limited to a single word comprised of alphanumeric characters.
-    #       Maximum 20 tags per role.
-
-dependencies: []
-  # List your role dependencies here, one per line. Be sure to remove the '[]' above,
-  # if you add dependencies to this list.
-  
\ No newline at end of file
diff --git a/roles/nifi/tasks/main.yml b/roles/nifi/tasks/main.yml
index b68c8ce4cc129d9d5f4990e16dab7b7419164f7c..fd1ef9f4c4ff7c3d028dff73c69675d55611e5c9 100644
--- a/roles/nifi/tasks/main.yml
+++ b/roles/nifi/tasks/main.yml
@@ -1,88 +1,63 @@
 ---
-# tasks file for nifi
 
-- name: Install required packages
-  apt:
-    name: ["aptitude","jq","xmlstarlet","procps","sudo","unzip","openjdk-8-jdk"]
-    state: present
-
-- name: Create system group for Nifi
-  group:
-    name: nifi
-    gid: "{{ nifi_gid }}"
-    state: present
-    system: yes
-
-- name: Create system user for Nifi
-  user:
-    name: nifi
-    uid: "{{ nifi_uid }}"
-    state: present
-    groups: nifi
-    system: yes
-    shell: /bin/false
-  
-- name: Create directory {{ nifi_base_dir }}
-  file:
-    path: "{{ nifi_base_dir }}"
-    state: directory
-    owner: nifi
-    group: nifi
-  
-- name: Download and extract Nifi
-  unarchive:
-    src: http://apache.uib.no/nifi/{{ nifi_version }}/nifi-{{ nifi_version }}-bin.tar.gz
-    remote_src: yes
-    dest: "{{ nifi_base_dir }}"
-  tags: download
-
-- name: Download and extract Nifi-toolkit
-  unarchive:
-    src: http://apache.uib.no/nifi/{{ nifi_toolkit_version }}/nifi-toolkit-{{ nifi_version }}-bin.zip
-    remote_src: yes
-    dest: "{{ nifi_base_dir }}"
-  tags: download
-
-- name: Link archives to standard locations
-  file:
-    src: "{{ item.src }}"
-    dest: "{{ item.dest }}"
-    state: link
-    follow: no
-  loop:
-    - { src: "{{ nifi_base_dir }}/nifi-{{ nifi_version }}", dest: "{{ nifi_home }}" }
-    - { src: "{{ nifi_base_dir }}/nifi-toolkit-{{ nifi_toolkit_version  }}", dest: "{{ nifi_toolkit_home }}" }
-
-- name: Create directories
-  file:
-    path: "{{ item }}"
-    state: directory
-  loop:
-    - "{{ nifi_home }}/conf"
-    - "{{ nifi_home }}/database_repository"
-    - "{{ nifi_home }}/flowfile_repository"
-    - "{{ nifi_home }}/content_repository"
-    - "{{ nifi_home }}/provenance_repository"
-    - "{{ nifi_home }}/state"
-    - "{{ nifi_log_dir }}"
-    - "{{ nifi_home }}/scripts"
-
-- name: Modify nifi.env.sh
+- name: Copy certificates in NiFi conf dir
   copy:
-    src: nifi-env.sh
-    dest: "{{ nifi_home }}/bin/nifi-env.sh"
-    mode: "0755"
-  when: docker is defined
-
-- name: Copy files
+    src:  "{{ item }}"
+    dest: "conf/{{ item }}"
+  with_items:
+    - "{{ inventory_hostname }}.p12"
+    - cacerts.jks
+  tags:
+    - start
+
+- name: Copy flow in NiFi conf dir
   copy:
-    src: "{{ item }}"
-    dest: "{{ nifi_home }}/scripts/{{ item }}"
-    mode: "0755"
-  loop:
-      - start.sh
-      - common.sh
-      - secure.sh
-      - toolkit.sh
-      - update_cluster_state_management.sh
-      - update_login_providers.sh
+    src:  "{{ role_path }}/files/flow-{{ inventory_hostname }}.xml.gz"
+    dest: "{{ ansible_facts.env['NIFI_HOME'] }}/conf/flow.xml.gz"
+  when:
+    - "'{{ role_path }}/files/flow-{{ inventory_hostname }}.xml.gz' is is_file"
+  tags:
+    - start
+
+- name: Configure NiFi properties for secure servers
+  template:
+    src: nifi.properties.j2
+    dest: conf/nifi.properties
+  tags:
+    - start
+
+- name: Configure NiFi authorizers for secure servers
+  template:
+    src: authorizers.xml.j2
+    dest: conf/authorizers.xml
+  tags:
+    - start
+
+- name: Start NiFi
+  command: "./bin/nifi.sh start"
+  tags:
+    - start
+
+#- name: check reachable hosts
+#  gather_facts: no
+#  tasks:
+#    - command: ping -c1 {{ inventory_hostname }}
+#      delegate_to: localhost
+#      register: ping_result
+#      ignore_errors: yes
+#    - group_by: key=reachable
+#      when: ping_result|success
+
+- name: Stop NiFi
+  command: "./bin/nifi.sh stop"
+  tags:
+    - stop
+
+- name: Copy flow from NiFi
+  fetch:
+    src: "{{ ansible_facts.env['NIFI_HOME'] }}/conf/flow.xml.gz"
+    dest: "{{ role_path }}/files/flow-{{ inventory_hostname }}.xml.gz"
+    flat: yes
+  tags:
+    - stop
+
diff --git a/roles/nifi/templates/authorizers.xml.j2 b/roles/nifi/templates/authorizers.xml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..2b3114aa17f134451569b18b1450610f14d4465f
--- /dev/null
+++ b/roles/nifi/templates/authorizers.xml.j2
@@ -0,0 +1,319 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+      http://www.apache.org/licenses/LICENSE-2.0
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<!--
+    This file lists the userGroupProviders, accessPolicyProviders, and authorizers to use when running securely. In order
+    to use a specific authorizer it must be configured here and it's identifier must be specified in the nifi.properties file.
+    If the authorizer is a managedAuthorizer, it may need to be configured with an accessPolicyProvider and an userGroupProvider.
+    This file allows for configuration of them, but they must be configured in order:
+
+    ...
+    all userGroupProviders
+    all accessPolicyProviders
+    all Authorizers
+    ...
+-->
+<authorizers>
+
+    <!--
+        The FileUserGroupProvider will provide support for managing users and groups which is backed by a file
+        on the local file system.
+
+        - Users File - The file where the FileUserGroupProvider will store users and groups.
+
+        - Legacy Authorized Users File - The full path to an existing authorized-users.xml that will be automatically
+            be used to load the users and groups into the Users File.
+
+        - Initial User Identity [unique key] - The identity of a users and systems to seed the Users File. The name of
+            each property must be unique, for example: "Initial User Identity A", "Initial User Identity B",
+            "Initial User Identity C" or "Initial User Identity 1", "Initial User Identity 2", "Initial User Identity 3"
+
+            NOTE: Any identity mapping rules specified in nifi.properties will also be applied to the user identities,
+            so the values should be the unmapped identities (i.e. full DN from a certificate).
+    -->
+    <userGroupProvider>
+        <identifier>file-user-group-provider</identifier>
+        <class>org.apache.nifi.authorization.FileUserGroupProvider</class>
+        <property name="Users File">./conf/users.xml</property>
+        <property name="Legacy Authorized Users File"></property>
+
+        <property name="Initial User Identity 1">CN=bozidar_proevski</property>
+{% for nifi in groups['nificontainers'] %}
+        <property name="Initial User Identity {{ loop.index +1 }}">CN={{ nifi }}</property>
+{% endfor %}
+    </userGroupProvider>
+
+    <!--
+        The LdapUserGroupProvider will retrieve users and groups from an LDAP server. The users and groups
+        are not configurable.
+
+        'Authentication Strategy' - How the connection to the LDAP server is authenticated. Possible
+            values are ANONYMOUS, SIMPLE, LDAPS, or START_TLS.
+
+        'Manager DN' - The DN of the manager that is used to bind to the LDAP server to search for users.
+        'Manager Password' - The password of the manager that is used to bind to the LDAP server to
+            search for users.
+
+        'TLS - Keystore' - Path to the Keystore that is used when connecting to LDAP using LDAPS or START_TLS.
+        'TLS - Keystore Password' - Password for the Keystore that is used when connecting to LDAP
+            using LDAPS or START_TLS.
+        'TLS - Keystore Type' - Type of the Keystore that is used when connecting to LDAP using
+            LDAPS or START_TLS (i.e. JKS or PKCS12).
+        'TLS - Truststore' - Path to the Truststore that is used when connecting to LDAP using LDAPS or START_TLS.
+        'TLS - Truststore Password' - Password for the Truststore that is used when connecting to
+            LDAP using LDAPS or START_TLS.
+        'TLS - Truststore Type' - Type of the Truststore that is used when connecting to LDAP using
+            LDAPS or START_TLS (i.e. JKS or PKCS12).
+        'TLS - Client Auth' - Client authentication policy when connecting to LDAP using LDAPS or START_TLS.
+            Possible values are REQUIRED, WANT, NONE.
+        'TLS - Protocol' - Protocol to use when connecting to LDAP using LDAPS or START_TLS. (i.e. TLS,
+            TLSv1.1, TLSv1.2, etc).
+        'TLS - Shutdown Gracefully' - Specifies whether the TLS should be shut down gracefully
+            before the target context is closed. Defaults to false.
+
+        'Referral Strategy' - Strategy for handling referrals. Possible values are FOLLOW, IGNORE, THROW.
+        'Connect Timeout' - Duration of connect timeout. (i.e. 10 secs).
+        'Read Timeout' - Duration of read timeout. (i.e. 10 secs).
+
+        'Url' - Space-separated list of URLs of the LDAP servers (i.e. ldap://<hostname>:<port>).
+        'Page Size' - Sets the page size when retrieving users and groups. If not specified, no paging is performed.
+        'Sync Interval' - Duration of time between syncing users and groups (i.e. 30 mins). Minimum allowable value is 10 secs.
+
+        'User Search Base' - Base DN for searching for users (i.e. ou=users,o=nifi). Required to search users.
+        'User Object Class' - Object class for identifying users (i.e. person). Required if searching users.
+        'User Search Scope' - Search scope for searching users (ONE_LEVEL, OBJECT, or SUBTREE). Required if searching users.
+        'User Search Filter' - Filter for searching for users against the 'User Search Base' (i.e. (memberof=cn=team1,ou=groups,o=nifi) ). Optional.
+        'User Identity Attribute' - Attribute to use to extract user identity (i.e. cn). Optional. If not set, the entire DN is used.
+        'User Group Name Attribute' - Attribute to use to define group membership (i.e. memberof). Optional. If not set
+            group membership will not be calculated through the users. Will rely on group membership being defined
+            through 'Group Member Attribute' if set. The value of this property is the name of the attribute in the user ldap entry that
+            associates them with a group. The value of that user attribute could be a dn or group name for instance. What value is expected
+            is configured in the 'User Group Name Attribute - Referenced Group Attribute'.
+        'User Group Name Attribute - Referenced Group Attribute' - If blank, the value of the attribute defined in 'User Group Name Attribute'
+            is expected to be the full dn of the group. If not blank, this property will define the attribute of the group ldap entry that
+            the value of the attribute defined in 'User Group Name Attribute' is referencing (i.e. name). Use of this property requires that
+            'Group Search Base' is also configured.
+
+        'Group Search Base' - Base DN for searching for groups (i.e. ou=groups,o=nifi). Required to search groups.
+        'Group Object Class' - Object class for identifying groups (i.e. groupOfNames). Required if searching groups.
+        'Group Search Scope' - Search scope for searching groups (ONE_LEVEL, OBJECT, or SUBTREE). Required if searching groups.
+        'Group Search Filter' - Filter for searching for groups against the 'Group Search Base'. Optional.
+        'Group Name Attribute' - Attribute to use to extract group name (i.e. cn). Optional. If not set, the entire DN is used.
+        'Group Member Attribute' - Attribute to use to define group membership (i.e. member). Optional. If not set
+            group membership will not be calculated through the groups. Will rely on group membership being defined
+            through 'User Group Name Attribute' if set. The value of this property is the name of the attribute in the group ldap entry that
+            associates them with a user. The value of that group attribute could be a dn or memberUid for instance. What value is expected
+            is configured in the 'Group Member Attribute - Referenced User Attribute'. (i.e. member: cn=User 1,ou=users,o=nifi vs. memberUid: user1)
+        'Group Member Attribute - Referenced User Attribute' - If blank, the value of the attribute defined in 'Group Member Attribute'
+            is expected to be the full dn of the user. If not blank, this property will define the attribute of the user ldap entry that
+            the value of the attribute defined in 'Group Member Attribute' is referencing (i.e. uid). Use of this property requires that
+            'User Search Base' is also configured. (i.e. member: cn=User 1,ou=users,o=nifi vs. memberUid: user1)
+
+        NOTE: Any identity mapping rules specified in nifi.properties will also be applied to the user identities.
+            Group names are not mapped.
+    -->
+    <!-- To enable the ldap-user-group-provider remove 2 lines. This is 1 of 2.
+    <userGroupProvider>
+        <identifier>ldap-user-group-provider</identifier>
+        <class>org.apache.nifi.ldap.tenants.LdapUserGroupProvider</class>
+        <property name="Authentication Strategy">START_TLS</property>
+
+        <property name="Manager DN"></property>
+        <property name="Manager Password"></property>
+
+        <property name="TLS - Keystore"></property>
+        <property name="TLS - Keystore Password"></property>
+        <property name="TLS - Keystore Type"></property>
+        <property name="TLS - Truststore"></property>
+        <property name="TLS - Truststore Password"></property>
+        <property name="TLS - Truststore Type"></property>
+        <property name="TLS - Client Auth"></property>
+        <property name="TLS - Protocol"></property>
+        <property name="TLS - Shutdown Gracefully"></property>
+
+        <property name="Referral Strategy">FOLLOW</property>
+        <property name="Connect Timeout">10 secs</property>
+        <property name="Read Timeout">10 secs</property>
+
+        <property name="Url"></property>
+        <property name="Page Size"></property>
+        <property name="Sync Interval">30 mins</property>
+
+        <property name="User Search Base"></property>
+        <property name="User Object Class">person</property>
+        <property name="User Search Scope">ONE_LEVEL</property>
+        <property name="User Search Filter"></property>
+        <property name="User Identity Attribute"></property>
+        <property name="User Group Name Attribute"></property>
+        <property name="User Group Name Attribute - Referenced Group Attribute"></property>
+
+        <property name="Group Search Base"></property>
+        <property name="Group Object Class">group</property>
+        <property name="Group Search Scope">ONE_LEVEL</property>
+        <property name="Group Search Filter"></property>
+        <property name="Group Name Attribute"></property>
+        <property name="Group Member Attribute"></property>
+        <property name="Group Member Attribute - Referenced User Attribute"></property>
+    </userGroupProvider>
+    To enable the ldap-user-group-provider remove 2 lines. This is 2 of 2. -->
+
+    <!--
+        The CompositeUserGroupProvider will provide support for retrieving users and groups from multiple sources.
+
+        - User Group Provider [unique key] - The identifier of user group providers to load from. The name of
+            each property must be unique, for example: "User Group Provider A", "User Group Provider B",
+            "User Group Provider C" or "User Group Provider 1", "User Group Provider 2", "User Group Provider 3"
+
+            NOTE: Any identity mapping rules specified in nifi.properties are not applied in this implementation. This behavior
+            would need to be applied by the base implementation.
+    -->
+    <!-- To enable the composite-user-group-provider remove 2 lines. This is 1 of 2.
+    <userGroupProvider>
+        <identifier>composite-user-group-provider</identifier>
+        <class>org.apache.nifi.authorization.CompositeUserGroupProvider</class>
+        <property name="User Group Provider 1"></property>
+    </userGroupProvider>
+    To enable the composite-user-group-provider remove 2 lines. This is 2 of 2. -->
+
+    <!--
+        The CompositeConfigurableUserGroupProvider will provide support for retrieving users and groups from multiple sources.
+        Additionally, a single configurable user group provider is required. Users from the configurable user group provider
+        are configurable, however users loaded from one of the User Group Provider [unique key] will not be.
+
+        - Configurable User Group Provider - A configurable user group provider.
+
+        - User Group Provider [unique key] - The identifier of user group providers to load from. The name of
+            each property must be unique, for example: "User Group Provider A", "User Group Provider B",
+            "User Group Provider C" or "User Group Provider 1", "User Group Provider 2", "User Group Provider 3"
+
+            NOTE: Any identity mapping rules specified in nifi.properties are not applied in this implementation. This behavior
+            would need to be applied by the base implementation.
+    -->
+    <!-- To enable the composite-configurable-user-group-provider remove 2 lines. This is 1 of 2.
+    <userGroupProvider>
+        <identifier>composite-configurable-user-group-provider</identifier>
+        <class>org.apache.nifi.authorization.CompositeConfigurableUserGroupProvider</class>
+        <property name="Configurable User Group Provider">file-user-group-provider</property>
+        <property name="User Group Provider 1"></property>
+    </userGroupProvider>
+    To enable the composite-configurable-user-group-provider remove 2 lines. This is 2 of 2. -->
+
+    <!--
+        The FileAccessPolicyProvider will provide support for managing access policies which is backed by a file
+        on the local file system.
+
+        - User Group Provider - The identifier for an User Group Provider defined above that will be used to access
+            users and groups for use in the managed access policies.
+
+        - Authorizations File - The file where the FileAccessPolicyProvider will store policies.
+
+        - Initial Admin Identity - The identity of an initial admin user that will be granted access to the UI and
+            given the ability to create additional users, groups, and policies. The value of this property could be
+            a DN when using certificates or LDAP, or a Kerberos principal. This property will only be used when there
+            are no other policies defined. If this property is specified then a Legacy Authorized Users File can not be specified.
+
+            NOTE: Any identity mapping rules specified in nifi.properties will also be applied to the initial admin identity,
+            so the value should be the unmapped identity. This identity must be found in the configured User Group Provider.
+
+        - Legacy Authorized Users File - The full path to an existing authorized-users.xml that will be automatically
+            converted to the new authorizations model. If this property is specified then an Initial Admin Identity can
+            not be specified, and this property will only be used when there are no other users, groups, and policies defined.
+
+            NOTE: Any users in the legacy users file must be found in the configured User Group Provider.
+
+        - Node Identity [unique key] - The identity of a NiFi cluster node. When clustered, a property for each node
+            should be defined, so that every node knows about every other node. If not clustered these properties can be ignored.
+            The name of each property must be unique, for example for a three node cluster:
+            "Node Identity A", "Node Identity B", "Node Identity C" or "Node Identity 1", "Node Identity 2", "Node Identity 3"
+
+            NOTE: Any identity mapping rules specified in nifi.properties will also be applied to the node identities,
+            so the values should be the unmapped identities (i.e. full DN from a certificate). This identity must be found
+            in the configured User Group Provider.
+
+        - Node Group - The name of a group containing NiFi cluster nodes. The typical use for this is when nodes are dynamically
+            added/removed from the cluster.
+
+            NOTE: The group must exist before starting NiFi.
+    -->
+    <accessPolicyProvider>
+        <identifier>file-access-policy-provider</identifier>
+        <class>org.apache.nifi.authorization.FileAccessPolicyProvider</class>
+        <property name="User Group Provider">file-user-group-provider</property>
+        <property name="Authorizations File">./conf/authorizations.xml</property>
+        <property name="Initial Admin Identity">CN=bozidar_proevski</property>
+        <property name="Legacy Authorized Users File"></property>
+{% for nifi in groups['nificontainers'] %}
+        <property name="Node Identity {{ loop.index }}">CN={{ nifi }}</property>
+{% endfor %}
+        <property name="Node Group"></property>
+    </accessPolicyProvider>
+
+    <!--
+        The StandardManagedAuthorizer. This authorizer implementation must be configured with the
+        Access Policy Provider which it will use to access and manage users, groups, and policies.
+        These users, groups, and policies will be used to make all access decisions during authorization
+        requests.
+
+        - Access Policy Provider - The identifier for an Access Policy Provider defined above.
+    -->
+    <authorizer>
+        <identifier>managed-authorizer</identifier>
+        <class>org.apache.nifi.authorization.StandardManagedAuthorizer</class>
+        <property name="Access Policy Provider">file-access-policy-provider</property>
+    </authorizer>
+
+    <!--
+        NOTE: This Authorizer has been replaced with the more granular approach configured above with the Standard
+        Managed Authorizer. However, it is still available for backwards compatibility reasons.
+
+        The FileAuthorizer is NiFi's provided authorizer and has the following properties:
+
+        - Authorizations File - The file where the FileAuthorizer will store policies.
+
+        - Users File - The file where the FileAuthorizer will store users and groups.
+
+        - Initial Admin Identity - The identity of an initial admin user that will be granted access to the UI and
+            given the ability to create additional users, groups, and policies. The value of this property could be
+            a DN when using certificates or LDAP, or a Kerberos principal. This property will only be used when there
+            are no other users, groups, and policies defined. If this property is specified then a Legacy Authorized
+            Users File can not be specified.
+
+            NOTE: Any identity mapping rules specified in nifi.properties will also be applied to the initial admin identity,
+            so the value should be the unmapped identity.
+
+        - Legacy Authorized Users File - The full path to an existing authorized-users.xml that will be automatically
+            converted to the new authorizations model. If this property is specified then an Initial Admin Identity can
+            not be specified, and this property will only be used when there are no other users, groups, and policies defined.
+
+        - Node Identity [unique key] - The identity of a NiFi cluster node. When clustered, a property for each node
+            should be defined, so that every node knows about every other node. If not clustered these properties can be ignored.
+            The name of each property must be unique, for example for a three node cluster:
+            "Node Identity A", "Node Identity B", "Node Identity C" or "Node Identity 1", "Node Identity 2", "Node Identity 3"
+
+            NOTE: Any identity mapping rules specified in nifi.properties will also be applied to the node identities,
+            so the values should be the unmapped identities (i.e. full DN from a certificate).
+    -->
+    <!-- <authorizer>
+        <identifier>file-provider</identifier>
+        <class>org.apache.nifi.authorization.FileAuthorizer</class>
+        <property name="Authorizations File">./conf/authorizations.xml</property>
+        <property name="Users File">./conf/users.xml</property>
+        <property name="Initial Admin Identity"></property>
+        <property name="Legacy Authorized Users File"></property>
+
+        <property name="Node Identity 1"></property>
+    </authorizer>
+    -->
+</authorizers>
diff --git a/roles/nifi/templates/nifi.properties.j2 b/roles/nifi/templates/nifi.properties.j2
new file mode 100644
index 0000000000000000000000000000000000000000..e655879e0e3b6e7ea94d047ddcf5e6706c821892
--- /dev/null
+++ b/roles/nifi/templates/nifi.properties.j2
@@ -0,0 +1,256 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Core Properties #
+nifi.flow.configuration.file=./conf/flow.xml.gz
+nifi.flow.configuration.archive.enabled=true
+nifi.flow.configuration.archive.dir=./conf/archive/
+nifi.flow.configuration.archive.max.time=30 days
+nifi.flow.configuration.archive.max.storage=500 MB
+nifi.flow.configuration.archive.max.count=
+nifi.flowcontroller.autoResumeState=true
+nifi.flowcontroller.graceful.shutdown.period=10 sec
+nifi.flowservice.writedelay.interval=500 ms
+nifi.administrative.yield.duration=30 sec
+# If a component has no work to do (is "bored"), how long should we wait before checking again for work?
+nifi.bored.yield.duration=10 millis
+nifi.queue.backpressure.count=10000
+nifi.queue.backpressure.size=1 GB
+
+nifi.authorizer.configuration.file=./conf/authorizers.xml
+nifi.login.identity.provider.configuration.file=./conf/login-identity-providers.xml
+nifi.templates.directory=./conf/templates
+nifi.ui.banner.text=
+nifi.ui.autorefresh.interval=30 sec
+nifi.nar.library.directory=./lib
+nifi.nar.library.autoload.directory=./extensions
+nifi.nar.working.directory=./work/nar/
+nifi.documentation.working.directory=./work/docs/components
+
+####################
+# State Management #
+####################
+nifi.state.management.configuration.file=./conf/state-management.xml
+# The ID of the local state provider
+nifi.state.management.provider.local=local-provider
+# The ID of the cluster-wide state provider. This will be ignored if NiFi is not clustered but must be populated if running in a cluster.
+nifi.state.management.provider.cluster=zk-provider
+# Specifies whether or not this instance of NiFi should run an embedded ZooKeeper server
+nifi.state.management.embedded.zookeeper.start=false
+# Properties file that provides the ZooKeeper properties to use if <nifi.state.management.embedded.zookeeper.start> is set to true
+nifi.state.management.embedded.zookeeper.properties=./conf/zookeeper.properties
+
+
+# H2 Settings
+nifi.database.directory=./database_repository
+nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
+
+# FlowFile Repository
+nifi.flowfile.repository.implementation=org.apache.nifi.controller.repository.WriteAheadFlowFileRepository
+nifi.flowfile.repository.wal.implementation=org.apache.nifi.wali.SequentialAccessWriteAheadLog
+nifi.flowfile.repository.directory=./flowfile_repository
+nifi.flowfile.repository.partitions=256
+nifi.flowfile.repository.checkpoint.interval=2 mins
+nifi.flowfile.repository.always.sync=false
+
+nifi.swap.manager.implementation=org.apache.nifi.controller.FileSystemSwapManager
+nifi.queue.swap.threshold=20000
+nifi.swap.in.period=5 sec
+nifi.swap.in.threads=1
+nifi.swap.out.period=5 sec
+nifi.swap.out.threads=4
+
+# Content Repository
+nifi.content.repository.implementation=org.apache.nifi.controller.repository.FileSystemRepository
+nifi.content.claim.max.appendable.size=1 MB
+nifi.content.claim.max.flow.files=100
+nifi.content.repository.directory.default=./content_repository
+nifi.content.repository.archive.max.retention.period=12 hours
+nifi.content.repository.archive.max.usage.percentage=50%
+nifi.content.repository.archive.enabled=true
+nifi.content.repository.always.sync=false
+nifi.content.viewer.url=../nifi-content-viewer/
+
+# Provenance Repository Properties
+nifi.provenance.repository.implementation=org.apache.nifi.provenance.WriteAheadProvenanceRepository
+nifi.provenance.repository.debug.frequency=1_000_000
+nifi.provenance.repository.encryption.key.provider.implementation=
+nifi.provenance.repository.encryption.key.provider.location=
+nifi.provenance.repository.encryption.key.id=
+nifi.provenance.repository.encryption.key=
+
+# Persistent Provenance Repository Properties
+nifi.provenance.repository.directory.default=./provenance_repository
+nifi.provenance.repository.max.storage.time=24 hours
+nifi.provenance.repository.max.storage.size=1 GB
+nifi.provenance.repository.rollover.time=30 secs
+nifi.provenance.repository.rollover.size=100 MB
+nifi.provenance.repository.query.threads=2
+nifi.provenance.repository.index.threads=2
+nifi.provenance.repository.compress.on.rollover=true
+nifi.provenance.repository.always.sync=false
+# Comma-separated list of fields. Fields that are not indexed will not be searchable. Valid fields are:
+# EventType, FlowFileUUID, Filename, TransitURI, ProcessorID, AlternateIdentifierURI, Relationship, Details
+nifi.provenance.repository.indexed.fields=EventType, FlowFileUUID, Filename, ProcessorID, Relationship
+# FlowFile Attributes that should be indexed and made searchable.  Some examples to consider are filename, uuid, mime.type
+nifi.provenance.repository.indexed.attributes=
+# Large values for the shard size will result in more Java heap usage when searching the Provenance Repository
+# but should provide better performance
+nifi.provenance.repository.index.shard.size=500 MB
+# Indicates the maximum length that a FlowFile attribute can be when retrieving a Provenance Event from
+# the repository. If the length of any attribute exceeds this value, it will be truncated when the event is retrieved.
+nifi.provenance.repository.max.attribute.length=65536
+nifi.provenance.repository.concurrent.merge.threads=2
+
+
+# Volatile Provenance Respository Properties
+nifi.provenance.repository.buffer.size=100000
+
+# Component Status Repository
+nifi.components.status.repository.implementation=org.apache.nifi.controller.status.history.VolatileComponentStatusRepository
+nifi.components.status.repository.buffer.size=1440
+nifi.components.status.snapshot.frequency=1 min
+
+# Site to Site properties
+nifi.remote.input.host={{ inventory_hostname }}
+nifi.remote.input.secure=true
+nifi.remote.input.socket.port=10443
+nifi.remote.input.http.enabled=true
+nifi.remote.input.http.transaction.ttl=30 sec
+nifi.remote.contents.cache.expiration=30 secs
+
+# web properties #
+nifi.web.war.directory=./lib
+nifi.web.http.host=
+nifi.web.http.port=
+nifi.web.http.network.interface.default=
+nifi.web.https.host={{ inventory_hostname }}
+nifi.web.https.port=9443
+nifi.web.https.network.interface.default=
+nifi.web.jetty.working.directory=./work/jetty
+nifi.web.jetty.threads=200
+nifi.web.max.header.size=16 KB
+nifi.web.proxy.context.path=/nifi
+nifi.web.proxy.host={{ dslproxy }}
+
+# security properties #
+nifi.sensitive.props.key=
+nifi.sensitive.props.key.protected=
+nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
+nifi.sensitive.props.provider=BC
+nifi.sensitive.props.additional.keys=
+
+nifi.security.keystore=./conf/{{ inventory_hostname }}.p12
+nifi.security.keystoreType=pkcs12
+nifi.security.keystorePasswd={{ kspass}}
+#nifi.security.keyPasswd=IP7Jgn7amiAYi3LRSRk5LGg3t4zlfh0kEKcAaaoxHDo
+nifi.security.truststore=./conf/cacerts.jks
+nifi.security.truststoreType=jks
+nifi.security.truststorePasswd={{ tspass}}
+nifi.security.user.authorizer=managed-authorizer
+nifi.security.user.login.identity.provider=
+nifi.security.ocsp.responder.url=
+nifi.security.ocsp.responder.certificate=
+
+# OpenId Connect SSO Properties #
+nifi.security.user.oidc.discovery.url=
+nifi.security.user.oidc.connect.timeout=5 secs
+nifi.security.user.oidc.read.timeout=5 secs
+nifi.security.user.oidc.client.id=
+nifi.security.user.oidc.client.secret=
+nifi.security.user.oidc.preferred.jwsalgorithm=
+
+# Apache Knox SSO Properties #
+nifi.security.user.knox.url=
+nifi.security.user.knox.publicKey=
+nifi.security.user.knox.cookieName=hadoop-jwt
+nifi.security.user.knox.audiences=
+
+# Identity Mapping Properties #
+# These properties allow normalizing user identities such that identities coming from different identity providers
+# (certificates, LDAP, Kerberos) can be treated the same internally in NiFi. The following example demonstrates normalizing
+# DNs from certificates and principals from Kerberos into a common identity string:
+#
+# nifi.security.identity.mapping.pattern.dn=^CN=(.*?), OU=(.*?), O=(.*?), L=(.*?), ST=(.*?), C=(.*?)$
+# nifi.security.identity.mapping.value.dn=$1@$2
+# nifi.security.identity.mapping.transform.dn=NONE
+# nifi.security.identity.mapping.pattern.kerb=^(.*?)/instance@(.*?)$
+# nifi.security.identity.mapping.value.kerb=$1@$2
+# nifi.security.identity.mapping.transform.kerb=UPPER
+
+# Group Mapping Properties #
+# These properties allow normalizing group names coming from external sources like LDAP. The following example
+# lowercases any group name.
+#
+# nifi.security.group.mapping.pattern.anygroup=^(.*)$
+# nifi.security.group.mapping.value.anygroup=$1
+# nifi.security.group.mapping.transform.anygroup=LOWER
+
+# cluster common properties (all nodes must have same values) #
+nifi.cluster.protocol.heartbeat.interval=5 sec
+nifi.cluster.protocol.is.secure=true
+
+# cluster node properties (only configure for cluster nodes) #
+nifi.cluster.is.node=true
+nifi.cluster.node.address={{ inventory_hostname }}
+nifi.cluster.node.protocol.port=11443
+nifi.cluster.node.protocol.threads=10
+nifi.cluster.node.protocol.max.threads=50
+nifi.cluster.node.event.history.size=25
+nifi.cluster.node.connection.timeout=5 sec
+nifi.cluster.node.read.timeout=5 sec
+nifi.cluster.node.max.concurrent.requests=100
+nifi.cluster.firewall.file=
+nifi.cluster.flow.election.max.wait.time=1 min
+nifi.cluster.flow.election.max.candidates=
+
+# cluster load balancing properties #
+nifi.cluster.load.balance.host=
+nifi.cluster.load.balance.port=6342
+nifi.cluster.load.balance.connections.per.node=4
+nifi.cluster.load.balance.max.thread.count=8
+nifi.cluster.load.balance.comms.timeout=30 sec
+
+# zookeeper properties, used for cluster management #
+nifi.zookeeper.connect.string=dsoclab-zookeeper:2181
+nifi.zookeeper.connect.timeout=3 secs
+nifi.zookeeper.session.timeout=3 secs
+nifi.zookeeper.root.node=/nifi
+
+# Zookeeper properties for the authentication scheme used when creating acls on znodes used for cluster management
+# Values supported for nifi.zookeeper.auth.type are "default", which will apply world/anyone rights on znodes
+# and "sasl" which will give rights to the sasl/kerberos identity used to authenticate the nifi node
+# The identity is determined using the value in nifi.kerberos.service.principal and the removeHostFromPrincipal
+# and removeRealmFromPrincipal values (which should align with the kerberos.removeHostFromPrincipal and kerberos.removeRealmFromPrincipal
+# values configured on the zookeeper server).
+nifi.zookeeper.auth.type=
+nifi.zookeeper.kerberos.removeHostFromPrincipal=
+nifi.zookeeper.kerberos.removeRealmFromPrincipal=
+
+# kerberos #
+nifi.kerberos.krb5.file=
+
+# kerberos service principal #
+nifi.kerberos.service.principal=
+nifi.kerberos.service.keytab.location=
+
+# kerberos spnego principal #
+nifi.kerberos.spnego.principal=
+nifi.kerberos.spnego.keytab.location=
+nifi.kerberos.spnego.authentication.expiration=12 hours
+
+# external properties files for variable registry
+# supports a comma delimited list of file locations
+nifi.variable.registry.properties=
diff --git a/roles/nifi/tests/inventory b/roles/nifi/tests/inventory
deleted file mode 100644
index 878877b0776c44f55fc4e458f70840f31da5bb01..0000000000000000000000000000000000000000
--- a/roles/nifi/tests/inventory
+++ /dev/null
@@ -1,2 +0,0 @@
-localhost
-
diff --git a/roles/nifi/tests/test.yml b/roles/nifi/tests/test.yml
deleted file mode 100644
index 8d8452925b0cd8d47ac7883baa2ed32af6f348e9..0000000000000000000000000000000000000000
--- a/roles/nifi/tests/test.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-- hosts: localhost
-  remote_user: root
-  roles:
-    - nifi
\ No newline at end of file
diff --git a/roles/nifi/vars/main.yml b/roles/nifi/vars/main.yml
index e3fa9199ef3f856b2d6c8a59cbdf222406e063fb..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644
--- a/roles/nifi/vars/main.yml
+++ b/roles/nifi/vars/main.yml
@@ -1,2 +0,0 @@
----
-# vars file for nifi
\ No newline at end of file
diff --git a/roles/zookeeper/defaults/main.yml b/roles/zookeeper/defaults/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/roles/zookeeper/handlers/main.yml b/roles/zookeeper/handlers/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/roles/zookeeper/meta/main.yml b/roles/zookeeper/meta/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/roles/zookeeper/tasks/main.yml b/roles/zookeeper/tasks/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/roles/zookeeper/vars/main.yml b/roles/zookeeper/vars/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/soctools-inventory b/soctools-inventory
new file mode 100644
index 0000000000000000000000000000000000000000..5f453c399ec17c7d7453350ab3fdf96d1e5f4ba2
--- /dev/null
+++ b/soctools-inventory
@@ -0,0 +1,11 @@
+[dsldev]
+localhost ansible_connection=local
+
+[nificontainers]
+dsoclab-nifi-1 ansible_connection=docker
+dsoclab-nifi-2 ansible_connection=docker
+dsoclab-nifi-3 ansible_connection=docker
+
+[nginx]
+dsoclab-nginx ansible_connection=docker
+
diff --git a/soctools.yml b/soctools.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c25b56f32c95d5973e64ce70d6a1d7b4c3eae539
--- /dev/null
+++ b/soctools.yml
@@ -0,0 +1,10 @@
+---
+
+- name: Start soctools cluster
+  import_playbook: startsoctools.yml
+  when: "'start' in ansible_run_tags"
+
+- name: Stop soctools cluster
+  import_playbook: stopsoctools.yml
+  when: "'stop' in ansible_run_tags"
+
diff --git a/startsoctools.yml b/startsoctools.yml
new file mode 100644
index 0000000000000000000000000000000000000000..216a9c9c1ca2416a99f68ebc49b021fe786a2a23
--- /dev/null
+++ b/startsoctools.yml
@@ -0,0 +1,17 @@
+---
+
+- name: Start docker containers 
+  hosts: dsldev
+  roles:
+    - docker
+
+- name: Reconfigure and start nginx
+  hosts: nginx
+  roles:
+    - nginx
+
+- name: Reconfigure and start NiFi
+  hosts: nificontainers
+  roles:
+    - nifi
+
diff --git a/stopsoctools.yml b/stopsoctools.yml
new file mode 100644
index 0000000000000000000000000000000000000000..045c3f06243bc3358245c8bbf219d68e9f89a9a5
--- /dev/null
+++ b/stopsoctools.yml
@@ -0,0 +1,12 @@
+---
+
+- name: Get flow from Nifi
+  hosts: nificontainers
+  roles:
+    - nifi
+
+- name: Stop all containers
+  hosts: dsldev
+  roles:
+    - docker
+