Files
workshop/aula-11/setup.sh
Allyson de Paula 8e743f6e69 aula-11: ArgoCD + GitLab Runner para GitOps CI/CD
- ArgoCD via Helm com recursos mínimos (~1Gi)
- GitLab Runner com executor Kubernetes
- Exemplo node-bugado com Dockerfile e .gitlab-ci.yml
- Manifests K8s para repositório GitOps
- README.md da aula-03 (liveness + readiness probes)
2025-12-31 21:19:40 -03:00

457 lines
14 KiB
Bash
Executable File

#!/bin/bash
# =============================================================================
# Aula 11 - ArgoCD + GitLab Runner (GitOps)
# =============================================================================
#
# Este script instala:
# 1. GitLab Runner (executor kubernetes) para CI
# 2. ArgoCD para CD declarativo (GitOps)
# 3. Integração com GitLab self-hosted (aula-10)
#
# Pré-requisitos:
# - Cluster Kubernetes (aula-08)
# - GitLab instalado (aula-10)
# - NGINX Ingress Controller
# - kubectl e helm instalados
#
# =============================================================================
set -e
# Cores para output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Funções de log
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[OK]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# Diretório do script
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ENV_FILE="${SCRIPT_DIR}/.env"
# =============================================================================
# VERIFICAR PRÉ-REQUISITOS
# =============================================================================
log_info "Verificando pré-requisitos..."
# Verificar kubectl
if ! command -v kubectl &> /dev/null; then
log_error "kubectl não encontrado. Instale com: brew install kubectl"
exit 1
fi
# Verificar helm
if ! command -v helm &> /dev/null; then
log_error "helm não encontrado. Instale com: brew install helm"
exit 1
fi
# Verificar conexão com cluster
if ! kubectl cluster-info &> /dev/null; then
log_error "Não foi possível conectar ao cluster Kubernetes"
log_info "Verifique se KUBECONFIG está configurado corretamente"
log_info "Exemplo: export KUBECONFIG=\$(pwd)/../aula-08/kubeconfig"
exit 1
fi
# Verificar se GitLab está instalado
if ! kubectl get namespace gitlab &> /dev/null; then
log_error "Namespace 'gitlab' não encontrado"
log_info "Execute primeiro a aula-10 para instalar o GitLab"
exit 1
fi
# Verificar NGINX Ingress
if ! kubectl get ingressclass nginx &> /dev/null; then
log_error "NGINX Ingress Controller não encontrado"
log_info "Execute o script de instalação do NGINX Ingress na aula-08"
exit 1
fi
log_success "Pré-requisitos verificados"
# =============================================================================
# CARREGAR CONFIGURAÇÃO EXISTENTE
# =============================================================================
# Carregar configuração local PRIMEIRO (se existir)
if [[ -f "$ENV_FILE" ]]; then
log_info "Carregando configuração local..."
source "$ENV_FILE"
fi
# Se não tiver configuração local, tentar herdar da aula-10
if [[ -z "$GITLAB_HOST" ]]; then
AULA10_ENV="${SCRIPT_DIR}/../aula-10/.env"
if [[ -f "$AULA10_ENV" ]]; then
log_info "Herdando configuração da aula-10..."
source "$AULA10_ENV"
GITLAB_HOST="${GITLAB_HOST:-}"
DOMAIN="${DOMAIN:-}"
USE_CLOUDFLARE="${USE_CLOUDFLARE:-false}"
USE_LETSENCRYPT="${USE_LETSENCRYPT:-false}"
LETSENCRYPT_EMAIL="${LETSENCRYPT_EMAIL:-}"
fi
fi
# =============================================================================
# COLETAR CONFIGURAÇÃO
# =============================================================================
echo ""
echo "=========================================="
echo " Configuração do ArgoCD + GitLab CI"
echo "=========================================="
echo ""
# GitLab Host
if [[ -z "$GITLAB_HOST" ]]; then
read -p "Hostname do GitLab (ex: git.kube.quest): " GITLAB_HOST
fi
log_info "GitLab: https://${GITLAB_HOST}"
# Extrair domínio base
if [[ -z "$DOMAIN" ]]; then
DOMAIN=$(echo "$GITLAB_HOST" | sed 's/^[^.]*\.//')
fi
# ArgoCD Host
if [[ -z "$ARGOCD_HOST" ]]; then
DEFAULT_ARGOCD="argocd.${DOMAIN}"
read -p "Hostname do ArgoCD [${DEFAULT_ARGOCD}]: " ARGOCD_HOST
ARGOCD_HOST="${ARGOCD_HOST:-$DEFAULT_ARGOCD}"
fi
log_info "ArgoCD: https://${ARGOCD_HOST}"
# TLS (herdar da aula-10 ou perguntar)
if [[ "$USE_CLOUDFLARE" != "true" && "$USE_LETSENCRYPT" != "true" ]]; then
echo ""
echo "Configuração de TLS:"
echo " 1) CloudFlare (proxy ativo - TLS na borda)"
echo " 2) Let's Encrypt (cert-manager)"
echo " 3) HTTP apenas (desenvolvimento)"
read -p "Escolha [1-3]: " TLS_CHOICE
case $TLS_CHOICE in
1)
USE_CLOUDFLARE=true
USE_LETSENCRYPT=false
;;
2)
USE_CLOUDFLARE=false
USE_LETSENCRYPT=true
if [[ -z "$LETSENCRYPT_EMAIL" ]]; then
read -p "Email para Let's Encrypt: " LETSENCRYPT_EMAIL
fi
;;
*)
USE_CLOUDFLARE=false
USE_LETSENCRYPT=false
;;
esac
fi
# Salvar configuração
cat > "$ENV_FILE" << EOF
# Configuração gerada pelo setup.sh
# $(date)
GITLAB_HOST=${GITLAB_HOST}
ARGOCD_HOST=${ARGOCD_HOST}
DOMAIN=${DOMAIN}
USE_CLOUDFLARE=${USE_CLOUDFLARE}
USE_LETSENCRYPT=${USE_LETSENCRYPT}
LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}
EOF
log_success "Configuração salva em ${ENV_FILE}"
# =============================================================================
# INSTALAR GITLAB RUNNER
# =============================================================================
echo ""
log_info "=== Instalando GitLab Runner ==="
# Adicionar repositório Helm
helm repo add gitlab https://charts.gitlab.io 2>/dev/null || true
helm repo update
# Verificar se já está instalado
if helm status gitlab-runner -n gitlab &> /dev/null; then
log_warn "GitLab Runner já instalado, fazendo upgrade..."
HELM_CMD="upgrade"
else
HELM_CMD="install"
fi
# Obter runner registration token
log_info "Obtendo token de registro do GitLab Runner..."
# Tentar obter o token do secret
RUNNER_TOKEN=""
if kubectl get secret gitlab-gitlab-runner-secret -n gitlab &> /dev/null; then
RUNNER_TOKEN=$(kubectl get secret gitlab-gitlab-runner-secret -n gitlab -o jsonpath='{.data.runner-registration-token}' 2>/dev/null | base64 -d 2>/dev/null || echo "")
fi
if [[ -z "$RUNNER_TOKEN" ]]; then
log_warn "Token de registro não encontrado automaticamente"
echo ""
echo "Para obter o token:"
echo " 1. Acesse https://${GITLAB_HOST}/admin/runners"
echo " 2. Clique em 'New instance runner'"
echo " 3. Copie o registration token"
echo ""
read -p "Cole o registration token: " RUNNER_TOKEN
fi
if [[ -z "$RUNNER_TOKEN" ]]; then
log_error "Token de registro é obrigatório"
exit 1
fi
# Instalar GitLab Runner
log_info "Instalando GitLab Runner via Helm..."
helm ${HELM_CMD} gitlab-runner gitlab/gitlab-runner \
--namespace gitlab \
-f "${SCRIPT_DIR}/gitlab-runner-values.yaml" \
--set gitlabUrl="https://${GITLAB_HOST}" \
--set runnerRegistrationToken="${RUNNER_TOKEN}" \
--wait --timeout 5m
log_success "GitLab Runner instalado"
# Verificar pods
log_info "Verificando pods do GitLab Runner..."
kubectl get pods -n gitlab -l app=gitlab-runner
# =============================================================================
# INSTALAR CERT-MANAGER (se Let's Encrypt)
# =============================================================================
if [[ "$USE_LETSENCRYPT" == "true" ]]; then
echo ""
log_info "=== Verificando cert-manager ==="
if ! kubectl get namespace cert-manager &> /dev/null; then
log_info "Instalando cert-manager..."
helm repo add jetstack https://charts.jetstack.io 2>/dev/null || true
helm repo update
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--set crds.enabled=true \
--wait --timeout 5m
log_success "cert-manager instalado"
else
log_success "cert-manager já instalado"
fi
# Criar ClusterIssuer se não existir
if ! kubectl get clusterissuer letsencrypt-prod &> /dev/null; then
log_info "Criando ClusterIssuer letsencrypt-prod..."
kubectl apply -f - << EOF
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: ${LETSENCRYPT_EMAIL}
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
EOF
log_success "ClusterIssuer criado"
fi
fi
# =============================================================================
# INSTALAR ARGOCD
# =============================================================================
echo ""
log_info "=== Instalando ArgoCD ==="
# Adicionar repositório Helm
helm repo add argo https://argoproj.github.io/argo-helm 2>/dev/null || true
helm repo update
# Criar namespace
kubectl create namespace argocd 2>/dev/null || true
# Verificar se já está instalado
if helm status argocd -n argocd &> /dev/null; then
log_warn "ArgoCD já instalado, fazendo upgrade..."
HELM_CMD="upgrade"
else
HELM_CMD="install"
fi
# Construir argumentos Helm
HELM_ARGS=""
HELM_ARGS="$HELM_ARGS --set global.domain=${ARGOCD_HOST}"
HELM_ARGS="$HELM_ARGS --set server.ingress.hosts[0]=${ARGOCD_HOST}"
if [[ "$USE_LETSENCRYPT" == "true" ]]; then
HELM_ARGS="$HELM_ARGS --set server.ingress.tls[0].secretName=argocd-server-tls"
HELM_ARGS="$HELM_ARGS --set server.ingress.tls[0].hosts[0]=${ARGOCD_HOST}"
HELM_ARGS="$HELM_ARGS --set 'server.ingress.annotations.cert-manager\.io/cluster-issuer=letsencrypt-prod'"
elif [[ "$USE_CLOUDFLARE" == "true" ]]; then
# CloudFlare faz TLS na borda
HELM_ARGS="$HELM_ARGS --set server.ingress.tls="
fi
# Instalar ArgoCD
log_info "Instalando ArgoCD via Helm..."
eval helm ${HELM_CMD} argocd argo/argo-cd \
--namespace argocd \
-f "${SCRIPT_DIR}/argocd-values.yaml" \
${HELM_ARGS} \
--wait --timeout 10m
log_success "ArgoCD instalado"
# =============================================================================
# OBTER SENHA DO ADMIN
# =============================================================================
echo ""
log_info "=== Credenciais do ArgoCD ==="
# Aguardar secret ser criado
log_info "Aguardando secret de credenciais..."
for i in {1..30}; do
if kubectl get secret argocd-initial-admin-secret -n argocd &> /dev/null; then
break
fi
sleep 2
done
ARGOCD_PASSWORD=$(kubectl get secret argocd-initial-admin-secret -n argocd -o jsonpath='{.data.password}' 2>/dev/null | base64 -d 2>/dev/null || echo "")
if [[ -z "$ARGOCD_PASSWORD" ]]; then
log_warn "Não foi possível obter a senha inicial"
log_info "Tente: kubectl get secret argocd-initial-admin-secret -n argocd -o jsonpath='{.data.password}' | base64 -d"
else
echo ""
echo "=========================================="
echo " ArgoCD Credenciais"
echo "=========================================="
echo " URL: https://${ARGOCD_HOST}"
echo " Username: admin"
echo " Password: ${ARGOCD_PASSWORD}"
echo "=========================================="
fi
# =============================================================================
# CONFIGURAR INTEGRAÇÃO GITLAB
# =============================================================================
echo ""
log_info "=== Configurando Integração GitLab ==="
# Obter host key do GitLab
log_info "Obtendo SSH host key do GitLab..."
SSH_HOST_KEY=$(ssh-keyscan -t ed25519 ${GITLAB_HOST} 2>/dev/null || ssh-keyscan ${GITLAB_HOST} 2>/dev/null || echo "")
if [[ -n "$SSH_HOST_KEY" ]]; then
# Criar ConfigMap com known hosts
kubectl create configmap argocd-ssh-known-hosts-cm \
--from-literal=ssh_known_hosts="${SSH_HOST_KEY}" \
-n argocd \
--dry-run=client -o yaml | kubectl apply -f -
log_success "SSH host key configurado"
else
log_warn "Não foi possível obter SSH host key"
log_info "Configure manualmente: argocd cert add-ssh --batch < known_hosts"
fi
# =============================================================================
# INSTRUÇÕES FINAIS
# =============================================================================
echo ""
echo "=========================================="
echo " Instalação Concluída!"
echo "=========================================="
echo ""
echo "ArgoCD:"
echo " URL: https://${ARGOCD_HOST}"
echo " Username: admin"
if [[ -n "$ARGOCD_PASSWORD" ]]; then
echo " Password: ${ARGOCD_PASSWORD}"
else
echo " Password: kubectl get secret argocd-initial-admin-secret -n argocd -o jsonpath='{.data.password}' | base64 -d"
fi
echo ""
echo "GitLab Runner:"
echo " Namespace: gitlab"
echo " Verificar: kubectl get pods -n gitlab -l app=gitlab-runner"
echo " Status no GitLab: https://${GITLAB_HOST}/admin/runners"
echo ""
echo "Próximos passos:"
echo ""
echo "1. Configure DNS:"
echo " Adicione registro A para ${ARGOCD_HOST} apontando para o LoadBalancer"
echo ""
echo "2. Crie um repositório GitOps no GitLab:"
echo " - Nome: gitops-demo"
echo " - Estrutura: apps/node-bugado/{deployment,service,configmap}.yaml"
echo ""
echo "3. Configure repositório no ArgoCD:"
echo " a) Gere uma deploy key:"
echo " ssh-keygen -t ed25519 -f argocd-deploy-key -N ''"
echo ""
echo " b) Adicione a chave pública no GitLab:"
echo " Settings → Repository → Deploy Keys"
echo ""
echo " c) Conecte o repositório no ArgoCD:"
echo " - Acesse https://${ARGOCD_HOST}"
echo " - Settings → Repositories → Connect Repo"
echo " - Method: SSH"
echo " - URL: git@${GITLAB_HOST}:<usuario>/gitops-demo.git"
echo " - SSH private key: (conteúdo de argocd-deploy-key)"
echo ""
echo "4. Crie uma Application no ArgoCD:"
echo " kubectl apply -f - << 'EOF'"
echo " apiVersion: argoproj.io/v1alpha1"
echo " kind: Application"
echo " metadata:"
echo " name: node-bugado"
echo " namespace: argocd"
echo " spec:"
echo " project: default"
echo " source:"
echo " repoURL: git@${GITLAB_HOST}:<usuario>/gitops-demo.git"
echo " targetRevision: HEAD"
echo " path: apps/node-bugado"
echo " destination:"
echo " server: https://kubernetes.default.svc"
echo " namespace: demo"
echo " syncPolicy:"
echo " automated:"
echo " prune: true"
echo " selfHeal: true"
echo " syncOptions:"
echo " - CreateNamespace=true"
echo " EOF"
echo ""
echo "Comandos úteis:"
echo " kubectl get pods -n argocd"
echo " kubectl get applications -n argocd"
echo " kubectl logs -n gitlab -l app=gitlab-runner -f"
echo ""