diff --git a/app/fields.py b/app/fields.py
index a5ed4fb40d699e07bd2abae891f98c7a0ae8c5c7..bc35c41688b7033285d31b8feef20c25d11da80c 100644
--- a/app/fields.py
+++ b/app/fields.py
@@ -13,6 +13,18 @@ import yaml
 from wtforms import TextAreaField
 
 
+# String can be encoded with ansible-vault and stored in yaml files
+# using the "!vault" tag.
+# To be used in a dynamic inventory, it shall be converted to the mapping
+# {"__ansible_vault": value} as it needs to be returned as JSON.
+def vault_constructor(loader, node):
+    value = loader.construct_scalar(node)
+    return {"__ansible_vault": value}
+
+
+yaml.SafeLoader.add_constructor("!vault", vault_constructor)
+
+
 class YAMLField(TextAreaField):
     """This field represents an HTML ``<textarea>`` used to input YAML"""
 
diff --git a/docs/_static/ansible/awx_ansible_vault_credential.png b/docs/_static/ansible/awx_ansible_vault_credential.png
new file mode 100644
index 0000000000000000000000000000000000000000..a50a1ad92b9626e0e5446d64b2ef85992c969e56
Binary files /dev/null and b/docs/_static/ansible/awx_ansible_vault_credential.png differ
diff --git a/docs/_static/ansible/enter_vault_variable.png b/docs/_static/ansible/enter_vault_variable.png
new file mode 100644
index 0000000000000000000000000000000000000000..e9b1e8d7776cf1355c9d07623fc129575d645607
Binary files /dev/null and b/docs/_static/ansible/enter_vault_variable.png differ
diff --git a/docs/_static/ansible/saved_vault_variable.png b/docs/_static/ansible/saved_vault_variable.png
new file mode 100644
index 0000000000000000000000000000000000000000..a03083a6f9bef86930ed47f663864ef1035607ca
Binary files /dev/null and b/docs/_static/ansible/saved_vault_variable.png differ
diff --git a/docs/network.rst b/docs/network.rst
index f7d18c322790eecb4857c0660157049d241aa230..71cf6c550ba24a3feb2fbc535cb4cb08505c903a 100644
--- a/docs/network.rst
+++ b/docs/network.rst
@@ -125,3 +125,42 @@ You can also create `groups of groups <https://docs.ansible.com/ansible/latest/u
 To do so, just select the group names in the *Children* field when registering a new group:
 
 .. image:: _static/ansible/create_ansible_group_of_groups.png
+
+Encrypted variables
+~~~~~~~~~~~~~~~~~~~
+
+`Ansible vault`_ allows to create encrypted variables to embed in yaml using the `ansible-vault encrypt_string`_ command.
+
+::
+
+    $ ansible-vault encrypt_string -n mypassord acomplexpassword
+    New Vault password:
+    Confirm New Vault password:
+    mypassord: !vault |
+              $ANSIBLE_VAULT;1.1;AES256
+              33383731306533343464396365336135653261316639643937326134313430313833316438633238
+              3237613332396239363134346462653831626237663231360a356235306262333634653036336236
+              32333435306334343839353664396165343861373333613830383762393734393434346633653839
+              6139663637336462330a316366326461633964386135346239303338366237383561643034353263
+              66623362333866373530316437366564303332353032643961663435343939633164
+    Encryption successful
+
+You can directly copy/paste the result of the command to CSEntry:
+
+.. image:: _static/ansible/enter_vault_variable.png
+
+The ``!vault`` tag is used to embed encrypted variables in yaml. But variables are saved in JSON in CSEntry as
+this is the format used by the dynamic inventory.
+The scalar value is thus automatically converted to the mapping ``{"__ansible_vault": "encrypted_value"}`` which
+is what AWX expects.
+So this is what you'll see when you save the variable:
+
+.. image:: _static/ansible/saved_vault_variable.png
+
+When encrypting variables, be sure to use the vault password that is defined in AWX.
+And don't forget to add the **ansible-vault** credential to your template to allow AWX to decrypt the variable.
+
+.. image:: _static/ansible/awx_ansible_vault_credential.png
+
+.. _Ansible vault: https://docs.ansible.com/ansible/2.6/user_guide/vault.html
+.. _ansible-vault encrypt_string: https://docs.ansible.com/ansible/2.6/user_guide/vault.html#use-encrypt-string-to-create-encrypted-variables-to-embed-in-yaml
diff --git a/tests/unit/test_fields.py b/tests/unit/test_fields.py
new file mode 100644
index 0000000000000000000000000000000000000000..99e2a9be433eea1cb33a3ced998fad2e0cb04e6d
--- /dev/null
+++ b/tests/unit/test_fields.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+"""
+tests.unit.test_fields
+~~~~~~~~~~~~~~~~~~~~~~
+
+This module defines fields tests.
+
+:copyright: (c) 2018 European Spallation Source ERIC
+:license: BSD 2-Clause, see LICENSE for more details.
+
+"""
+from app.fields import yaml
+
+
+def test_vault_yaml_tag_load():
+    s = """foo: !vault |
+              $ANSIBLE_VAULT;1.1;AES256
+              31333561643032383935666363366337303435363132373238313334663563346164613433616231
+              3464663834343564663638613062386366303836646136360a343231373731656261303830363837
+              63636137336163383637383135643065306436306365343136373138393762366534346161316633
+              3166363036616162620a346536663132343137663464653663383163646239313537316537626165
+              3839
+    """
+    value = yaml.safe_load(s)
+    assert value == {
+        "foo": {
+            "__ansible_vault": """$ANSIBLE_VAULT;1.1;AES256
+31333561643032383935666363366337303435363132373238313334663563346164613433616231
+3464663834343564663638613062386366303836646136360a343231373731656261303830363837
+63636137336163383637383135643065306436306365343136373138393762366534346161316633
+3166363036616162620a346536663132343137663464653663383163646239313537316537626165
+3839
+"""
+        }
+    }