Infraestrutura como código: conceito
Esta aula apresenta o conceito de Infraestrutura como Código (IaC), sua importância no DevOps, as diferenças entre abordagens declarativas e imperativas, o princípio de idempotência e os principais benefícios para times de operações e desenvolvimento.
Infraestrutura como Código (IaC) é uma prática fundamental no mundo DevOps que consiste em gerenciar e provisionar infraestrutura por meio de código, em vez de processos manuais. Em vez de configurar servidores, redes e outros componentes manualmente, você define o estado desejado da infraestrutura em arquivos de configuração versionáveis, que podem ser revisados, testados e aplicados de forma automatizada. Essa abordagem traz consistência, repetibilidade e escalabilidade para o gerenciamento de ambientes, reduzindo drasticamente erros humanos e aumentando a velocidade de entrega.
Nesta aula, vamos explorar os conceitos essenciais de IaC, desde sua definição até os benefícios práticos. Você entenderá como a IaC se encaixa no ciclo de vida DevOps, as diferenças entre os estilos declarativo e imperativo, e por que a idempotência é uma propriedade crucial. Ao final, você terá uma base sólida para começar a adotar IaC em seus projetos.
O que é IaC
Infraestrutura como Código (IaC) é a prática de tratar a infraestrutura de TI como software: você escreve código que define servidores, redes, bancos de dados, balanceadores de carga e outros componentes. Esse código é armazenado em repositórios de versionamento (como Git), permitindo rastreabilidade, colaboração e revisão. Ferramentas como Terraform, AWS CloudFormation, Ansible, Puppet e Chef são exemplos populares de IaC.
A ideia central é que a infraestrutura pode ser criada, modificada e destruída de forma programática e reproduzível. Em vez de clicar em um painel de controle ou executar comandos manuais, você declara o que deseja e a ferramenta cuida de como alcançar esse estado. Isso elimina a 'deriva de configuração' (quando ambientes se tornam diferentes ao longo do tempo) e permite recriar ambientes idênticos em qualquer momento.
# Exemplo de código Terraform (HCL) para criar uma instância EC2 na AWS
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
No exemplo acima, o código declara que queremos uma instância EC2 com determinada AMI e tipo. Ao executar terraform apply, a ferramenta interage com a AWS para criar o recurso. O mesmo código pode ser aplicado em diferentes ambientes (produção, staging, desenvolvimento) com pequenas variações, garantindo que todos sigam o mesmo padrão.
Declarativo vs imperativo
Existem duas abordagens principais para escrever código de infraestrutura: declarativa e imperativa. Entender a diferença é essencial para escolher a ferramenta e o estilo adequados ao seu cenário.
Abordagem imperativa: Você especifica os passos exatos para alcançar o estado desejado. Ou seja, você diz 'faça isso, depois aquilo'. É como dar instruções passo a passo para alguém montar um móvel. Ferramentas como Ansible (em alguns casos) e scripts de shell seguem essa lógica. O problema é que, se você executar o mesmo script duas vezes, ele pode falhar ou causar efeitos colaterais, porque não verifica o estado atual.
# Exemplo imperativo (Ansible task - instala nginx e inicia o serviço)
- name: Instala nginx
apt:
name: nginx
state: present
- name: Inicia nginx
service:
name: nginx
state: started
Abordagem declarativa: Você declara o estado final desejado e a ferramenta determina como chegar lá. É como dizer 'quero que o móvel fique montado assim'. Terraform, CloudFormation e Kubernetes (para workloads) usam essa abordagem. A ferramenta compara o estado atual com o desejado e aplica apenas as mudanças necessárias. Isso torna o processo mais seguro e idempotente.
# Exemplo declarativo (Terraform - declara que queremos uma instância EC2)
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
Na prática, muitas ferramentas modernas combinam os dois estilos, mas a tendência é preferir a abordagem declarativa por sua simplicidade e robustez. Ao usar IaC, você geralmente escreve arquivos declarativos que descrevem a infraestrutura desejada, e a ferramenta cuida da execução.
Idempotência
Idempotência é a propriedade de uma operação que, quando aplicada múltiplas vezes, produz o mesmo resultado que uma única aplicação. Em outras palavras, executar o mesmo código de IaC repetidamente não deve causar efeitos colaterais indesejados ou alterações adicionais. Isso é crucial para que você possa aplicar configurações com segurança, sem medo de quebrar algo.
Por exemplo, se você roda terraform apply duas vezes, na segunda vez a ferramenta deve detectar que nada mudou e não fazer nada. Isso é possível porque a ferramenta mantém um estado (um arquivo de estado) que registra os recursos existentes. Com idempotência, você pode executar seus scripts de provisionamento sempre que necessário, sem preocupação.
# Comandos Terraform repetidos - o segundo apply não fará nada se nada mudou
terraform apply # primeira execução cria recursos
tterraform apply # segunda execução não altera nada (idempotente)
A idempotência também é importante em scripts de configuração (como Ansible). Por exemplo, uma tarefa que garante que o nginx esteja instalado deve ser idempotente: se o nginx já está instalado, ela não deve fazer nada. Isso evita erros e torna a automação confiável.
Benefícios
Adotar IaC traz inúmeros benefícios para times de DevOps e operações. Vamos destacar os principais:
- Velocidade e eficiência: Provisionar infraestrutura em minutos, não em dias. A automação elimina tarefas manuais repetitivas, permitindo que os times foquem em atividades de maior valor.
- Consistência e redução de erros: Ambientes são criados de forma idêntica, eliminando variações que causam problemas. Erros manuais são minimizados, pois o código é revisado e testado.
- Versionamento e rastreabilidade: Todo o código de infraestrutura fica versionado no Git. Você pode auditar quem mudou o quê, quando e por quê, facilitando a auditoria e a conformidade.
- Reutilização e modularização: Módulos de IaC podem ser compartilhados entre equipes, promovendo boas práticas e padronização. Por exemplo, um módulo para criar um balanceador de carga pode ser reutilizado em vários projetos.
- Recuperação de desastres: Se um ambiente for perdido, você pode recriá-lo rapidamente a partir do código. Isso reduz o RTO (Recovery Time Objective) e aumenta a resiliência.
- Integração com CI/CD: IaC pode ser integrada a pipelines de CI/CD, permitindo que a infraestrutura seja testada e implantada automaticamente junto com o código da aplicação. Isso promove a entrega contínua.
Esses benefícios tornam a IaC uma prática indispensável para organizações que buscam agilidade e confiabilidade em suas operações.
Boas práticas
Para aproveitar ao máximo a IaC, considere as seguintes boas práticas:
- Versionar todo o código: Sempre armazene seu código de infraestrutura em um repositório Git, com commits claros e revisões.
- Use ambientes separados: Mantenha ambientes de desenvolvimento, staging e produção com configurações separadas, mas baseadas no mesmo código.
- Teste sua infraestrutura: Use ferramentas como Terratest ou InSpec para testar a configuração antes de aplicar em produção.
- Mantenha o estado seguro: Para ferramentas como Terraform, o arquivo de estado é sensível. Use backends remotos com bloqueio de estado (ex.: S3 + DynamoDB) para evitar conflitos.
- Documente e padronize: Crie módulos reutilizáveis e documente como usá-los. Isso facilita a colaboração e a manutenção.
Referências
- AWS - Infrastructure as Code
- Terraform Documentation
- Ansible Documentation
- Microsoft Azure - Infrastructure as Code
- Kubernetes Configuration Overview
- Martin Fowler - Infrastructure as Code
- Red Hat - What is Infrastructure as Code
Exercícios
Explique, com suas palavras, a diferença entre abordagem declarativa e imperativa em IaC. Dê um exemplo de cada uma.
✓ Resposta: Na abordagem declarativa, você especifica o estado final desejado e a ferramenta decide como alcançá-lo. Exemplo: Terraform declarando uma instância EC2. Na imperativa, você especifica os passos exatos. Exemplo: um script de shell que executa comandos sequenciais para instalar e configurar um servidor.Qual é a importância da idempotência em IaC? Dê um exemplo de uma operação não idempotente e como ela pode causar problemas.
✓ Resposta: Idempotência garante que executar a mesma operação várias vezes produza o mesmo resultado, sem efeitos colaterais. Um exemplo de operação não idempotente é adicionar uma linha a um arquivo sem verificar se ela já existe; executar duas vezes duplicaria a linha. Em IaC, isso poderia causar configurações incorretas ou recursos duplicados.Liste três benefícios da IaC e explique como cada um impacta positivamente um time de DevOps.
✓ Resposta: Benefícios: 1) Velocidade: provisionamento automatizado reduz o tempo de criação de ambientes. 2) Consistência: ambientes idênticos eliminam discrepâncias. 3) Versionamento: código versionado permite rastreabilidade e rollback. Isso melhora a colaboração, reduz erros e acelera entregas.Dado o seguinte trecho de código Terraform (imperativo? declarativo?), identifique a abordagem e explique o que ele faz:
resource "aws_instance" "web" { ami = "ami-0c55b159cbfafe1f0" instance_type = "t2.micro" }✓ Resposta: É declarativo, pois declara o estado desejado (uma instância EC2 com determinada AMI e tipo) sem especificar os passos para criá-la. O Terraform determina como alcançar esse estado.Você precisa provisionar um servidor web com Nginx instalado. Escreva um exemplo de código (pode ser conceitual) em uma ferramenta de IaC de sua escolha, mostrando a abordagem declarativa.
✓ Resposta: Exemplo com Ansible (embora seja mais procedural, pode ser usado declarativamente):
Ou com Terraform, você poderia usar um provisioner, mas a forma mais declarativa seria usar um módulo de configuração (ex: user_data).- name: Garantir que o nginx esteja instalado e rodando hosts: web tasks: - name: Instalar nginx apt: name: nginx state: present - name: Iniciar nginx service: name: nginx state: started