Можно ли проанализировать зашифрованные значения хранилища Ansible из динамического инвентаря в сборнике пьес?

#ansible #ansible-inventory #ansible-vault

#ansible #ansible-инвентаризация #ansible-vault

Вопрос:

У меня настроена динамическая инвентаризация, которая извлекает хосты и их переменные из базы данных MySQL. Сам динамический инвентарь работает отлично.

Некоторые переменные внутри инвентаря чувствительны, поэтому я бы предпочел не хранить их в виде обычного текста.

Итак, в качестве теста я зашифровал значение, используя:

 ansible-vault encrypt_string 'foobar'
 

Что привело к:

 !vault |
          $ANSIBLE_VAULT;1.1;AES256
          39653264643032353830336333356665663638353839356162386462303338363661333564633737
          3737356131303563626564376634313865613433346438630a343534363066393431633366393863
          30333636386536333166363533373239303864633830653566316663616432633336393936656233
          6633666134306530380a356664333834353265663563656162396435353030663833623166363466
          6436
Encryption successful
 

Я решил сохранить зашифрованное значение как переменную внутри MySQL. Во избежание сомнений, после некоторого тестирования вы можете нормализовать зашифрованную строку на:

 $ANSIBLE_VAULT;1.1;AES256
363635393063363466313636633166356562396562336633373239333630643032646637383866656463366137623232653531613135623464353932653665300a376461666332626538386263343732333039356663363132333533663339313466346435373064343931383536393736303731393834323964613063323362370a3361313132396239336130643839623939346438616363383932616639656463
 

Вы можете проверить, что этот формат работает с простым сборником воспроизведения:

 ---
- hosts: all

  gather_facts: no
  
  vars:
    final_var: !vault "$ANSIBLE_VAULT;1.1;AES256n363635393063363466313636633166356562396562336633373239333630643032646637383866656463366137623232653531613135623464353932653665300a376461666332626538386263343732333039356663363132333533663339313466346435373064343931383536393736303731393834323964613063323362370a3361313132396239336130643839623939346438616363383932616639656463"

  tasks:
    - name: Display variable
      debug:
        msg: "{{ final_var }}"
 

При выполнении сборника воспроизведения наблюдается следующий результат:

 ok: [target] => {
    "msg": "foobar"
}
 

Трудность возникает при попытке получить переменную ( my_secret ) из инвентаря вместо того, чтобы ссылаться на нее непосредственно в файле.

 ---
- hosts: all

  gather_facts: no
  
  vars:
    final_var: !vault "{{ my_secret }}"

  tasks:
    - name: Display variable
      debug:
        msg: "{{ final_var }}"
 

Это приводит к:

 fatal: [target]: FAILED! => {"msg": "input is not vault encrypted data"}
 

Теперь, хотя я много говорил о значении, хранящемся в динамическом инвентаре в MySQL, мы можем получить аналогичное поведение, если мы удалим это из уравнения.

 ---
- hosts: all

  gather_facts: no
  
  vars:
    secret: "$ANSIBLE_VAULT;1.1;AES256n363635393063363466313636633166356562396562336633373239333630643032646637383866656463366137623232653531613135623464353932653665300a376461666332626538386263343732333039356663363132333533663339313466346435373064343931383536393736303731393834323964613063323362370a3361313132396239336130643839623939346438616363383932616639656463"
    final_var: !vault "{{ secret }}"

  tasks:
    - name: Display variable
      debug:
        msg: "{{ final_var }}"
 

Теперь это почти идентично рабочему примеру, но зашифрованная строка записывается не в строку, а поступает из другой переменной.

Это приводит к той же ошибке:

 fatal: [target]: FAILED! => {"msg": "input is not vault encrypted data"}
 

Это может указывать на то, что более широкая проблема заключается в том, что Ansible по какой-то причине не может проанализировать зашифрованные данные, хранящиеся в виде переменной. Возможно, когда анализируется YAML, он буквально пытается расшифровать "{{ my_secret }}" , а не $ANSIBLE_VAULT;1.1;AES256 ... .

Какой вид имеет смысл, но я хотел пройти мимо вас, ребята, и спросить, есть ли способ обойти это или вы рекомендуете совершенно другой подход. Спасибо.

Комментарии:

1. просто любопытно, почему вы не сохраняете !valut в своем секрете? почему вы отделяете этот конкретный фрагмент от сгенерированной зашифрованной строки?

2. !vault является частью самого синтаксиса YAML, который использует Ansible, а не частью зашифрованной строки. Он сообщает Ansible, что далее следует зашифрованная строка. Если бы это была часть зашифрованной строки, Ansible прочитал бы ее буквально как обычную строку и не знал бы, что с ней делать.

Ответ №1:

Вам будет лучше поместить переменные в зашифрованные файлы. Храните зашифрованные файлы в MySQL вместо зашифрованных переменных. Если у вас уже «настроена динамическая инвентаризация, которая извлекает хосты и их переменные из базы данных MySQL», не должно возникнуть проблем с изменением настройки. Извлеките зашифрованные файлы из базы данных и сохраните их в host_vars (и / или group_vars, play vars, role vars …) вместо хранения зашифрованных переменных в инвентаре (и / или в коде playbook, role, …). Таким образом, в коде вам все равно, зашифрована переменная или нет.

Например

 shell> tree host_vars/
host_vars/
├── test_01
   └── final_var.yml
├── test_02
   └── final_var.yml
└── test_03
    └── final_var.yml

shell> cat host_vars/test_01/final_var.yml 
final_var: final_var for test_01

shell> cat host_vars/test_02/final_var.yml 
final_var: final_var for test_02

shell> cat host_vars/test_03/final_var.yml 
final_var: final_var for test_03
 

Зашифруйте файлы. Например

 shell> ansible-vault encrypt host_vars/test_01/final_var.yml
Encryption successful

shell> cat host_vars/test_01/final_var.yml
$ANSIBLE_VAULT;1.1;AES256
37363965336263366466336236336466323033353763656262633836323062626135613834396435
3665356363396132356131663336396138663962646434330a346433353039383864333638633462
35623034363338356362346133303262393233346439363264353036386337356236336135626434
6533333864623132330a346566656630376439643533373263303338313063373239343463333431
62353230323336383263376335613635616339383934313164323938363066616136373036326461
3538613937663530326364376335343438366139366639303230
 

Затем в сборнике воспроизведения ниже

 - hosts: test_01,test_02,test_03
  tasks:
    - debug:
        msg: "{{ inventory_hostname }}: {{ final_var }}"
 

дает (сокращенный)

     "msg": "test_02: final_var for test_02"
    "msg": "test_01: final_var for test_01"
    "msg": "test_03: final_var for test_03"
 

Комментарии:

1. Мне потребовалось некоторое время, чтобы вернуться к этому, но я действительно ценю вашу помощь. Это подход, который я собираюсь использовать, поэтому я пометил ваш как принятый ответ. Еще раз спасибо!