In this example we are going to transfer our public and private SSH files to a server as well as a secret variable. To do that we will use Ansible vault. It is advised that you should never transfer sensitive data over network and never keep them in source control. If you have to then you have to encrypt them first.


Structure


.
├── Vagrantfile
└── provisioning
├── group_vars
│   └── vars
├── hosts.yml
└── site.yml

Files


Vagrantfile


# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/xenial64"

config.vm.define :vagrant do |vagrant|
vagrant.vm.hostname = "test"
vagrant.vm.network "private_network", ip: "192.168.99.30"
end

config.vm.provider :virtualbox do |virtualbox|
virtualbox.name = "test - 192.168.99.30 - 16.04"
end

config.vm.provision :ansible do |ansible|
ansible.raw_arguments = Shellwords.shellsplit(ENV["ANSIBLE_ARGS"]) if ENV["ANSIBLE_ARGS"]
ansible.verbose = "-vvv"
ansible.inventory_path = "provisioning/hosts.yml"
ansible.playbook = "provisioning/site.yml"
end
end

hosts.yml (version 1)


all:
hosts:
vagrant:
ansible_python_interpreter: /usr/bin/python3
ansible_host: 192.168.99.30

hosts.yml (version 2)


all:
hosts:
vagrant:
ansible_python_interpreter: /usr/bin/python3
ansible_connection: ssh
ansible_user: ubuntu
ansible_host: 192.168.99.30
ansible_port: 22

site.yml (version 1)


---
# This playbook sets up whole stack.

- name: Configurations to "vagrant" host
hosts: vagrant
remote_user: ubuntu
become: yes

tasks:
- name: Import variable file
include_vars:
file: "group_vars/vars"
no_log: true

- name: Copy SSH private key
copy:
content: "{{ ssh_private_key }}"
dest: "/home/ubuntu/.ssh/id_rsa"
owner: ubuntu
group: ubuntu
mode: 0600
no_log: true

- name: Copy SSH public key
copy:
content: "{{ ssh_public_key }}"
dest: "/home/ubuntu/.ssh/id_rsa.pub"
owner: ubuntu
group: ubuntu
mode: 0600
no_log: true

- name: Copy database password
copy:
content: "{{ database_password }}"
dest: "/home/ubuntu/database_password"
owner: ubuntu
group: ubuntu
no_log: true

site.yml (version 2)


---
# This playbook sets up whole stack.

- name: Configurations to "vagrant" host
hosts: vagrant

tasks:
- name: Import variable file
include_vars:
file: "group_vars/vars"
no_log: true

- name: Copy SSH private key
copy:
content: "{{ ssh_private_key }}"
dest: "/home/ubuntu/.ssh/id_rsa"
mode: 0600
no_log: true

- name: Copy SSH public key
copy:
content: "{{ ssh_public_key }}"
dest: "/home/ubuntu/.ssh/id_rsa.pub"
mode: 0600
no_log: true

- name: Copy database password
copy:
content: "{{ database_password }}"
dest: "/home/ubuntu/database_password"
no_log: true

vars


This is the one which we must encrypt and transfer.


# Do not include this in your source control
# Include it in your source control after encrypting it with vault

database_password: 123123

ssh_private_key: |
This is my
SSH private key "~/.ssh/id_rsa"

ssh_public_key: |
This is my
SSH public key "~/.ssh/id_rsa.pub"

Vault command options


First of all see what commands available for us to use.


$ ansible-vault -help

Usage: ansible-vault [create|decrypt|edit|encrypt|encrypt_string|rekey|view] [options] [vaultfile.yml]

encryption/decryption utility for Ansible data files

Options:
--ask-vault-pass ask for vault password
-h, --help show this help message and exit
--new-vault-id=NEW_VAULT_ID the new vault identity to use for rekey
--new-vault-password-file=NEW_VAULT_PASSWORD_FILES new vault password file for rekey
--vault-id=VAULT_IDS the vault identity to use
--vault-password-file=VAULT_PASSWORD_FILES vault password file
-v, --verbose verbose mode (-vvv for more, -vvvv to enable connection debugging)
--version show program's version number and exit

See 'ansible-vault --help' for more information on a specific command.

Create vault password file


First we need to create a ansible "vault password file" with command below. When it opens up an editor, you don't have to enter anything into it. Just save and exit.


$ ansible-vault create ~/ansible-vault-password.yml
New Vault password:
Confirm New Vault password:

Let's confirm if it has been created.


$ ls -l ~
-rw------- 1 inanzzz staff 355 2 Apr 15:42 ansible-vault-password.yml

$ cat ~/ansible-vault-password.yml
$ANSIBLE_VAULT;1.1;AES256
63373361313436303532636565643533316535346635623964363338346664383837383963386138
3666323839326133646436366530326166633034623264380a363563396463323763633362313035
33643431326539373366623431356261643435353339306162363434616630393163636161636636
6463653039653662350a383735316361356635613832303736663530353636623338393039396435
3132

This file will be used to encrypt and decrypt your sensitive variable files stored under "group_vars" or "host_vars" folders. This file must be stored somewhere safe so that no one can access to it. You will have to share it with others who needs access to the vault though.


Encrypt vars file


You can see the previous content of our vars file above. The command below will encrypt it by using ansible-vault-password.yml we created earlier.


$ ansible-vault encrypt provisioning/group_vars/vars --vault-password-file=~/ansible-vault-password.yml
Encryption successful

As you can see below, vars file is now secure.


$ cat provisioning/group_vars/vars
$ANSIBLE_VAULT;1.1;AES256
62313134636233643938646132643833313930396531613033653731366533643562643533336263
3836313035316261326533373633613161656638366534360a353865316563653764653233336266
38363861306432343734653136656338663838623331613830663933316664396337393334356130
6336663965383934370a666230366230366461353530363561323935376265383366313833336261
62383663323933356562356432643734666335353430333363656434303363336638643333653932
64353438336337396664623835323032393163626138303439306264303634393734316130336530
35323534626438313566653361663866383336313239353036323261346535393666303831346465
33386635323462646363616432623336396539616433653534643831366333623338373034633864
38333136623531373866646163363236613638373064623031386435373132623962393232396433
30313631393432306635373463343064336564613832333263356532393963383064623564316631
34343062313263613665636363643034343531613138323836656534373166356539643838366532
35643662343133626335343536633139303536306164383338326339613863393336656663306236
62346563626331386134666230323861613265626664343234626630643462363063643335653663
65333936353164633266656432306566663436303537313931656331323436376538393834326131
64326264653831353665656433653466383765353733376633623766353332323031386561363036
34346234313932353462

Decrypt vars file


All you have to do is, use the same command above but change encrypt to decrypt.


Building the box


# Asks vault password
$ ANSIBLE_ARGS='--ask-vault-pass' vagrant up

# Doesn't ask vault password (This will automatically use vault password)
$ ANSIBLE_ARGS='--vault-password-file=~/ansible-vault-password.yml' vagrant up

PLAY [Configurations to "vagrant" host] ****************************************

TASK [Gathering Facts] *********************************************************
ok: [vagrant]

TASK [Import variable file] ****************************************************
ok: [vagrant]

TASK [Copy SSH private key] ****************************************************
changed: [vagrant]

TASK [Copy SSH public key] *****************************************************
changed: [vagrant]

TASK [Copy database password] **************************************************
changed: [vagrant]

PLAY RECAP *********************************************************************
vagrant : ok=5 changed=3 unreachable=0 failed=0

Verify


ubuntu@test:~$ vagrant ssh

ubuntu@test:~$ ls -l ~
-rw-r--r-- 1 ubuntu ubuntu 6 Apr 2 16:51 database_password

ubuntu@test:~$ cat ~/database_password
123123

ubuntu@test:~$ ls -l ~/.ssh
-rw------- 1 ubuntu ubuntu 389 Apr 2 16:47 authorized_keys
-rw------- 1 ubuntu ubuntu 43 Apr 2 16:51 id_rsa
-rw------- 1 ubuntu ubuntu 46 Apr 2 16:51 id_rsa.pub

ubuntu@test:~$ cat ~/.ssh/id_rsa
This is my
SSH private key "~/.ssh/id_rsa"

ubuntu@test:~$ cat ~/.ssh/id_rsa.pub
This is my
SSH public key "~/.ssh/id_rsa.pub"