Ir para o conteúdo

Seção 1: Configuração da Máquina de Controle Ansible

A máquina de controle Ansible é o seu "cockpit" para automação. É a partir dela que você executará os playbooks Ansible para provisionar, configurar e gerenciar toda a sua infraestrutura de servidor doméstico.

Pré-requisitos

  • Uma máquina (PC/Notebook) com Linux, macOS ou Windows (usando WSL2).
  • Acesso à Internet para baixar pacotes e coleções Ansible.
  • O projeto home-server clonado do seu repositório Git, ou com a estrutura de diretórios criada conforme a Seção 0.2: Estrutura do Repositório Git.

1.1. Instalação do Ambiente de Controle (scripts/bootstrap.sh)

Para simplificar e padronizar a configuração da sua máquina de controle, utilizaremos o script bootstrap.sh fornecido no projeto.

Conteúdo do Script scripts/bootstrap.sh

O arquivo home-server/scripts/bootstrap.sh contém:

#!/bin/bash
# scripts/bootstrap.sh
# Configura a máquina de controle Ansible (Linux/macOS)

GREEN='\033[0;32m'
YELLOW='\033[0;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color

echo -e "${GREEN}Iniciando a configuração do ambiente de controle Ansible...${NC}"

# 1. Verifica e atualiza o gerenciador de pacotes do sistema
if [[ "$OSTYPE" == "darwin"* ]]; then
    echo -e "${YELLOW}Detectado macOS. Verificando e atualizando Homebrew...${NC}"
    if ! command -v brew &> /dev/null; then
        echo -e "${RED}Homebrew não encontrado. Por favor, instale o Homebrew primeiro.${NC}"
        echo "Visite https://brew.sh/"
        exit 1
    fi
    brew update && brew upgrade
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
    # Assumindo Debian/Ubuntu. Adapte para outros gerenciadores (yum, dnf) se necessário.
    echo -e "${YELLOW}Detectado Linux (Debian/Ubuntu based). Atualizando apt...${NC}"
    sudo apt update && sudo apt upgrade -y
else
    echo -e "${RED}Sistema operacional não suportado por este script (apenas macOS e Linux baseados em Debian/Ubuntu).${NC}"
    exit 1
fi

# 2. Instala Python 3, Pip e Venv (se não existirem)
echo -e "${YELLOW}Verificando Python 3, Pip e Venv...${NC}"
if ! command -v python3 &> /dev/null || ! python3 -m pip --version &> /dev/null # Venv check removido pois ensurepip instala venv
then
    echo -e "${YELLOW}Python 3 ou Pip não encontrados. Instalando...${NC}"
    if [[ "$OSTYPE" == "darwin"* ]]; then
        brew install [email protected] # Ou a versão LTS mais recente suportada pelo Ansible
    fi
    if [[ "$OSTYPE" == "linux-gnu"* ]]; then
        sudo apt install -y python3 python3-pip python3-venv # Venv ainda é útil ter explicitamente
    fi
else
    echo -e "${GREEN}Python 3 e Pip já instalados.${NC}"
fi
# Garante que pip e venv estejam associados ao python3 e atualizados
python3 -m ensurepip --upgrade

# 3. Instala Ansible
echo -e "${YELLOW}Verificando e instalando Ansible...${NC}"
if ! command -v ansible &> /dev/null; then
    echo -e "${YELLOW}Ansible não encontrado. Instalando Ansible...${NC}"
    if [[ "$OSTYPE" == "darwin"* ]]; then
        brew install ansible
    fi
    if [[ "$OSTYPE" == "linux-gnu"* ]]; then
        sudo python3 -m pip install ansible # Instalar via pip para versão mais recente
    fi
else
    echo -e "${GREEN}Ansible já instalado.${NC}"
    # Opcional: Atualizar Ansible se já estiver instalado
    # if [[ "$OSTYPE" == "linux-gnu"* ]]; then sudo python3 -m pip install --upgrade ansible; fi
    # if [[ "$OSTYPE" == "darwin"* ]]; then brew upgrade ansible; fi
fi

# 4. Instala coleções Ansible necessárias
echo -e "${YELLOW}Instalando/Atualizando coleções Ansible: community.general, community.docker, community.proxmox...${NC}"
ansible-galaxy collection install community.general community.docker community.proxmox --force # --force para garantir a atualização

# 5. Instala SDK Docker para Python (necessário para módulos Docker do Ansible)
echo -e "${YELLOW}Instalando/Atualizando Docker SDK para Python...${NC}"
python3 -m pip install --user --upgrade docker # --user para instalar no diretório do usuário

# 6. Instala Proxmoxer SDK para Python (necessário para módulos Proxmox do Ansible)
echo -e "${YELLOW}Instalando/Atualizando Proxmoxer SDK para Python...${NC}"
python3 -m pip install --user --upgrade proxmoxer

echo -e "\n${GREEN}Configuração do ambiente de controle Ansible concluída!${NC}"
echo -e "${YELLOW}--------------------------------------------------------------------------------${NC}"
echo -e "${YELLOW}Próximos Passos Manuais IMPORTANTES:${NC}"
echo -e "${YELLOW}1. Gere uma chave SSH dedicada para este homelab se ainda não tiver:${NC}"
echo -e "   ${GREEN}ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_homelab -C \"homelab_ansible_key\"${NC}"
echo -e "${YELLOW}   (Pressione Enter para não definir passphrase para automação total sem ssh-agent, ou defina uma e use ssh-agent).${NC}"
echo -e "${YELLOW}2. A chave pública (~/.ssh/id_ed25519_homelab.pub) precisará ser copiada para o host Proxmox e para as VMs.${NC}"
echo -e "${YELLOW}   O acesso inicial ao Proxmox (como root) para copiar a chave será manual, ANTES de rodar o primeiro playbook nele.${NC}"
echo -e "${YELLOW}--------------------------------------------------------------------------------${NC}"

Executando o Script bootstrap.sh

  1. Torne o script executável: Na raiz do seu projeto home-server/:
    chmod +x scripts/bootstrap.sh
    
  2. Execute o script:

    ./scripts/bootstrap.sh
    
    O script poderá solicitar sua senha sudo para instalar pacotes no sistema.

  3. Verifique a instalação do Ansible:

    ansible --version
    
    Você deverá ver a versão do Ansible, a versão do Python utilizada e os caminhos de configuração.

Ação Chave SSH (Essencial para Automação)

Ansible se conecta aos servidores (Proxmox host e VMs) via SSH. A autenticação baseada em chaves SSH é o método preferido e mais seguro.

  1. Gere um par de chaves SSH dedicado para este projeto: Se você ainda não tem uma chave SSH que deseja usar especificamente para este homelab, gere uma nova:

    ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_homelab -C "homelab_ansible_key"
    

    • -t ed25519: Especifica o algoritmo de chave (moderno e seguro).
    • -f ~/.ssh/id_ed25519_homelab: Local e nome do arquivo para a chave privada (a pública terá .pub adicionado). Use um nome descritivo.
    • -C "homelab_ansible_key": Um comentário para identificar a chave facilmente.
  2. Sobre a Passphrase da Chave:

    • Sem Passphrase (Mais fácil para automação total): Pressione Enter quando solicitado pela passphrase. A chave privada não será protegida por uma senha adicional.

    Segurança da Chave Privada sem Passphrase

    Se você optar por não usar uma passphrase, qualquer pessoa com acesso ao arquivo da sua chave privada (~/.ssh/id_ed25519_homelab) poderá acessar seus servidores como se fosse você. Proteja este arquivo com permissões restritas (e.g., chmod 600 ~/.ssh/id_ed25519_homelab).

    • Com Passphrase (Mais seguro, requer ssh-agent para conveniência): Digite uma passphrase forte e única. Se você definir uma passphrase, precisará:
      • Digitar a passphrase toda vez que o Ansible usar a chave.
      • Ou usar o ssh-agent para armazenar a chave descriptografada na memória durante sua sessão de login. Para usar ssh-agent:
        eval "$(ssh-agent -s)"  # Inicia o ssh-agent
        ssh-add ~/.ssh/id_ed25519_homelab # Adiciona sua chave ao agent (você digitará a passphrase aqui)
        

A chave pública (~/.ssh/id_ed25519_homelab.pub) será o que você copiará para os servidores remotos para permitir o login sem senha via Ansible.

1.2. Criação e Gerenciamento de Variáveis Sensíveis (Ansible Vault)

Dados sensíveis como senhas, tokens de API e chaves privadas não devem ser armazenados em texto plano no seu repositório Git. O Ansible Vault é a ferramenta integrada do Ansible para criptografar esses dados.

  1. Crie o Arquivo Vault: Na raiz do seu projeto home-server/ (onde o ansible.cfg estaria, ou onde o Ansible o encontrará), execute:
    ansible-vault create ansible/inventories/home/group_vars/all/vault.yml
    
    • Você será solicitado a criar e confirmar uma senha para o Vault. Escolha uma senha forte e única.

Guarde Bem a Senha do Vault!

Esta senha é essencial. Sem ela, você não poderá acessar ou modificar os segredos no arquivo vault.yml, nem executar playbooks que dependam dele. Armazene-a em um gerenciador de senhas seguro.

  1. Adicione suas Variáveis Sensíveis ao vault.yml: Após o comando create, o arquivo será aberto no seu editor de texto padrão (geralmente vi ou nano). Cole o conteúdo abaixo, substituindo TODOS os placeholders em MAIÚSCULAS com seus valores reais e secretos.

    # ansible/inventories/home/group_vars/all/vault.yml
    # Edite SEMPRE com: ansible-vault edit ansible/inventories/home/group_vars/all/vault.yml
    
    # --- Credenciais Proxmox ---
    # Usuário e senha para a API do Proxmox.
    # Inicialmente, pode ser root@pam. Após o setup inicial do host Proxmox,
    # é recomendado criar um usuário API dedicado no Proxmox com um token API.
    proxmox_api_user: "root@pam"
    proxmox_api_password: "SENHA_DO_ROOT_DO_PROXMOX_DEFINIDA_NA_INSTALACAO"
    # Se optar por usar um Token API do Proxmox (mais seguro a longo prazo):
    # proxmox_api_user: "ansible_api_user@pve!meuapitokenid" # Formato: usuario@realm!TokenID
    # proxmox_api_token_id: "meuapitokenid"                   # O ID do token
    # proxmox_api_token_secret: "SEGREDO_LONGO_DO_TOKEN_API_PROXMOX" # O segredo gerado
    
    # --- Credenciais VMs ---
    # Senha para o usuário Ansible ('{{ vm_ansible_user_name }}') que será criado nas VMs via Cloud-Init.
    vm_ansible_user_password_plain: "SENHA_FORTE_E_UNICA_PARA_USUARIO_ANSIBLE_NAS_VMS"
    
    # --- Cloudflare ---
    # Token de API da Cloudflare com permissões para editar registros DNS no seu domínio.
    # Crie em: Cloudflare Dashboard > My Profile > API Tokens > Create Token > Use "Edit zone DNS" template.
    cloudflare_api_token: "TOKEN_API_CLOUDFLARE_PARA_EDICAO_DNS_DO_SEU_DOMINIO"
    # Token do Cloudflare Tunnel. Obtido ao criar um túnel no dashboard Cloudflare Zero Trust.
    # Siga: Zero Trust > Access > Tunnels > Create a tunnel. Após criado, você verá o comando para
    # rodar o conector, que inclui o token. Ou use `cloudflared tunnel token <TUNNEL_NAME_OR_ID>`.
    cloudflare_tunnel_token: "TOKEN_LONGO_ALFANUMERICO_DO_SEU_CLOUDFLARE_TUNNEL"
    # O ID do túnel (UUID) pode ser útil para referência, mas o token é o principal para o conector.
    # cloudflare_tunnel_id: "UUID_DO_SEU_TUNNEL_CLOUDFLARE_EX_AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE"
    
    # --- Authelia ---
    # Segredos para JWT (JSON Web Token) e Sessão. Gere strings aleatórias longas e seguras.
    # Exemplo de geração: openssl rand -base64 64
    authelia_jwt_secret: "SEU_SECRET_JWT_PARA_AUTHELIA_MUITO_LONGO_E_ALEATORIO"
    authelia_session_secret: "SEU_SECRET_DE_SESSAO_PARA_AUTHELIA_MUITO_LONGO_E_ALEATORIO"
    # Usuário administrador inicial do Authelia.
    authelia_admin_user_initial: "admin" # Ou seu nome de admin preferido
    # Hash da senha do administrador do Authelia. Gere com o comando Docker:
    # docker run --rm authelia/authelia:latest authelia crypto hash generate argon2 --password 'SUA_SENHA_ADMIN_AUTHELIA_FORTE'
    # Copie a saída completa, incluindo o $argon2id$...
    authelia_admin_password_hash_initial: "$argon2id$v=19$m=65536,t=3,p=4$SEU_SALT_GERADO_PELO_COMANDO$SEU_HASH_GERADO_PELO_COMANDO"
    # Senha para o usuário 'authelia' no banco de dados PostgreSQL do Authelia.
    authelia_storage_postgres_password: "SENHA_FORTE_PARA_O_USUARIO_AUTHELIA_NO_DB_POSTGRES"
    
    # --- Configurações Gerais ---
    # Email para notificações do Let's Encrypt (renovação de certificados, problemas).
    letsencrypt_email: "[email protected]"
    # Seu domínio base, SEM https:// ou www (e.g., meuhomelab.com).
    base_domain: "seudominio.com"
    # Fuso horário para os sistemas. Encontre o seu com `timedatectl list-timezones` no Linux.
    system_timezone: "America/Sao_Paulo" # Exemplo, ajuste para o seu.
    
    # --- Docker User/Group IDs (Numéricos) ---
    # Usados para consistência de permissões nos volumes NFS e dentro dos containers.
    # Geralmente 1000 para o primeiro usuário não-root criado em um sistema Linux.
    # Verifique o UID/GID do usuário que você deseja que seja o "dono" dos arquivos Docker.
    docker_puid: 1000
    docker_pgid: 1000
    
    # --- Senhas de Bancos de Dados de Aplicações (Adicione conforme necessário) ---
    nextcloud_db_password: "SENHA_FORTE_E_UNICA_PARA_O_DB_DO_NEXTCLOUD"
    # Senha para o usuário administrador inicial do Nextcloud (criado na primeira execução).
    nextcloud_admin_initial_password: "SENHA_FORTE_PARA_O_ADMIN_INICIAL_DO_NEXTCLOUD"
    
    grafana_db_password: "SENHA_FORTE_E_UNICA_PARA_O_DB_DO_GRAFANA"
    grafana_admin_initial_password: "SENHA_FORTE_PARA_O_ADMIN_INICIAL_DO_GRAFANA"
    

    Como Editar o Arquivo Vault no Futuro

    Para editar o arquivo vault.yml após sua criação, SEMPRE use o comando:

    ansible-vault edit ansible/inventories/home/group_vars/all/vault.yml
    
    Você será solicitado a fornecer a senha do Vault que você definiu. Não tente editar o arquivo criptografado diretamente.

  2. Salve e feche o editor. O arquivo vault.yml agora estará criptografado no seu sistema de arquivos.

  3. Verifique se vault.yml está listado no seu arquivo .gitignore (conforme Seção 0.2). Isso é uma precaução extra caso você descriptografe o arquivo localmente para alguma verificação e se esqueça de criptografá-lo novamente antes de um commit. O arquivo criptografado deve ser commitado no Git.

1.3. Configuração do Inventário Ansible

O inventário Ansible é o coração da sua automação. Ele define:

  • Quais hosts (servidores, VMs) o Ansible gerenciará.
  • Como o Ansible se conectará a esses hosts (IPs, usuários, chaves SSH).
  • Como os hosts são agrupados para aplicar configurações em conjunto.
  • Variáveis específicas de hosts ou grupos.

Arquivo de Hosts (ansible/inventories/home/hosts.ini)

Crie o arquivo home-server/ansible/inventories/home/hosts.ini. Este arquivo define seus servidores e VMs. Ajuste os endereços IP e nomes de host conforme sua rede e preferências.

# ansible/inventories/home/hosts.ini

# Grupo para o(s) seu(s) host(s) Proxmox VE
[proxmox_hosts]
# 'proxmox_main_host' é um nome lógico que você usará nos playbooks Ansible.
# 'ansible_host' é o endereço IP real ou hostname DNS do seu host Proxmox.
# 'ansible_user' é o usuário que o Ansible usará para se conectar ao Proxmox host.
# A variável '{{ proxmox_ansible_user_on_host }}' será resolvida de group_vars/all/main.yml.
proxmox_main_host ansible_host=192.168.15.10 ansible_user={{ proxmox_ansible_user_on_host }}

# Grupo para suas máquinas virtuais
# Estes são os nomes lógicos que você usará nos playbooks.
# Os IPs (ansible_host) devem ser os IPs estáticos que você planeja para estas VMs.
[virtual_machines]
core-services-vm ansible_host=192.168.15.11
ai-desktop-vm ansible_host=192.168.15.12 GUI_ENABLED=true # GUI_ENABLED é uma variável de host

# Grupo 'filho' que inclui todas as VMs que rodam Ubuntu Server.
# Isso permite aplicar roles comuns a todas elas facilmente.
[ubuntu_vms:children]
core-services-vm
ai-desktop-vm # Inclua aqui se você planeja criar e gerenciar esta VM

# Variáveis globais aplicadas a TODOS os hosts definidos neste inventário.
[all:vars]
# Usuário Ansible padrão para se conectar às VMs (será criado via Cloud-Init).
# A variável '{{ vm_ansible_user_name }}' será resolvida de group_vars/all/main.yml.
ansible_user="{{ vm_ansible_user_name }}"
# Caminho para a chave SSH privada gerada anteriormente (na sua máquina de controle).
ansible_ssh_private_key_file="~/.ssh/id_ed25519_homelab"
# Método para escalação de privilégios (e.g., para se tornar root).
ansible_become_method=sudo
# Se o usuário Ansible nas VMs não tiver 'NOPASSWD: ALL' no sudoers,
# você precisaria descomentar a linha abaixo e fornecer a senha (do vault.yml).
# No entanto, o setup com Cloud-Init configurará 'NOPASSWD: ALL' para o usuário Ansible.
# ansible_become_pass="{{ vm_ansible_user_password_plain }}"

# --- IPs para Referência em Templates ---
# Estas variáveis são convenientes para usar em templates de configuração (e.g., prometheus.yml).
# Elas devem corresponder aos IPs 'ansible_host' definidos acima para consistência.
proxmox_host_ip_var: 192.168.15.10
core_services_vm_ip_var: 192.168.15.11
ai_desktop_vm_ip_var: 192.168.15.12

Nomes de Hosts vs. IPs de Conexão

  • proxmox_main_host, core-services-vm, ai-desktop-vm são nomes lógicos (apelidos) que você usará nos seus playbooks Ansible para se referir aos hosts.
  • ansible_host especifica o endereço IP real (ou hostname DNS, se você tiver DNS local configurado e funcionando) que o Ansible usará para se conectar ao host.
  • As variáveis *_ip_var são uma convenção para ter os IPs facilmente acessíveis em templates, sem depender da resolução de ansible_host dentro do template.

Variáveis Globais Não Sensíveis (ansible/inventories/home/group_vars/all/main.yml)

Crie o arquivo home-server/ansible/inventories/home/group_vars/all/main.yml. Este arquivo define variáveis que se aplicam a todos os hosts no seu inventário e que não são secretas (segredos vão no vault.yml).

# ansible/inventories/home/group_vars/all/main.yml

# --- Configurações do Host Proxmox ---
# Nome do usuário Ansible dedicado a ser criado no host Proxmox.
proxmox_ansible_user_on_host: "proxmox_ansible_user"
# CIDRs da sua rede local permitidos para SSH e acesso à Web UI do Proxmox.
# AJUSTE ESTES VALORES PARA CORRESPONDER À SUA REDE LOCAL!
proxmox_ssh_allowed_cidrs: "192.168.15.0/24"
proxmox_web_ui_allowed_cidrs: "192.168.15.0/24"
# Bridge de rede padrão no Proxmox (geralmente vmbr0, conectada à sua LAN).
proxmox_default_bridge: "vmbr0"
# Storage no Proxmox onde os discos virtuais das VMs serão armazenados (geralmente 'local-lvm' no SSD NVMe).
proxmox_storage_vm_disks: "local-lvm"
# Storage no Proxmox onde ISOs e templates de VM são armazenados (geralmente 'local' no SSD NVMe).
proxmox_storage_iso_templates: "local"
# Nome do template Ubuntu Cloud-Init que será criado no Proxmox.
proxmox_ubuntu_template_name: "ubuntu-2204-cloudinit-template-v1"

# --- Configurações Padrão para Máquinas Virtuais (VMs) ---
# Nome do usuário Ansible a ser criado nas VMs via Cloud-Init.
vm_ansible_user_name: "vm_ansible_user"
# Gateway padrão para as VMs (geralmente o IP do seu roteador doméstico).
# AJUSTE ESTE VALOR PARA O SEU GATEWAY!
vm_cloud_init_gateway: "192.168.15.1"
# Servidores DNS para as VMs.
vm_cloud_init_nameservers: "1.1.1.1,8.8.8.8" # Ou seu DNS local preferido (e.g., Pi-hole IP).
# Recursos padrão para VMs. Estes podem ser sobrescritos por VM no playbook `vm-deploy.yml`.
# Com 48GB de RAM no host, temos mais flexibilidade.
vm_default_cores: 2
vm_default_memory_mb: 4096 # 4GB como padrão (ajustaremos para VMs específicas)
vm_default_disk_gb: 50     # Tamanho do disco da VM em GB como padrão

# --- Docker User/Group nas VMs ---
# Nomes para o usuário e grupo dedicados que serão proprietários dos arquivos nos volumes NFS
# e com cujos PUID/PGID os containers Docker rodarão.
# Os IDs numéricos (PUID/PGID) estão definidos no vault.yml.
docker_user_name_on_vm: "dockeruser"
docker_group_name_on_vm: "dockergroup"

# --- Caminhos e Nomes de Datasets ZFS no Host Proxmox ---
# O pool ZFS principal (criado nos HDDs) será montado em /data.
zfs_base_pool_path: "/data"
# Nomes dos datasets ZFS a serem criados sob o pool 'data'.
# Estes serão montados em, por exemplo, /data/docker-volumes, /data/media, etc.
zfs_docker_volumes_dataset_name: "docker-volumes"
zfs_media_dataset_name: "media"
zfs_downloads_dataset_name: "downloads"
zfs_rag_sources_dataset_name: "rag_sources"       # Para a VM de IA, se usada.
zfs_backups_dataset_name: "backups"

# --- Caminhos de Montagem NFS DENTRO das VMs ---
# Ponto de montagem base DENTRO das VMs para os datasets ZFS compartilhados do Host Proxmox.
vm_nfs_mount_base_path: "/mnt/pve_data_zfs"

# --- Configuração do Servidor NFS (no Host Proxmox) ---
# IPs ou CIDRs das VMs que terão permissão para montar os compartilhamentos NFS.
# Deve cobrir os IPs de todas as suas VMs que precisarão de acesso NFS.
# AJUSTE ESTE VALOR PARA A SUB-REDE DAS SUAS VMs!
vm_nfs_allowed_clients_cidr: "192.168.15.0/24"

# --- Caminhos para Templates `.env` para Stacks Portainer ---
# Usado por playbooks Ansible para preparar arquivos .env para as stacks Docker.
# portainer_env_template_src: "templates/portainer_stack_env.j2" # Caminho relativo ao diretório de roles/playbooks
# Onde os arquivos .env resolvidos (preenchidos pelo Ansible) serão colocados na VM
# para o Portainer usar ao criar/atualizar stacks.
portainer_env_files_dest_path_on_vm: "/opt/portainer_stack_envs"

Com a máquina de controle Ansible devidamente configurada, o inventário definido e os segredos guardados no Vault, você está pronto para prosseguir para a próxima etapa: Instalação e Configuração Base do Proxmox VE.