Adding new environment variable with Ansible variable as value

Hi guys,

I searched a lot but I can’t find a solution for this issue.

My problem is based on this topic but is a little bit different. I’m trying to add a custom environment variable called ACF_PRO_KEY inside the .env file, with its value set by an Ansible variable.

So I customized the group_vars/<environment>/vault.yml file as follow:

# Documentation: https://roots.io/trellis/docs/vault/
vault_mysql_root_password: devpw

# Advanced Custom Field Pro license key, see https://github.com/PhilippBaschke/acf-pro-installer
vault_acf_pro_key: myACFkey

# Variables to accompany `group_vars/development/wordpress_sites.yml`
# Note: the site name (`example.com`) must match up with the site name in the above file.
vault_wordpress_sites:
  example.com:
    admin_password: admin
    env:
      db_password: example_dbpassword
      acf_pro_key: "{{ vault_acf_pro_key }}"

When I re-provision/deploy (based on which environment we are interested in), the .env file contains the ACF_PRO_KEY variable, but the value is ACF_PRO_KEY='{{ vault_acf_pro_key }}' instead of ACF_PRO_KEY='myACFkey'.

I’ve experienced this issue with Trellis 0.9.9 and the latest version downloaded directly from the GitHub master branch. But it works as expected with Trellis 0.9.6.

Is this a bug with the latest versions? I would like to use Ansible variables as value for custom environment variables, thank you.

You should just be able to do this in group_vars/<environment>/vault.yml:

# Documentation: https://roots.io/trellis/docs/vault/
vault_mysql_root_password: devpw

# Variables to accompany `group_vars/development/wordpress_sites.yml`
# Note: the site name (`example.com`) must match up with the site name in the above file.
vault_wordpress_sites:
  example.com:
    admin_password: admin
    env:
      db_password: example_dbpassword
      acf_pro_key: "myACFkey"

If you do this it will just get added to the .env file.

Setting a variable (e.g. vault_acf_pro_key) is only really necessary if you want to reuse it in different environments. I expect trying to set and use it in the same file is causing issues, as there have been some vault changes in recent months. If that’s what you want to do, you could set that variable in group_vars/all/vault.yml:

vault_acf_pro_key: "myACFkey"

…and then reference it in group_vars/<environment>/wordpress_sites.yml:

    env:
      acf_pro_key: "{{ vault_acf_pro_key }}"
1 Like

Assuming you wanted the key in vault.yml to keep it secret, I especially like @ned’s second example. I’ll point out below how to make your original approach work. However, @ned’s examples have the added value that if you were to search your Trellis codebase for acf_pro_key (e.g., via grep) it would find and return a file showing that variable.

Your original implementation would only have that variable name in vault.yml, but grep won’t find that name if vault.yml is encrypted. You personally may never forget the location, but the ‘ungrepability’ could affect someone examining/inheriting your code who isn’t familiar with the Trellis convention to put vault_somename vars in vault.yml files.


Your original implementation will work if you add specificity to the raw_vars in group_vars/all/main.yml:

 raw_vars:
    - vault_mail_password
    - vault_mysql_root_password
    - vault_users.*.password
    - vault_users.*.salt
-   - vault_wordpress_sites
+   - vault_wordpress_sites.*_password
+   - vault_wordpress_sites.*.*_password
+   - vault_wordpress_sites.*.*_salt
+   - vault_wordpress_sites.*.auth_key
+   - vault_wordpress_sites.*.secure_auth_key
+   - vault_wordpress_sites.*.logged_in_key
+   - vault_wordpress_sites.*.nonce_key

Trellis will then no longer wrap all vault_wordpress_sites values in {% raw %}, only those newly specified above. For background on raw_vars, see roots/trellis#615.

1 Like

Hi, sorry for the delay and thank you for the quick answers.

For me, following the @ned’s advice putting the vault_acf_pro_key: myACFkey in the group_vars/all/vault.yml doesn’t fix the problem. Even though I realize it’s more correct and prevents other issues (I have more than one website in a single Trellis machine so for me it’s useful to declare the ACF key only in one place and reuse it in different environments).

To finally fix the problem, in addition to what @ned reported, I followed the @fullyint’s advice, declaring every single raw_var which I’m interested in, as follow:

 raw_vars:
    - vault_mail_password
    - vault_mysql_root_password
    - vault_users.*.password
    - vault_users.*.salt
-   - vault_wordpress_sites
+   - vault_wordpress_sites.*_password
+   - vault_wordpress_sites.*.*_password
+   - vault_wordpress_sites.*.*_salt
+   - vault_wordpress_sites.*.auth_key
+   - vault_wordpress_sites.*.secure_auth_key
+   - vault_wordpress_sites.*.logged_in_key
+   - vault_wordpress_sites.*.nonce_key

Thank you very much for all the help. Really, really appreciated!


EDIT

Thank you so much @fullyint, now I’ve really understood it all (before I didn’t understand the purpose of raw_vars, but now it’s all clear) and modified the above post with your advice.

@valentinocossar Glad you got it worked out. I realize you probably understand it all, but I want to clarify a couple items to prevent potential confusion for readers in the future.

Perhaps you were just posting a diff as I did, but of course you won’t want the extra plus and minus signs in your code block.

If you type this in discourse (without the 2 spaces indent I’ve added to make this appear):

  ```diff
    regular line
  - removed line
  + added line

it becomes this in discourse output: 

```diff
  regular line
- removed line
+ added line

I used the diff format just to get the red (remove) and green (add) highlighting to show. Copying it directly unfortunately copies the extra plus and minus characters that you won’t want.


So, just to be certain about the format, here’s what I think should work for you:

raw_vars:
  - vault_mail_password
  - vault_mysql_root_password
  - vault_users.*.password
  - vault_users.*.salt
  - vault_wordpress_sites.*_password
  - vault_wordpress_sites.*.*_password
  - vault_wordpress_sites.*.*_salt
  - vault_wordpress_sites.*.auth_key
  - vault_wordpress_sites.*.secure_auth_key
  - vault_wordpress_sites.*.logged_in_key
  - vault_wordpress_sites.*.nonce_key

This differs from the default by removing vault_wordpress_sites because its presence in raw_vars prevents all the values it contains from being templated/interpolated. The original vault_wordpress_sites contained your acf_pro_key variable so the .env file ended up with an uninterpolated value ACF_PRO_KEY='{{ vault_acf_pro_key }}'. When vault_wordpress_sites is absent from raw_vars, its values may be interpolated and your .env file will have the desired ACF_PRO_KEY='myACFkey'.

It is safer to have the other values in vault_wordpress_sites still wrapped in {% raw %} so the example adds to raw_vars the patterns that match all the variables other than your your acf_pro_key. roots/trellis#615 added this raw_vars functionality to prevent Jinja2 from trying to interpret—and getting tripped up on—“delimiters” that may occur by chance in random passwords.


Your code example for raw_vars added vault_wordpress_sites.*.vault_acf_pro_key but you’ll notice that my example omits that item.

raw_vars is a list of variable names or “keys.” In your original post your variable name or “key” within vault_wordpress_sites was actually acf_pro_key. If you’ve kept that pattern, I’m guessing there is no sub-variable in your vault_wordpress_sites with the name/key of vault_acf_pro_key. The variable by that name/key is probably in the vault.yml file, but not within the vault_wordpress_sites dictionary.

All that is to say that I think you can simply omit the vault_wordpress_sites.*.vault_acf_pro_key item from your raw_vars because I don’t think it serves any purpose, referring to a nonexistent variable.