Crie imagens de máquina virtual personalizadas com o GitHub Actions e o Azure

Comece a usar as Ações do GitHub criando um fluxo de trabalho para criar uma imagem de máquina virtual.

Com o GitHub Actions, você pode acelerar seu processo de CI/CD criando imagens de máquina virtual personalizadas com artefatos de seus fluxos de trabalho. Você pode criar imagens e distribuí-las para uma Galeria de Imagens Compartilhadas.

Em seguida, você pode usar essas imagens para criar máquinas virtuais e conjuntos de dimensionamento de máquinas virtuais.

A ação de criar imagem de máquina virtual usa o serviço Azure Image Builder.

Pré-requisitos

Visão geral do arquivo de fluxo de trabalho

Um fluxo de trabalho é definido por um arquivo YAML (.yml) no caminho no /.github/workflows/ repositório. Esta definição contém as várias etapas e parâmetros que compõem o fluxo de trabalho.

O ficheiro tem três secções:

Secção Tarefas
Autenticação 1. Adicione uma identidade gerenciada pelo usuário.
2. Configure uma entidade de serviço ou Open ID Connect.
3. Crie um segredo do GitHub.
Compilação 1. Configure o ambiente.
2. Crie o aplicativo.
Image 1. Crie uma imagem de VM.
2. Crie uma máquina virtual.

Criar uma identidade gerenciada pelo usuário

Você precisará de uma identidade gerenciada pelo usuário para o Azure Image Builder (AIB) para distribuir imagens. Sua identidade gerenciada atribuída pelo usuário do Azure será usada durante a compilação da imagem para ler e gravar imagens em uma Galeria de Imagens Compartilhadas.

  1. Crie uma identidade gerenciada pelo usuário com a CLI do Azure ou o portal do Azure. Anote o nome da sua identidade gerenciada.

  2. Personalize este código JSON. Substitua os espaços reservados para {subscriptionID} e com o ID da assinatura e {rgName}o nome do grupo de recursos.

    {
    "properties": {
        "roleName": "Image Creation Role",
        "IsCustom": true,
        "description": "Azure Image Builder access to create resources for the image build",
        "assignableScopes": [
          "/subscriptions/{subscriptionID}/resourceGroups/{rgName}"
        ],
        "permissions": [
            {
                "actions": [
                    "Microsoft.Compute/galleries/read",
                    "Microsoft.Compute/galleries/images/read",
                    "Microsoft.Compute/galleries/images/versions/read",
                    "Microsoft.Compute/galleries/images/versions/write",
                    "Microsoft.Compute/images/write",
                    "Microsoft.Compute/images/read",
                    "Microsoft.Compute/images/delete"
                ],
                "notActions": [],
                "dataActions": [],
                "notDataActions": []
            }
        ]
        } 
    } 
    
  3. Use este código JSON para criar uma nova função personalizada com JSON.

  4. No portal do Azure, abra sua Galeria de Computação do Azure e vá para Controle de acesso (IAM).

  5. Selecione Adicionar atribuição de função e atribua a Função de Criação de Imagem à sua identidade gerenciada pelo usuário.

Gerar credenciais de implantação

Crie uma entidade de serviço com o comando az ad sp create-for-rbac na CLI do Azure. Execute este comando com o Azure Cloud Shell no portal do Azure ou selecionando o botão Experimentar .

az ad sp create-for-rbac --name "myML" --role contributor \
                            --scopes /subscriptions/<subscription-id>/resourceGroups/<group-name> \
                            --json-auth

O parâmetro --json-auth está disponível nas versões >da CLI do Azure = 2.51.0. Versões anteriores a este uso --sdk-auth com um aviso de descontinuação.

No exemplo acima, substitua os espaços reservados pela ID da assinatura, nome do grupo de recursos e nome do aplicativo. A saída é um objeto JSON com as credenciais de atribuição de função que fornecem acesso ao seu aplicativo do Serviço de Aplicativo semelhante ao abaixo. Copie este objeto JSON para mais tarde.

  {
    "clientId": "<GUID>",
    "clientSecret": "<GUID>",
    "subscriptionId": "<GUID>",
    "tenantId": "<GUID>",
    (...)
  }

Criar segredos do GitHub

  1. No GitHub, vá para o seu repositório.

  2. Vá para Configurações no menu de navegação.

  3. Selecione Segredos de Segurança > e Ações de variáveis>.

    Screenshot of adding a secret

  4. Selecione Novo segredo do repositório.

  5. Cole toda a saída JSON do comando CLI do Azure no campo de valor do segredo. Dê o nome AZURE_CREDENTIALSao segredo .

  6. Selecione Add secret (Adicionar segredo).

Usar a ação de logon do Azure

Use seu segredo do GitHub com a ação Logon do Azure para autenticar no Azure.

Neste fluxo de trabalho, você se autentica usando a ação de logon do Azure com os detalhes da entidade de serviço armazenados no secrets.AZURE_CREDENTIALS. Em seguida, execute uma ação da CLI do Azure. Para obter mais informações sobre como fazer referência a segredos do GitHub em um arquivo de fluxo de trabalho, consulte Usando segredos criptografados em um fluxo de trabalho no GitHub Docs.

on: [push]

name: Create Custom VM Image

jobs:
  build-image:
    runs-on: ubuntu-latest
    steps:
      - name: Log in with Azure
        uses: azure/login@v1
        with:
          creds: '${{ secrets.AZURE_CREDENTIALS }}'

Configurar o Java

Configure o ambiente Java com a ação Java Setup SDK. Neste exemplo, você configurará o ambiente, compilará com o Maven e, em seguida, produzirá um artefato.

Os artefatos do GitHub são uma maneira de compartilhar arquivos em um fluxo de trabalho entre trabalhos. Você criará um artefato para armazenar o arquivo JAR e adicioná-lo à imagem da máquina virtual.

on: [push]

name: Create Custom VM Image

jobs:
  build-image:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        java: [ '17' ]

    steps:
    - name: Checkout
      uses: actions/checkout@v3    

    - name: Login via Az module
      uses: azure/login@v1
      with:
        creds: ${{secrets.AZURE_CREDENTIALS}}

    - name: Set up JDK ${{matrix.java}}
      uses: actions/setup-java@v2
      with:
        java-version: ${{matrix.java}}
        distribution: 'adopt'
        cache: maven
    - name: Build with Maven Wrapper
      run: ./mvnw -B package
        
    - name: Build Java
      run: mvn --batch-mode --update-snapshots verify

    - run: mkdir staging && cp target/*.jar staging
    - uses: actions/upload-artifact@v2
      with:
        name: Package
        path: staging

Construa a sua imagem

Use a ação Criar Imagem de Máquina Virtual do Azure para criar uma imagem de máquina virtual personalizada.

Substitua os espaços reservados para {subscriptionID}o , e pelo ID da assinatura, {rgName}nome do grupo de recursos e {Identity} nome da identidade gerenciada. Substitua os valores de e pelo nome da galeria de imagens e {imageName} o nome da {galleryName} imagem.

Nota

Se a ação Criar Imagem Baked do Aplicativo falhar com um erro de permissão, verifique se você atribuiu a Função de Criação de Imagem à sua identidade gerenciada pelo usuário.

    - name: Create App Baked Image
      id: imageBuilder
      uses: azure/build-vm-image@v0
      with:
        location: 'eastus2'
        resource-group-name: '{rgName}'
        managed-identity: '{Identity}' # Managed identity
        source-os-type: 'windows'
        source-image-type: 'platformImage'
        source-image: MicrosoftWindowsServer:WindowsServer:2019-Datacenter:latest #unique identifier of source image
        dist-type: 'SharedImageGallery'
        dist-resource-id: '/subscriptions/{subscriptionID}/resourceGroups/{rgName}/providers/Microsoft.Compute/galleries/{galleryName}/images/{imageName}/versions/0.1.${{ GITHUB.RUN_ID }}' #Replace with the resource id of your shared image  gallery's image definition
        dist-location: 'eastus2'

Argumentos de ação da máquina virtual

Entrada Obrigatório Descrição
resource-group-name Sim O grupo de recursos usado para armazenar e salvar artefatos durante o processo de compilação.
image-builder-template-name Não O nome do recurso de modelo do construtor de imagens usado.
location Sim O local onde o Azure Image Builder será executado. Consulte os locais suportados.
build-timeout-in-minutes Não Tempo após o qual a compilação é cancelada. O padrão é 240.
vm-size Opcional Por padrão, Standard_D1_v2 será usado. Consulte os tamanhos das máquinas virtuais.
managed-identity Sim A identidade gerenciada pelo usuário que você criou anteriormente. Use o identificador completo se sua identidade estiver em um grupo de recursos diferente. Use o nome se ele estiver no mesmo grupo de recursos.
source-os Sim O tipo de SO da imagem base (Linux ou Windows)
source-image-type Sim O tipo de imagem base que será usado para criar a imagem personalizada.
source-image Sim O identificador de recurso para a imagem base. Uma imagem de origem deve estar presente na mesma região do Azure definida no valor de entrada do local.
customizer-source Não O diretório onde você pode manter todos os artefatos que precisam ser adicionados à imagem base para personalização. Por padrão, o valor é ${{ GITHUB.WORKSPACE }}/workflow-artifacts.
customizer-destination Não Este é o diretório na imagem personalizada para o qual os artefatos são copiados.
customizer-windows-update Não Apenas para Windows. Valor booleano. Se trueo , o construtor de imagens executará a atualização do Windows no final das personalizações.
dist-location Não Para SharedImageGallery, este é o dist-type.
dist-image-tags Não Essas são tags definidas pelo usuário que são adicionadas à imagem personalizada criada (exemplo: version:beta).

Crie sua máquina virtual

Como último passo, crie uma máquina virtual a partir da sua imagem.

  1. Substitua os espaços reservados por {rgName}pelo nome do grupo de recursos.

  2. Adicione um segredo do GitHub com a senha da máquina virtual (VM_PWD). Certifique-se de anotar a senha, porque você não será capaz de vê-la novamente. O nome de utilizador é myuser.

    - name: CREATE VM
      uses: azure/CLI@v1
      with:
        azcliversion: 2.0.72
        inlineScript: |
        az vm create --resource-group ghactions-vMimage  --name "app-vm-${{ GITHUB.RUN_NUMBER }}"  --admin-username myuser --admin-password "${{ secrets.VM_PWD }}" --location  eastus2 \
            --image "${{ steps.imageBuilder.outputs.custom-image-uri }}"              

YAML completo

  on: [push]

  name: Create Custom VM Image

  jobs:
    build-image:
      runs-on: ubuntu-latest    
      steps:
      - name: Checkout
        uses: actions/checkout@v2    

      - name: Login via Az module
        uses: azure/login@v1
        with:
          creds: ${{secrets.AZURE_CREDENTIALS}}

      - name: Setup Java 1.8.x
        uses: actions/setup-java@v1
        with:
          java-version: '1.8.x'
          
      - name: Build Java
        run: mvn --batch-mode --update-snapshots verify

      - run: mkdir staging && cp target/*.jar staging
      - uses: actions/upload-artifact@v2
        with:
          name: Package
          path: staging

      - name: Create App Baked Image
        id: imageBuilder
        uses: azure/build-vm-image@v0
        with:
          location: 'eastus2'
          resource-group-name: '{rgName}'
          managed-identity: '{Identity}' # Managed identity
          source-os-type: 'windows'
          source-image-type: 'platformImage'
          source-image: MicrosoftWindowsServer:WindowsServer:2019-Datacenter:latest #unique identifier of source image
          dist-type: 'SharedImageGallery'
          dist-resource-id: '/subscriptions/{subscriptionID}/resourceGroups/{rgName}/providers/Microsoft.Compute/galleries/{galleryName}/images/{imageName}/versions/0.1.${{ GITHUB.RUN_ID }}' #Replace with the resource id of your shared image  gallery's image definition
          dist-location: 'eastus2'

      - name: CREATE VM
        uses: azure/CLI@v1
        with:
          azcliversion: 2.0.72
          inlineScript: |
          az vm create --resource-group ghactions-vMimage  --name "app-vm-${{ GITHUB.RUN_NUMBER }}"  --admin-username myuser --admin-password "${{ secrets.VM_PWD }}" --location  eastus2 \
              --image "${{ steps.imageBuilder.outputs.custom-image-uri }}"              

Próximos passos

  • Saiba como implantar no Azure.