0

I have a YAML file that has an ssh private key in it. I need to replace that key with a new one as part of a key rotation process. I am performing this process via Ansible, so can use native Ansible modules, bash commands, or custom python filters. The format of the file must be maintained. Some values are specified in a single quoted style:

my_new_key: 'This is a value'

but the ssh keys are specified as literals:

ssh_key_data: |
  AKJHAKJHHJLKJAHSDDKJHSADKJHKJS
  LKJAHSDLKJH*&EYIUHCS*&YCHIJHSK

I've tried using pyyaml, but that doesn't honour the format of the original file and set's everything to the same style, I.E all single-quoted, or all literals. The downstream system that uses this file is particularly fussy about the format, so I need to maintain it. I have the current ssh key as a variable, so can use that to search the file, but the key in the file may be indented by an arbitrary number of spaces, whereas the one in the variable will not be indented. Also, the key may contain slashes that could be interpreted as an escape sequence. I've tried using sed

sed -i 's%{{ current_key }}%{{ new_key }}%g'

but I get errors about unterminated 's'commands. The structure looks like the below.

- name: bob_dylans_trousers
  stuff: egg_shells
  content:
    ssh-key-data: |
      -----BEGIN RSA PRIVATE KEY-----
      MIIJKAIBAAKCAgEAtjd9po0fzwXpazk9uM9pNXdxAR3MSDfE0DAWP+37l4DanG6A
      CI3nOoaQRPCrqvOh03Yu1aab8nmavHSMClCfQjy2+BfoYh9EkG+OEtBlZj68TnGl
      HuLhX4IyyTar1+Xx7+4Ki8H9dKp/r9bYjiCZOYFe6bkiwjwwlIa6zGJzeDE+kLyk
      Ey56rSIA0gAF4RSKqGhnez2fpmMn+DegPE5Zs1wSEnKKZ8r6Cid3D5NRpJj5HOwc
      ma581lB5BosNW394WukkuTDk6lI1v7uGT7O78lpTO6FknvoFO/S+f+dXwVYZU8XX
      6mDiMzfRh5eDbrk4KdHIRT5w0n0pgAhhUC2tm+SkYCETrKIakfhAj7RQ0CYCHBVB
      -----END RSA PRIVATE KEY-----      

Bearing all that in mind, can anyone suggest a method to replace the key in the file, whilst maintaining the format?

MJM
  • 357
  • 1
  • 4
  • 16
  • I don't imagine sed is the answer here, but is your sed statement really missing the terminating ' as it is in the code above? As for a potential solution, if your target config file can tolerate arbitrary commented marker lines, the blockinfile module (https://docs.ansible.com/ansible/latest/modules/blockinfile_module.html) might do the trick for you. – clockworknet Dec 18 '18 at 14:28
  • Thanks. Fixed the typo above, which didn't occur in my actual sed command. I tried looking at blockinfile last night, but couldn't see how to replace a block. My understanding is that it can insert a block (and will then add markers), or, it will replace a block that already has the markers. The YAML file contains many ssh keys, so I think i'd have to manually add markers first, and then have a process that added markers whenever a new SSH key was added to the YAML (it's quite possible that my understanding is completely wrong though) – MJM Dec 18 '18 at 14:40
  • Yes, sorry. Had missed the subtlety of your problem. This (very old) answer that you may have already seen might give a clue to a Python solution: https://stackoverflow.com/questions/6432605/any-yaml-libraries-in-python-that-support-dumping-of-long-strings-as-block-liter – clockworknet Dec 18 '18 at 15:27
  • Why don't you keep the ssh key in a file and copy this file? – JGK Dec 18 '18 at 22:20

0 Answers0