Se você deseja alterar apenas o usuário NGINX, enquanto mantém os padrões para outros vars, você ainda tem que definir todos os vars em nginx_main_template
dict.
Com esses vars:
nginx_main_template_enable: true
nginx_main_template:
user: www-data
Isso causa o seguinte erro:
TASK [nginxinc.nginx : (Setup: All NGINX) Dynamically Generate NGINX Main Configuration File] ************************
fatal: [sandbox]: FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'dict object' has no attribute 'worker_processes'"}
Devemos ter permissão para definir apenas alguns vars e manter os padrões para os outros.
Concordo totalmente com @alexsegura. A opção de definir parâmetros únicos está na lista de pendências. O desenvolvimento do papel tem sido um pouco mais lento do que eu gostaria, mas as coisas devem começar a melhorar nos próximos meses. Dito isso, sinta-se à vontade para enviar um PR, se desejar 😄
Obrigado pela sua mensagem.
Sim, posso contribuir com uma solicitação de pull 🙂
O problema que vejo aqui e ali nesta função é que os padrões são codificados permanentemente.
Portanto, se os padrões mudarem, você deve se lembrar de alterá-los tanto em defaults/main.yml
quanto em modelos.
Suponho que seja porque, ao usar dicts como padrão, eles são substituídos. Existe uma configuração hash_behavior , mas é global, eu acho.
Você conhece uma maneira de recuperar os vars padrão "intocados" para uma função?
Algo como role_defaults['var_name']
?
@alexsegura Não conheço uma ótima maneira de realizar esse comportamento. O ideal é que você deseje uma configuração em que a função possa implantar uma configuração útil sem usar nenhum dos valores em defaults/main.yml
.
O pensamento principal que me vem à mente é usar vars/main.yml
para codificar alguns dos valores padrão e então fazer algo como | default(var_main_upload_src)
, mas não tenho certeza se esse é o melhor caminho a seguir.
Provavelmente, a única maneira de fazer isso é no próprio modelo com o filtro padrão.
Certo, essa é uma boa solução para parâmetros relacionados a modelos (e se você olhar os arquivos de modelo, o filtro padrão já é usado em alguns lugares). E é verdade que isso resolveria o problema original. Seria uma tarefa muito demorada, mas é factível.
No entanto, a questão permanece sobre qual é a melhor abordagem para variáveis não relacionadas a modelos e, mais ainda, existe uma melhor abordagem?
Pelo que vejo aqui e ali, a melhor abordagem para os padrões é evitar o uso de dictos, por exemplo
nginx_main_template_user: www-data
ao invés de
nginx_main_template:
user: www-data
Isso resolveria parcialmente o problema e, inicialmente, foi assim que a função foi estruturada. Mas quando comecei a introduzir opções de modelos mais complexas (por exemplo, vários blocos de localização), dicionários e listas começaram a fazer mais sentido.
Ou você pode usar dicionários separados para configuração padrão e do usuário e mesclá-los com o filtro combine
. Tenho usado uma função para implantar o fluxo de ar onde este método é usado:
airflow_config: "{{ airflow_defaults_config | combine(airflow_user_config, recursive=True) }}"
Eu acho que isso também removeria a necessidade de ter padrões codificados permanentemente nos modelos.
A função a que me refiro pode ser verificada aqui .
Hm, essa é uma abordagem interessante e posso ver que está funcionando. Talvez valesse a pena criar um pequeno PoC com um dos dicionários menores (estou pensando nos modelos main
ou stream
) para ver como funcionaria na prática.
Já tentei isso para o template principal e estava funcionando conforme o esperado. No entanto, como segui o caminho de menor esforço, juntei dois dicionários nginx_default_main_template
dos padrões e nginx_user_main_template
do manual do usuário em nginx_main_template
.
Isso introduziria uma alteração significativa, então irei refatorar a função para usar o dicionário mesclado com um novo nome e enviar um PR.
O modelo http é muito mais difícil porque possivelmente existem vários dicionários do usuário para mesclar. Âncoras e aliases combinados com o operador de mesclagem podem ser uma alternativa, mas o usuário é responsável por fazer a mesclagem.
Vou passar algum tempo nessa frente também.
BTW: Existe um motivo pelo qual você escolheu usar um dicionário em vez de uma lista para definir vários modelos http? Pelo que descobri, a chave nunca é realmente usada.
BTW: Existe um motivo pelo qual você escolheu usar um dicionário em vez de uma lista para definir vários modelos http? Pelo que descobri, a chave nunca é realmente usada.
Não, na verdade não. Olhando para trás, acho que pode melhorar a legibilidade ter uma chave para cada modelo HTTP que você definir, mas não me oponho a alterá-lo para uma lista se isso tornar as coisas mais fáceis.
Eu tive um problema semelhante e, posteriormente, esse problema. Eu gostaria de oferecer uma perspectiva alternativa:
Os valores padrão para uma configuração não devem ser codificados permanentemente e ser deixados para o software que está sendo instalado.
Como @alexsegura já apontou, o problema é que você precisa manter os valores em sincronia, o que por natureza nem sempre será o caso (humanos são propensos a erros).
Se você sentir que deve fornecer uma configuração padrão, sugiro manter as subseções em diretórios separados e combiná-los no nível mais baixo se o usuário especificar um valor e, em seguida, mesclá-los na configuração.
Mas mesmo isso, imo, não está dentro do escopo de uma função - ele deve copiar a configuração para o destino, e não ter certeza de que seus valores estão corretos; No máximo, eu daria um erro se o software não pudesse iniciar devido a um erro de configuração (ou use a função de validação do software, se disponível).
Curiosamente, atualmente estou trabalhando em maneiras de melhorar a forma como os modelos funcionam na função. Tem sido um processo muito lento (limitei bastante a largura de banda para dedicar à função no momento), mas acho que encontrei uma solução OK para resolver esses problemas. Espero que as mudanças estejam ativadas em uma filial separada em alguns meses no máximo 😉
Algum progresso com este problema?
Não. Ainda há planos para voltar a isso em um futuro "próximo", mas algumas outras tarefas têm prioridade.
Comentários muito úteis
Ou você pode usar dicionários separados para configuração padrão e do usuário e mesclá-los com o filtro
combine
. Tenho usado uma função para implantar o fluxo de ar onde este método é usado:airflow_config: "{{ airflow_defaults_config | combine(airflow_user_config, recursive=True) }}"
Eu acho que isso também removeria a necessidade de ter padrões codificados permanentemente nos modelos.
A função a que me refiro pode ser verificada aqui .