Ansible Encryption Module Vault

Keywords: Linux ansible network

Ansible-vault can be encrypted or decrypted as long as it is used to encrypt configuration files. The specific ways of using ansible-vault are as follows:

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

You can see many subcommands:

  • create: create a new file and encrypt it directly
  • decrypt: decrypted file
  • Edit: Used to edit ansible-vault encrypted files
  • encrypy: Encrypted file
  • encrypt_strin: Encrypted string, which is retrieved from the command line
  • view: view encrypted files

Encrypted file

First create a file and write something to it:

[root@Ansible ~]# echo "123456" > pass.txt
[root@Ansible ~]# cat pass.txt 
123456
[root@Ansible ~]# 

Then encrypt the file with ansible-vault encrypt:

[root@Ansible ~]# ansible-vault encrypt pass.txt
New Vault password: 
Confirm New Vault password: 
Encryption successful
[root@Ansible ~]# 

The password is required here.

Now go and open the file and see:

[root@Ansible ~]# cat pass.txt 
$ANSIBLE_VAULT;1.1;AES256
62633762393035316438663662343964656465376634393131313466313536336361333163313238
6162356161653365623961353533356264386134653830640a353531623635653337636564383763
38316636383334323533363666383963666161633332663461316338333332623434376162326265
6565623130373539330a313737646431626131336637663033656664383932393934633337383666
6334
[root@Ansible ~]# 

To view the contents of the file, you can use the ansible-vault view command:

[root@Ansible ~]# ansible-vault view pass.txt
Vault password: 
123456
[root@Ansible ~]# 

To restore a file, you can use the ansible-vault decrypt command:

[root@Ansible ~]# ansible-vault decrypt pass.txt
Vault password: 
Decryption successful
[root@Ansible ~]# cat pass.txt 
123456
[root@Ansible ~]# 

Encrypted Profile

The above demonstration is just a separate use of a small tool. Here's a look at the use of the combined ansible command.
Add a new host to the / etc/ansible/hosts file for testing:

host1 ansible_host=127.0.0.1 ansible_connection=local

Here's the local machine.

Then create the host's variable file / etc/ansible/host_vars/host1 separately and write some variables randomly:

---
key1: vaule1
key2: VALUE2

Let's first verify that:

[root@Ansible ~]# ansible host1 -a "echo key1={{key1}}, key2={{key2}}" 
host1 | CHANGED | rc=0 >>
key1=vaule1, key2=VALUE2
[root@Ansible ~]# 

Now encrypt the configuration file:

[root@Ansible ~]# ansible-vault encrypt /etc/ansible/host_vars/host1 
New Vault password: 
Confirm New Vault password: 
Encryption successful
[root@Ansible ~]# ansible host1 -a "echo key1={{key1}}, key2={{key2}}" 
ERROR! Attempting to decrypt but no vault secrets found
[root@Ansible ~]# 

It's no use to run after encryption. Here we need to add a parameter, ask-vault-pass, to provide the vault encrypted password:

[root@Ansible ~]# ansible host1 -a "echo key1={{key1}}, key2={{key2}}"  --ask-vault-pass
Vault password: 
host1 | CHANGED | rc=0 >>
key1=vaule1, key2=VALUE2
[root@Ansible ~]# 

Using File Encryption

Previously, passwords were used directly for encryption. For us, it's just encrypting one password with another. When using it, we do not use the original password, but the vault password.
For convenience, you can write the password in the file instead of typing it every time. However, it is always unsafe to write the password in plain text directly in the document. Using ansible-vault allows us to write passwords directly in the configuration (or a separate configuration file), and then encrypt files with sensitive information. The advantage of this is that all configuration information for the entire project is complete, including the passwords used in the project, and encrypted.
If you still don't want to enter a password every time you use it, you can also write the vault password to a file (plaintext), so that each time you use it, instead of manually entering, you can let ansible automatically get the password from the file.

Or reuse the previous configuration file, first decrypt the file:

[root@Ansible ~]# ansible-vault decrypt /etc/ansible/host_vars/host1 
Vault password: 
Decryption successful
[root@Ansible ~]# 

Then the file is generated and encrypted with the file:

[root@Ansible ~]# echo "123456" > vault-pass-file
[root@Ansible ~]# ansible host1 -a "echo key1={{key1}}, key2={{key2}}"
ERROR! Attempting to decrypt but no vault secrets found
[root@Ansible ~]# ansible host1 -a "echo key1={{key1}}, key2={{key2}}" --vault-password-file vault-pass-file
host1 | CHANGED | rc=0 >>
key1=vaule1, key2=VALUE2
[root@Ansible ~]# ansible host1 -a "echo key1={{key1}}, key2={{key2}}" --ask-vault-pass
Vault password: 
host1 | CHANGED | rc=0 >>
key1=vaule1, key2=VALUE2
[root@Ansible ~]#

Finally, I tried to use the password - ask-vault-pass effect in fact and use - vault-password-file is the same. One is to enter the password manually, and the other is to read the password string from the file.

Encrypted variables

The above encryption method is to encrypt the entire file. After encryption, sensitive and insensitive content in the file can not be seen, which is also inconvenient. One solution is to separate sensitive and insensitive content, write in different files, and only encrypt sensitive files. As in the previous example.
There is also a more flexible way to encrypt values using ansible-vault encrypt_string.

Encryption through files

Prepare documents for vault authentication:

[root@Ansible ~]# ansible-vault encrypt_string --vault-id vault-pass-file 'ssh_pass' --name 'key3'
key3: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          66613666353739356536663965336234383363373563353231353939303839313430616161336365
          6662336162386231316132633365366232363936613561650a313637643339323861626364633864
          32653666626333623961643866656235653764646333613533343231303734313862376232393734
          6563343539393264650a653438326463646364646338656339356236383537663135633935313239
          3664
Encryption successful
[root@Ansible ~]# 

The parameter -- name, which you can write without. After writing, the final generated content is keyed, otherwise it is only part of the generated value, and keys can be added manually.

Manual input password

If you don't use a file, instead of entering it manually, you can replace the specified file name with prompt, which will allow us to enter two password confirmations:

[root@Ansible ~]# ansible-vault encrypt_string --vault-id prompt 'ssh_pass' --name 'key3'
New vault password (default): 
Confirm new vault password (default): 
key3: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          30666333366265346464383165373062613165666130373066613930316364363432376336613938
          3131663337633863373539666134643661623734613330350a616661613934633335303365366266
          36363433613334386664663839346435656534373732333632303532303939383466303662396438
          3433633535333130350a323934373162356139363762383739386139333937666237613564313939
          3137
Encryption successful
[root@Ansible ~]#

Add user ID

The official documents are as follows:
https://docs.ansible.com/ansible/latest/network/getting_started/first_inventory.html#protecting-sensitive-variables-with-ansible-vault

In the case of official documents, the parameter values of vault-id are all represented by user names, separated by @ before the file name or prompt:

$ ansible-vault encrypt_string --vault-id steed@vault-pass-file 'ssh_pass' --name 'key3'
$ ansible-vault encrypt_string --vault-id steed@prompt 'ssh_pass' --name 'key3'

It seems useless, but the generated content will have this user ID. It's better to refer to the official advice as much as possible.

Generate a new variable to write the encrypted value to the configuration file:

[root@Ansible ~]# ansible-vault encrypt_string --vault-id steed@vault-pass-file 'ssh_pass' --name 'key3' >> /etc/ansible/host_vars/host1
[root@Ansible ~]# cat /etc/ansible/host_vars/host1
---
key1: vaule1
key2: VALUE2
key3: !vault |
          $ANSIBLE_VAULT;1.2;AES256;steed
          30343264386638623133383632353762356632643531643735653131663662623164303533373163
          3032646663363765386135386362376433326131333262310a366636396233653038646133336334
          62376532343064396639623835646563643663613530383739666239663565386364303931316637
          6137343936636266340a306233633039323537346332336132313766383039653565646230393662
          6332
[root@Ansible ~]# 

Here you can see the last line of ciphertext with the user identification information added before.

When using it, you can either use a password or specify a file:

[root@Ansible ~]# ansible host1 -a "echo key1={{key1}}, key3={{key3}}" --vault-id vault-pass-file 
host1 | CHANGED | rc=0 >>
key1=vaule1, key3=ssh_pass
[root@Ansible ~]# ansible host1 -a "echo key1={{key1}}, key3={{key3}}" --vault-password-file vault-pass-file 
host1 | CHANGED | rc=0 >>
key1=vaule1, key3=ssh_pass
[root@Ansible ~]# 

Official documents use - vault-id to specify the files for decryption, but try - vault-password-file is also possible.

Debug with debug module

Official advice is to debug with debug module:

To see the original value, you can use the debug module.

The previous example is unchanged, using debug module, simple can be used as follows:

[root@Ansible ~]# ansible host1 -m debug -a 'var="key1,key2,key3"' --vault-password-file vault-pass-file
host1 | SUCCESS => {
    "key1,key2,key3": "('vaule1', 'VALUE2', 'ssh_pass')"
}
[root@Ansible ~]# 

Posted by smilinmonki666 on Sun, 25 Aug 2019 02:17:17 -0700