Qual é a maneira preferida de armazenar configurações de aplicativos?


38

Na maioria das vezes, eu armazeno a configuração do aplicativo de desenvolvimento no diretório raiz do projeto, assim:

app
|-- config.json

Mas essa não parece ser a melhor abordagem, pois essa configuração acaba sendo armazenada no sistema de controle de versão - possivelmente resultando em nomes de usuário, senhas e outras coisas confidenciais vazadas.

O guia 12 Factor App recomenda eliminar completamente os arquivos de configuração e usar variáveis ​​de ambiente para a instalação:

... armazena a configuração em variáveis ​​de ambiente. Os envs são fáceis de alterar entre implantações sem alterar nenhum código; ao contrário dos arquivos de configuração, há pouca chance deles serem verificados no repositório de códigos acidentalmente; e, diferentemente dos arquivos de configuração personalizados ou de outros mecanismos de configuração, como as Propriedades do sistema Java, eles são um padrão independente de idioma e sistema operacional.

Isso me parece muito bom, mas onde se armazena essas variáveis ​​de ambiente, sem as verificar no controle de origem? E quais ferramentas posso usar para passar essas variáveis ​​para o aplicativo? Pode haver dezenas de opções de configuração, e digitá-las manualmente sempre que você inicia o aplicativo não é bom - portanto, elas precisam ser armazenadas em algum tipo de arquivo em algum lugar. O arquivo, portanto, acabará no controle de origem e voltaremos para onde começamos.

Existe alguma maneira universalmente aceita de lidar com opções de configuração, que não corre o risco de armazenar a configuração local no controle de origem?


11
Bem, pelo menos o git tem algo como .gitignoreonde eu posso definir arquivos ou pastas que não devem ser verificados no controle de versão. Como você diz, não vejo onde o Env vars realmente deve ajudar, mas você tem um script para defini-los e deve ser armazenado junto com o projeto ou você os encontra em algum lugar do seu sistema (diretório inicial ou mesmo na inicialização da máquina) scripts), que parece criar muitos problemas por si só, especialmente se muita configuração for necessária. De qualquer forma, eu dividiria os arquivos de configuração para que as informações confidenciais fossem inseridas em arquivos diferentes.
22615 Thorsten Müller

@ thorstenmüller - único problema com .gitignore que a configuração base / modelo ainda precisa ser armazenada, o que significa que o aplicativo precisa ler duas configurações - base uma, com opções padrão (armazenadas em scm) e local, que substitui a base (e não é armazenado no scm). Com os env vars, imagino que a implantação em massa seja mais fácil - é mais simples especificar variáveis ​​de ambiente para a nova configuração de máquina virtual do que gravar algo em algum arquivo não padrão.
Rogach

Boa pergunta, Depois que eu comecei a usar armazenamento de dados aplicação normal específicas do usuário para isso, a vida se tornou mais fácil ;-)
Lobo

11
Você já tentou "Redis" redis.io . Destina-se especialmente apenas ao armazenamento da estrutura de valores-chave.
Karan

2
@jporcenaluk - Eu gosto de armazenamentos de valores-chave, mas adicionar um redis completo ao aplicativo apenas para lidar com o gerenciamento de configurações parece um pouco exagerado. Por outro lado, talvez nunca tenha trabalhado em projetos grandes o suficiente.
Rogach 14/05

Respostas:


16

Possivelmente não há uma boa resposta para isso. Parece que você precisa armazenar esses dados em algum lugar seguro, pois serão necessários para fins de recuperação de desastres um dia. Isso se aplica igualmente aos arquivos e scripts de propriedades que configuram variáveis ​​de ambiente.

  • Com o código fonte (em SVN / GIT etc) é uma péssima idéia, pois esses dados conterão senhas de banco de dados de produção e similares.
  • Seu backup noturno corporativo pode ser suficiente, mas é improvável que você mantenha um histórico de alterações prontamente acessível.
  • Os dados precisam ser versionados separadamente para o software consumidor. Em nosso sistema atual, uma alteração na configuração leva a uma nova compilação de aplicativos, e isso está totalmente errado.

Atualmente, estamos procurando soluções para esse problema e estamos inclinados para um repositório de código com acesso restrito. Este repositório conteria apenas dados de cofiguração. Outros têm experiências para compartilhar?


2
Ter dois repositórios separados para um projeto não parece uma boa idéia - você não pode fazer reversões limpas ou trabalhar com ramificações, porque precisará manipular dois repositórios simultaneamente (por exemplo, outra ramificação requer alguma nova opção de configuração e quando você mudar para esse novo ramo sem também alternar no repositório de configuração, as coisas quebram de maneiras estranhas).
Rogach

2
@ Rogach Eu entendo o seu ponto. Existem razões válidas para manter alguma configuração com o código, mas, como você diz na sua pergunta, coisas sensíveis precisam ir para outro lugar. Portanto, dois repositórios parecem inevitáveis. Além disso, não mencionei que os servidores de aplicativos geralmente ajudam aqui. As fontes de dados e as variáveis ​​JNDI podem ser configuradas pelo administrador e não serão públicas.
Kiwiron

Uma segunda loja faz sentido. Talvez haja outros tipos de dados, também confidenciais, que possam ser armazenados junto com a configuração (por exemplo, dados de produção que estão sendo analisados ​​para corrigir problemas dos clientes).
Lobo

11
@ Rogach Eles parecem atrair muito ódio, mas os submódulos git lidariam com isso muito bem, eu acho - se o principal fosse configurado corretamente, e o repositório de acesso restrito pudesse viver dentro dele.
precisa saber é o seguinte

9

Ao examinar problemas e possíveis soluções, me ajuda a usar um método popularizado por Jeff Atwood : Se Deus criasse uma maneira de armazenar informações confidenciais de configuração, como ele faria isso?

Bem, ele saberia quem precisa de informações de configuração e as forneceria apenas a essas pessoas, e as informações nunca poderiam ser acessadas por mais ninguém.

A primeira parte já deve ser resolvida: seu sistema de controle de origem deve autenticar usuários. E essa abordagem também tem validade, de acordo com o item 10 dos 10 mandamentos de controle de fontes de Troy Hunt , "as dependências precisam estar no controle de fontes".

Mas como mantê-lo seguro se vazar? Bem, ele não precisa ser armazenado lá em texto simples! Use criptografia. No .NET, existem etapas que você pode executar para criptografar os dados da cadeia de conexão nos seus arquivos de configuração . Você precisaria encontrar os métodos equivalentes para fazer isso com sua tecnologia de escolha específica.


3
Só queria esclarecer - como a configuração de criptografia ajudará? Pelo que entendi, você precisará compartilhar a mesma senha de descriptografia entre todos os desenvolvedores, e isso parece exigir problemas.
Rogach 20/05

Se alguém de fora da sua empresa obtiver acesso ao seu repositório, suas senhas serão ofuscadas. Se alguém copiar os arquivos de um projeto em uma unidade USB e deixá-lo em algum lugar, a mesma coisa. Será mais trabalho para manter, é claro. Mais segurança geralmente custa o preço da conveniência. Esta solução é um pouco pesada, eu vou lhe dar isso. Estou aberto a uma maneira melhor de resolver a pergunta do OP!
jporcenaluk

5

Muitas pessoas criticam o armazenamento da configuração em arquivos regulares, juntamente com o seu código-fonte, mas, na minha experiência, essa é realmente uma solução muito boa:

  • Simples de implementar em qualquer idioma. Em muitos, você obtém suporte para arquivos de configuração complexos imediatamente. Por exemplo, no caso do Java com Spring Boot, você obtém suporte YAML que pode expressar qualquer estrutura semelhante a uma árvore, e é fácil ter arquivos de configuração separados para diferentes ambientes, bem como uma configuração de linha de base a partir da qual os arquivos específicos do ambiente podem herdar.
  • A configuração é necessária para executar o software, e as alterações no código geralmente exigem que as configurações sejam adicionadas / modificadas, por isso é natural manter a configuração e o código juntos.
  • O armazenamento da configuração com a fonte oferece todos os benefícios do controle da fonte, como saber quem modificou qual configuração e quando ou pode verificar as configurações durante uma revisão regular do código.
  • A menos que você trabalhe para a CIA, o argumento de segurança parece exagerado para mim. Portanto, sua senha do banco de dados é armazenada em um arquivo na máquina em que seu aplicativo é executado. Bem, se alguém obtém acesso à máquina com seu aplicativo, você provavelmente já está com muitos problemas - eles podem, por exemplo, desativar seu aplicativo e iniciar seu próprio aplicativo em seu lugar na mesma porta. Nesse cenário, ter acesso à senha do banco de dados pode não ser um problema tão grande. A menos que todas as suas conexões sejam totalmente criptografadas e tenham acesso à sua máquina, elas podem capturar grande parte dos dados interessantes das interfaces de rede.
  • Você pode usar uma ferramenta como o Hiera para ter um arquivo de configuração de texto, mas não armazenar senhas ou outros dados confidenciais dentro dele.

Portanto, em muitos casos, a configuração textual armazenada no controle de origem juntamente com o código é um bom começo.

Se você estiver em sistemas distribuídos ou desejar trocar sua configuração a quente sem reimplementar seus aplicativos, poderá encontrar uma solução melhor baseada em um servidor de configuração. O Spring Cloud tem suporte para esses mecanismos , e as configurações de veiculação de back-end podem ser um repositório git ou Eureka . Você também pode rolar o seu próprio usando, por exemplo, Zookeeper . Qualquer uma dessas abordagens facilitará o gerenciamento de configurações consistentes em muitos servidores para atualizar configurações sem a necessidade de reconstruir e reimplementar seu software. Isso tem um custo, é claro, que é aprender o servidor de configuração e como usá-lo em seus aplicativos, além de outro sistema para implantar e manter.


Mas o código muda de mãos para alguém que não possui os segredos nos arquivos de configuração, haverá uma verdadeira bagunça.
precisa saber é o seguinte

@TimLudwinski As chaves / segredos pertencem à empresa, não aos desenvolvedores individuais; portanto, elas devem ser mantidas de forma a não se perderem se um indivíduo sair. Eles podem ser problemas e mantidos por administradores / equipe de segurança, por exemplo, para que haja um registro central.
Michał Kosmulski

5

Estamos lutando contra o mesmo problema em que trabalho. No momento, todas as nossas configurações são baseadas em arquivos e controladas pela fonte com os aplicativos individuais que as utilizam. Isso leva à duplicação e aos desenvolvedores tendo acesso às senhas de produção / qa, em vez de apenas desenvolvimento.

Dito isto, acho que apresentamos uma boa solução daqui para frente. Estamos movendo nossos arquivos de configuração para um repositório git separado (rotulado como repositório de configuração). Em seguida, configuramos um servidor spring-cloud-config (java) que simplesmente serve os arquivos do repositório de configuração com base nos perfis transmitidos a ele. Isso é ótimo para aplicativos Java que podem usar o cliente e baixá-los no momento da inicialização. Para nossos aplicativos PHP / não-java, baixaremos o arquivo diretamente. (Não é ideal). No futuro, poderemos escrever algo que permita que o aplicativo PHP faça o download das configurações por conta própria e as armazene em algum lugar, mas não é de alta prioridade na primeira execução. Penso nesta solução como config-as-a-service, que não viola explicitamente as recomendações de aplicativos de 12 fatores.

Eu acredito que o zookeeper pode ser usado para a mesma coisa (eu vi uma configuração com o kubernetes + zookeeper), então não tenho muita certeza do porquê dessa resposta ter um -1 acima.

Ligações:

https://spring.io/guides/gs/centralized-configuration/

https://cloud.spring.io/spring-cloud-config/


3

Em vez de armazenar toda a configuração em um arquivo, armazene-a em vários arquivos.

  • Tenha um diretório de configuração . Todos os arquivos são interpretados como arquivos de configuração, exceto talvez README*.
  • Todos os nomes de arquivos são classificados em ordem alfabética e os arquivos são carregados nessa ordem. É por isso que os arquivos em tais casos, muitas vezes começam com um dígito ou dois: 01-logging.json. 02-database.jsonetc.
  • Os dados de todos os arquivos são carregados na mesma estrutura de configuração disponível para o aplicativo. É assim que vários arquivos podem complementar as configurações uns dos outros e até substituí-los de maneira previsível.
  • Armazene somente no VCS os arquivos de configuração com valores seguros para ver ou valores padrão. Adicione os arquivos de configuração com segredos durante a implantação ou, melhor ainda, use um serviço de armazenamento de segredos autenticado.

Na sua caixa Linux mais próxima, dê uma olhada em /etc/sudoers.dou /etc/nginx/conf.d. Mostra o mesmo padrão.

A gestão de segredos é uma fera diferente. Você pode gerenciá-los como uma etapa manual enquanto é pequeno. Você pode usar coisas como o Zookeeper. Você pode até verificar os segredos em um VCS na forma criptografada e descriptografá-los como uma etapa de implantação. Existem várias outras opções.

(Além disso, um artigo de opinião: JSON não é um bom formato de arquivo de configuração, porque não permite comentários; comentários são cruciais. Os formatos TOML, YAML e até INI são melhores em uso prático.)


2

Eu acho que suas opções são um pouco definidas pelo sistema operacional para o qual você está implantando

Eu sugeriria, sim, coloque os valores no controle de origem. MAS apenas as versões 'dev'. Você quer que seu código fonte compile E funcione! não inclui etapas secretas extras

Seu processo de compilação e implantação deve trocar esses valores por ambiente durante a implantação. (o polvo tem esse tipo de modelo)


0

O Apache zookeeper oferece opções maravilhosas para armazenar as configurações de aplicativos para sistemas distribuídos. As alterações feitas no zookeeper podem ser capturadas e processadas com um curador ou ouvinte do zookeeper no final do aplicativo.


6
Quais são as opções? como funciona? Onde os armazena? Um prefere outro? Quais são as várias vantagens e desvantagens de cada opção? Como isso interage em diferentes sistemas operacionais?

3
@Gangz - Eu estaria interessado em uma resposta mais detalhada, por favor, não desanime com os votos negativos e melhore sua resposta para que possa ser útil.
Jay Elston
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.