Search code examples
ansibleansible-vault

Dynamically encrypting configuration variables and placing them in specific folders


I have a configuration file that contains a list of string variables that the user is required to change to suit their environment:

Configuration file example:

# first_file.yml

value_one: <UPDATE>
value_two: <UPDATE>

# second_file.yml

value_one: <UPDATE>
value_two: <UPDATE>

Once the user has changed the UPDATE value, I want to be able to use vault to encrypt each variable before copying the encrypted variable to a file specified in the comment, with the desired out below:

# first_file.yml

value_one: !vault |
      $ANSIBLE_VAULT;1.1;AES256
      30663734346135353432323531336536636566643739656332613031636630383237666636366630
      6164633835363766666535656438306534343565636434330a626239396536373032373866353861
      37376665313438363561323262393337313266613237313065396338376438313737393234303434
      3035326633616339340a346164646366623932313261613662633938356662373438643831643830
      3432

value_two: !vault |
      $ANSIBLE_VAULT;1.1;AES256...

I am unsure how to best approach this problem, with the main challenge being how to:

  1. Encrypt each variable successfully, without encrypting the entire file
  2. Copy the encrypted variable over to a specified file

Solution

  • I just threw this together, but it works for your case, preserving structure and indents:

    #!/bin/bash
    IFS=; while read line; do
      # read key and value from line
      key=$( echo "${line}" | cut -d: -f1 )
      value=$( echo "${line}" | cut -d: -f2 | tr -d '\n' )
    
      # Get spaces to indent
      indent=$( echo "${key}" | grep -o '^ *' )
    
      # if value is not empty... 
      if [ -n "$value" ]; then
        # Encrypt value and indent
        cval=$( echo -n "${value## }" | sed -e "s/^'//" -e "s/'$//" | ansible-vault encrypt_string --vault-password-file ~/.ssh/vault_key.txt | sed "s/^ / ${indent}/")
      fi
    
      # if key is not empty...
      if [ -n "$key" ]; then
        echo -n "${key}: ${cval}"
      fi
      # End the line
      echo
      # unset cval
      unset cval
    done < /dev/stdin
    

    Name it encrypt_values.sh, run chmod +x encrypt_values.sh, then you can run it with

    cat {input-file} | ./encrypt_values.sh > {output_file}
    

    If you have some bizzare structure, run the file through yq first to clean it up:

    yq r {imput-file} | ./encrypt_values.sh > {output_file}