Skip to content

Commit 48341c7

Browse files
authored
Let the sensitive parts of credentials to be defined externally as variables (#121)
* let the sensitive parts of credentials to be defined externally as variables * change from the command line to an example playbook * add changelog fragments * get rid off the command line
1 parent 10abae7 commit 48341c7

File tree

8 files changed

+144
-12
lines changed

8 files changed

+144
-12
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
minor_changes:
3+
- Let the sensitive data of the credentials and users to be defined externally through a well know variables
4+
...

roles/filetree_create/README.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ The following variables are required for that role to work properly:
2525
| `output_path` | `/tmp/filetree_output` | yes | str | The path to the output directory where all the generated `yaml` files with the corresponding Objects as code will be written to. |
2626
| `input_tag` | `['all']` | no | List of Strings | The tags which are applied to the 'sub-roles'. If 'all' is in the list (the default value) then all roles will be called. Valid tags can be found under `vars/valid_tags` |
2727
| `flatten_output` | N/A | no | bool | Whether to flatten the output in single files per each object type instead of the normal exportation structure |
28+
| `secrets_as_variables` | N/A | no | bool | Whether to export the secrets as variables that can be populated from existing variables/files. An example: `vaulted_eda_credentials_my_eda_credential_password`, that follows the syntax: `<secrets_as_variables_prefix>_<object_type>_<object_name>_<field_name>` |
29+
| `secrets_as_variables_prefix` | vaulted | no | str | The prefix to use for the variables defined by `secrets_as_variables` feature. |
2830
| `show_encrypted` | N/A | no | bool | Whether to remove the string '\$encrypted\$' in credentials output (not the actual credential value) |
2931
| `omit_id` | N/A | no | bool | Whether to create output files without objects id.|
3032
| `organization`| N/A | no | str | Default organization for all objects that have not been set in the source controller.|
@@ -247,6 +249,95 @@ This example will export all object but some with modifications:
247249
...
248250
```
249251

252+
## Usage example for the `secrets_as_variables` feature
253+
254+
To let the credentials and the users to be exported and imported 'as is', without any modification, the sensitive data (that can't be exported through the API) can be abstracted to extra vars (or variable's file) and vaulted. Those variables can be referenced at the original objects' code, so they can be imported without any manual modification. To clarify the described scenario, the following output shows the exported object for a gateway user, using the `secrets_as_variable` feature:
255+
256+
Sample playbook:
257+
258+
```yaml
259+
---
260+
- name: Filetree Create Test
261+
hosts: all
262+
connection: local
263+
gather_facts: false
264+
vars:
265+
aap_username: "{{ vault_aap_username | default(lookup('env', 'CONTROLLER_USERNAME')) }}"
266+
aap_password: "{{ vault_aap_password | default(lookup('env', 'CONTROLLER_PASSWORD')) }}"
267+
aap_hostname: "{{ vault_aap_hostname | default(lookup('env', 'CONTROLLER_HOST')) }}"
268+
aap_validate_certs: "{{ vault_aap_validate_certs | default(lookup('env', 'CONTROLLER_VERIFY_SSL')) }}"
269+
output_path: /tmp/filetree_output_25
270+
# Let the secrets to be defined externally (and vaulted) through well known variables
271+
secrets_as_variables: true
272+
273+
pre_tasks:
274+
- name: "Setup authentication (block)"
275+
no_log: "{{ controller_configuration_filetree_create_secure_logging }}"
276+
when: aap_oauthtoken is not defined
277+
tags:
278+
- always
279+
block:
280+
- name: "Get the Authentication Token for the future requests"
281+
ansible.builtin.uri:
282+
url: "https://{{ aap_hostname }}/api/gateway/v1/tokens/"
283+
user: "{{ aap_username }}"
284+
password: "{{ aap_password }}"
285+
method: POST
286+
force_basic_auth: true
287+
validate_certs: "{{ aap_validate_certs }}"
288+
status_code: 201
289+
register: authtoken_res
290+
291+
- name: "Set the oauth token to be used since now"
292+
ansible.builtin.set_fact:
293+
aap_oauthtoken: "{{ authtoken_res.json.token }}"
294+
aap_oauthtoken_url: "{{ authtoken_res.json.url }}"
295+
296+
roles:
297+
- infra.aap_configuration_extended.filetree_create
298+
299+
post_tasks:
300+
- name: "Delete the Authentication Token used"
301+
ansible.builtin.uri:
302+
url: "https://{{ aap_hostname }}{{ aap_oauthtoken_url }}"
303+
user: "{{ aap_username }}"
304+
password: "{{ aap_password }}"
305+
method: DELETE
306+
force_basic_auth: true
307+
validate_certs: "{{ aap_validate_certs }}"
308+
status_code: 204
309+
when: aap_oauthtoken_url is defined
310+
...
311+
```
312+
313+
Generated file: `/tmp/filetree_output_25/gateway_users.yaml`
314+
315+
```yaml
316+
---
317+
aap_user_accounts:
318+
- username: "test_user"
319+
email: ""
320+
first_name: ""
321+
last_name: ""
322+
password: "{{ vaulted_gateway_users_test_user_password }}"
323+
is_superuser: "False"
324+
authenticators: []
325+
authenticator_uid: ""
326+
...
327+
```
328+
329+
The variable `vaulted_gateway_users_test_user_password` can be defined in a third file:
330+
331+
`~/vaulted_credentials.yaml`:
332+
333+
```yaml
334+
vaulted_gateway_users_test_user_password: "SuperSecretPassword"
335+
```
336+
337+
That file can be encrypted using `ansible-vault`.
338+
339+
The import process can be executed directly, using that file with the extra_vars option: `ansible-playbook -e@~/vaulted_credentials.yaml`.
340+
250341
## License
251342

252343
GPLv3+

roles/filetree_create/defaults/main.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,6 @@ eda_configuration_filetree_create_secure_logging: "{{ controller_configuration_s
3434
input_tag:
3535
- all
3636
organization: 'ORGANIZATIONLESS'
37+
38+
secrets_as_variables_prefix: "vaulted"
3739
...

roles/filetree_create/templates/controller_credentials.j2

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,17 @@ controller_credentials:
1515
{% if template_overrides_resources.credential[current_credentials_asset_value.name].inputs is defined
1616
or (current_credentials_asset_value.inputs is defined and current_credentials_asset_value.inputs is not match('{}')) %}
1717
inputs:
18-
{% if show_encrypted is defined and show_encrypted %}
19-
{{ current_credentials_asset_value.inputs | to_nice_yaml(indent=2, sort_keys=false) | indent(width=6, first=true) }}
20-
{% else %}
21-
{{ template_overrides_resources.credential[current_credentials_asset_value.name].inputs
22-
| default(current_credentials_asset_value.inputs)
23-
| to_nice_yaml(indent=2, sort_keys=false) | indent(width=6, first=true) | replace("$encrypted$", "\'\'") }}
24-
{% endif %}
18+
{% for input in (template_overrides_resources.credential[current_credentials_asset_value.name].inputs |
19+
default(current_credentials_asset_value.inputs)) | dict2items %}
20+
{% if show_encrypted is defined and show_encrypted %}
21+
{{ input.key }}: {{ input.value }}
22+
{% elif secrets_as_variables is defined and secrets_as_variables %}
23+
{{ input.key }}: {{ input.value | replace("$encrypted$", "\"{{ " + secrets_as_variables_prefix + "_controller_credentials_" + (current_credentials_asset_value.name | replace(' ', '_') | lower) + "_" + (input.key | replace(' ', '_') | lower) + " }}\"") }}
24+
{% else %}
25+
{{ input.key }}: {{ input.value | replace("$encrypted$", "\'\'") }}
26+
{% endif %}
27+
{% endfor %}
28+
2529
{% endif %}
2630
{% if last_credential | default(true) | bool %}
2731
...

roles/filetree_create/templates/controller_users.j2

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@
33
aap_user_accounts:
44
{% endif %}
55
- username: "{{ current_users_asset_value.username }}"
6+
{% if show_encrypted is defined and show_encrypted %}
7+
password: "{{ current_users_asset_value.password }}"
8+
{% elif secrets_as_variables is defined and secrets_as_variables %}
9+
password: "{{ current_users_asset_value.password | replace("$encrypted$", "{{ " + secrets_as_variables_prefix + "controller_users_" + (current_users_asset_value.username | replace(' ', '_') | lower) + "_password }}") }}"
10+
{% else %}
611
password: "INITIAL"
12+
{% endif %}
713
email: "{{ template_overrides_resources.user[current_users_asset_value.username].email
814
| default(template_overrides_global.user.email)
915
| default(current_users_asset_value.email) }}"

roles/filetree_create/templates/eda_credentials.j2

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,16 @@ eda_credentials:
1818
{% endif %}
1919
{% if eda_credential.inputs is defined %}
2020
inputs:
21-
{{ template_overrides_resources.eda_credential[eda_credential.name].inputs
22-
| default(eda_credential.inputs) | to_nice_yaml(indent=2,sort_keys=False) | indent(width=6, first=True) }}
21+
{% for input in (template_overrides_resources.eda_credential[eda_credential.name].inputs |
22+
default(eda_credential.inputs)) | dict2items %}
23+
{% if show_encrypted is defined and show_encrypted %}
24+
{{ input.key }}: {{ input.value }}
25+
{% elif secrets_as_variables is defined and secrets_as_variables %}
26+
{{ input.key }}: {{ input.value | replace("$encrypted$", "\"{{ " + secrets_as_variables_prefix + "_eda_credentials_" + (eda_credential.name | replace(' ', '_') | lower) + "_" + (input.key | replace(' ', '_') | lower) + " }}\"") }}
27+
{% else %}
28+
{{ input.key }}: {{ input.value | replace("$encrypted$", "\'\'") }}
29+
{% endif %}
30+
{% endfor %}
2331
{%- endif %}
2432
{% endfor %}
2533
...

roles/filetree_create/templates/gateway_users.j2

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
---
22
aap_user_accounts:
33
{% for current_user in current_gateway_users_asset_value %}
4-
- username: "{{ template_overrides_resources.gateway_user[current_user.username].username
4+
{% set _username = template_overrides_resources.gateway_user[current_user.username].username
55
| default(template_overrides_global.gateway_user.username)
6-
| default(current_user.username) }}"
6+
| default(current_user.username) %}
7+
- username: "{{ _username }}"
78
email: "{{ template_overrides_resources.gateway_user[current_user.name].email
89
| default(template_overrides_global.gateway_user.email)
910
| default(current_user.email) }}"
@@ -13,9 +14,19 @@ aap_user_accounts:
1314
last_name: "{{ template_overrides_resources.gateway_user[current_user.name].last_name
1415
| default(template_overrides_global.gateway_user.last_name)
1516
| default(current_user.last_name) }}"
17+
{% if show_encrypted is defined and show_encrypted %}
1618
password: "{{ template_overrides_resources.gateway_user[current_user.name].password
1719
| default(template_overrides_global.gateway_user.password)
18-
| default(current_user.password) | replace("$encrypted$", "\'\'") }}"
20+
| default(current_user.password) }}"
21+
{% elif secrets_as_variables is defined and secrets_as_variables %}
22+
password: "{{ template_overrides_resources.gateway_user[current_user.name].password
23+
| default(template_overrides_global.gateway_user.password)
24+
| default(current_user.password) | replace("$encrypted$", "{{ " + secrets_as_variables_prefix + "_gateway_users_" + (_username | replace(' ', '_') | lower) + "_password }}") }}"
25+
{% else %}
26+
password: "{{ template_overrides_resources.gateway_user[current_user.name].password
27+
| default(template_overrides_global.gateway_user.password)
28+
| default(current_user.password) | replace("$encrypted$", "") }}"
29+
{% endif %}
1930
is_superuser: "{{ template_overrides_resources.gateway_user[current_user.name].is_superuser
2031
| default(template_overrides_global.gateway_user.is_superuser)
2132
| default(current_user.is_superuser) }}"

roles/filetree_create/vars/main.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ valid_tags:
2424
- controller_schedules
2525
- controller_gateway_authenticator
2626
- controller_gateway_authenticator_maps
27+
- eda_credentials
28+
- eda_credential_types
29+
- eda_decision_environments
30+
- eda_event_streams
31+
- eda_projects
32+
- eda_rulebook_activations
2733
- gateway_applications
2834
- gateway_authenticator_maps
2935
- gateway_authenticators

0 commit comments

Comments
 (0)