diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 8b2d1d4a572136ab73abd276cc8d51f57885d1d2..02674d480b8abb9a123147660e50338e5d4707a4 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -25,9 +25,6 @@ terraform-single:
     - rm -fv clouds.yaml testsuite.auto.tfvars
     - ln -sfv $CLOUDS_YAML clouds.yaml
     - ln -sfv $TERRAFORM_CONFIG testsuite.auto.tfvars
-    - install -d -m 0700 ~/.ssh
-    - eval $(ssh-agent -s)
-    - ssh-add $SSH_KEY
     # https://github.com/terraform-provider-openstack/terraform-provider-openstack/issues/1160
     - touch ./secure.yml
   cache:
@@ -38,8 +35,10 @@ terraform-single:
       - "*.tfstate"
   script:
     - ./launch.sh -var type=hadoop-single -var flavor=standard.large -var n=0 -var domain=terra1 -var image=$IMAGE
-    - ansible -i ./inventory -m synchronize -a 'src=image/tests dest=/home/debian/ mode=push' master
-    - ansible -i ./inventory --become-user=debian -m command -a 'sh -xe ~/tests/run-tests.sh' master
+    - eval $(ssh-agent -s)
+    - ssh-add ./ssh-key.terra1.txt
+    - ansible -i ./inventory --become-user=debian -m synchronize -a 'src=image/tests dest=/home/debian/ mode=push' master
+    - ansible -i ./inventory --become-user=debian -m shell -a 'cd; sh -xe ~/tests/run-tests.sh' master
     - terraform destroy -auto-approve
   rules:
     - if: '$JOB =~ /all|test-single/'
@@ -58,8 +57,10 @@ terraform-cluster:
       - "*.tfstate"
   script:
     - ./launch.sh -var type=hadoop -var domain=terra2 -var image=$IMAGE
-    - ansible -i ./inventory -m synchronize -a 'src=image/tests dest=/home/debian/ mode=push' master
-    - ansible -i ./inventory --become-user=debian -m command -a 'sh -xe ~/tests/run-tests.sh' master
+    - eval $(ssh-agent -s)
+    - ssh-add ./ssh-key.terra2.txt
+    - ansible -i ./inventory --become-user=debian -m synchronize -a 'src=image/tests dest=/home/debian/ mode=push' master
+    - ansible -i ./inventory --become-user=debian -m shell -a 'cd; sh -xe ~/tests/run-tests.sh' master
     - terraform destroy -auto-approve
   rules:
     - if: '$JOB =~ /all|test-cluster/'
diff --git a/deploy.tf b/deploy.tf
index 8279a501c1f18588999770f94856d7cc981267ea..bed6ab3035509fe02c51160bb0138b6bd67cc88f 100644
--- a/deploy.tf
+++ b/deploy.tf
@@ -12,6 +12,11 @@ terraform {
 
 locals {
 	ord = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
+	keyfile = "ssh-key.${var.domain}.txt"
+}
+
+data "openstack_compute_keypair_v2" "userkey" {
+	name = var.ssh
 }
 
 data "template_file" "user_data_common" {
@@ -40,6 +45,7 @@ data "template_cloudinit_config" "ctx" {
 #cloud-config
 
 %{ if count.index != 0 ~}
+
 fs_setup:
 %{ for i in range(0, var.volumes) ~}
   - label: DATA${i + 1}
@@ -47,15 +53,48 @@ fs_setup:
     device: /dev/sd${local.ord[i + 1]}
     partition: none
 %{ endfor ~}
+
 mounts:
 %{ for i in range(0, var.volumes) ~}
   - [ LABEL=DATA${i + 1}, /data/${i + 1} ]
 %{ endfor ~}
 %{ endif ~}
+
+users:
+  - default
+  - name: deployadm
+    gecos: Deploy Admin
+    shell: /bin/bash
+    ssh_authorized_keys:
+      - ${openstack_compute_keypair_v2.localkey.public_key}
+    sudo:
+      - ALL=(ALL) NOPASSWD:ALL
+%{ if count.index == 0 ~}
+
+write_files:
+  - path: /home/deployadm/.ssh/id_rsa
+    owner: deployadm:deployadm
+    permissions: '0600'
+    content: |
+      ${indent(6, openstack_compute_keypair_v2.localkey.private_key)~}
+%{ endif ~}
+
+runcmd:
+  - chown -R deployadm:deployadm /home/deployadm
 EOT
 	}
 }
 
+resource "openstack_compute_keypair_v2" "localkey" {
+	name = var.domain
+}
+
+resource "local_file" "localkey" {
+    filename = local.keyfile
+	file_permission = "0600"
+    sensitive_content = openstack_compute_keypair_v2.localkey.private_key
+}
+
 resource "openstack_compute_instance_v2" "server" {
 	count = var.n + 1
 	name = data.template_file.user_data_common[count.index].vars.host
diff --git a/launch.sh b/launch.sh
index d3c3bafdf6661f235b17d67abb5ca3488c241637..383772d64d83f20df734ef661f5d9ccd1b930bdb 100755
--- a/launch.sh
+++ b/launch.sh
@@ -2,14 +2,6 @@
 
 TERRAFORM="`PATH=$PATH:. which terraform`"
 
-if ! ssh-add -l >/dev/null; then
-	cat <<EOF
-The ssh agent with ssh key required. Add key using:
-  ssh-add SSH_KEY_FILE
-EOF
-	exit 1
-fi
-
 if [ ! -s ./secrets.auto.tfvars ]; then
 	touch ./secrets.auto.tfvars
 	chmod 0600 ./secrets.auto.tfvars
@@ -29,9 +21,15 @@ $TERRAFORM apply -auto-approve "$@"
 touch config.json; chmod 0600 config.json
 $TERRAFORM output -json > config.json
 
+eval $(ssh-agent -s)
+trap "kill $SSH_AGENT_PID" INT TERM
+ssh-add ssh-key.*.txt
+
 if [ -z "$NO_DEPLOYMENT" ]; then
 	./orchestrate.py
 else
 	./orchestrate.py files ping init wait
 	./orchestrate.py -n deployment
 fi
+
+kill $SSH_AGENT_PID
diff --git a/orchestrate.py b/orchestrate.py
index 5520537687ab0c7fd8b96dd31da3276424c9d5d8..81e186688e3e8d6aa53821d96328f23005b215c5 100755
--- a/orchestrate.py
+++ b/orchestrate.py
@@ -84,7 +84,7 @@ hosts = j['hosts']['value']
 public_hosts = j['public_hosts']['value']
 master_hostname = config['master_hostname']
 master_ip = public_hosts[master_hostname]
-user = config['image_user']
+user = 'deployadm'
 secrets = config['secrets']
 t = config.get('type', None)
 ssh = [args.ssh] + args.ssh_opts.split(r' ')