Quando construímos aplicações em .NET (especialmente .NET Core e posteriores), temos acesso a um pipeline de configuração bastante poderoso, que permite combinar diversas fontes de configuração: arquivos JSON, variáveis de ambiente, User Secrets, Azure Key Vault, entre outras.
Entretanto, não é tão raro esbarrar projetos que utilizem exclusivamente arquivos appsettings.json (e suas variações, como appsettings.Development.json, appsettings.Production.json, etc.) e inadvertidamente não só se ignorem o uso de variáveis de ambiente, mas também impossibilitem sua utilização.
O inferno tem um lugar especial para quem faz isso intencionalmente.
Você talvez já tenha visto projetos manipulando o IConfigurationBuilder para criar instâncias de IConfiguration
.
Por exemplo, ao pesquisar por “IConfigurationBuilder IConfiguration” no google esbarramos na primeira página com uma publicação que sugere o seguinte:

Nesse contexto, temos uma questão.
Essa abordagem remove o que esperamos que seja default em um projeto asp.net.
Remove o que a Microsoft entrega como ponto de partida.
O que esperamos de um projeto .NET qualquer?
Não esperamos muito, apenas o que já vem com o ASP.NET, só esperamos que ninguém sacaneie o projeto removendo as capacidades básicas de configuração.
Pois é isso que a Microsoft entrega no código do Runtime .NET :

Isso quer dizer que, qualquer um que estiver diante de um projeto .NET tem a expectativa de que:
- Possa se usar o arquivo appsettings.json
- Que o arquivo $”appsettings.{env.EnvironmentName}.json” que usa EnvironmentName como parte do nome do arquivo.
- Que em desenvolvimento, seja possível usar UserSecrets
- Que possa usar Variáveis de Ambiente.
- Que possa usar o args, enviado para o processo.
Essa exata sequência é esperada. Nessa ordem, porque a próxima fonte de configuração sobrescreve as fontes de configuração anteriores.
Mas o que você quer dizer com sobrescrever?
As fontes se somam e, assim durante o carregamento o que for comum à duas fontes, é sobrescrito pela última. Last Win.
Assim, se no appsettings.json temos um json
{ "ConnectionStrings": { "xpto": "exemplo1" } }
basta usarmos a variável de ambiente ConnectionStrings__xpto
para sobrescrever o valor com algo que a aplicação reconhecerá.
A variável de ambiente não sobrescreve o arquivo, as fontes se somam em memória, essa a grande diferença desse mecanismo em relação ao que tínhamos no web.config.
Por que usar variáveis de ambiente?
- Segurança: Em muitos cenários, preferimos não colocar senhas e credenciais em arquivos de configuração (que acabam versionados no controle de versão). É mais seguro passar estes dados via variáveis de ambiente ou via serviços de “secret management”.
- Flexibilidade: Quando rodamos a aplicação em diferentes ambientes (desenvolvimento local, homologação, produção), nem sempre é prático ter um appsettings.json para cada pequena variação. As variáveis de ambiente permitem mudar configurações sem precisar mexer no arquivo e sem precisar fazer deploy de novos arquivos.
- Contêineres: Em orquestradores como Docker, Kubernetes, etc., definir variáveis de ambiente nos contêineres é um padrão, simplificando a gestão de configurações externas.
- Cloud: Muitos cloud providers possuem mecanismos de gerenciamento de de configuração que possuem mecanismos para fazer bind da configuração com variáveis de ambiente, assim é possível determinar rollouts que atualizem essas variáveis reiniciando todas as aplicações dependentes dela.
Variáveis de ambiente são best in class?
Negativo: Variáveis de ambiente são melhores do que arquivos de configuração, mas serviços como Vault, são ainda melhores e mais seguros, mas como tudo em tecnologia, não são para todos nem para todos os projetos.
Conclusão
Apesar do template padrão do .NET Core já fornecer uma configuração com suporte a variáveis de ambiente, é comum ver projetos que, por desconhecimento ou tentativa de simplificação, removem esse suporte ou simplesmente não o utilizam em desenvolvimento. Isso leva a grandes dores de cabeça na hora de colocar a aplicação em produção ou em contêineres, pois então surgem necessidades de reescrever partes do projeto para considerar variáveis de ambiente.
O melhor caminho é desde o início assumir que sua aplicação será configurada por múltiplas fontes (appsettings, variáveis de ambiente, secrets etc.), mantendo o pipeline de configuração completo e aproveitando as funcionalidades já existentes no .NET Core. Desse modo, você não ficará “preso” a arquivos JSON e terá maior flexibilidade e segurança para lidar com credenciais e demais configurações em produção.
0 comentários