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.