Tutorial Anterior: Estação de Trabalho como Código (Parte 8): Criando Imagens com Packer
Introdução
Criar imagens com Packer é apenas metade da história. A outra metade é garantir que essas imagens funcionem conforme esperado. Antes de usar uma imagem em produção ou em um laboratório crítico, você deve testá-la e validá-la. Isso envolve iniciar máquinas virtuais a partir da imagem, executar testes de funcionalidade, verificar configurações de segurança e garantir que tudo está funcionando corretamente.
Neste tutorial, vamos aprender a criar um framework de testes para validar nossas imagens. Vamos usar Terraform para provisionar máquinas virtuais de teste, scripts Bash para executar testes de funcionalidade e segurança, e colecionar os resultados em um relatório estruturado.
Observação: Esta parte é essencial para garantir qualidade das imagens antes de usar em produção. Se você preferir apenas provisionar VMs sem testes, pode pular para a Parte 10. No entanto, recomendamos completar esta parte para entender boas práticas de QA.
Objetivos desta Parte
- Entender a importância de testes em infraestrutura como código
- Criar estrutura de testes para validar imagens
- Usar Terraform para provisionar máquinas virtuais de teste
- Desenvolver scripts de teste automatizados
- Executar testes de funcionalidade e segurança
- Gerar relatórios de validação
- Integrar testes com fluxo de CI/CD
- Documentar e versionar testes
Pré-requisitos
- Conclusão da Parte 8 desta série
- Imagens Packer construídas com sucesso
- Terraform funcionando corretamente
- Conhecimento básico de Bash scripting
A quem se destina
Este tutorial é ideal para:
- DevOps Engineers: Que precisam validar imagens antes de produção
- SysAdmins: Que querem garantir qualidade de infraestrutura
- QA Engineers: Que trabalham com infraestrutura
- Profissionais de TI: Que querem implementar boas práticas
Pré-conhecimento: Conhecimento básico de Terraform, Bash e testes (coberto nas partes anteriores) é recomendado.
Tempo Estimado
⏱ 90-120 minutos
Isso inclui:
- Leitura e compreensão: ~15 min
- Preparação de estrutura: ~10 min
- Criação de testes: ~30 min
- Execução de testes: ~20 min
- Análise de resultados: ~15 min
Dica Útil: Testes podem ser reutilizados para múltiplas imagens, economizando tempo no futuro.
Entendendo Testes em Infraestrutura
Antes de começar, é importante entender por que testes são importantes.
Por que Testar Imagens?
Razões principais:
- Garantir Funcionalidade - Verificar que todos os pacotes estão instalados
- Validar Segurança - Confirmar que hardening foi aplicado
- Detectar Problemas Cedo - Antes de usar em produção
- Documentar Comportamento - Deixar claro o que a imagem faz
- Facilitar Manutenção - Testes ajudam a identificar regressões
Tipos de Testes
| Tipo | Descrição | Exemplos |
|---|
| Funcionalidade | Verifica se recursos funcionam | Pacotes instalados, serviços rodando |
| Segurança | Valida configurações de segurança | Permissões, hardening, atualizações |
| Performance | Mede desempenho | Tempo de boot, uso de recursos |
| Compatibilidade | Testa com diferentes ambientes | Diferentes hipervisores, redes |
| Regressão | Detecta mudanças indesejadas | Comparação com versão anterior |
Verificando Pré-Requisitos
Antes de começar, certifique-se de que seu ambiente está pronto.
Passo 1: Verificar Imagem Packer
1
2
3
4
5
| # Verifique se a imagem foi criada
$ ls -lh ~/workspace-as-code/kvm/templates/debian12-packer.qcow2
# Você deve ver:
# -rw-r--r-- debian12-packer.qcow2 (~ 500 MB)
|
1
2
3
4
5
| # Verifique se Terraform está instalado
$ terraform --version
# Você deve ver:
# Terraform v1.14.5
|
Passo 3: Verificar LIBVIRT
1
2
3
4
5
| # Verifique se libvirtd está rodando
$ systemctl is-active libvirtd
# Você deve ver:
# active
|
Criando Estrutura de Testes
Passo 1: Criar Diretórios
1
2
3
4
5
6
7
| # Crie a estrutura de diretórios
$ mkdir -p ~/workspace-as-code/tests/image-validation/{terraform,scripts,reports}
$ cd ~/workspace-as-code/tests/image-validation
# Verifique
$ pwd
# /home/ubuntu/workspace-as-code/tests/image-validation
|
Passo 2: Criar Arquivos
1
2
3
4
5
6
7
| # Crie os arquivos necessários
$ touch terraform/{main.tf,variables.tf,outputs.tf}
$ touch scripts/{test-functionality.sh,test-security.sh,test-performance.sh,run-all-tests.sh}
$ touch reports/.gitkeep
# Verifique
$ ls -la
|
Passo 1: Criar main.tf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
| $ cat > ~/workspace-as-code/tests/image-validation/terraform/main.tf << 'EOF'
terraform {
required_version = ">= 1.7.0"
required_providers {
libvirt = {
source = "dmacvicar/libvirt"
version = "~> 0.9.2"
}
}
}
provider "libvirt" {
uri = "qemu:///system"
}
# Volume base da imagem
resource "libvirt_volume" "test_image_base" {
name = "debian12-test-base.qcow2"
pool = "templates"
source = var.image_path
format = "qcow2"
}
# Volume da VM de teste (cópia da imagem base)
resource "libvirt_volume" "test_image_disk" {
name = "debian12-test-${var.test_id}.qcow2"
pool = "images"
base_volume_id = libvirt_volume.test_image_base.id
format = "qcow2"
}
# Cloud-Init para configuração de teste
resource "libvirt_cloudinit_disk" "test_cloudinit" {
name = "debian12-test-${var.test_id}-cloudinit.iso"
user_data = base64encode(templatefile("${path.module}/../cloud-init.yml", { ssh_key = file("~/.ssh/terraform-vms.pub") }))
pool = "images"
}
# Máquina Virtual de Teste
resource "libvirt_domain" "test_vm" {
name = "test-debian12-${var.test_id}"
memory = var.vm_memory
vcpu = var.vm_cpus
cpu {
mode = "host-passthrough"
}
cloudinit = libvirt_cloudinit_disk.test_cloudinit.id
network_interface {
network_name = var.network_name
wait_for_lease = true
}
console {
type = "pty"
target_port = "0"
target_type = "serial"
}
disk {
volume_id = libvirt_volume.test_image_disk.id
}
graphics {
type = "spice"
listen_type = "none"
}
depends_on = [libvirt_volume.test_image_base]
}
# Output com informações da VM
output "vm_ip" {
value = libvirt_domain.test_vm.network_interface[0].addresses[0]
description = "IP da máquina virtual de teste"
}
output "vm_name" {
value = libvirt_domain.test_vm.name
description = "Nome da máquina virtual de teste"
}
EOF
# Verifique
$ cat ~/workspace-as-code/tests/image-validation/terraform/main.tf
|
Passo 2: Criar variables.tf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| $ cat > ~/workspace-as-code/tests/image-validation/terraform/variables.tf << 'EOF'
variable "image_path" {
type = string
default = "/home/ubuntu/workspace-as-code/kvm/templates/debian12-packer.qcow2"
description = "Caminho da imagem Packer para teste"
}
variable "test_id" {
type = string
default = "001"
description = "ID único para esta execução de testes"
}
variable "vm_memory" {
type = number
default = 2048
description = "Memória em MB"
}
variable "vm_cpus" {
type = number
default = 2
description = "Número de vCPUs"
}
variable "network_name" {
type = string
default = "lab-network"
description = "Nome da rede"
}
EOF
# Verifique
$ cat ~/workspace-as-code/tests/image-validation/terraform/variables.tf
|
Passo 3: Criar outputs.tf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| $ cat > ~/workspace-as-code/tests/image-validation/terraform/outputs.tf << 'EOF'
output "test_vm_ip" {
value = libvirt_domain.test_vm.network_interface[0].addresses[0]
description = "IP da máquina virtual de teste"
}
output "test_vm_name" {
value = libvirt_domain.test_vm.name
description = "Nome da máquina virtual de teste"
}
output "test_image_path" {
value = var.image_path
description = "Caminho da imagem testada"
}
EOF
# Verifique
$ cat ~/workspace-as-code/tests/image-validation/terraform/outputs.tf
|
Passo 4: Criar Cloud-Init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| $ cat > ~/workspace-as-code/tests/image-validation/cloud-init.yml << 'EOF'
#cloud-config
# Gerenciar /etc/hosts
manage_etc_hosts: true
# Hostname
hostname: test-debian12
fqdn: test-debian12.lab
# Usuários
users:
- name: debian
gecos: "Debian User"
sudo: "ALL=(ALL) NOPASSWD:ALL"
groups: users, sudo
shell: /bin/bash
lock_passwd: false
ssh_authorized_keys:
- ${ssh_key}
# Permitir SSH com senha
ssh_pwauth: true
# Comandos a executar
runcmd:
- echo "Cloud-Init concluído" > /var/log/cloud-init-custom.log
# Pacotes a instalar
packages:
- curl
- wget
EOF
# Verifique
$ cat ~/workspace-as-code/tests/image-validation/cloud-init.yml
|
Criando Scripts de Teste
Passo 1: Teste de Funcionalidade
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
| $ cat > ~/workspace-as-code/tests/image-validation/scripts/test-functionality.sh << 'EOF'
#!/bin/bash
set -e
# Cores para output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Variáveis
TEST_REPORT="reports/functionality-test-$(date +%Y%m%d-%H%M%S).txt"
PASSED=0
FAILED=0
# Função para registrar resultado
test_result() {
local test_name=$1
local result=$2
local message=$3
if [ "$result" -eq 0 ]; then
echo -e "${GREEN}✓${NC} $test_name: $message" | tee -a "$TEST_REPORT"
((PASSED++))
else
echo -e "${RED}✗${NC} $test_name: $message" | tee -a "$TEST_REPORT"
((FAILED++))
fi
}
# Inicializar relatório
echo "Teste de Funcionalidade - $(date)" > "$TEST_REPORT"
echo "========================================" >> "$TEST_REPORT"
echo "" >> "$TEST_REPORT"
# Obter IP da VM
VM_IP=$(terraform -chdir=terraform output -raw test_vm_ip)
SSH_KEY="$HOME/.ssh/terraform-vms"
echo "Testando VM em $VM_IP..."
# Teste 1: Conectividade SSH
echo -e "${YELLOW}[1/8]${NC} Testando conectividade SSH..."
if ssh -i "$SSH_KEY" -o ConnectTimeout=5 -o StrictHostKeyChecking=no debian@"$VM_IP" "echo 'SSH OK'" &> /dev/null; then
test_result "SSH Connectivity" 0 "Conectado com sucesso"
else
test_result "SSH Connectivity" 1 "Falha na conexão SSH"
exit 1
fi
# Teste 2: Verificar Debian
echo -e "${YELLOW}[2/8]${NC} Verificando versão do Debian..."
DEBIAN_VERSION=$(ssh -i "$SSH_KEY" debian@"$VM_IP" "cat /etc/os-release | grep VERSION_ID | cut -d= -f2 | tr -d '\"'")
if [ ! -z "$DEBIAN_VERSION" ]; then
test_result "Debian Version" 0 "Debian $DEBIAN_VERSION detectado"
else
test_result "Debian Version" 1 "Não foi possível detectar versão"
fi
# Teste 3: Verificar pacotes essenciais
echo -e "${YELLOW}[3/8]${NC} Verificando pacotes essenciais..."
PACKAGES=("curl" "wget" "git" "vim" "htop")
for pkg in "${PACKAGES[@]}"; do
if ssh -i "$SSH_KEY" debian@"$VM_IP" "which $pkg" &> /dev/null; then
test_result "Package: $pkg" 0 "Instalado"
else
test_result "Package: $pkg" 1 "Não encontrado"
fi
done
# Teste 4: Verificar espaço em disco
echo -e "${YELLOW}[4/8]${NC} Verificando espaço em disco..."
DISK_USAGE=$(ssh -i "$SSH_KEY" debian@"$VM_IP" "df -h / | tail -1 | awk '{print $5}' | tr -d '%'")
if [ "$DISK_USAGE" -lt 80 ]; then
test_result "Disk Space" 0 "Uso: ${DISK_USAGE}%"
else
test_result "Disk Space" 1 "Uso crítico: ${DISK_USAGE}%"
fi
# Teste 5: Verificar memória
echo -e "${YELLOW}[5/8]${NC} Verificando memória..."
MEMORY=$(ssh -i "$SSH_KEY" debian@"$VM_IP" "free -h | grep Mem | awk '{print $2}'")
test_result "Memory" 0 "Total: $MEMORY"
# Teste 6: Verificar CPUs
echo -e "${YELLOW}[6/8]${NC} Verificando CPUs..."
CPUS=$(ssh -i "$SSH_KEY" debian@"$VM_IP" "nproc")
test_result "CPUs" 0 "Total: $CPUS"
# Teste 7: Verificar hostname
echo -e "${YELLOW}[7/8]${NC} Verificando hostname..."
HOSTNAME=$(ssh -i "$SSH_KEY" debian@"$VM_IP" "hostname")
if [ "$HOSTNAME" = "test-debian12" ]; then
test_result "Hostname" 0 "Correto: $HOSTNAME"
else
test_result "Hostname" 1 "Incorreto: $HOSTNAME"
fi
# Teste 8: Verificar conectividade de rede
echo -e "${YELLOW}[8/8]${NC} Verificando conectividade de rede..."
if ssh -i "$SSH_KEY" debian@"$VM_IP" "ping -c 1 8.8.8.8" &> /dev/null; then
test_result "Network Connectivity" 0 "Conectado à internet"
else
test_result "Network Connectivity" 1 "Sem conectividade"
fi
# Resumo
echo "" >> "$TEST_REPORT"
echo "========================================" >> "$TEST_REPORT"
echo "Resumo: $PASSED passaram, $FAILED falharam" >> "$TEST_REPORT"
echo "========================================" >> "$TEST_REPORT"
echo ""
echo -e "${GREEN}Testes de funcionalidade concluídos!${NC}"
echo "Relatório: $TEST_REPORT"
exit $FAILED
EOF
# Tornar executável
$ chmod +x ~/workspace-as-code/tests/image-validation/scripts/test-functionality.sh
# Verifique
$ ls -la ~/workspace-as-code/tests/image-validation/scripts/
|
Passo 2: Teste de Segurança
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
| $ cat > ~/workspace-as-code/tests/image-validation/scripts/test-security.sh << 'EOF'
#!/bin/bash
set -e
# Cores para output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Variáveis
TEST_REPORT="reports/security-test-$(date +%Y%m%d-%H%M%S).txt"
PASSED=0
FAILED=0
# Função para registrar resultado
test_result() {
local test_name=$1
local result=$2
local message=$3
if [ "$result" -eq 0 ]; then
echo -e "${GREEN}✓${NC} $test_name: $message" | tee -a "$TEST_REPORT"
((PASSED++))
else
echo -e "${RED}✗${NC} $test_name: $message" | tee -a "$TEST_REPORT"
((FAILED++))
fi
}
# Inicializar relatório
echo "Teste de Segurança - $(date)" > "$TEST_REPORT"
echo "========================================" >> "$TEST_REPORT"
echo "" >> "$TEST_REPORT"
# Obter IP da VM
VM_IP=$(terraform -chdir=terraform output -raw test_vm_ip)
SSH_KEY="$HOME/.ssh/terraform-vms"
echo "Testando segurança da VM em $VM_IP..."
# Teste 1: Verificar atualizações disponíveis
echo -e "${YELLOW}[1/6]${NC} Verificando atualizações de segurança..."
UPDATES=$(ssh -i "$SSH_KEY" debian@"$VM_IP" "sudo apt list --upgradable 2>/dev/null | wc -l")
if [ "$UPDATES" -le 5 ]; then
test_result "Security Updates" 0 "$UPDATES atualizações disponíveis"
else
test_result "Security Updates" 1 "$UPDATES atualizações pendentes"
fi
# Teste 2: Verificar SSH hardening
echo -e "${YELLOW}[2/6]${NC} Verificando SSH hardening..."
SSH_CONFIG=$(ssh -i "$SSH_KEY" debian@"$VM_IP" "grep '^PermitRootLogin' /etc/ssh/sshd_config || echo 'not found'")
if [[ "$SSH_CONFIG" == *"no"* ]]; then
test_result "SSH Root Login" 0 "Desabilitado"
else
test_result "SSH Root Login" 1 "Habilitado (risco de segurança)"
fi
# Teste 3: Verificar permissões de arquivo
echo -e "${YELLOW}[3/6]${NC} Verificando permissões de arquivo..."
SUDOERS_PERMS=$(ssh -i "$SSH_KEY" debian@"$VM_IP" "stat -c '%a' /etc/sudoers")
if [ "$SUDOERS_PERMS" = "440" ]; then
test_result "Sudoers Permissions" 0 "Correto: $SUDOERS_PERMS"
else
test_result "Sudoers Permissions" 1 "Incorreto: $SUDOERS_PERMS"
fi
# Teste 4: Verificar firewall
echo -e "${YELLOW}[4/6]${NC} Verificando firewall..."
if ssh -i "$SSH_KEY" debian@"$VM_IP" "sudo ufw status" &> /dev/null; then
test_result "Firewall" 0 "UFW disponível"
else
test_result "Firewall" 1 "UFW não disponível"
fi
# Teste 5: Verificar fail2ban
echo -e "${YELLOW}[5/6]${NC} Verificando fail2ban..."
if ssh -i "$SSH_KEY" debian@"$VM_IP" "which fail2ban-client" &> /dev/null; then
test_result "Fail2ban" 0 "Instalado"
else
test_result "Fail2ban" 1 "Não instalado"
fi
# Teste 6: Verificar logs
echo -e "${YELLOW}[6/6]${NC} Verificando logs de segurança..."
LOGS=$(ssh -i "$SSH_KEY" debian@"$VM_IP" "sudo tail -5 /var/log/auth.log | wc -l")
if [ "$LOGS" -gt 0 ]; then
test_result "Security Logs" 0 "Logs disponíveis"
else
test_result "Security Logs" 1 "Sem logs"
fi
# Resumo
echo "" >> "$TEST_REPORT"
echo "========================================" >> "$TEST_REPORT"
echo "Resumo: $PASSED passaram, $FAILED falharam" >> "$TEST_REPORT"
echo "========================================" >> "$TEST_REPORT"
echo ""
echo -e "${GREEN}Testes de segurança concluídos!${NC}"
echo "Relatório: $TEST_REPORT"
exit $FAILED
EOF
# Tornar executável
$ chmod +x ~/workspace-as-code/tests/image-validation/scripts/test-security.sh
|
Passo 3: Script Principal de Testes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
| $ cat > ~/workspace-as-code/tests/image-validation/scripts/run-all-tests.sh << 'EOF'
#!/bin/bash
set -e
# Cores para output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}Suite de Testes de Validação de Imagens${NC}"
echo -e "${BLUE}========================================${NC}"
echo ""
# Passo 1: Provisionar VM de teste
echo -e "${YELLOW}[1/4] Provisionando máquina virtual de teste...${NC}"
cd terraform
terraform init
terraform validate
terraform plan
terraform apply -auto-approve
cd ..
# Aguardar VM estar pronta
echo -e "${YELLOW}Aguardando VM ficar pronta...${NC}"
sleep 30
# Passo 2: Executar testes de funcionalidade
echo ""
echo -e "${YELLOW}[2/4] Executando testes de funcionalidade...${NC}"
./scripts/test-functionality.sh
# Passo 3: Executar testes de segurança
echo ""
echo -e "${YELLOW}[3/4] Executando testes de segurança...${NC}"
./scripts/test-security.sh
# Passo 4: Limpar recursos
echo ""
echo -e "${YELLOW}[4/4] Limpando recursos...${NC}"
cd terraform
terraform destroy -auto-approve
cd ..
echo ""
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}Suite de testes concluída com sucesso!${NC}"
echo -e "${GREEN}========================================${NC}"
echo ""
echo "Relatórios disponíveis em: reports/"
ls -lh reports/
EOF
# Tornar executável
$ chmod +x ~/workspace-as-code/tests/image-validation/scripts/run-all-tests.sh
|
Executando Testes
Passo 1: Preparar Ambiente
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # Navegue para o diretório de testes
$ cd ~/workspace-as-code/tests/image-validation
# Verifique estrutura
$ tree .
# Você deve ver:
# .
# ├── terraform/
# │ ├── main.tf
# │ ├── variables.tf
# │ └── outputs.tf
# ├── scripts/
# │ ├── test-functionality.sh
# │ ├── test-security.sh
# │ └── run-all-tests.sh
# ├── cloud-init.yml
# └── reports/
|
1
2
3
4
5
6
7
8
9
10
| # Valide a configuração Terraform
$ cd terraform
$ terraform init
$ terraform validate
$ terraform fmt
# Você deve ver:
# Success! The configuration is valid.
$ cd ..
|
Passo 3: Executar Testes Manualmente (Opcional)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # Se preferir executar passo a passo:
# 1. Provisionar VM
$ cd terraform
$ terraform apply -auto-approve
$ cd ..
# 2. Aguardar VM estar pronta
$ sleep 30
# 3. Executar testes
$ ./scripts/test-functionality.sh
$ ./scripts/test-security.sh
# 4. Destruir VM
$ cd terraform
$ terraform destroy -auto-approve
$ cd ..
|
Passo 4: Executar Suite Completa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # Execute a suite completa de testes
$ ./scripts/run-all-tests.sh
# Você verá progresso como:
# ========================================
# Suite de Testes de Validação de Imagens
# ========================================
#
# [1/4] Provisionando máquina virtual de teste...
# [2/4] Executando testes de funcionalidade...
# [3/4] Executando testes de segurança...
# [4/4] Limpando recursos...
#
# ========================================
# Suite de testes concluída com sucesso!
# ========================================
|
Analisando Resultados
Passo 1: Verificar Relatórios
1
2
3
4
5
6
| # Liste os relatórios gerados
$ ls -lh reports/
# Você deve ver:
# -rw-r--r-- functionality-test-20260228-120000.txt
# -rw-r--r-- security-test-20260228-120015.txt
|
Passo 2: Examinar Relatório de Funcionalidade
1
2
3
4
5
6
7
8
9
10
11
12
13
| # Veja o relatório de funcionalidade
$ cat reports/functionality-test-*.txt
# Você deve ver:
# Teste de Funcionalidade - Fri Feb 28 12:00:00 UTC 2026
# ========================================
# ✓ SSH Connectivity: Conectado com sucesso
# ✓ Debian Version: Debian 12 detectado
# ✓ Package: curl: Instalado
# ...
# ========================================
# Resumo: 8 passaram, 0 falharam
# ========================================
|
Passo 3: Examinar Relatório de Segurança
1
2
3
4
5
6
7
8
9
10
11
12
13
| # Veja o relatório de segurança
$ cat reports/security-test-*.txt
# Você deve ver:
# Teste de Segurança - Fri Feb 28 12:00:15 UTC 2026
# ========================================
# ✓ Security Updates: 3 atualizações disponíveis
# ✓ SSH Root Login: Desabilitado
# ✓ Sudoers Permissions: Correto: 440
# ...
# ========================================
# Resumo: 6 passaram, 0 falharam
# ========================================
|
Exemplos Práticos
Exemplo 1: Adicionar Teste Customizado
1
2
3
4
5
6
7
8
9
10
11
12
13
| # Crie um novo teste
$ cat > ~/workspace-as-code/tests/image-validation/scripts/test-custom.sh << 'EOF'
#!/bin/bash
VM_IP=$(terraform -chdir=terraform output -raw test_vm_ip)
SSH_KEY="$HOME/.ssh/terraform-vms"
# Seu teste customizado aqui
ssh -i "$SSH_KEY" debian@"$VM_IP" "your-command-here"
EOF
# Tornar executável
$ chmod +x ~/workspace-as-code/tests/image-validation/scripts/test-custom.sh
|
Exemplo 2: Testar Múltiplas Imagens
1
2
3
4
5
6
7
8
9
10
| # Crie um loop para testar múltiplas imagens
for image in debian12-packer debian12-custom; do
echo "Testando $image..."
terraform -chdir=terraform apply -auto-approve \
-var "image_path=/home/ubuntu/workspace-as-code/kvm/templates/$image.qcow2"
./scripts/test-functionality.sh
terraform -chdir=terraform destroy -auto-approve
done
|
1
2
3
4
5
6
7
8
9
| # Adicione ao seu pipeline CI/CD (ex: GitLab CI)
test_image:
stage: test
script:
- cd tests/image-validation
- ./scripts/run-all-tests.sh
artifacts:
paths:
- tests/image-validation/reports/
|
Tabela de Testes
| Teste | Tipo | Descrição | Esperado |
|---|
| SSH Connectivity | Funcionalidade | Conectar via SSH | Sucesso |
| Debian Version | Funcionalidade | Verificar versão | Debian 12 |
| Pacotes | Funcionalidade | Verificar instalação | Todos presentes |
| Espaço em Disco | Funcionalidade | Verificar uso | < 80% |
| Memória | Funcionalidade | Verificar disponível | > 0 |
| CPUs | Funcionalidade | Verificar quantidade | Correto |
| Hostname | Funcionalidade | Verificar nome | test-debian12 |
| Rede | Funcionalidade | Conectividade | OK |
| Atualizações | Segurança | Verificar patches | Mínimas |
| SSH Hardening | Segurança | Root login | Desabilitado |
| Permissões | Segurança | Sudoers | 440 |
| Firewall | Segurança | UFW | Disponível |
| Fail2ban | Segurança | Proteção | Instalado |
| Logs | Segurança | Auth logs | Presentes |
Troubleshooting
Erro: “SSH connection timeout”
Problema: Não consegue conectar via SSH.
Solução:
1
2
3
4
5
| # Aguarde mais tempo
$ sleep 60
# Ou verifique se a VM está rodando
$ virsh list
|
Problema: Terraform não está no PATH.
Solução:
1
2
3
4
5
| # Instale Terraform
$ sudo apt install -y terraform
# Ou use caminho completo
$ /usr/bin/terraform --version
|
Testes falhando
Problema: Testes estão falhando.
Solução:
1
2
3
4
5
| # Verifique os logs da VM
$ ssh -i ~/.ssh/terraform-vms debian@<ip> "sudo tail -50 /var/log/syslog"
# Ou execute teste manualmente
$ ssh -i ~/.ssh/terraform-vms debian@<ip> "curl --version"
|
VM não inicia
Problema: VM não consegue iniciar.
Solução:
1
2
3
4
5
| # Verifique se há espaço em disco
$ df -h ~/workspace-as-code/kvm/
# Ou verifique logs do LIBVIRT
$ sudo tail -50 /var/log/libvirt/libvirtd.log
|
Dicas e Boas Práticas
Dica 1: Use Variáveis para Reutilização
1
2
3
4
| # Defina variáveis comuns
TEST_ID=$(date +%s)
VM_IP=$(terraform -chdir=terraform output -raw test_vm_ip)
SSH_KEY="$HOME/.ssh/terraform-vms"
|
Dica 2: Organize Relatórios por Data
1
2
| # Use timestamp em nomes
REPORT="reports/test-$(date +%Y%m%d-%H%M%S).txt"
|
Dica 3: Use Cores para Melhor Legibilidade
1
2
3
4
5
6
7
| # Defina cores
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m'
# Use em outputs
echo -e "${GREEN}Sucesso!${NC}"
|
Dica 4: Documente Testes
1
2
3
| # Adicione comentários explicativos
# Teste 1: Verificar conectividade SSH
# Este teste valida se a VM está acessível via SSH
|
Dica 5: Versione Testes
1
2
3
| # Adicione ao Git
$ git add tests/
$ git commit -m "feat: add comprehensive test suite"
|
Passo 1: Organizar Estrutura
1
2
3
4
5
6
7
8
9
10
| # Verifique a estrutura
$ tree ~/workspace-as-code/tests/
# Você deve ver:
# ~/workspace-as-code/tests/
# └── image-validation/
# ├── terraform/
# ├── scripts/
# ├── cloud-init.yml
# └── reports/
|
Passo 2: Criar .gitignore
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| # Crie arquivo .gitignore
$ cat > ~/workspace-as-code/tests/.gitignore << 'EOF'
# Terraform
terraform/.terraform/
terraform/.terraform.lock.hcl
terraform/terraform.tfstate*
# Reports
reports/*
!reports/.gitkeep
# Logs
*.log
EOF
# Verifique
$ cat ~/workspace-as-code/tests/.gitignore
|
Passo 3: Versionar no Git
1
2
3
4
5
6
7
8
| # Adicione ao Git
$ cd ~/workspace-as-code
$ git add tests/
$ git commit -m "feat: add image validation test suite"
$ git push origin main
# Verifique
$ git log --oneline | head -5
|
Script de Validação
Para verificar se tudo foi configurado corretamente:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| #!/bin/bash
# Script de validação de testes
echo "Validando estrutura de testes..."
# Verificar diretórios
if [ -d "terraform" ] && [ -d "scripts" ] && [ -d "reports" ]; then
echo "✓ Diretórios criados"
else
echo "✗ Diretórios não encontrados"
exit 1
fi
# Verificar arquivos Terraform
if [ -f "terraform/main.tf" ] && [ -f "terraform/variables.tf" ]; then
echo "✓ Arquivos Terraform existem"
else
echo "✗ Arquivos Terraform não encontrados"
exit 1
fi
# Verificar scripts de teste
if [ -f "scripts/test-functionality.sh" ] && [ -f "scripts/test-security.sh" ]; then
echo "✓ Scripts de teste existem"
else
echo "✗ Scripts de teste não encontrados"
exit 1
fi
# Validar Terraform
if terraform -chdir=terraform validate &> /dev/null; then
echo "✓ Configuração Terraform válida"
else
echo "✗ Configuração Terraform inválida"
exit 1
fi
echo ""
echo "Validação concluída com sucesso!"
|
Conclusão
Você aprendeu a criar um framework de testes para validar imagens antes de usar em produção. Com testes automatizados, você pode garantir qualidade, consistência e confiabilidade em seu ambiente de infraestrutura.
O Que Você Alcançou
✓ Entendimento da importância de testes em infraestrutura ✓ Criação de estrutura de testes ✓ Uso de Terraform para provisionar VMs de teste ✓ Desenvolvimento de scripts de teste automatizados ✓ Execução de testes de funcionalidade e segurança ✓ Geração de relatórios de validação ✓ Integração com workspace-as-code
- Verifique pré-requisitos:
1
2
| $ systemctl is-active libvirtd
$ terraform --version
|
- Crie estrutura:
1
2
| $ mkdir -p ~/workspace-as-code/tests/image-validation/{terraform,scripts,reports}
$ cd ~/workspace-as-code/tests/image-validation
|
- Configure Terraform:
1
2
| $ terraform -chdir=terraform init
$ terraform -chdir=terraform validate
|
- Execute testes:
1
| $ ./scripts/run-all-tests.sh
|
- Verifique relatórios:
1
2
| $ cat reports/functionality-test-*.txt
$ cat reports/security-test-*.txt
|
- Versione no Git:
1
2
3
4
| $ cd ~/workspace-as-code
$ git add tests/
$ git commit -m "feat: add image validation test suite"
$ git push origin main
|
Próximo Tutorial
Com imagens testadas e validadas, o próximo passo é aprender a provisionar máquinas virtuais com configurações específicas usando Ansible, um orquestrador de configuração poderoso.
Recursos Adicionais
Fim da Parte 9
Próxima: Provisionamento com Ansible e Docker