DEV Community

Luiz Bernardo
Luiz Bernardo

Posted on

Criando AMI usando o Packer e Amazon Linux 2023 (AL2023) com o Azure Pipelines

Recentemente a AWS anunciou o novo sistema operacional da AWS baseado em Linux. Tem um comparativo super legal entre Amazon Linux 2 e Amazon Linux 2023 [nesse link](https://docs.aws.amazon.com/linux/al2023/ug/compare-with-al2.html). 
Resolvi testar o novo sistema operacional criando a AMI com o Packer. 

Packer HashiCorp é uma ferramenta de automação de criação de imagens de máquinas virtuais que permite criar imagens idênticas para múltiplas plataformas usando arquivos de configuração.

Para instalar o Packer, siga as etapas abaixo:

  1. Acesse o site oficial do Packer: https://www.packer.io/downloads
  2. Faça o download da versão do Packer compatível com o seu sistema operacional.
  3. Extraia o arquivo ZIP baixado em uma pasta de sua escolha.
  4. Adicione a pasta contendo o executável do Packer ao PATH do sistema para que possa ser acessado de qualquer lugar no terminal.
  5. Para verificar se o Packer foi instalado corretamente, abra o terminal e digite o comando "packer version". Se a instalação foi bem-sucedida, a versão do Packer instalada será exibida.

Obs_1: As etapas exatas podem variar dependendo do sistema operacional em que o Packer está sendo instalado.

Obs_2: Essa etapa é apenas informativa, vou utilizar o Azure Pipelines no tutorial abaixo.

Assim como os outros produtos da HashiCorp ele utiliza o HCL2 como linguagem, mas nem sempre foi assim, antes ele utilizava json como linguagem e como ainda estão em fase de migração tem um how to de como fazer a migração para HCL2 [aqui](https://developer.hashicorp.com/packer/tutorials/configuration-language/hcl2-upgrade).

Você pode estar organizando o seu diretório packer com os arquivos abaixo, vamos ver o conteúdo de cada um deles.

├── packer
│    └── provider.pkr.hcl
│    └── builders.pkr.hcl
│    └── sources.pkr.hcl
│    └── variable.pkr.hcl
│    └── locals.pkr.hcl
├── install
│    └── nginx.sh
├── pipelines
│    └── azure_pipelines.yml
Enter fullscreen mode Exit fullscreen mode

provider.pkr.hcl Contém informações sobre o tipo de provedor, como o nome da conta, região e outras configurações específicas do provedor. Vamos ao código:

#provider.pkr.hcl
packer {
  required_plugins {
    amazon = {
      version = ">= 1.2.2"
      source  = "github.com/hashicorp/amazon"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

builders.pkr.hcl Contém informações sobre o tipo de máquina virtual que será criada, como sistema operacional, tamanho da memória, armazenamento e outras configurações relacionadas à infraestrutura. Vamos ao código:

#builders.pkr.hcl
build {
  name    = "ami-packer"
  sources = ["source.amazon-ebs.al-2023"]

  provisioner "shell" {
    environment_vars = ["FOO=hello world"]
    script           = "../install/nginx.sh"
    pause_before     = "10s"
    timeout          = "10s"
  }
}
Enter fullscreen mode Exit fullscreen mode

sources.pkr.hcl Contém informações sobre o tipo de origem, como um arquivo ISO, uma imagem pré-existente ou uma receita do Chef. Vamos ao código:

#sources.pkr.hcl
source "amazon-ebs" "al-2023" {
  ami_name      = "${var.ami_prefix}-${local.timestamp}"
  instance_type = "t3.micro"
  region        = "us-east-1"
  source_ami_filter {
    filters = {
      name                = "al2023-ami-2023.*-kernel-6.1-x86_64"
      root-device-type    = "ebs"
      virtualization-type = "hvm"
    }
    most_recent = true
    owners      = ["amazon"]
  }
  ssh_username = "ec2-user"
  tags = {
    Name = "AMI 2023"
  }
}
Enter fullscreen mode Exit fullscreen mode

variable.pkr.hcl Contém informações sobre o tipo de variável, como seu nome, tipo e valor padrão, que podem ser substituídos por um valor personalizado durante a execução do processo. Vamos ao código:

#variable.pkr.hcl
variable "ami_prefix" {
  type    = string
  default = "AMI"
}
Enter fullscreen mode Exit fullscreen mode

locals.pkr.hcl E Um valor local atribui um nome a uma expressão , portanto, você pode usar o nome várias vezes em um módulo em vez de repetir a expressão. Vamos ao código:

#locals.pkr.hcl
locals {
  timestamp = regex_replace(timestamp(), "[- TZ:]", "")
}
Enter fullscreen mode Exit fullscreen mode

Criei o diretório install apenas para organizar os scripts de instalação do que for interessante, no caso vou estar instalando o Nginx com um arquivo shell nginx.sh. Vamos ao código:

#nginx.sh
#!/bin/bash

# Atualiza os pacotes
sudo dnf update -y

# Instala o Nginx
sudo dnf install nginx -y

# Inicia o serviço do Nginx
sudo systemctl start nginx

# Habilita o serviço do Nginx para iniciar automaticamente na inicialização do sistema
sudo systemctl enable nginx

# Verifica o status do Nginx
sudo systemctl status nginx
Enter fullscreen mode Exit fullscreen mode

Tudo certo, vamos agora ao Azure Pipelines. 

Para organizar também criei um diretório chamado pipelines e inclui o arquivo azure_pipelines.yml. Vamos ao código:

#azure_pipelines.yml
trigger:
  branches:
    include:
    - master
pool:
  vmImage: Ubuntu-20.04
stages:
- stage: BuildAMI
  displayName: Build AMI
  jobs:
  - job: BuildAMI
    displayName: 'Build AMI with Packer'
    steps:
      - task: Bash@3
        displayName: 'Install Packer'
        inputs:
          targetType: 'inline'
          script: |
              echo "# Downloading Packer v1.8.6"
              wget https://releases.hashicorp.com/packer/1.7.6/packer_1.7.6_linux_amd64.zip
              echo "# Unzipping files"
              unzip packer_1.7.6_linux_amd64.zip

              echo "# Configuring packer and checking version"
              export PACKER_PATH=$(which packer)
              ls -lha
              sudo mv packer $PACKER_PATH

              packer -v
      - task: AWSShellScript@1
        displayName: 'Build AMI'
        inputs:
          awsCredentials: aws-teste-dev
          regionName: $(AWS_REGION)
          scriptType: 'inline'
          inlineScript: |
            cd projects/PocPacker/packer
            packer init .
            packer build .
Enter fullscreen mode Exit fullscreen mode

Em outro post eu explico com mais detalhes como executar uma pipeline no Azure Pipelines. Bora executar a pipeline.

Crie um repositório no Azure Repos

Para criar um novo repositório no Azure Repos, siga os seguintes passos:

  1. Abra o seu projeto no Azure DevOps;
  2. Selecione a opção Repositórios no menu lateral esquerdo;
  3. Clique em Novo Repositório no canto superior direito;
  4. Selecione o tipo de repositório que deseja criar (Git ou Team Foundation Version Control);
  5. Defina as opções de configuração do repositório, como nome, descrição e visibilidade;
  6. Clique em Criar para criar o novo repositório.

Após criar o repositório, você poderá cloná-lo localmente para trabalhar em sua máquina, além de adicionar, editar e remover arquivos, criar ramificações e realizar outras operações de gerenciamento de código.

Tudo certo, é só enviar o código para o Azure Repos

  1. Faça o download e instale um cliente de controle de versão de sua preferência, como o Git ou o Azure Repos Extension para o Visual Studio;
  2. Inicialize um repositório Git em seu projeto local, se ainda não tiver feito isso, usando o comando "git init";
  3. Adicione os arquivos e pastas ao seu repositório local usando o comando "git add";
  4. Grave suas alterações locais no repositório usando o comando "git commit";
  5. Conecte seu repositório local ao repositório remoto no Azure Repos usando o comando "git remote add origin ";
  6. Empurre suas alterações locais para o repositório remoto usando o comando "git push origin "

Por último, vamos criar o pipeline no Azure Pipelines.

  1. Selecione o projeto que deseja configurar o pipeline;
  2. Clique em "Pipelines" no menu à esquerda e depois em "New Pipeline";
  3. Escolha o repositório que contém o código do seu projeto (GitHub, Bitbucket, Azure Repos, etc);
  4. Selecione o template do pipeline que deseja utilizar (como .NET Core, Node.js, Python, etc) ou comece do zero;
  5. Configure o pipeline, adicionando tarefas, definindo variáveis, configurando gatilhos e definindo opções de agendamento;
  6. Salve e execute o pipeline.

Agora é só acompanhar o andamento.

Jobs in Run

Criei uma instância EC2 para ver se está tudo ok a partir da imagem que criamos. 

ec2 instance

Espero que tenha gostado, criei um repositório no github com todo código utilizado https://github.com/brbernardo/packer

Vlw flw.

Top comments (2)

Collapse
 
xophere profile image
Chris Schafer

Oh there is a typo in the packer number and echo but I would just swap this code from hashi corp in instead.
developer.hashicorp.com/packer/dow...

wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install packer
Enter fullscreen mode Exit fullscreen mode
Collapse
 
xophere profile image
Chris Schafer

Thanks. I don't speak Portuguese but this was very helpful. :)