Criar imagens de máquina virtual personalizadas com GitHub Actions e Azure
Comece com o GitHub Actions criando um fluxo de trabalho para criar uma imagem de máquina virtual.
Com o GitHub Actions, você pode acelerar o 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 a 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 do Construtor de Imagens do Azure.
Pré-requisitos
- Uma conta do Azure com uma assinatura ativa. Crie uma conta gratuitamente.
- Uma conta do GitHub com um repositório ativo. Caso ainda não tenha uma, inscreva-se gratuitamente.
- Este exemplo usa o aplicativo de exemplo PetClinic em Java Spring.
- Uma Galeria de Computação do Azure com uma imagem.
- Crie uma Galeria de Computação do Azure.
- Criar uma imagem.
Visão geral do arquivo do fluxo de trabalho
Um fluxo de trabalho é definido por um arquivo YAML (.yml) no caminho /.github/workflows/
no repositório. Essa definição contém as várias etapas e os parâmetros que compõem o fluxo de trabalho.
O arquivo tem três seções:
Seção | Tarefas |
---|---|
Autenticação | 1. Adicionar uma identidade gerenciada pelo usuário. 2. Configure uma entidade de serviço ou Open ID Connect. 3. Criar um segredo do GitHub. |
Compilar | 1. Configurar o ambiente. 2. Criar o aplicativo. |
Imagem | 1. Criar uma imagem de VM. 2. Criar uma máquina virtual. |
Criar uma identidade gerenciada pelo usuário
Você precisará de uma identidade gerenciada pelo usuário para o AIB (Construtor de Imagens do Azure) para distribuir imagens. Sua identidade gerenciada atribuída pelo usuário do Azure será usada durante a criação da imagem para ler e gravar imagens em uma Galeria de Imagens Compartilhadas.
Crie uma identidade gerenciada pelo usuário com a CLI do Azure ou o portal do Azure. Anote o nome da sua identidade gerenciada.
Personalize este código JSON. Substitua os espaços reservados para
{subscriptionID}
e{rgName}
pela sua ID de assinatura e 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": [] } ] } }
Use este código JSON para criar uma nova função personalizada com JSON.
No portal do Azure, abra sua Galeria de Computação do Azure e vá para Controle de acesso (IAM).
Selecione Adicionar atribuição de função e atribua a Função de Criação de Imagem à sua identidade gerenciada pelo usuário.
Gerar as credenciais de implantação
Crie uma entidade de serviço com o comando az ad sp create-for-rbac na CLI do Azure. Execute esse 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 essa usam --sdk-auth
com um aviso de substituiçã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 aplicativo do Serviço de Aplicativo semelhante ao mostrado abaixo. Copie esse objeto JSON para uso posterior.
{
"clientId": "<GUID>",
"clientSecret": "<GUID>",
"subscriptionId": "<GUID>",
"tenantId": "<GUID>",
(...)
}
Criar segredos do GitHub
No GitHub, acesse seu repositório.
Acesse Configurações no menu de navegação.
Selecione Segurança > Segredos e variáveis > Ações.
Selecione Novo segredo de repositório.
Cole toda a saída JSON do comando da CLI do Azure no campo valor do segredo. Dê ao segredo o nome
AZURE_CREDENTIALS
.Selecione 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ê autentica usando a ação de logon do Azure com os detalhes da entidade de serviço armazenados em secrets.AZURE_CREDENTIALS
. Em seguida, você executa uma ação da CLI do Azure. Para obter mais informações sobre como consultar os segredos do GitHub em um arquivo do fluxo de trabalho, confira Usando segredos criptografados em um fluxo de trabalho, nos Documentos do GitHub.
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 do SDK de instalação do Java. Para este exemplo, você configurará o ambiente, criará com o Maven e, em seguida, produzirá um artefato.
Os artefatos do GitHub são um modo de compartilhar arquivos em um fluxo de trabalho entre trabalhos. Você criará um artefato para manter o arquivo JAR e, em seguida, 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
Crie 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}
, {rgName}
e {Identity}
pela sua ID de assinatura, nome do grupo de recursos e nome da identidade gerenciada. Substitua os valores de {galleryName}
e {imageName}
pelo nome da galeria de imagens e pelo nome da imagem.
Observação
Se a ação Criar Imagem Assada de 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 build. |
image-builder-template-name |
Não | O nome do recurso de modelo do construtor de imagens usado. |
location |
Sim | O local em que o Construtor de Imagens do Azure será executado. Consulte os locais com suporte. |
build-timeout-in-minutes |
Não | Tempo após o qual o build é cancelado. O valor padrão é 240. |
vm-size |
Opcional | Por padrão, Standard_D1_v2 será usado. Consulte os tamanhos de máquina virtual. |
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 em que 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 | Esse é o diretório na imagem personalizada na qual os artefatos são copiados. |
customizer-windows-update |
Não | Somente Windows. $True. Se true , 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 marcas definidas pelo usuário que são adicionadas à imagem personalizada criada (exemplo: version:beta ). |
Criar sua máquina virtual
Como uma última etapa, crie uma máquina virtual usando sua imagem.
Substitua os espaços reservados para
{rgName}
pelo nome do grupo de recursos.Adicione um segredo do GitHub com a senha da máquina virtual (
VM_PWD
). Certifique-se de anotar a senha porque você não poderá vê-la novamente. O nome de usuário é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 }}"
Concluir YAML
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óximas etapas
- Saiba como implantar no Azure.