(Relacionado a callbacks ou ganchos e séries reutilizáveis de tarefas, em papéis Ansible ):
Existe alguma maneira melhor de anexar a uma lista ou adicionar uma chave a um dicionário no Ansible do que (ab) usando uma expressão de modelo jina2?
Eu sei que você pode fazer algo como:
- name: this is a hack
shell: echo "{% originalvar.append('x') %}New value of originalvar is {{originalvar}}"
mas não há realmente nenhum tipo de meta-tarefa ou auxiliar para fazer isso?
Parece frágil, não documentado e depende de muitas suposições sobre como as variáveis funcionam no Ansible.
Meu caso de uso são várias funções (extensões de servidor de banco de dados), cada uma precisa fornecer alguma configuração para uma função base (o servidor de banco de dados). Não é tão simples quanto anexar uma linha ao arquivo de configuração do servidor db; cada alteração se aplica à mesma linha , por exemplo, as extensões bdr
e pg_stat_statements
ambas devem aparecer em uma linha de destino:
shared_preload_libaries = 'bdr, pg_stat_statements'
A maneira Ansible de fazer isso é apenas processar o arquivo de configuração várias vezes (uma vez por extensão) com um regexp que extrai o valor atual, analisa-o e o reescreve? Em caso afirmativo, como você torna isso idempotente em várias execuções?
E se a configuração for mais difícil de analisar e não for tão simples quanto acrescentar outro valor separado por vírgula? Pense em arquivos de configuração XML.
Desde o Ansible v2.x, você pode fazer o seguinte:
todos os itens acima estão documentados em: https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#combining-hashes-dictionaries
Você pode mesclar duas listas em uma variável com
+
. Digamos que você tenha umgroup_vars
arquivo com este conteúdo:E é usado em um modelo
pgsql.conf.j2
como:Você pode anexar extensões aos servidores de banco de dados de teste como este:
Quando a função for executada em qualquer um dos servidores de teste, as extensões adicionais serão adicionadas.
Não tenho certeza se isso também funciona para dicionários, e também tome cuidado com os espaços e deixe uma vírgula pendente no final da linha.
você precisa dividir o loop em 2
e addhost.yml
Quase todas as respostas aqui requerem mudanças nas tarefas, mas eu precisava mesclar dinamicamente os dicionários na definição de vars, não durante a execução.
Por exemplo, eu quero definir alguns vars compartilhados
all
group_vars
e, em seguida, quero estendê-los em algum outrogroup
ouhost_vars
. Muito útil ao trabalhar para funções.Se você tentar usar os filtros
combine
ouunion
substituindo a variável original em arquivos var, você terminará em loop infinito durante a modelagem, então criei esta solução alternativa (não é solução).Você pode definir várias variáveis com base em algum padrão de nome e carregá-las automaticamente na função.
group_vars/all.yml
group_vars/group1.yml
trecho de código de função
do_some_stuff.yml
É apenas um trecho, mas você deve ter uma ideia de como funciona. nota: lookup('varnames','') está disponível desde ansible 2.8
Acho que também seria possível mesclar todas as variáveis
dictionary_of_bla.*
em um dicionário durante o tempo de execução usando a mesma pesquisa.A vantagem dessa abordagem é que você não precisa definir listas exatas de nomes de variáveis, mas apenas o padrão e o usuário podem defini-la dinamicamente.
Não tenho certeza de quando eles adicionaram isso, mas pelo menos para dicionários/hashes (NÃO listas/arrays), você pode definir a variável hash_behaviour , assim:
hash_behaviour = merge
em seu arquivoansible.cfg
.Levei algumas horas para tropeçar acidentalmente nessa configuração: S
Ansible
é um sistema de automação e, em relação ao gerenciamento de arquivos de configuração, não é muito diferente doapt
. A razão pela qual cada vez mais software oferece o recurso para ler trechos de configuração de umconf.d
diretório é permitir que esses sistemas de automação tenham diferentes pacotes/funções para adicionar configuração ao software. Acredito que não seja a filosofia deAnsible
fazer o que você tem em mente, mas sim usar oconf.d
truque. Se o software que está sendo configurado não oferece essa funcionalidade, você pode estar com problemas.Já que você mencionou arquivos de configuração XML, aproveito a oportunidade para reclamar. Há uma razão para a tradição Unix de usar arquivos de configuração de texto simples. Os arquivos de configuração binários não se prestam bem à automação do sistema, portanto, qualquer tipo de formato binário causará problemas e provavelmente exigirá que você crie um programa para lidar com a configuração. (Se alguém pensa que XML é um formato de texto simples, deveria ter seus cérebros examinados.)
Agora, no seu
PostgreSQL
problema específico.PostgreSQL
suporta oconf.d
truque. Primeiro, eu verificaria seshared_preload_libraries
pode ser especificado várias vezes. Não encontrei nenhuma dica na documentação de que possa, mas ainda assim tentaria. Se não puder ser especificado várias vezes, eu explicaria meu problema para osPostgreSQL
caras caso eles tivessem ideias; isso é umPostgreSQL
problema e não umAnsible
problema. Se não houver solução e eu realmente não conseguir mesclar as diferentes funções em uma, implementaria um sistema para compilar a configuração no host gerenciado. Nesse caso, provavelmente criaria um script/usr/local/sbin/update_postgresql_config
que compilaria/etc/postgresql/postgresql.conf.jinja
em/etc/postgresql/9.x/main/postgresql.conf
. O script leria as bibliotecas de pré-carregamento compartilhadas de/etc/postgresql/shared_preload_libraries.txt
, uma biblioteca por linha e as forneceria para jinja.Não é incomum que os sistemas de automação façam isso.
exim4
Um exemplo é o pacote Debian .