Docker + Azure DevOps: build e deployment automatizado de aplicações
Plataforma com foco em DevOps e mantida pela Microsoft, o Azure DevOps é uma solução bastante abrangente. Dentre as funcionalidades oferecidas por este serviço estão controle de versão do código-fonte de projetos de software (GIT ou TFVC), gestão de tarefas baseando-se para isto em Scrum ou Kanban, integração contínua e deployment automatizado, automação de testes e dashboards para monitoramento de um projeto como um todo.
Neste tutorial demonstrarei como efetuar o build de imagens Docker e o deployment automatizado empregando containers, fazendo uso para isto dos seguintes recursos:
- Uma API REST criada com o ASP.NET Core 3.1;
- Um repositório do GitHub contendo este projeto baseado no ASP.NET Core 3.1;
- Hospedagem de imagens Docker privadas com Azure Container Registry;
- Hospedagem da aplicação Web com o Azure Web App for Containers;
- O Azure DevOps no build e deployment automatizado da aplicação.
Ao optar pela utilização de Docker em conjunto com o Azure DevOps conseguimos simplificar em muito o processo de build e deployment, já que essa integração nos isenta da necessidade de instalar runtimes específicos e realizar inúmeros ajustes de configuração (as definições presentes no arquivo Dockerfile costumam ser mais do que suficientes para a compilação do projeto e o build da imagem correspondente).
E aproveito este espaço também para um convite…
Que tal aprender mais sobre Azure Functions e desenvolvimento de soluções Serverless, em um workshop que acontecerá durante um sábado (dia 18/01/2020) em São Paulo Capital e implementando um case na prática? Acesse então o link a seguir para efetuar sua inscrição com um desconto especial de 25%: http://bit.ly/anp-serverless-blog-groffe
E caso você precise conhecer mais sobre o Microsoft Azure como um todo, não deixe de aproveitar o preço promocional de lançamento da primeira turma online do treinamento Azure na Prática que acontecerá dia 15/02/2020 (também um sábado). Aproveite para conhecer mais sobre dezenas de serviços e possibilidades oferecidas pelo Azure e, o melhor, no conforto de sua casa ou ambiente de trabalho! Acesse o link a seguir para informações e efetuar sua inscrição: http://bit.ly/anp-online-blog-groffe
Informações sobre o projeto no GitHub
O projeto ASP.NET Core 3.1 que servirá de base para esse tutorial já foi disponibilizado no GitHub:
https://github.com/renatogroffe/ASPNETCore3.1-API-REST_Docker-Alpine
Acabei optando por duplicar este repositório, já que nesta cópia será gravado um arquivo com configurações de build do Azure Pipelines.
Já na listagem a seguir está o conteúdo do arquivo Dockerfile, em que estão referenciadas as imagens Alpine do SDK do .NET Core 3.1 (para restauração de pacotes e build da aplicação) e do runtime do ASP.NET Core 3.1 (com o ambiente necessário para a execução da API REST a partir de um container):
Criando um novo recurso do Azure Container Registry
O Azure Containter Registry permite o armazenamento de imagens de containers de maneira privada, representando assim uma alternativa dentro da nuvem da Microsoft ao Docker Hub.
Nesta seção demonstrarei a criação de um novo recurso baseado no Container Registry, a fim de que no mesmo constem as imagens geradas através do build automatizado do projeto via Azure DevOps. Acionar para isto no Portal do Azure a opção Create a resource:
Em Containers selecionar Container Registry:
E finalmente preencher em Create container registry:
- O nome do recurso (Registry name), o resource group ao qual o mesmo estará vinculado e o Data Center (Location);
- Em Admin user acionar a opção Enable, a fim de que o acesso a este recurso se faça mediante as credenciais de um administrador (geradas pelo próprio Azure).
Confirmar finalmente a geração do Container Registry clicando no botão Create:
Criando um novo projeto do Azure DevOps
Projetos do Azure DevOps estarão agrupados em Organizations. Para o exemplo descrito nesse tutorial será criada uma Organization chamada groffe-demos. Acessar para isto a opção New organization:
Será solicitado então um aceite dos termos de utilização do Azure DevOps:
Informar em seguida o nome da Organization, bem como o Data Center em que novos recursos no Azure DevOps estarão hospedados; concluir este procedimento acionando a opção Continue:
Na tela inicial da Organization groffe-demos será solicitada a criação de um novo projeto, no qual constarão as definições para build e release/deployment da aplicação ASP.NET Core. Preencher para isto os campos Project name e Description, selecionando ainda a opção Private , Git em Version control, Basic em Worker item process e finalmente clicando na opção Create project:
A próxima imagem traz o projeto APIContagem já criado; acionar na sequência a opção Project settings:
Aparecerão agora diversas opções para configuração do projeto:
Deslocar a barra de rolagem para baixo até Pipelines, clicando então na opção Service connections:
Teremos agora que criar uma nova conexão para o recurso do Azure Container Registry gerado anteriormente. Em New service connection selecionar a opção Docker Registry:
Em New Docker Registry service Connection:
- Selecionar a opção Azure Container Registry em Registry type;
- Escolher a assinatura do Azure a ser utilizada em Subscription;
- Em Azure container registry selecionar o Container Registry (groffeazuredevops);
- Em Service connection name informar o nome que identificará esta conexão, além de um texto detalhando a mesma em Description;
- Já em Security a opção Grant access permission to all pipelines deverá estar marcada.
Confirmar este procedimento acionando a opção Save:
Na imagem a seguir podemos observar a conexão ao Azure Container Registry já criada:
Implementando o Pipeline para build automatizado das imagens Docker
Será por meio do Azure Pipelines que definiremos o processo automatizado (pipeline) de build de imagens Docker para o projeto APIContagem. Retornando à seção Summary deste projeto acessar na barra lateral Pipelines > Pipelines, como indicado na imagem a seguir:
Acessar agora a opção Create Pipeline:
Em Where is your code? selecionar a opção GitHub YAML:
Já em Select a repository definir o repositório do GitHub ao qual estará atrelado o pipeline de build:
Será solicitado neste momento que o usuário se autentique junto ao GitHub. Realizado este procedimento, aparecerá agora uma tela com informações do Azure Pipelines:
Descer então com a barra de rolagem até o final da página, certificando-se de que o repositório a ser utilizado está selecionado em Repository access. Confirmar esta escolha acionando o botão Approve and install:
Em Configure your pipeline selecionar a opção Starter pipeline, a fim de iniciar a montagem do pipeline com um mínimo de configurações:
Neste momento aparecerá a tela Revise your pipeline YAML. Posicionar agora o cursor ao final do conteúdo do arquivo YAML com definições de pipeline:
Acionar na sequência o botão Show assistant:
Localizar agora a task Docker e clicar sobre a mesma:
A partir deste ponto serão preenchidas as configurações da task correspondente ao build de uma imagem Docker. Em Container registry selecionar a conexão criada anteriormente para o Azure Container Registry:
Em Container repository informar o nome da imagem a ser gerada (apicontagem-azuredevops para o exemplo aqui descrito):
Já em Commands:
- Certificar-se de que a opção buildAndPush foi selecionada em Command, assim como o caminho/nome do arquivo com as configurações para a geração da imagem em Dockerfile;
- Em Tags acrescentar o valor latest na segunda linha, logo após a configuração $(Build.BuildId) (serão geradas assim uma tag com o número do build e outra identificada como latest, com ambas correspondendo à versão mais recente da aplicação);
- Manter selecionada a opção Add Pipeline metadata to image(s).
Concluir o processo acionando o botão Add:
Na próxima imagem podemos observar o conteúdo do YAML do pipeline de build já atualizado:
Foram acrescentadas as definições destacadas na imagem a seguir (em vermelho):
Concluir a configuração deste pipeline acionando a opção Save and run:
Em Save and run:
- Definir uma mensagem para o campo Commit message;
- Uma descrição opcional poderá ser informada em Optional extended description;
- Manter selecionada a opção Commit directly to the master branch (trabalharemos apenas com a branch master no exemplo deste tutorial).
Acionar finalmente o botão Save and run:
Neste momento terá início um Job para build da imagem Docker da aplicação de testes (ícone azul):
Clicando sobre este Job podemos observar o andamento do mesmo:
Após algum tempo o status do Job indicará que o processo de geração da imagem Docker teve sucesso (ícone verde):
Observando o repositório no GitHub será possível constatar a presença do arquivo azure-pipelines.yml, gerado via Azure DevOps e no qual constam as definições de build:
Já na próxima imagem temos o conteúdo do arquivo azure-pipelines.yml, com as configurações especificadas nos passos anteriores desta seção:
Acessando o recurso do Azure Container Registry criado na seção anterior será possível notar a presença da imagem apicontagem-azuredevops em Repositories:
Clicando sobre esta imagem serão listadas as diferentes tags/versões existentes para a mesma (11 e latest, que basicamente correspondem à mesma imagem):
Testando o build automatizado de imagens
A gravação de uma alteração na branch master fará com que o processo de build das imagens apicontagem-azuredevops seja disparado automaticamente. A fim de simular isto farei aqui uma alteração no arquivo ContadorController.cs:
Uma nova execução do build terá início e poderá ser consultada via Azure DevOps (detalhes como o que acontece no Job envolvido neste processo podem ser obtidos seguindo as orientações da seção anterior):
Após algum tempo o processo concluirá, indicando sucesso na geração de uma nova imagem:
Voltando ao recurso do Azure Container Registry poderemos constatar a presença de uma nova tag de número 12 (a tag latest é a mais atual, juntamente com 12):
Criando um novo recurso do Azure Web App for Containers
Nesta seção demonstrarei a criação de um novo recurso baseado no Azure Web App for Containers, o qual fará uso da imagem apicontagem-azuredevops (hospedada no Container Registry groffeazuredevops) para a execução de instâncias da API de testes a partir de containers na nuvem Microsoft.
Utilizando o Portal do Azure incluir um novo recurso, utilizando para isto a opção Web App for Containers:
Em Web App informar:
- O nome do recurso em Name;
- Em Publish certificar-se de que está selecionada a opção Docker Container, assim como Linux em Operating System;
- Informar ainda o Resource Group, Region (Data Center) e o Linux Plan em App Service Plan (neste último caso definindo a infraestrutura a ser alocada).
Dar andamento à criação do recurso acionando a opção Next: Docker>.
Informar na seção Docker as definições da imagem utilizada no deployment da aplicação:
- Em Options deverá estar marcada a opção Single Container, ao passo que em Image Source será necessário selecionar Azure Container Registry;
- Em Registry informar o nome do recurso do Azure Container Registry;
- Selecionar ainda a imagem em Image, bem como a versão em Tag.
Clicar em seguida no botão Review + create:
Após a revisão acionar finalmente o botão Create, para assim finalizar este processo com a geração de um novo recurso do Azure Web App for Containers:
Na próxima imagem podemos observar o recurso já criado, com o endereço de acesso ao mesmo destacado em vermelho:
Um teste de acesso à API REST trará no resultado a alteração realizada na branch master:
Implementando o Pipeline para release/deployment automatizado
Ainda no Azure Pipelines iremos configurar o pipeline para release/deployment automatizado da aplicação, fazendo uso para isso de imagens do Azure Container Registry e do recurso do Azure Web App for Containers descrito na seção anterior.
Acessar para isso em Pipelines a opção Releases, clicando em seguida no botão New pipeline:
Em Select a template acionar a opção Azure App Service deployment, posicionando o mouse sobre a mesma e efetuando um clique no botão Apply:
Preencher o campo Stage name em Stage com o valor Deploy Web App:
Retornando ao diagrama do Pipeline clicar na opção 1 job, 1 task do item Deploy Web App:
Preencher agora as seguites configurações para a execução do stage Deploy Web App (seção Parameters):
- Em Azure subscription selecionar a assinatura do Azure;
- Em App Type marcar a opção Web App for Containers (Linux);
- Em App service name selecionar o recurso do Azure Web App for Containers criado na seção anterior (groffeapi-azuredevops);
- Em Registry or Namespace informar o Container Registry em que as imagens geradas no build serão armazenadas (groffeazuredevops.azurecr.io);
- Em Repository indicar o nome da imagem (apicontagem-azuredevops).
Acionar então o botão Save, a fim de confirmar as configurações realizadas:
Um comentário poderá ser preenchido na janela Save; concluir este procedimento clicando no botão OK:
Clicar agora na opção + Add em Artifacts:
Em Add an artifact:
- Selecionar a opção Build;
- Em Project deverá estar marcado o projeto APIContagem;
- Selecionar em Source (build pipeline) o pipeline de build de imagens montado anteriormente;
- Certificar-se de que em Default version está marcada a opção Latest (isto fará com que seja utilizada sempre a última imagem Docker gerada);
- Em Source alias deverá estar selecionado o repositório empregado no build das imagens Docker.
Na sequência teremos que ativar o deployment automatizado. Acionar para isto a opção Continuous deployment trigger em Artifacts (ícone com o sinal de um raio):
Marcar então o item Continuos deployment trigger como Enabled:
Neste momento um sinal de check aparecerá do lado do ícone com o raio em Artifacts, indicando que o deployment contínuo/automatizado foi devidamente configurado. Concluir os ajustes clicando no botão Save:
Informar se necessário um comentário na janela Save, confirmando os ajustes realizados através de um clique no botão OK:
Testando o deployment automatizado
Sucessivos commits na branch master resultarão no build de novas imagens da APIs REST (como já demonstrado anteriormente). A novidade agora está também no deployment automatizado após os últimos ajustes, fazendo uso de tais imagens para publicação no recurso baseado no Azure Web App for Containers.
Considerando uma alteração como a indicada a seguir:
Logo depois do build das imagens acontecerá início o deployment automatizado, como indicado na próxima imagem:
Na imagem a seguir podemos observar o deployment em andamento:
E finalmente concluído:
Analisando o recurso do Azure Container Registry veremos que 18 foi a tag da última imagem gerada:
Verificando a seção Container settings do recurso do Azure Web App for Containers é possível constatar que o mesmo já foi atualizado para trabalhar com containers baseados nesta tag (18):
Acessando a API para testes notaremos que no retorno da mesma já consta a alteração efetuada na classe ContadorController.cs: