Infraestrutura como Código (IaC)¶
O que é Infraestrutura como Código (IaC)?¶
A Infraestrutura como Código (Infrastructure as Code – IaC) é uma prática fundamental nas abordagens modernas de DevOps e engenharia de software. Ela permite que a infraestrutura de TI — servidores, redes, máquinas virtuais, armazenamento e até serviços de nuvem — seja gerenciada e provisionada por meio de arquivos de código, de maneira automatizada, reproduzível e versionável. Essa abordagem transforma a infraestrutura em um ativo de software, permitindo que equipes tratem a infraestrutura com os mesmos princípios e práticas que aplicam ao desenvolvimento de software.
Origens da IaC¶
A prática de Infraestrutura como Código (IaC) tem suas raízes na automação de TI e na virtualização. Com o advento de tecnologias de virtualização, como VMware e Hyper-V, as equipes de TI começaram a automatizar o provisionamento de máquinas virtuais. Essa automação inicial evoluiu para a necessidade de gerenciar não apenas máquinas virtuais, mas também redes, armazenamento e outros componentes de infraestrutura de forma programática.
A popularização de serviços de nuvem, como Amazon Web Services (AWS) e Microsoft Azure, também impulsionou a adoção da IaC. Esses provedores de nuvem oferecem APIs e ferramentas que permitem que a infraestrutura seja definida e gerenciada por meio de código, tornando a IaC uma prática padrão nas operações em nuvem.
Antes do surgimento da IaC, a configuração de servidores era feita manualmente (via SSH, scripts shell, edições em tempo real de arquivos de configuração), o que era demorado, sujeito a erros e difícil de auditar ou replicar. Mesmo com a virtualização, embora ferramentas como VMWare e VirtualBox possibilitaram a criação de ambientes mais rápidos, ainda havia a dependência de interação manual. Mais recentemente, com o avanço do DevOps e da computação em nuvem, tornou-se essencial criar ambientes automatizados e reproduzíveis — daí a adoção do IaC.
Benefícios da IaC¶
O uso de Infraestrutura como Código (IaC) traz uma série de benefícios significativos para as equipes de desenvolvimento e operações:
-
Automação: A IaC permite a automação do provisionamento e gerenciamento da infraestrutura, reduzindo a necessidade de intervenções manuais e minimizando erros.
-
Reproduzibilidade: Com a IaC, é possível reproduzir ambientes de forma consistente, garantindo que as mesmas configurações sejam aplicadas em diferentes ambientes (desenvolvimento, teste, produção).
-
Versionamento: Assim como o código-fonte, a infraestrutura pode ser versionada, permitindo que equipes rastreiem alterações, revertam para versões anteriores e colaborem de forma mais eficaz.
-
Escalabilidade: A IaC facilita a escalabilidade da infraestrutura, permitindo que recursos sejam provisionados ou desprovisionados rapidamente, conforme a demanda.
-
Integração Contínua e Entrega Contínua (CI/CD): A IaC é uma parte essencial das práticas de CI/CD, permitindo que a infraestrutura seja tratada como código e integrada aos pipelines de entrega de software.
-
Auditoria e Conformidade: Com a IaC, é possível auditar as configurações da infraestrutura de forma mais eficaz, garantindo que as políticas de conformidade sejam seguidas e facilitando a identificação de desvios.
-
Redução de error humanos: A automação e a padronização proporcionadas pela IaC reduzem significativamente a probabilidade de erros humanos, que são comuns em processos manuais de configuração.
Limitações da IaC¶
Apesar dos muitos benefícios, a Infraestrutura como Código (IaC) também apresenta algumas limitações e desafios:
-
Complexidade: A IaC pode introduzir complexidade adicional, especialmente em ambientes grandes e distribuídos, onde a gestão de dependências e configurações pode se tornar desafiadora.
-
Curva de Aprendizado: Para equipes que não estão familiarizadas com a IaC, pode haver uma curva de aprendizado significativa para entender as ferramentas e práticas associadas.
-
Dependência de Ferramentas: A IaC geralmente depende de ferramentas específicas, o que pode levar a um acoplamento indesejado entre a infraestrutura e as ferramentas utilizadas.
-
Gerenciamento de Estado: Em algumas ferramentas de IaC, o gerenciamento do estado da infraestrutura pode ser complicado, especialmente em ambientes dinâmicos onde os recursos são frequentemente criados e destruídos.
-
Segurança: A IaC pode introduzir riscos de segurança se não for gerenciada adequadamente, especialmente se as credenciais e segredos forem armazenados em código ou repositórios de forma insegura.
Classificação da IaC quanto à abordagem de implementação¶
A Infraestrutura como Código (IaC) pode ser classificada em duas categorias principais:
-
Declarativa: Nesse modelo, o usuário descreve o estado desejado da infraestrutura, e a ferramenta de IaC se encarrega de criar ou modificar os recursos para alcançar esse estado. Exemplos de ferramentas incluem Terraform e AWS CloudFormation.
-
Imperativa: Nesse modelo, o usuário especifica os passos necessários para alcançar o estado desejado da infraestrutura. A ferramenta executa esses passos em ordem. Exemplos de ferramentas incluem Ansible e Chef.
Tipos de ferramentas de IaC¶
As ferramentas de Infraestrutura como Código (IaC) podem ser divididas em duas categorias principais:
-
Ferramentas de Provisionamento: Essas ferramentas são usadas para criar e gerenciar recursos de infraestrutura, como máquinas virtuais, redes e serviços em nuvem. Elas permitem que os usuários definam a infraestrutura desejada em arquivos de configuração e automatizem o processo de provisionamento. Exemplos incluem Terraform, AWS CloudFormation e Pulumi.
-
Ferramentas de Configuração: Essas ferramentas são usadas para configurar e gerenciar o software e as aplicações em execução na infraestrutura provisionada. Elas permitem que os usuários definam o estado desejado do software e automatizem a configuração dos sistemas. Exemplos incluem Ansible, Chef e Puppet.
-
Ferramentas de Orquestração: Essas ferramentas são usadas para coordenar e gerenciar a execução de várias tarefas e processos em um ambiente de infraestrutura. Elas ajudam a garantir que as dependências sejam atendidas e que os recursos sejam provisionados e configurados na ordem correta. Exemplos incluem Kubernetes (para orquestração de contêineres) e Apache Mesos.
-
Ferramentas de Empacotamento: Essas ferramentas são usadas para empacotar e distribuir a infraestrutura como código, facilitando o compartilhamento e a reutilização de configurações. Elas permitem que os usuários criem pacotes de infraestrutura que podem ser facilmente implantados em diferentes ambientes. É muito comum para a criação de ambientes locais. Exemplos incluem Docker (para contêineres) e Vagrant (para ambientes de desenvolvimento).
Ferramentas Comuns de IaC¶
Existem várias ferramentas populares que suportam a prática de IaC, incluindo:
-
Terraform: Uma ferramenta de código aberto que permite definir e provisionar infraestrutura em nuvem usando uma linguagem de configuração declarativa.
-
AWS CloudFormation: Um serviço da Amazon Web Services que permite criar e gerenciar recursos da AWS usando arquivos de modelo.
-
Ansible: Uma ferramenta de automação que pode ser usada para configurar e gerenciar infraestrutura de forma declarativa.
-
Pulumi: Uma plataforma que permite definir a infraestrutura usando linguagens de programação convencionais, como JavaScript, TypeScript e Python.
Laboratório de integração do Packer + Vagrant + VirtualBox¶
Vamos fazer um laboratório de integração do Packer com o Vagrant e o VirtualBox. O objetivo é criar uma imagem de máquina virtual personalizada usando o Packer, que será utilizada pelo Vagrant para provisionar ambientes de desenvolvimento consistentes.
Fundamentos das ferramentas¶
- Packer: É uma ferramenta de código aberto para criar imagens de máquina virtual idempotentes e reutilizáveis. Ele permite que você defina a configuração da imagem em um arquivo JSON ou HCL, especificando os recursos e as etapas de provisionamento necessários. O Packer suporta vários provedores de virtualização, incluindo VirtualBox, AWS, Azure e outros. Foi criado pela HashiCorp, a mesma empresa por trás do Terraform.
- Vagrant: É uma ferramenta de código aberto para criar e gerenciar ambientes de desenvolvimento virtualizados. Ele permite que você defina a configuração do ambiente em um arquivo Vagrantfile, especificando o sistema operacional, as dependências e as configurações necessárias. O Vagrant é amplamente utilizado para criar ambientes de desenvolvimento consistentes e reproduzíveis, facilitando o trabalho em equipe e a colaboração entre desenvolvedores. Foi criado também pela HashiCorp.
- VirtualBox: É um software de virtualização de código aberto que permite criar e executar máquinas virtuais em diferentes sistemas operacionais. Ele é amplamente utilizado como provedor de virtualização para o Vagrant, permitindo que os desenvolvedores criem e gerenciem ambientes de desenvolvimento virtualizados de forma fácil e eficiente. O VirtualBox suporta uma ampla variedade de sistemas operacionais convidados e é compatível com várias plataformas, incluindo Windows, macOS e Linux. Ele foi desenvolvido pela Oracle e é uma das ferramentas de virtualização mais populares no mundo do desenvolvimento de software.
Pré-requisitos¶
- Packer: Certifique-se de ter o Packer instalado em sua máquina. Você pode baixar a versão mais recente do Packer em packer.io.
- Vagrant: Instale o Vagrant em sua máquina. Você pode encontrar as instruções de instalação em vagrantup.com.
- VirtualBox: Instale o VirtualBox, que é o provedor de virtualização utilizado pelo Vagrant. Você pode baixar o VirtualBox em virtualbox.org.
Criando uma imagem personalizada com o Packer¶
-
Crie um diretório para o projeto:
O arquivo deve ser:
-
Crie um arquivo de configuração do Packer
Crie um arquivo chamado
packer.pkr.hclcom o seguinte conteúdo:packer { required_plugins { virtualbox = { version = "~> 1" source = "github.com/hashicorp/virtualbox" } vagrant = { version = ">= 1.1.1" source = "github.com/hashicorp/vagrant" } } }Nesse caso estamos utilizando o HCL (HashiCorp Configuration Language) para definir a configuração do Packer. O arquivo especifica os plugins necessários, como o VirtualBox e o Vagrant. Os plugins são responsáveis por fornecer suporte a diferentes provedores de virtualização e ferramentas de provisionamento. Mais informações sobre o HCL podem ser encontradas na documentação do Packer.
Você precisar agora inicializar o projeto Packer e instalar o plugins registrados. Para isso, execute os seguintes comandos:
-
Crie um arquivo de configuração do Packer
Crie um arquivo chamado
debian.jsoncom o seguinte conteúdo:{ "variables": { "vm_name": "debian12", "iso_url": "https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-12.11.0-amd64-netinst.iso", "iso_checksum": "sha256:30ca12a15cae6a1033e03ad59eb7f66a6d5a258dcf27acd115c2bd42d22640e8" }, "builders": [ { "type": "virtualbox-iso", "guest_os_type": "Debian_64", "vm_name": "{{user `vm_name`}}", "iso_url": "{{user `iso_url`}}", "iso_checksum": "{{user `iso_checksum`}}", "ssh_username": "vagrant", "ssh_password": "vagrant", "ssh_timeout": "20m", "shutdown_command": "echo 'vagrant' | sudo -S shutdown -P now", "disk_size": 61440, "http_directory": "http", "boot_wait": "5s", "boot_command": [ "<esc><wait>", "auto url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed.cfg ", "debian-installer=en_US auto locale=pt_BR ", "kbd-chooser/method=us ", "hostname={{user `vm_name`}} ", "fb=false debconf/frontend=noninteractive ", "keyboard-configuration/layout=Brazilian ", "keyboard-configuration/variant=Brazilian<enter>" ], "vboxmanage": [ ["modifyvm", "{{.Name}}", "--memory", "2048"], ["modifyvm", "{{.Name}}", "--cpus", "2"], ["modifyvm", "{{.Name}}", "--nic1", "nat"], ["modifyvm", "{{.Name}}", "--nictype1", "82540EM"], ["modifyvm", "{{.Name}}", "--cableconnected1", "on"] ] } ], "provisioners": [ { "type": "shell", "inline": [ "echo 'Provisionando como vagrant...'", "echo 'auto enp0s8' | sudo tee -a /etc/network/interfaces", "echo 'iface enp0s8 inet dhcp' | sudo tee -a /etc/network/interfaces", "mkdir -p /home/vagrant/.ssh", "chmod 700 /home/vagrant/.ssh", "curl -fsSL https://raw.githubusercontent.com/hashicorp/vagrant/main/keys/vagrant.pub -o /home/vagrant/.ssh/authorized_keys", "cat /home/vagrant/.ssh/authorized_keys", "chmod 600 /home/vagrant/.ssh/authorized_keys", "chown -R vagrant:vagrant /home/vagrant/.ssh" ] } ], "post-processors": [ { "type": "vagrant", "output": "debian12.box" } ] }Nesse arquivo, definimos as variáveis necessárias, como o nome da máquina virtual, a URL do ISO do Debian e o checksum do ISO. Em seguida, configuramos o construtor
virtualbox-iso, que especifica as configurações da máquina virtual, como o tipo de sistema operacional convidado, o nome da máquina virtual, a URL do ISO e as configurações de rede. O comando de inicialização é configurado para automatizar a instalação do Debian usando um arquivo de pré-configuração.Na chave
builderespecificamos o tipo de construtor comovirtualbox-iso, que é responsável por criar uma imagem de máquina virtual usando o VirtualBox. As configurações incluem:guest_os_type: Define o tipo de sistema operacional convidado, neste caso, Debian 64 bits.vm_name: Define o nome da máquina virtual. Essa informação é passada como uma variável, permitindo que você altere facilmente o ISO sem modificar o arquivo principal.iso_url: Especifica a URL do ISO do Debian que será usado para criar a imagem. Essa informação também é uma variável.iso_checksum: Fornece o checksum do ISO para garantir a integridade do arquivo. Como as duas anteriores, é uma variável.ssh_usernameessh_password: Definem as credenciais SSH para acessar a máquina virtual durante o provisionamento.ssh_timeout: Define o tempo limite para a conexão SSH.shutdown_command: Especifica o comando para desligar a máquina virtual após o provisionamento.disk_size: Define o tamanho do disco da máquina virtual em megabytes.http_directory: Especifica o diretório onde o Packer procurará arquivos HTTP para provisionamento.boot_wait: Define o tempo de espera antes de iniciar o processo de boot.boot_command: Define os comandos de boot que serão enviados para a máquina virtual durante o processo de inicialização. Esses comandos são usados para automatizar a instalação do Debian usando um arquivo de pré-configuração. Essas informações são passadas como uma lista de strings, onde cada string representa um comando a ser enviado para a máquina virtual no momento do boot.vboxmanage: Permite modificar as configurações da máquina virtual usando comandos do VirtualBox. Aqui, estamos configurando a memória, o número de CPUs e as configurações de rede. Nesse caso, estamos configurando a máquina virtual para usar 2 GB de memória, 2 CPUs e uma interface de rede NAT.
O bloco
provisionersdefine as etapas de provisionamento que serão executadas após a criação da imagem. Neste caso, estamos usando um provisionador do tiposhell, que executa comandos shell na máquina virtual. Os comandos incluem a configuração da interface de rede e a adição da chave SSH do Vagrant. Note que ele baixa a chave pública do Vagrant diretamente do repositório oficial, que será usada para autenticação SSH no provisionamento.O bloco
post-processorsdefine as etapas que serão executadas após o provisionamento. Neste caso, estamos usando um post-processor do tipovagrant, que cria um arquivo.boxque pode ser usado pelo Vagrant para criar máquinas virtuais a partir da imagem criada pelo Packer. -
Crie um arquivo de pré-configuração:
Crie um diretório chamado
httpe dentro dele, crie um arquivo chamadopreseed.cfgcom o seguinte conteúdo:d-i debian-installer/locale string pt_BR.UTF-8 d-i console-setup/ask_detect boolean false d-i keyboard-configuration/xkb-keymap select br d-i keyboard-configuration/layout select Brazil d-i keyboard-configuration/variant select abnt2 d-i keyboard-configuration/modelcode string abnt2 d-i netcfg/choose_interface select enp0s3 d-i netcfg/choose_interface_if_needed boolean false d-i netcfg/choose_interface priority critical d-i netcfg/get_hostname string debian12 d-i netcfg/get_domain string localdomain d-i mirror/country string manual d-i mirror/http/hostname string deb.debian.org d-i mirror/http/directory string /debian d-i mirror/http/proxy string d-i accessibility-profile/choose-profile select none d-i clock-setup/utc boolean true d-i time/zone string America/Sao_Paulo d-i clock-setup/ntp boolean true d-i partman-auto/method string regular d-i partman-auto/choose_recipe select atomic d-i partman-partitioning/confirm_write_new_label boolean true d-i partman/choose_partition select finish d-i partman/confirm boolean true d-i partman/confirm_nooverwrite boolean true d-i passwd/user-fullname string Vagrant User d-i passwd/username string vagrant d-i passwd/user-password password vagrant d-i passwd/user-password-again password vagrant d-i user-setup/encrypt-home boolean false d-i user-setup/allow-password-weak boolean true d-i passwd/user-default-groups string sudo d-i passwd/root-login boolean false d-i passwd/root-password password root d-i passwd/root-password-again password root d-i grub-installer/only_debian boolean true d-i grub-installer/bootdev string /dev/sda d-i finish-install/reboot_in_progress note d-i preseed/late_command string in-target adduser vagrant sudo d-i preseed/late_command string in-target sh -c "echo 'vagrant ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/vagrant && chmod 440 /etc/sudoers.d/vagrant" d-i pkgsel/run_tasksel boolean false d-i pkgsel/include string openssh-server build-essential d-i pkgsel/include string sudo curl vim net-tools ssh lynx ansible d-i pkgsel/upgrade select full-upgrade -
Crie o arquivo de imagem
Execute o seguinte comando para criar a sua imagem:
-
Adicione a imagem criada ao Vagrant
Após a criação da imagem, você pode adicionar a imagem ao Vagrant usando o seguinte comando:
Isso registrará a imagem
debian12.boxno Vagrant, permitindo que você crie máquinas virtuais a partir dela. -
Crie o arquivo de configuração do Vagrant:
Crie um arquivo chamado
Vagrantfile, com seguinte conteúdo:Vagrant.configure("2") do |config| config.vm.box = "debian12" config.vm.network "public_network", bridge: "enp2s0" config.vm.provider "virtualbox" do |vb| vb.memory = "2048" vb.cpus = 2 end endCaso você queira, por exemplo, levantar três máquinas virtuais, você pode modificar o arquivo
Vagrantfilepara incluir múltiplas máquinas. Veja um exemplo:Vagrant.configure("2") do |config| (1..3).each do |i| config.vm.define "debian#{i}" do |machine| machine.vm.box = "debian12" machine.vm.network "public_network", bridge: "enp2s0" machine.vm.provider "virtualbox" do |vb| vb.memory = "2048" vb.cpus = 2 end end end endNesse exemplo, estamos criando três máquinas virtuais chamadas
debian1,debian2edebian3, todas com as mesmas configurações de rede e recursos. -
Use o seu ambiente com o vagrant
Para usar o ambiente criado execute:
Laboratório de Ansible¶
Ansible é uma ferramenta de automação de TI que permite gerenciar e configurar sistemas, implantar aplicativos e orquestrar tarefas complexas de forma simples e eficiente. Ele utiliza uma abordagem declarativa, onde o usuário define o estado desejado da infraestrutura ou dos sistemas, e o Ansible se encarrega de aplicar as mudanças necessárias para alcançar esse estado.
Ansible é amplamente utilizado em ambientes de DevOps e Infraestrutura como Código (IaC) devido à sua simplicidade, flexibilidade e capacidade de automação. Ele é especialmente útil para gerenciar grandes quantidades de servidores e serviços, permitindo que as equipes de TI automatizem tarefas repetitivas e se concentrem em atividades mais estratégicas.
Pré-requisitos¶
Antes de começar a trabalhar com Ansible, é necessário ter um ambiente configurado. Aqui estão os pré-requisitos:
- Sistema Operacional: Ansible é compatível com sistemas baseados em Unix/Linux. Certifique-se de ter um sistema operacional adequado instalado, como Ubuntu, CentOS ou Debian.
- Python: Ansible requer Python 3.6 ou superior. Verifique se o Python está instalado no seu sistema executando o comando
python3 --version. - Acesso SSH: Ansible utiliza SSH para se conectar aos servidores remotos. Certifique-se de ter acesso SSH configurado para os servidores que deseja gerenciar.
- Instalação do Ansible: Você pode instalar o Ansible usando o gerenciador de pacotes do seu sistema.
Note que você precise dos servidores que deseja gerenciar com Ansible. Para este laboratório, você pode usar máquinas virtuais (que criamos no laboratório anterior) ou servidores na nuvem.
Além disso, você deve gerar uma chave SSH para autenticação sem senha. Você pode fazer isso com o comando ssh-keygen e copiar a chave pública para os servidores remotos usando ssh-copy-id.
Laboratório Prático¶
Neste laboratório, vamos criar um playbook simples do Ansible para instalar e configurar um servidor web Nginx em uma máquina virtual. O objetivo é demonstrar como o Ansible pode ser usado para automatizar a configuração de servidores. Sugiro que você faça isso dentro de uma pasta chamada ansible dentro do diretório devops. Isso é importante para dividir as configurações do Ansible de outras ferramentas e práticas de DevOps, com o Packer, Vagrant e Docker.
-
Criar um arquivo de inventário
Crie um arquivo chamado
hostsna pastaansiblee adicione o seguinte conteúdo:[webservers] webserver1 ansible_host=192.168.56.101 webserver2 ansible_host=192.168.56.102 [all:vars] ansible_ssh_private_key_file=/caminho/para/chave/privada/ssh ansible_user=vagrantSubstitua os endereços IP pelos endereços dos seus servidores. Esses IPs podem ser os endereços das máquinas virtuais criadas no laboratório anterior.
-
Criar um playbook do Ansible
Crie um arquivo chamado
install_nginx.ymlna pastaansiblee adicione o seguinte conteúdo:--- - name: Instalar e configurar Nginx hosts: webservers become: yes tasks: - name: Instalar o Nginx apt: name: nginx state: present update_cache: yes - name: Garantir que o Nginx esteja rodando service: name: nginx state: startedVocê pode fazer várias outras configurações, como adicionar um arquivo de configuração personalizado ou copiar arquivos estáticos para o servidor. Também é possível adicionar outras tarefas, como instalar pacotes adicionais ou configurar o firewall.
-
Executar o playbook do Ansible
Para executar o playbook, abra um terminal na pasta
ansiblee execute o seguinte comando:Isso irá conectar-se aos servidores definidos no arquivo de inventário e executar as tarefas definidas no playbook.
Conclusão¶
A Infraestrutura como Código (IaC) é uma prática essencial para equipes de DevOps que buscam aumentar a eficiência, reduzir erros e melhorar a colaboração. Ao tratar a infraestrutura como código, as organizações podem aproveitar os benefícios da automação, reproduzibilidade e versionamento, tornando-se mais ágeis e responsivas às necessidades de negócios em constante mudança.
Note que é importante escolher a ferramenta de IaC certa com base nas necessidades específicas da equipe e do projeto, considerando fatores como a complexidade da infraestrutura, a familiaridade da equipe com as ferramentas e os requisitos de integração com outras práticas de DevOps. Também, é muito comum que as equipes utilizem uma combinação de ferramentas para atender a diferentes aspectos da IaC, como provisionamento, configuração e orquestração.