Este é o primeiro post de uma nova série que estou iniciando aqui no blog. A ideia desta nova série é apresentar insights sobre Microsoft Azure. Insights estes que pude computar ao longo dos últimos quatro anos trabalhando em projetos dos mais diferentes tipos e tamanhos utilizando como plataforma de backend o Azure. Falei um pouco sobre isso na página que hospeda todos os posts da série (ver link abaixo).
Fico feliz em iniciar a série falando sobre um assunto que não é tradicional aqui do blog – PHP. Se você já teve a curiosidade de navegar por aqui, deve ter constatado que os assuntos tratados são quase sempre associados a tecnologias Microsoft, como ASP.NET, Azure, C#, dentre outras. Mas hoje estamos mudando o padrão. Vamos falar sobre um insight relacionado a aplicações PHP que são hospedadas em Web Apps (um recurso do PaaS do Azure) e que precisam de configurações adicionais, além daquelas tradicionalmente disponibilizadas pelo portal de gerenciamento ou até mesmo via Power Shell ou Azure CLI.
Digo que fico feliz por falar sobre isso a esta altura, porque realmente acho bem legal ver uma plataforma oferecer recursos e serviços para diferentes tecnologias, como é o caso do Azure. Hoje bem mais maduro, o Azure consegue oferecer de fato, serviços robustos para aplicações como PHP, Ruby, Java, Pyton e claro, .NET. O que prova esta afirmação é a grande quantidade de projetos open source que têm sido migrados para a plataforma.
O problema
Um dos grandes diferenciais do Azure em relação a seus concorrentes é a ampla gama de serviços oferecidos no modelo PaaS. Sabemos que é um grande diferencial porque esta vertical acumula uma série de aspectos positivos, dentre os quais podemos destacar: simplicidade na gestão dos recursos, segurança acoplada e redução considerável de custos.
Uma vez que isso é posicionado da maneira correta para um cliente e ainda, existindo a viabilidade técnica (essa é uma análise que deve ser criteriosamente realizada por pessoal competente) de mover determinada solução para a nuvem, um interesse natural pelo modelo PaaS surge. Afinal de contas, quem não quer pagar menos e ter menos trabalho para gerenciar uma aplicação?
Especificamente considerando a natureza das aplicações web, quando aumentamos o zoom sobre a área, é super comum encontrarmos aplicações de todos os portes estruturadas sobre PHP. Considerando ainda que a viabilidade técnica da migração para PaaS foi confirmada, o que acontece então? Inicia-se o processo de movimentação destas aplicações PHP para um ambiente PaaS. Geralmente (por n razões que fogem ao escopo deste texto), a escolha natural é por um ambiente de Web App (anteriormente, Azure Websites).
O problema do qual irei tratar neste texto surge (em geral por desconhecimento) quando a aplicação já encontra-se hospedada no Azure Web App. O problema é:
Preciso customizar os recursos do servidor mas não consigo. Como resolver?
Se você já fez alguma coisa mais séria com PHP, deve saber que uma prática comum por parte dos desenvolvedores no sentido de otimizar a execução da aplicação, é fazer com que ela (aplicação) se integre de maneira ótima com os recursos do servidor e essa amarração é realizada através da criação dos famosos arquivos “.htaccess”. Nestes arquivos são estruturadas diretivas que “falam” de maneira direta com o servidor web disponibilizando características interessantes do mesmo para a aplicação.
O problema destacado acima começa a aparecer para a maioria das aplicações no Azure por um motivo muito simples: em geral, aplicações PHP são hospedadas em ambientes Linux (seu habitat natural) e por consequência rodam sobre Apache, logo, estes arquivos são estruturados para utilizar os recursos deste container web. Como as Web Apps do Azure rodam todas sobre Windows com IIS (sim, hoje em dia o IIS oferece um bom suporte para PHP), naturalmente as configurações deixam de funcionar neste novo ambiente. Como fazemos então para solucionar problemas como este?
Solução recomendada (boa prática)
Felizmente existe uma solução efetiva e relativamente simples de ser implementada. Trata-se de um processo de tradução destes arquivos .htaccess baseados em Apache (ou outra tecnologia que se estava utilizando), para um equivalente que o IIS seja capaz de “entender”. E qual é mesmo o arquivo de configuração que o IIS conhece? Sim, “web.config”.
A solução recomendada para este tipo de cenário é exatamente criar um novo arquivo de configuração no root do projeto PHP e fazer a tradução dos comandos do arquivo original para este novo respeitando a nomenclatura e propriedades do web.config.
Para exemplificar com um caso prático, considere o seguinte trecho de arquivo .htaccess (Listagem 1) de um projeto PHP real, já em produção em um servidor Linux com Apache.
Listagem 1. Request Filtering definido em um arquivo .htaccess
Uma breve explicação: o código da Listagem 1 faz uso da diretiva FilesMatch para fazer uma filtragem em relação a requisições diretas para arquivos ou componentes internos da aplicação. Bem importante a implementação desta regra e de fato, não há como ficar sem.
O que fazemos na Listagem 2 (a seguir) é implementar esta mesma regra em um arquivo web.config, inteligível ao IIS e que portanto garantirá o mesmo comportamento para a aplicação.
Listagem 2. Request filtering definido para um arquivo web.config
Com esta abordagem conseguimos endereçar o problema mencionado anteriormente de maneira elegante e efetiva. O único ponto de atenção aqui é o fato de que, geralmente, desenvolvedores PHP não conhecem tão bem o modus operandi do IIS e isso aumenta um pouco a curva de implantação da solução no ambiente de produção das Web Apps. Entretanto é um custo que vale a pena ter, considerando todos os benefícios oferecidos pelo modelo de plataforma e especialmente o de Web Apps.
Além disso, vale salientar que, de forma geral, arquivos web.config são vem mais legíveis que arquivos .htaccess. É claro que isso depende do ponto de vista mas, não poderia deixar de dar meus 2 cents 🙂 .
Uma dica importante aqui é: na grande maioria dos casos, as alterações de comportamento implementadas no web.config não são automaticamente aplicadas/refletidas pelo IIS. Se isso ocorrer com você, um simples restart na Web App (via portal, PowerShell ou CLI) deverá resolver o problema.
É isso. Espero que este insight lhe seja útil em algum momento no futuro.
Pingback: Insight – A importância do Availability Set e do Affinity Group em um projeto no Azure – Fabrício Sanchez