Conceitos Infrastructure as Code
O que é IaC?
Infrastructure as Code (IaC) é a prática de gerenciar e provisionar a infraestrutura por meio de arquivos de configuração, em vez de processos manuais.
┌─────────────────────────────────────────────────────────────┐
│ IaC vs MANUAL │
├─────────────────────────────────────────────────────────────┤
│ │
│ PROVISIONAMENTO MANUAL │
│ ────────────────────── │
│ 1. Abrir o console da AWS │
│ 2. Clicar em "Launch Instance" │
│ 3. Configurar manualmente... │
│ 4. Repetir para cada recurso │
│ 5. Documentar os parâmetros │
│ │
│ Problemas: │
│ ❌ Não reprodutível │
│ ❌ Erros humanos │
│ ❌ Sem versionamento │
│ ❌ Documentação desatualizada │
│ ❌ Difícil de auditar │
│ │
│ ──────────────────────────────────────────────────────── │
│ │
│ INFRASTRUCTURE AS CODE │
│ ────────────────────── │
│ 1. Escrever um template (YAML/JSON) │
│ 2. Versionar no Git │
│ 3. Fazer deploy com CloudFormation │
│ 4. Automatizar via CI/CD │
│ │
│ Vantagens: │
│ ✅ Reprodutível (mesmo resultado sempre) │
│ ✅ Versionado (histórico completo) │
│ ✅ Revisão de código (peer review) │
│ ✅ Documentação viva (o código É a documentação) │
│ ✅ Automatizável (CI/CD) │
│ │
└─────────────────────────────────────────────────────────────┘
AWS CloudFormation
Visão Geral
┌─────────────────────────────────────────────────────────────┐
│ CLOUDFORMATION │
├─────────────────────────────────────────────────────────────┤
│ │
│ COMPONENTES: │
│ │
│ ┌─────────────┐ │
│ │ TEMPLATE │ Arquivo YAML/JSON descrevendo │
│ │ (código) │ a infraestrutura desejada │
│ └──────┬──────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ STACK │ Instância de um template │
│ │ │ com recursos reais │
│ └──────┬──────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ RECURSOS AWS │ │
│ │ │ │
│ │ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ │
│ │ │ VPC │ │ EC2 │ │ RDS │ │ ALB │ │ SG │ │ │
│ │ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ CICLO DE VIDA: │
│ Create → Update → Delete │
│ (ou Rollback em caso de erro) │
│ │
└─────────────────────────────────────────────────────────────┘
Estrutura de um Template
Seções
AWSTemplateFormatVersion: "2010-09-09"
Description: Descrição do template
# 1. PARAMETERS - Variáveis de entrada
Parameters:
EnvironmentType:
Type: String
Default: dev
AllowedValues: [dev, staging, prod]
# 2. MAPPINGS - Tabelas de lookup
Mappings:
RegionAMI:
us-east-1:
AMI: ami-0123456789
# 3. CONDITIONS - Lógica condicional
Conditions:
IsProd: !Equals [!Ref EnvironmentType, prod]
# 4. RESOURCES - Os recursos a serem criados (OBRIGATÓRIO)
Resources:
MyEC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !FindInMap [RegionAMI, !Ref "AWS::Region", AMI]
InstanceType: t3.micro
# 5. OUTPUTS - Valores exportados
Outputs:
InstanceId:
Value: !Ref MyEC2Instance
Export:
Name: MyInstanceId
Tipos de Recursos Comuns
| Tipo | Descrição |
|---|---|
AWS::EC2::Instance | Instância EC2 |
AWS::EC2::VPC | VPC |
AWS::EC2::Subnet | Sub-rede |
AWS::EC2::SecurityGroup | Security Group |
AWS::RDS::DBInstance | Banco de dados RDS |
AWS::S3::Bucket | Bucket S3 |
AWS::Lambda::Function | Função Lambda |
AWS::ElasticLoadBalancingV2::LoadBalancer | ALB/NLB |
Funções Intrínsecas
As Mais Utilizadas
Resources:
# !Ref - Referenciar um parâmetro ou recurso
MyInstance:
Type: AWS::EC2::Instance
Properties:
InstanceType: !Ref InstanceType # Parâmetro
SubnetId: !Ref MySubnet # Recurso
# !GetAtt - Obter um atributo de um recurso
MyDNSRecord:
Type: AWS::Route53::RecordSet
Properties:
Name: app.example.com
ResourceRecords:
- !GetAtt MyInstance.PublicIp # IP público da instância
# !Sub - Substituição de variáveis
MyBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub "${AWS::StackName}-${AWS::Region}-data"
# !Join - Concatenar valores
MyTag:
Type: AWS::EC2::Instance
Properties:
Tags:
- Key: Name
Value: !Join ["-", [web, !Ref EnvironmentType, server]]
# !If - Condição
MyVolume:
Type: AWS::EC2::Volume
Properties:
Size: !If [IsProd, 100, 20] # 100 GB em prod, 20 caso contrário
# !FindInMap - Lookup em Mappings
MyInstance2:
Type: AWS::EC2::Instance
Properties:
ImageId: !FindInMap [RegionAMI, !Ref "AWS::Region", AMI]
Exemplo Completo: Infraestrutura Web
AWSTemplateFormatVersion: "2010-09-09"
Description: Infraestrutura web simples com EC2 e Security Group
Parameters:
Environment:
Type: String
Default: dev
AllowedValues: [dev, staging, prod]
Description: Environment name
InstanceType:
Type: String
Default: t3.micro
AllowedValues: [t3.micro, t3.small, t3.medium]
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Description: EC2 Key Pair for SSH access
Mappings:
RegionAMI:
us-east-1:
AMI: ami-0c55b159cbfafe1f0
eu-west-1:
AMI: ami-0d729a60
Resources:
# Security Group
WebSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP and SSH
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: !Sub "${Environment}-web-sg"
- Key: Environment
Value: !Ref Environment
# EC2 Instance
WebServer:
Type: AWS::EC2::Instance
Properties:
ImageId: !FindInMap [RegionAMI, !Ref "AWS::Region", AMI]
InstanceType: !Ref InstanceType
KeyName: !Ref KeyName
SecurityGroupIds:
- !Ref WebSecurityGroup
Tags:
- Key: Name
Value: !Sub "${Environment}-web-server"
- Key: Environment
Value: !Ref Environment
UserData:
Fn::Base64: |
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "<h1>Hello from CloudFormation!</h1>" > /var/www/html/index.html
Outputs:
InstanceId:
Description: Instance ID
Value: !Ref WebServer
Export:
Name: !Sub "${Environment}-WebServerId"
PublicIP:
Description: Public IP address
Value: !GetAtt WebServer.PublicIp
WebsiteURL:
Description: URL of the website
Value: !Sub "http://${WebServer.PublicIp}"
Comandos CLI
# Validar um template
aws cloudformation validate-template \
--template-body file://template.yaml
# Criar uma stack
aws cloudformation create-stack \
--stack-name my-web-stack \
--template-body file://template.yaml \
--parameters \
ParameterKey=Environment,ParameterValue=dev \
ParameterKey=KeyName,ParameterValue=my-key
# Ver o status da stack
aws cloudformation describe-stacks \
--stack-name my-web-stack
# Ver eventos (debug)
aws cloudformation describe-stack-events \
--stack-name my-web-stack
# Atualizar uma stack
aws cloudformation update-stack \
--stack-name my-web-stack \
--template-body file://template.yaml \
--parameters \
ParameterKey=Environment,ParameterValue=staging
# Deletar uma stack
aws cloudformation delete-stack \
--stack-name my-web-stack
Boas Práticas
┌─────────────────────────────────────────────────────────────┐
│ BOAS PRÁTICAS CLOUDFORMATION │
├─────────────────────────────────────────────────────────────┤
│ │
│ ✅ FAÇA │
│ ──────── │
│ • Versione os templates no Git │
│ • Use parâmetros para flexibilidade │
│ • Adicione descrições claras │
│ • Use nomes lógicos e significativos │
│ • Valide antes de fazer deploy │
│ • Use Change Sets para preview │
│ • Adicione tags em todos os recursos │
│ │
│ ❌ EVITE │
│ ───────── │
│ • Hardcode de valores (AMIs, IPs...) │
│ • Criar templates monolíticos (> 500 linhas) │
│ • Ignorar erros de validação │
│ • Fazer deploy sem revisão de código │
│ • Esquecer outputs para referências │
│ │
└─────────────────────────────────────────────────────────────┘
Resumo
| Conceito | Descrição |
|---|---|
| Template | Arquivo YAML/JSON que descreve a infraestrutura |
| Stack | Instância implantada de um template |
| Parameters | Variáveis de entrada configuráveis |
| Resources | Os recursos AWS a serem criados |
| Outputs | Valores exportados para referência |
| !Ref | Referenciar um recurso ou parâmetro |
| !GetAtt | Obter um atributo de um recurso |
Próxima seção: Lab CloudFormation