Integração Contínua + ACR

João ChiroliJoão Chiroli
4 min read

Laboratório 2 – Pipeline com Testes de Código + Publicação de Docker Image no ACR

  • Cenário: O time agora precisa versionar builds internamente.

  • Tarefas:

    • Gerar uma Docker image

    • Publicar no Azure Container Registry

    • Stages separados

  • Desafio real: Garantir que somente builds que passam os testes são publicados.

Pré requisitos

  • Ter feito o laboratório Pipeline CI com Validação (https://joaochiroli.com.br/pipeline-ci-com-validacao) iremos usar a mesma estrutura

  • Nesta etapa iremos fazer as configurações direto na branch main, desabilite a politica que bloqueia edições e commits direto na branch main.

1️⃣ Step 1: Ajustar configurações no arquivo azure-pipelines.yml

trigger:
  branches:
    include:
    -  main

pr:
  branches:
    include:
    -  main


stages:

# 1️⃣ Instala, Valida e Publica o Código

  - stage: InstallAndValidate
    displayName: Install And Validate
    pool: 
      vmImage: 'ubuntu-latest'
    jobs:
    - job: InstallAndValidate
      displayName: 'InstallAndValidate'
      steps:
      - checkout: self
        displayName: 'Checkout code'

      - task: UseNode@1
        inputs:
          version: '15.x'
        displayName: 'Install Node.js'

      - script: npm ci
        workingDirectory: '$(Build.SourcesDirectory)/assessment-cc-sre-kubernetes-sr-01/codebase/rdicidr-0.1.0'
        displayName: 'Install dependencies with ci'

      - script: npm run lint
        workingDirectory: '$(Build.SourcesDirectory)/assessment-cc-sre-kubernetes-sr-01/codebase/rdicidr-0.1.0'
        displayName: 'Linter (ESLint)'      

      - script: |
          npm install --save-dev prettier
          npm run prettier 
        workingDirectory: '$(Build.SourcesDirectory)/assessment-cc-sre-kubernetes-sr-01/codebase/rdicidr-0.1.0'
        displayName: 'Formatter (Prettier)'
        continueOnError: 'true'

      - script: CI=true npm run test
        workingDirectory: '$(Build.SourcesDirectory)/assessment-cc-sre-kubernetes-sr-01/codebase/rdicidr-0.1.0'
        displayName: 'Test (Jest) CI=true'

      - task: PublishPipelineArtifact@1
        inputs:
          targetPath: '$(Build.SourcesDirectory)/assessment-cc-sre-kubernetes-sr-01/codebase/rdicidr-0.1.0'
          artifact: 'validated-source'
          publishLocation: 'pipeline'
        displayName: 'Validated Source'

2️⃣ Step 2: Configurar uma conexão com o ARM service Connection

  1. Criar o Service Connection ARM:

    • Acesse o projeto no Azure DevOps.

    • Vá até Project Settings (canto inferior esquerdo).

    • Clique em Service connections (na seção “Pipelines”).

    • Clique em New service connection.

    • Escolha Azure Resource Manager.

    • Selecione Service principal (automatic) e clique em Next.

    • Escolha:

      • Subscription: selecione a desejada.

      • Resource Group (opcional): para limitar o escopo.

      • Service connection name: nome amigável para uso nas pipelines.

    • Marque Grant access permission to all pipelines (se necessário).

    • Clique em Save.

3️⃣Step 3: Criar o Docker Container Registry no Azure

1. Criar o ACR e Habilitar o Acesso Admin :

  • Acesse o portal do Azure.
  • No menu lateral, clique em "Container registries".

  • Clique em "+ Create".

  • Preencha os campos:

    • Subscription: selecione sua assinatura.

    • Resource Group: escolha um existente ou clique em "Create new".

    • Registry name: defina um nome único (ex.: meuacrdevops).

    • Location: selecione a região desejada.

    • SKU: escolha Basic, Standard ou Premium (geralmente Standard para DevOps).

  • Clique em "Review + Create".

  • Clique em "Create" para finalizar.

  1. Habilitar o Acesso Admin (Access Keys)

    1. Após criado, acesse seu ACR (vá em Container registries → Seu Registry).

    2. No menu lateral, clique em "Access keys".

    3. Ative a opção "Admin user" → marque como "Enabled".

    4. Serão exibidos:

      • Username (usuário do ACR)

      • Password / Password2 (senhas geradas)

4️⃣ Step 4: Criar o Dockerfile na raiz do projeto

  • Nesta etapa iremos realizar também a instalação dos pacotes e o build da aplicação tudo isso direto no Dockerfile.

  • Dockerfile:

      FROM node:15 AS builder
      WORKDIR /app
      COPY . .
      RUN npm ci && npm run build
    
      FROM node:15
      WORKDIR /app
      COPY --from=builder /app .
      RUN npm ci --omit=dev
      EXPOSE 3000
      CMD ["npm", "start"]
    

5️⃣ Step 5: Build e push para o ACR

  • Criação do stage que será responsável por fazer o build e o envio da imagem para o ACR:

    • azure-pipelines.yml

# 2️⃣ Builda e publica a imagem no Acr

  - stage: BuildAndPackage
    displayName: Build And Package
    dependsOn: InstallAndValidate
    condition: succeeded()
    pool: 
      vmImage: 'ubuntu-latest'
    jobs:
    - job: BuildAndPackage
      displayName: 'BuildAndPackage'
      steps:
      - task: DownloadPipelineArtifact@2
        inputs:
          artifactName: 'validated-source'
          targetPath: '$(Pipeline.Workspace)/validated-source'

      - task: UseNode@1
        inputs:
          version: '15.x'
        displayName: 'Install Node.js'

      - task: AzureCLI@2
        inputs:
          azureSubscription: 'projeto-user-arm'
          scriptType: 'bash'
          scriptLocation: 'inlineScript'
          inlineScript: | 
            az acr login --name acrplaygroundproject         
            docker build -t acrplaygroundproject.azurecr.io/playgroundgapp:$(Build.BuildId) $(Pipeline.Workspace)/validated-source
            docker push acrplaygroundproject.azurecr.io/playgroundgapp:$(Build.BuildId)
        displayName: 'Build and Push Docker Image'

Imagem salva no meu registry:

  • Ponto de atenção: ao usar o comando az acr login --name acrplaygroundproject o acrplaygroundproject tem que ser o nome do seu acr

6️⃣ Step 6: Arquivo yaml finalizado

trigger:
  branches:
    include:
    -  main

pr:
  branches:
    include:
    -  main


stages:

# 1️⃣ Instala, Valida e Publica o Código

  - stage: InstallAndValidate
    displayName: Install And Validate
    pool: 
      vmImage: 'ubuntu-latest'
    jobs:
    - job: InstallAndValidate
      displayName: 'InstallAndValidate'
      steps:
      - checkout: self
        displayName: 'Checkout code'

      - task: UseNode@1
        inputs:
          version: '15.x'
        displayName: 'Install Node.js'

      - script: npm ci
        workingDirectory: '$(Build.SourcesDirectory)/assessment-cc-sre-kubernetes-sr-01/codebase/rdicidr-0.1.0'
        displayName: 'Install dependencies with ci'

      - script: npm run lint
        workingDirectory: '$(Build.SourcesDirectory)/assessment-cc-sre-kubernetes-sr-01/codebase/rdicidr-0.1.0'
        displayName: 'Linter (ESLint)'      

      - script: |
          npm install --save-dev prettier
          npm run prettier 
        workingDirectory: '$(Build.SourcesDirectory)/assessment-cc-sre-kubernetes-sr-01/codebase/rdicidr-0.1.0'
        displayName: 'Formatter (Prettier)'
        continueOnError: 'true'

      - script: CI=true npm run test
        workingDirectory: '$(Build.SourcesDirectory)/assessment-cc-sre-kubernetes-sr-01/codebase/rdicidr-0.1.0'
        displayName: 'Test (Jest) CI=true'

      - task: PublishPipelineArtifact@1
        inputs:
          targetPath: '$(Build.SourcesDirectory)/assessment-cc-sre-kubernetes-sr-01/codebase/rdicidr-0.1.0'
          artifact: 'validated-source'
          publishLocation: 'pipeline'
        displayName: 'Validated Source'


# 2️⃣ Builda e publica a imagem no Acr

  - stage: BuildAndPackage
    displayName: Build And Package
    dependsOn: InstallAndValidate
    condition: succeeded()
    pool: 
      vmImage: 'ubuntu-latest'
    jobs:
    - job: BuildAndPackage
      displayName: 'BuildAndPackage'
      steps:
      - task: DownloadPipelineArtifact@2
        inputs:
          artifactName: 'validated-source'
          targetPath: '$(Pipeline.Workspace)/validated-source'

      - task: AzureCLI@2
        inputs:
          azureSubscription: 'projeto-user-arm'
          scriptType: 'bash'
          scriptLocation: 'inlineScript'
          inlineScript: | 
            az acr login --name acrplaygroundproject         
            docker build -t acrplaygroundproject.azurecr.io/playgroundgapp:$(Build.BuildId) $(Pipeline.Workspace)/validated-source
            docker push acrplaygroundproject.azurecr.io/playgroundgapp:$(Build.BuildId)
        displayName: 'Build and Push Docker Image'
0
Subscribe to my newsletter

Read articles from João Chiroli directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

João Chiroli
João Chiroli