feat(aula-08): adicionar seleção de arquitetura (arm64/amd64) e detectar tofu/terraform

- Variável `arch` no Terraform: arm64 (CAX11 em nbg1) ou amd64 (CPX21 em fsn1)
- locals map traduz arch → server_type + location
- setup.sh pergunta arquitetura interativamente (default: arm64)
- Detecta OpenTofu ou Terraform automaticamente (preferência tofu)
- Autoscaler: sed troca CAX→CPX nos server_types quando amd64
- tfvars gerado inclui arch selecionado
This commit is contained in:
ArgoCD Setup
2026-05-09 03:32:06 -03:00
parent 17a2891329
commit 72ffe47528
4 changed files with 112 additions and 37 deletions
+21 -8
View File
@@ -38,6 +38,19 @@ locals {
# Endpoint: LoadBalancer IP if enabled, otherwise Floating IP
cluster_endpoint_ip = var.enable_loadbalancer ? hcloud_load_balancer.cluster[0].ipv4 : hcloud_floating_ip.control_plane[0].ip_address
# Arquitetura: mapeia arm64→CAX (Nuremberg) ou amd64→CPX (Frankfurt)
arch_config = {
arm64 = {
server_type_cp = "cax11"
location = "nbg1"
}
amd64 = {
server_type_cp = "cpx21"
location = "fsn1"
}
}
selected_arch = local.arch_config[var.arch]
common_labels = {
cluster = local.cluster_name
environment = var.environment
@@ -192,15 +205,15 @@ resource "hcloud_placement_group" "cluster" {
}
############################################################
# CONTROL PLANE NODES (HA with 3 CAX11 nodes)
# CONTROL PLANE NODES (HA com 3 nodes)
############################################################
resource "hcloud_server" "control_plane" {
count = local.control_plane_count
name = "${local.cluster_name}-cp-${count.index}"
server_type = "cax11"
server_type = local.selected_arch.server_type_cp
image = data.hcloud_image.talos.id
location = "nbg1" # CAX11 only available in Nuremberg
location = local.selected_arch.location
ssh_keys = [local.ssh_key_id]
firewall_ids = [hcloud_firewall.cluster.id]
@@ -209,7 +222,7 @@ resource "hcloud_server" "control_plane" {
labels = merge(local.common_labels, {
role = "control-plane"
node = "cp-${count.index}"
arch = "arm64"
arch = var.arch
})
public_net {
@@ -373,15 +386,15 @@ resource "hcloud_load_balancer_target" "worker" {
}
############################################################
# WORKER NODE (Single CAX11)
# WORKER NODE
############################################################
resource "hcloud_server" "worker" {
count = 1
name = "${local.cluster_name}-worker-${count.index}"
server_type = "cax11"
server_type = local.selected_arch.server_type_cp
image = data.hcloud_image.talos.id
location = "nbg1"
location = local.selected_arch.location
ssh_keys = [local.ssh_key_id]
firewall_ids = [hcloud_firewall.cluster.id]
@@ -390,7 +403,7 @@ resource "hcloud_server" "worker" {
labels = merge(local.common_labels, {
role = "worker"
node = "worker-${count.index}"
arch = "arm64"
arch = var.arch
})
public_net {
+66 -24
View File
@@ -18,6 +18,9 @@ NC='\033[0m' # No Color
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
# Variáveis com defaults
ARCH="${ARCH:-arm64}"
# Funções de log
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
@@ -47,18 +50,23 @@ echo ""
log_info "Verificando pré-requisitos..."
# Verificar OpenTofu
if ! command -v tofu &> /dev/null; then
log_error "OpenTofu não encontrado!"
# Detectar OpenTofu ou Terraform
if command -v tofu &> /dev/null; then
TF_CMD="tofu"
log_success "OpenTofu $(tofu version | head -1)"
elif command -v terraform &> /dev/null; then
TF_CMD="terraform"
log_success "Terraform $(terraform version | head -1)"
else
log_error "OpenTofu ou Terraform não encontrado!"
echo ""
echo "Instale o OpenTofu:"
echo " brew install opentofu # macOS"
echo " snap install opentofu # Linux"
echo "Instale um deles:"
echo " brew install opentofu # OpenTofu (recomendado)"
echo " brew install terraform # Terraform"
echo ""
echo "Mais info: https://opentofu.org/docs/intro/install/"
exit 1
fi
log_success "OpenTofu $(tofu version | head -1)"
# Verificar talosctl
if ! command -v talosctl &> /dev/null; then
@@ -228,6 +236,23 @@ if [ "$SKIP_CREDENTIALS" != "true" ]; then
fi
echo ""
# Arquitetura
echo "6. Arquitetura dos nodes"
echo ""
echo " arm64 (CAX) - Ampere Altra, melhor custo/benefício"
echo " amd64 (CPX) - AMD EPYC, mais disponível"
echo ""
read -p " Arquitetura? (arm64/amd64) [arm64]: " arch_input
ARCH="${arch_input:-arm64}"
if [[ "$ARCH" == "amd64" ]]; then
log_success "AMD64 selecionado (CPX em fsn1)"
else
log_success "ARM64 selecionado (CAX em nbg1)"
ARCH="arm64"
fi
echo ""
# Criar terraform.tfvars
log_info "Criando terraform.tfvars..."
cat > terraform.tfvars << EOF
@@ -241,6 +266,7 @@ talos_image_id = $TALOS_IMAGE_ID
environment = "prod"
enable_ha = $ENABLE_HA
enable_loadbalancer = $ENABLE_LB
arch = "$ARCH"
EOF
log_success "terraform.tfvars criado"
fi
@@ -256,8 +282,8 @@ echo " Inicializando OpenTofu"
echo "============================================"
echo ""
log_info "Executando tofu init..."
tofu init
log_info "Executando $TF_CMD init..."
$TF_CMD init
log_success "OpenTofu inicializado"
echo ""
@@ -271,8 +297,8 @@ echo " Planejando Infraestrutura"
echo "============================================"
echo ""
log_info "Executando tofu plan..."
tofu plan -out=tfplan
log_info "Executando $TF_CMD plan..."
$TF_CMD plan -out=tfplan
echo ""
log_success "Plano criado!"
@@ -322,7 +348,7 @@ if [[ ! "$apply" =~ ^[Ss]$ ]]; then
log_warn "Operação cancelada pelo usuário"
echo ""
echo "Para aplicar manualmente:"
echo " tofu apply tfplan"
echo " $TF_CMD apply tfplan"
echo ""
exit 0
fi
@@ -331,7 +357,7 @@ echo ""
log_info "Aplicando infraestrutura..."
echo ""
tofu apply tfplan
$TF_CMD apply tfplan
echo ""
log_success "Infraestrutura provisionada!"
@@ -356,7 +382,7 @@ if [ -f "talosconfig" ]; then
export TALOSCONFIG="$SCRIPT_DIR/talosconfig"
# Obter IP do control plane
CP_IP=$(tofu output -raw control_plane_ip 2>/dev/null || echo "")
CP_IP=$($TF_CMD output -raw control_plane_ip 2>/dev/null || echo "")
if [ -n "$CP_IP" ]; then
log_info "Aguardando API do Talos em $CP_IP..."
@@ -405,7 +431,7 @@ echo ""
# Obter token do terraform.tfvars
HCLOUD_TOKEN=$(grep 'hcloud_token' terraform.tfvars | cut -d'"' -f2)
NETWORK_ID=$(tofu output -raw network_id 2>/dev/null || echo "")
NETWORK_ID=$($TF_CMD output -raw network_id 2>/dev/null || echo "")
if [ -z "$HCLOUD_TOKEN" ]; then
log_error "Não foi possível obter HCLOUD_TOKEN!"
@@ -469,11 +495,11 @@ echo ""
# Obter configurações do OpenTofu
log_info "Obtendo configurações do OpenTofu..."
WORKER_CONFIG_BASE64=$(tofu output -raw autoscaler_worker_config 2>/dev/null)
TALOS_IMAGE_ID=$(tofu output -raw autoscaler_image_id 2>/dev/null)
CLUSTER_NAME=$(tofu output -raw cluster_name 2>/dev/null)
FIREWALL_ID=$(tofu output -raw firewall_id 2>/dev/null)
SSH_KEY_NAME=$(tofu output -raw ssh_key_name 2>/dev/null)
WORKER_CONFIG_BASE64=$($TF_CMD output -raw autoscaler_worker_config 2>/dev/null)
TALOS_IMAGE_ID=$($TF_CMD output -raw autoscaler_image_id 2>/dev/null)
CLUSTER_NAME=$($TF_CMD output -raw cluster_name 2>/dev/null)
FIREWALL_ID=$($TF_CMD output -raw firewall_id 2>/dev/null)
SSH_KEY_NAME=$($TF_CMD output -raw ssh_key_name 2>/dev/null)
if [ -z "$WORKER_CONFIG_BASE64" ]; then
log_error "Não foi possível obter configuração do worker!"
@@ -495,7 +521,7 @@ kubectl label namespace cluster-autoscaler pod-security.kubernetes.io/enforce=pr
CLUSTER_CONFIG_JSON=$(cat <<CCEOF
{
"imagesForArch": {
"arm64": "$TALOS_IMAGE_ID"
"$ARCH": "$TALOS_IMAGE_ID"
},
"nodeConfigs": {
"worker-pool": {
@@ -536,12 +562,25 @@ log_success "Secret criado"
# Aplicar manifesto
log_info "Aplicando manifesto do cluster-autoscaler..."
cat cluster-autoscaler.yaml | \
# Ajustar server_types do autoscaler conforme arquitetura
if [[ "$ARCH" == "amd64" ]]; then
AUTOSCALER_FILE="${SCRIPT_DIR}/cluster-autoscaler.yaml"
# CPX equivalentes: CAX21→CPX31, CAX31→CPX41, CAX11→CPX21
cat "$AUTOSCALER_FILE" | \
sed "s|\${TALOS_IMAGE_ID}|$TALOS_IMAGE_ID|g" | \
sed "s|\${NETWORK_NAME}|$CLUSTER_NAME-network|g" | \
sed "s|\${FIREWALL_NAME}|$CLUSTER_NAME-firewall|g" | \
sed "s|\${SSH_KEY_NAME}|$SSH_KEY_NAME|g" | \
sed -e 's/CAX21/CPX31/g' -e 's/CAX31/CPX41/g' -e 's/CAX11/CPX21/g' | \
kubectl apply -f -
else
cat cluster-autoscaler.yaml | \
sed "s|\${TALOS_IMAGE_ID}|$TALOS_IMAGE_ID|g" | \
sed "s|\${NETWORK_NAME}|$CLUSTER_NAME-network|g" | \
sed "s|\${FIREWALL_NAME}|$CLUSTER_NAME-firewall|g" | \
sed "s|\${SSH_KEY_NAME}|$SSH_KEY_NAME|g" | \
kubectl apply -f -
fi
# Aguardar pod ficar pronto
log_info "Aguardando pod do autoscaler..."
@@ -641,8 +680,8 @@ echo ""
# Mostrar outputs
echo "Endpoints:"
tofu output -raw kubernetes_api_endpoint 2>/dev/null && echo "" || true
tofu output -raw talos_api_endpoint 2>/dev/null && echo "" || true
$TF_CMD output -raw kubernetes_api_endpoint 2>/dev/null && echo "" || true
$TF_CMD output -raw talos_api_endpoint 2>/dev/null && echo "" || true
echo ""
echo "Componentes instalados:"
@@ -651,6 +690,9 @@ echo " - Cluster Autoscaler (1-5 workers)"
echo " - Hetzner CSI Driver (StorageClass: hcloud-volumes)"
echo " - NGINX Ingress Controller + LoadBalancer"
echo ""
echo "Configuração:"
echo " - Arquitetura: $ARCH"
echo ""
# Mostrar IP do LoadBalancer
LB_IP=$(kubectl get svc -n ingress-nginx ingress-nginx-controller \
+5
View File
@@ -24,6 +24,11 @@ talos_image_id = 123456789
# Ambiente (prod, staging, dev)
environment = "workshop"
# Arquitetura dos nodes: arm64 (CAX) ou amd64 (CPX)
# arm64 = CAX11/21/31 em Nuremberg (nbg1) - melhor custo
# amd64 = CPX21/31/41 em Frankfurt (fsn1) - mais disponível
# arch = "arm64"
# Versão do Talos OS (opcional - default: v1.11.2)
# talos_version = "v1.11.2"
+15
View File
@@ -68,6 +68,21 @@ variable "talos_version" {
}
}
# ==========================================================
# ARQUITETURA
# ==========================================================
variable "arch" {
type = string
description = "Arquitetura dos nodes: arm64 (CAX - Ampere Altra, melhor custo) ou amd64 (CPX - AMD EPYC, mais disponível)"
default = "arm64"
validation {
condition = contains(["arm64", "amd64"], var.arch)
error_message = "arch deve ser arm64 ou amd64."
}
}
# ==========================================================
# LABELS CUSTOMIZADAS
# ==========================================================