Fazendo builds automatizadas na Azure

Posted on Sep 14, 2024

Isso demorou muuuuito mais do que eu esperava, mas eu pelo menos consegui aprender muito. Então, olho por olho

Tudo isso faz parte do meu trabalho de colocar meu blog no fediverso, e adicionar os comentários adicionados lá de forma estática no meu blog. Logo, eu preciso de uma forma de buildar meu site a cada novo comentário, e a maneira mais fácil que eu encontrei foi o Azure Container Apps. Ele me da muita flexibilidade para eu poder buscar os comentários feitos no banco de dados e gerar os arquivos para o mastodon necessários

E eu descobri ainda (depois de apanhar um pouco) que eu preciso da variação jobs, porque o container apps normal espera um serviço online 24/7, como um servidor com APIs. Mas o que eu preciso é que ele rode, crie e publique o site, depois saia e termine com o container. Eu evitei ela antes porque eu pensei que só daria para usar ela como evento, e as opções são bem complexas, como azure queue, pipelines, bus, enfim. Mas depois de pesquisar, eu vi que tem a opção de manual, mas que eu não preciso usar meeesmo a minha mão. Eu posso chamar por api, que vai ser super simples, e super conveniente depois de usar com as Azure Functions!

dockerimage

A imagem de container que eu fiz está bem não otimizada. Ela está agora hospedada no repositório de imagens na própria azure, assim (deve) ser mais rápido para carregar e rodar ela. Mas eu vou ter que mudar depois, porque é pago, e bem careiro até. Eu não levei mais tempo para otimizar ela porque eu não aguento mais usar o SWA. SWA é a ferramenta de linha de comando para fazer builds e deploys para o Azure Static Websites, logo eu vou obrigatoriamente precisar dela. Mas ela deixa muito a desejar. Então depois de eu tiver mais tempo, eu vou otimizar essa imagem, e colocar em um registro publico gratuito

De começo eu queria usar um Alpine Linux, uma imagem super pequena e simples, mas mais que capaz para esse trabalho. Mas depois de mexer um pouco, eu vi nas issues do Github que ela é altamente instável com a SWA, e depois de alguns problemas eu logo descartei porque tinha uma outra opção boa também, a UBI. Essas são imagens da RedHat próprias para containers, e eu que recentemente fiz uma certificação da RedHat como Specialist in Containers (jaba descarado) então quero usar mais as ferramentas dela. E com ela eu tentei muito mais. Enfrentei vário erros, mas eles tinham que ser da ferramenta, o ecossistema RHEL precisa ser grande o suficiente para ele ser suportado. Mas depois de quebrar muito a cabeça, tentar vários hacks, eu decidir tentar um bom e velhor Debian. Funcionou de primeira, e eu não olhei para trás. O Dockerfile está assim

dockerimage

Ela é bem simples, poucas dependências, mas não todas. A melhor maneira de baixar o hugo é direto do Github mesmo, e fora isso é o nodejs, e a azure SWA. O build script tá assim

bashimagem

aqui tem beeem mais coisa. Primeiro é um loop para pegar as variáveis de ambiente, que são umas 5 (eu cortei para não ocupar mais a tela). Tem coisas que eu acho que ficou inuteis. A parte cortada são 3 variáveis relacionadas ao login, que na luta que eu estava tendo antes eu fui colocando coisa. Mas agora que funcionou eu não vou voltar tirando as coisas bobas. E uma coisa chata é que o SWA ao rodar o deploy, acaba baixando outra dependência e ela não pode ser incluida na imagem. Tem issues disso no repositório da CLI, mas é bem capaz que acabe nunca sendo implementado. E no final, mesmo com esse download, a build demora em médias apenas um minuto, então tá tudo bem

E sobre

As Functions

Comparado com o docker, foi mais fácil. Mas eu ainda tive que quebrar bastante a cabeça. Por agora elas são as responsaveis por receber as requests do GitLab, validar a request, e mandar buildar o site. Depois elas também serão usadas para responder as solicitações do mastodon, mas se eu ficar pensando muito nisso minhas cabeça vai explodir kkkkkk

Essa é a primeira parte, a que recebe a resquest mesmo

python1imagem

Digo primeira parte, porque a resposta do gitlab precisa ser rápida (menos de 10 segundos). Que em geral é bem fácil ser alcançado… Se a função estiver quente. As funções quando estão a muito tempo sem ser usada, as são “descarregadas”, e na próxima request elas vão ser carregadas, e lidar com a request. Quando elas estão já estão carregadas/quentes demora 50ms para rodarem, mas o problema é quando elas náo estivem. Então essa funcão é a mais simples possível, e ainda assim eu estou na beira fazendo em média 9s. É bem possível que eu busque depois como deixar elas mais rápidas, e sair do limite

Então ai que entra essa post request no meio do código, ela é a segunda função, para dividir o trabalho e poder responder o mais rápido possível. E ainda tem um pouco da gambiarra em chamar ela usando um outro thread, se não eu precisaria esperar a próxima função terminar, então não ajudaria de nada. Esse é o código dela

python2imagem

Nela fica o trabalho mesmo de iniciar o container. Eu disse no começo que o container seria execudado via API, mas essas bibliotecas da azure são só uma fina camada em volta delas mesmo. Então para deixar o código mais bonito, eu preferi usá-las

Ela também está fazendo a validação desse Gitlab-token, mesmo que não esteja sendo chamada por ele. Mas isso foi escolha minha. A função precisa ser protegida de alguma maneira para que não seja rodada por qualquer um, e ao invés de usar outro valor, eu uso o mesmo do Gitlab, e reutilizo toda a lógica. Eu acho que tem um jeito mais certo, que é mudar o auth_level da função, mas para um MVP isso vai funcionar muito bem

Resultado

Depois de alguns dias quebrando a cabeça, ele está funcionando show! E é muito satisfatório fazer um push no git, e depois ver o histórico de execução de tudo rodando certinho lá. Me preucupa o tempo que isso levou, e que é só o começo. Então eu devo diminuir um pouco o escopo do projeto, só pra ter uma coisa funcionando no final do mês