Cloud & Infraestrutura

Boas Práticas de CloudFormation em Profundidade: Templates, Stacks e StackSets para Times Ágeis

7 min de leitura

Boas Práticas de CloudFormation em Profundidade: Templates, Stacks e StackSets para Times Ágeis

Fundamentos de CloudFormation para Automação de Infraestrutura CloudFormation é o serviço de Infrastructure as Code (IaC) da AWS que permite descrever e provisionar recursos através de templates. Diferente de cliques no console, você define sua infraestrutura em YAML ou JSON, versionável e reproduzível. Para times ágeis, isso significa deployments consistentes, rollbacks automáticos e documentação viva da sua arquitetura. Um template CloudFormation descreve recursos AWS, parâmetros de entrada e saídas. A mágica acontece quando você cria um Stack — uma instância daquele template. Se algo quebrar, a CloudFormation rastreia o estado e pode reverter mudanças atomicamente. Isso elimina aquele caos de "quem deployou o quê" e quando. Estruturando Templates para Escalabilidade e Reutilização Templates monolíticos quebram a escalabilidade. A melhor prática é decomposição: cada template cuida de um concern específico (networking, databases, compute). Use cross-stack references através de Exports para conectar outputs de um stack como inputs de outro. Implemente parâmetros sensatos com defaults, use Conditions para lógica condicional (dev vs

<h2>Fundamentos de CloudFormation para Automação de Infraestrutura</h2>

<p>CloudFormation é o serviço de Infrastructure as Code (IaC) da AWS que permite descrever e provisionar recursos através de templates. Diferente de cliques no console, você define sua infraestrutura em YAML ou JSON, versionável e reproduzível. Para times ágeis, isso significa deployments consistentes, rollbacks automáticos e documentação viva da sua arquitetura.</p>

<p>Um template CloudFormation descreve recursos AWS, parâmetros de entrada e saídas. A mágica acontece quando você cria um Stack — uma instância daquele template. Se algo quebrar, a CloudFormation rastreia o estado e pode reverter mudanças atomicamente. Isso elimina aquele caos de &quot;quem deployou o quê&quot; e quando.</p>

<pre><code class="language-yaml">AWSTemplateFormatVersion: &#039;2010-09-09&#039;

Description: &#039;VPC com subnet pública para aplicação web&#039;

Parameters:

CidrBlock:

Type: String

Default: 10.0.0.0/16

Description: CIDR da VPC

Resources:

MyVPC:

Type: AWS::EC2::VPC

Properties:

CidrBlock: !Ref CidrBlock

EnableDnsHostnames: true

EnableDnsSupport: true

Tags:

  • Key: Name

Value: production-vpc

PublicSubnet:

Type: AWS::EC2::Subnet

Properties:

VpcId: !Ref MyVPC

CidrBlock: 10.0.1.0/24

AvailabilityZone: !Select [0, !GetAZs &#039;&#039;]

MapPublicIpOnLaunch: true

InternetGateway:

Type: AWS::EC2::InternetGateway

Properties:

Tags:

  • Key: Name

Value: production-igw

AttachGateway:

Type: AWS::EC2::VPCGatewayAttachment

Properties:

VpcId: !Ref MyVPC

InternetGatewayId: !Ref InternetGateway

Outputs:

VPCId:

Description: ID da VPC criada

Value: !Ref MyVPC

Export:

Name: !Sub &#039;${AWS::StackName}-VPC-ID&#039;

SubnetId:

Description: ID da subnet pública

Value: !Ref PublicSubnet

Export:

Name: !Sub &#039;${AWS::StackName}-Subnet-ID&#039;</code></pre>

<h2>Estruturando Templates para Escalabilidade e Reutilização</h2>

<p>Templates monolíticos quebram a escalabilidade. A melhor prática é decomposição: cada template cuida de um concern específico (networking, databases, compute). Use cross-stack references através de Exports para conectar outputs de um stack como inputs de outro.</p>

<p>Implemente parâmetros sensatos com defaults, use Conditions para lógica condicional (dev vs produção), e Always mantenha templates versionados no Git. Adicione Metadata com descrições de parâmetros e use Mappings para valores específicos por região ou ambiente.</p>

<pre><code class="language-yaml">AWSTemplateFormatVersion: &#039;2010-09-09&#039;

Description: &#039;RDS MySQL com parâmetros customizáveis&#039;

Parameters:

DBName:

Type: String

Default: myappdb

DBUser:

Type: String

NoEcho: true

DBPassword:

Type: String

NoEcho: true

MinLength: 8

Environment:

Type: String

AllowedValues: [dev, staging, prod]

Default: dev

Conditions:

IsProd: !Equals [!Ref Environment, prod]

Mappings:

InstanceTypeMap:

dev:

InstanceType: db.t3.micro

staging:

InstanceType: db.t3.small

prod:

InstanceType: db.r5.large

Resources:

DBSubnetGroup:

Type: AWS::RDS::DBSubnetGroup

Properties:

DBSubnetGroupDescription: Subnets para RDS

SubnetIds:

  • !ImportValue networking-stack-Subnet-ID-1
  • !ImportValue networking-stack-Subnet-ID-2

MyDatabase:

Type: AWS::RDS::DBInstance

DeletionPolicy: Snapshot

Properties:

DBInstanceIdentifier: !Sub &#039;${AWS::StackName}-db&#039;

Engine: mysql

EngineVersion: &#039;8.0.35&#039;

DBInstanceClass: !FindInMap [InstanceTypeMap, !Ref Environment, InstanceType]

AllocatedStorage: !If [IsProd, &#039;100&#039;, &#039;20&#039;]

DBName: !Ref DBName

MasterUsername: !Ref DBUser

MasterUserPassword: !Ref DBPassword

DBSubnetGroupName: !Ref DBSubnetGroup

MultiAZ: !If [IsProd, true, false]

BackupRetentionPeriod: !If [IsProd, 30, 7]

Outputs:

DatabaseEndpoint:

Value: !GetAtt MyDatabase.Endpoint.Address

Export:

Name: !Sub &#039;${AWS::StackName}-DB-Endpoint&#039;</code></pre>

<h2>StackSets: Governança Multi-Conta e Multi-Região</h2>

<p>StackSets amplificam o poder da CloudFormation. Com um template único, você deploy simultaneamente em múltiplas contas AWS e regiões. Perfeito para times ágeis que precisam manter conformidade global e políticas corporativas.</p>

<p>Use StackSets com Auto Deployment habilitado: toda mudança no template propaga automaticamente para todas as target accounts e regions. Implemente Organizational Units (OUs) para controle granular e adicione Operation Preferences para controlar velocidade e tolerância a falhas do rollout.</p>

<pre><code class="language-yaml">AWSTemplateFormatVersion: &#039;2010-09-09&#039;

Description: &#039;Template para distribuição via StackSets - Security Baseline&#039;

Parameters:

SecurityGroupName:

Type: String

Default: baseline-sg

Resources:

BaselineSecurityGroup:

Type: AWS::EC2::SecurityGroup

Properties:

GroupDescription: Security group baseline para todas as contas

SecurityGroupIngress:

  • IpProtocol: tcp

FromPort: 443

ToPort: 443

CidrIp: 0.0.0.0/0

Description: HTTPS from anywhere

SecurityGroupEgress:

  • IpProtocol: -1

CidrIp: 0.0.0.0/0

Description: Allow all outbound

Tags:

  • Key: ManagedBy

Value: StackSet

  • Key: Purpose

Value: SecurityBaseline

CloudTrailRole:

Type: AWS::IAM::Role

Properties:

AssumeRolePolicyDocument:

Version: &#039;2012-10-17&#039;

Statement:

  • Effect: Allow

Principal:

Service: cloudtrail.amazonaws.com

Action: &#039;sts:AssumeRole&#039;

ManagedPolicyArns:

  • &#039;arn:aws:iam::aws:policy/CloudWatchLogsFullAccess&#039;

Outputs:

SecurityGroupId:

Value: !Ref BaselineSecurityGroup

Export:

Name: !Sub &#039;${AWS::StackName}-SG-ID&#039;

CloudTrailRoleArn:

Value: !GetAtt CloudTrailRole.Arn

Export:

Name: !Sub &#039;${AWS::StackName}-CTRole-ARN&#039;</code></pre>

<p>Para ativar StackSets via CLI, você precisaria (exemplo conceitual):</p>

<pre><code class="language-bash">aws cloudformation create-stack-set \

--stack-set-name security-baseline \

--template-body file://template.yaml \

--capabilities CAPABILITY_NAMED_IAM \

--auto-deployment Enabled=true,Retain=false

aws cloudformation create-stack-instances \

--stack-set-name security-baseline \

--accounts 123456789012 987654321098 \

--regions us-east-1 eu-west-1</code></pre>

<h2>Boas Práticas Críticas para Times Ágeis</h2>

<p><strong>Versionamento e CI/CD Integration</strong>: Mantenha templates no Git com histórico completo. Integre validação automática usando <code>cfn-lint</code> e <code>cfn-python-lint</code> no pipeline antes de deploy. Use Change Sets para visualizar exatamente o que vai mudar antes de aplicar.</p>

<p><strong>Monitoramento e Segurança</strong>: Ative Stack Policy para prevenir deletions acidentais. Use AWS Config para compliance contínuo. Implemente IAM roles específicas por equipe — nunca use credenciais root. Adicione DeletionPolicy correto em recursos críticos (Retain, Snapshot, Delete conforme o caso).</p>

<p><strong>Padrões de Reutilização</strong>: Crie uma biblioteca de templates base — VPC, RDS, Lambda patterns. Use Nested Stacks para composição, mas com moderação; StackSets são melhores para replicação. Documente outputs claramente e use Export Names padronizadas como <code>${ProjectName}-${ResourceType}-${Property}</code>.</p>

<p>Para times escalarem, implemente Change Set reviews obrigatórios: um desenvolvedor cria, outro aprova antes de execução. Isso reduz surpresas em produção e cria cultura de responsabilidade.</p>

<h2>Conclusão</h2>

<p>CloudFormation é sua arma contra infraestrutura caótica. Comece com templates simples, decomponha em stacks pequenos, e escale via StackSets. A maior lição: <strong>infraestrutura é código, trate como tal</strong> — versionamento, reviews, testes automáticos. Times ágeis que dominam IaC entregam com confiança e velocidade. Change Sets + Git = segurança em deployments. StackSets + OUs = governança corporativa sem fricção manual.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://docs.aws.amazon.com/cloudformation/" target="_blank" rel="noopener noreferrer">AWS CloudFormation User Guide - Official Documentation</a></li>

<li><a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/best-practices.html" target="_blank" rel="noopener noreferrer">AWS CloudFormation Best Practices</a></li>

<li><a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/what-is-cfnstacksets.html" target="_blank" rel="noopener noreferrer">CloudFormation Stack Sets for Multi-Account Deployment</a></li>

<li><a href="https://github.com/aws-cloudformation/cfn-python-lint" target="_blank" rel="noopener noreferrer">cfn-lint - CloudFormation Linter</a></li>

<li><a href="https://docs.aws.amazon.com/wellarchitected/latest/userguide/workload-review.html" target="_blank" rel="noopener noreferrer">AWS Well-Architected Framework - Infrastructure as Code</a></li>

</ul>

Comentários

Mais em Cloud & Infraestrutura

O que Todo Dev Deve Saber sobre CodeCommit, CodeBuild e CodeDeploy: CI/CD Nativo da AWS
O que Todo Dev Deve Saber sobre CodeCommit, CodeBuild e CodeDeploy: CI/CD Nativo da AWS

Entendendo a Tríade CI/CD da AWS A integração contínua e deployment contínuo...

Como Usar SQS em Profundidade: Standard, FIFO, DLQ e Visibility Timeout em Produção
Como Usar SQS em Profundidade: Standard, FIFO, DLQ e Visibility Timeout em Produção

SQS: Arquitetura e Diferenças Fundamentais AWS SQS (Simple Queue Service) é o...

Well-Architected Framework: Os Seis Pilares na Prática na Prática
Well-Architected Framework: Os Seis Pilares na Prática na Prática

Well-Architected Framework: Os Seis Pilares na Prática O AWS Well-Architected...