Olá, pessoal. Tudo bem?
Quem já trabalhou com CloudFormation, Terraform ou outra ferramenta de IaC, que forneça uma linguagem declarativa para escrevermos infraestrutura como código, sabe o quão útil elas são, mas também sabe o quão complexos e inflexível os templates criados por estas linguagens podem se tornar.
O AWS CDK (Cloud Development Kit) foi criado para endereçar estes problemas. O framework está disponível hoje em algumas das linguagens mais usadas no mercado (atualmente C#, Python, Java, Javascript e Typescript), permitindo a construção de estruturas de IaC com maior flexibilidade, utilizando todo o poder destas linguagens (loops, estruturas condicionais, etc).
Como o CDK funciona?
Basicamente, o CDK é formado por três estruturas elementares:
- Constructs: Constructs são a base de todos os componentes do CDK;
- Stacks: São constructs que permitem o provisionamento de coleções de recursos de forma unitária (Cloudformation stacks);
- Apps: Permitem o agrupamento e deploy de stacks dentro de um mesmo contexto e ciclo de vida.

O CDK fornece uma CLI para podermos gerir nossos projetos de infraestrutura. Alguns dos principais comandos são:
- init: Cria um projeto do CDK baseado em um template;
- synth: Sintetiza templates do CloudFormation a partir do app;
- deploy: Efetua o deploy do app na AWS, através do CloudFormation;
- destroy: Destrói as stacks na AWS.
Abaixo segue um exemplo para facilitar a visualização. Ele pode parecer pouco comum, visto que usei C# (minha linguagem favorita) para escrever meu projeto, mas é só por diversão. 😁
var vpc = new Vpc(this, "MainVPC", new VpcProps
{
Cidr = "192.168.0.0/16"
});
var loadBalancer = new ApplicationLoadBalancer(this, "PublicALB", new ApplicationLoadBalancerProps
{
InternetFacing = true,
Vpc = vpc
});
var listener = loadBalancer.AddListener("MyListener", new ApplicationListenerProps
{
Port = 80
});
var userData = UserData.ForLinux(new LinuxUserDataOptions
{
Shebang = "#!/bin/bash"
});
userData.AddCommands(
"yum update -y",
"yum install httpd -y",
"echo \"Hello World\" >> /var/www/html/index.html",
"service httpd start",
"chkconfig httpd on");
var ec2SG = new SecurityGroup(this, "Ec2SecurityGroup", new SecurityGroupProps
{
Vpc = vpc,
SecurityGroupName = "Ec2SG"
});
ec2SG.Connections.AllowFrom(loadBalancer, Port.Tcp(80), "FROM ALB");
var instanceIds = new List<string>();
for(var ix = 0; ix < vpc.PrivateSubnets.Length;ix++)
{
var instance = new Instance_(this, $"Instance-{ix}", new InstanceProps
{
InstanceType = InstanceType.Of(InstanceClass.BURSTABLE3, InstanceSize.MICRO),
VpcSubnets = new SubnetSelection()
{
SubnetType = SubnetType.PRIVATE
},
AvailabilityZone = vpc.PrivateSubnets[ix].AvailabilityZone,
Vpc = vpc,
MachineImage = new AmazonLinuxImage(),
UserData = userData,
KeyName = "test-cdk",
SecurityGroup = ec2SG
} );
instanceIds.Add(instance.InstanceId);
}
listener.AddTargets("Targets", new AddApplicationTargetsProps
{
Port = 80,
Targets = instanceIds.Select(i => new InstanceIdTarget(i, 80)).ToArray()
});
No exemplo acima, construiremos a estrutura abaixo:

Um ponto interessante que acredito valer a pena comentar, é que na primeira linha, quando críamos a VPC, o CDK já cria subnets públicas e privadas nas AZs disponíveis, faz o deploy de um NAT Gateway em cada uma das subnet públicas, e também do Internet Gateway, das Route Tables, etc, criando uma estrutura padrão para utilizarmos. O melhor é que podemos customizar tudo isso, caso este modelo não sirva para o nosso propósito.
Gostaria também de ressaltar a linha 39, onde utilizamos um for loop para criar uma instância EC2 em cada subnet privada. Essa é uma construção que as linguagens declarativas existentes (ao menos as que conheço) não possibilitam.
Para quem quiser ver mais, o exemplo está no Github. Sugiro mandar sintetizar o CloudFormation, e verificar a quantidade de linhas geradas no template (A diferença é enorme).
E se a biblioteca do CDK não possuir o construct para o serviço que necessito?
Ok, sem problemas. É possível incorporar código do CloudFormation diretamente dentro do CDK. Exemplo:
new CfnResource(this, "SSLCertificate", new CfnResourceProps
{
Type = "AWS::CertificateManager::Certificate",
Properties = new Dictionary<string, object>
{
["DomainName"] = "mydomain.com"
}
});
Ok, mas eu não poderia utilizar o SDK da AWS diretamente?
Se alguém está se perguntando se poderíamos usar o SDK da AWS sem o CDK, a resposta é, sim, você pode construir seus próprios artefatos usando o SDK. Contudo, o CDK traz algumas vantagens em relação a isso, como:
- Uma série de comandos prontos criados pela AWS, que permitem o provisionamento de estruturas complexas com poucas linhas de comando;
- Como vimos, no final ele transforma tudo em templates do CloudFormation, a ferramenta oficial da AWS para IaC. Por isso herdamos todas as vantagens do mesmo em relação ao provisionamento através da SDK, como rastreabilidade, gerenciamento dos recursos de forma unitária e detecção de drifts na infraestrutura;
Não tive a oportunidade de utilizar o CDK exaustivamente ainda, mas até o momento a experiência está sendo muito boa, com bastante praticidade e produtividade.
Para aqueles que já utilizam, o que vocês estão achando? Deixem seus comentários abaixo.
Forte abraço e até a próxima.