Voltar ao catálogo
Season 28 13 Episódios 48 min 2026

Terraform Fundamentals

Edição de 2026. Um guia abrangente para construir, alterar e versionar infraestruturas de forma segura e eficiente com Terraform. Produzido em 2026, cobrindo os conceitos do Terraform v1.14.

Infraestrutura como Código DevOps
Terraform Fundamentals
A Reproduzir
Click play to start
0:00
0:00
1
O Paradigma da Infraestrutura como Código
Exploramos o motivo pelo qual o Terraform se tornou a norma da indústria para o aprovisionamento de infraestruturas. Aprenda a diferença entre as abordagens declarativa e imperativa, e por que razão a infraestrutura imutável é importante para a sua empresa.
4m 10s
2
O Workflow Central do Terraform
Domine o processo fundamental de três passos que impulsiona todos os deployments de Terraform: Write, Plan e Apply. Descubra como o plano de execução evita erros catastróficos de deployment.
3m 06s
3
Providers e a Ligação ao Azure
O Terraform não sabe como falar com o Azure de origem. Explicamos como os Providers atuam como a camada de tradução entre o core do Terraform e as APIs de cloud externas.
3m 58s
4
Declarar Infraestrutura com Resources
O bloco Resource é o elemento de construção fundamental de qualquer configuração de Terraform. Aprenda a escrever código que aprovisiona um Azure Resource Group do mundo real.
3m 13s
5
Relações e Dependências de Resources
Os componentes da infraestrutura dependem uns dos outros. Explicamos como o Terraform calcula automaticamente a ordem de execução utilizando dependências implícitas, e quando forçar a ordenação com dependências explícitas.
3m 33s
6
Compreender o State do Terraform
O State é a fonte absoluta de verdade para o Terraform. Aprenda por que razão o ficheiro de state é obrigatório, como mapeia o seu código para o mundo real e por que nunca o deve editar manualmente.
4m 05s
7
Parametrizar com Input Variables
Fazer hardcode de valores de infraestrutura não é escalável. Descubra como utilizar input variables para criar configurações dinâmicas e reutilizáveis em diferentes ambientes empresariais.
3m 43s
8
Expor Dados com Output Values
Assim que a sua infraestrutura estiver construída, precisa de saber como se ligar a ela. Aprenda a utilizar blocos Output para extrair dados críticos, como IDs gerados automaticamente e endereços IP, dos seus deployments.
3m 49s
9
Consultar com Data Sources
Nem todos os recursos cloud são geridos pelo seu projeto atual. As Data Sources permitem ao Terraform ler e utilizar dinamicamente infraestruturas existentes, como uma rede core gerida por outra equipa.
3m 34s
10
Escalar com Count e For_Each
Pare de copiar e colar os seus blocos resource. Aprenda a utilizar os meta-argumentos count e for_each para escalar dinamicamente a sua infraestrutura para cima e para baixo com facilidade.
3m 38s
11
Construir Componentes Reutilizáveis com Modules
Os Modules permitem-lhe empacotar arquiteturas complexas em blocos de código únicos e reutilizáveis. Aprenda a construir child modules e a chamá-los a partir da sua configuração root para manter a sua empresa DRY.
3m 55s
12
Preparação Empresarial: Remote State e Locking
Um ficheiro de state local é aceitável para um developer a trabalhar sozinho, mas desastroso para uma equipa. Aprenda a configurar remote state backends e a implementar state locking para colaborar com segurança na infraestrutura empresarial.
3m 43s
13
Workflows Empresariais e CI/CD
Tire o Terraform do seu terminal e leve-o para a automação. Concluímos a série explorando pipelines de CI/CD, revisões automatizadas de PR e modelos de infraestrutura self-service.
4m 11s

Episódios

1

O Paradigma da Infraestrutura como Código

4m 10s

Exploramos o motivo pelo qual o Terraform se tornou a norma da indústria para o aprovisionamento de infraestruturas. Aprenda a diferença entre as abordagens declarativa e imperativa, e por que razão a infraestrutura imutável é importante para a sua empresa.

Download
Olá, daqui fala o Alex da DEV STORIES DOT EU. Fundamentos do Terraform, episódio 1 de 13. Provisionar servidores costumava significar abrir um ticket no helpdesk e esperar duas semanas para que alguém clicasse numa consola cloud. Hoje, exatamente o mesmo processo é um simples pull request que faz deploy com segurança em minutos. Esta mudança é totalmente impulsionada pelo paradigma de Infrastructure as Code, e o HashiCorp Terraform é o principal motor a alimentá-la. Infrastructure as Code é exatamente o que o nome sugere. Geres as tuas bases de dados, redes virtuais e instâncias de compute usando ficheiros de texto simples em vez de cliques manuais. Estes ficheiros podem ser versionados, revistos por colegas e testados automaticamente. Para perceberes por que é que isto é poderoso, considera um administrador de sistemas que precisa de uma nova virtual machine no Azure. Usando um workflow imperativo, ele poderá escrever um script complexo em PowerShell. Esse script tem de definir explicitamente cada ação por ordem. Ele diz ao sistema para fazer login, verificar se uma rede existe, criá-la caso não exista, alocar um IP público e, finalmente, fazer boot do servidor. Se o script falhar no passo quatro, ficas com uma infraestrutura parcialmente construída. Correr o script uma segunda vez causa frequentemente erros porque alguns recursos já existem. Em vez disso, o Terraform usa uma abordagem declarativa. Não escreves a sequência de passos. Simplesmente defines o estado final desejado. Escreves um ficheiro de configuração a declarar que queres uma virtual machine no Azure ligada a uma rede específica. O Terraform compara o teu state pedido com o que existe atualmente na cloud. A seguir, calcula a sequência exata de API calls necessárias para colmatar essa diferença. Se a rede já existir, o Terraform ignora-a e constrói apenas o servidor. Aqui está o ponto-chave. Muitos engenheiros confundem ferramentas de provisionamento de infraestrutura, como o Terraform, com ferramentas de gestão de configuração, como o Chef, o Puppet ou o Ansible. Não são a mesma coisa. O Terraform constrói a casa. As ferramentas de gestão de configuração arrumam a mobília. O Terraform provisiona os recursos brutos da cloud, como os load balancers e as virtual machines. O Ansible ou o Chef fazem depois login nessas máquinas para instalar pacotes de software e iniciar background services. As ferramentas de gestão de configuração foram fundamentalmente concebidas para infraestrutura mutável. Elas esperam que um servidor dure muito tempo e sofra patches e ajustes constantes. O Terraform empurra-te para uma infraestrutura imutável. Se um ambiente precisar de uma versão diferente do sistema operativo, o Terraform não faz login nem corre um upgrade script. Destrói o servidor antigo e provisiona um completamente novo com a imagem correta. Esta abordagem rigorosa garante que o teu código corresponde sempre à realidade, eliminando completamente o configuration drift. Este workflow é particularmente valioso porque é platform agnostic. Uma empresa raramente usa apenas um vendor. Podes correr os teus workloads principais no Azure, gerir o teu DNS através da Cloudflare e gerir o routing de incidentes no PagerDuty. O Terraform gere tudo isto através de um modelo de provider. Um provider é simplesmente um plugin que compreende a API de um vendor específico. Ao usar vários providers, podes criar uma única configuração que levanta uma base de dados no Azure, configura os registos DNS necessários e define os alertas de monitorização em simultâneo. As API calls subjacentes mudam, mas o teu workflow permanece exatamente o mesmo. Se quiseres ajudar a manter estes episódios a sair, podes procurar por DevStoriesEU no Patreon para apoiar o programa. Uma ferramenta que simplesmente automatiza tarefas torna-te mais rápido, mas uma ferramenta que impõe um state declarativo torna todo o teu sistema previsível. Gostaria de tirar um momento para te agradecer por ouvires — ajuda-nos imenso. Tem um excelente dia!
2

O Workflow Central do Terraform

3m 06s

Domine o processo fundamental de três passos que impulsiona todos os deployments de Terraform: Write, Plan e Apply. Descubra como o plano de execução evita erros catastróficos de deployment.

Download
Olá, daqui fala o Alex da DEV STORIES DOT EU. Fundamentos do Terraform, episódio 2 de 13. Fazes deploy, olhas para a consola e cruzas os dedos, a torcer para não teres mandado abaixo o ambiente de produção. Esse salto de fé às cegas é um risco enorme, e é exatamente isso que o core workflow do Terraform elimina. O workflow consiste em três passos rigorosos: write, plan e apply. Cada passo opera de forma independente para traduzir os teus requisitos em recursos em execução. Começas pela fase de write. Crias ficheiros de configuração que declaram a infraestrutura exata que queres. Não estás a escrever um script procedural que diz como construir um servidor passo a passo. Estás a descrever o estado final desejado do teu ambiente. Guardas estes ficheiros, e o teu código torna-se a single source of truth para o que deve existir. Os novos utilizadores às vezes pensam que o passo seguinte é apenas executar esses ficheiros sequencialmente, de cima para baixo. Não é assim que esta ferramenta funciona. Ela não corre comandos às cegas. Em vez disso, avança para a fase de plan. A fase de plan é o superpoder absoluto deste workflow. Quando corres o comando plan, a ferramenta avalia a tua nova configuração em relação ao estado atual e real da tua infraestrutura. Ela calcula um diff preciso entre a realidade e o teu código desejado. Aqui está o ponto chave. A ferramenta lê este diff e gera um dry run altamente detalhado de cada ação que pretende realizar. Imagina um engenheiro que precisa de adicionar um Azure Load Balancer a um ambiente de produção. Ele atualiza os seus ficheiros de configuração e corre o comando plan. O sistema liga-se ao cloud provider, verifica o estado ativo e imprime um resumo rigoroso. O engenheiro lê o output e vê um recurso para adicionar, zero para alterar e zero para destruir. O output detalha as propriedades exatas do novo load balancer. O engenheiro valida este dry run. Ele sabe que a alteração é segura antes de uma única API call modificar a infraestrutura real. Não há cá adivinhações. Após validar o output, avanças para a fase de apply. Este é o momento da execução. A ferramenta pega no diff exato calculado durante a fase de plan e constrói um execution graph rigoroso. Ela mapeia todas as dependências. Se o teu novo load balancer exigir um endereço IP público dedicado, o execution graph garante que o IP é provisionado primeiro. O sistema espera que o IP fique disponível, agarra o seu novo endereço e só então cria o load balancer. Ele gere o tempo e a ordem automaticamente. Como a fase de apply segue rigorosamente o plano de execução aprovado, nunca terás recursos a fazer spin up na ordem errada ou bases de dados existentes a serem apagadas acidentalmente devido a um typo. O workflow obriga-te a separar a intenção da execução. O aspeto mais poderoso deste processo não é o provisioning automatizado em si. É a eliminação completa da ansiedade operacional através de dry runs previsíveis e que podes rever. É tudo por agora. Obrigado por ouvires, e continua a desenvolver!
3

Providers e a Ligação ao Azure

3m 58s

O Terraform não sabe como falar com o Azure de origem. Explicamos como os Providers atuam como a camada de tradução entre o core do Terraform e as APIs de cloud externas.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. Terraform Fundamentals, episódio 3 de 13. Out of the box, a aplicação core do Terraform não sabe realmente como criar uma Virtual Machine no Azure ou uma database. É estritamente um engine que avalia código, determina dependências e gere o state. Para fazer qualquer trabalho real, depende de milhares de plugins de tradução disponíveis para download. Isto leva-nos aos providers e a como tu ligas o teu código ao Azure. Um ponto comum de confusão é pensar que a própria aplicação Terraform contém a lógica para todas as plataformas cloud. Não contém. O binário que instalas na tua máquina é completamente agnóstico em relação à infraestrutura. Ele entende a linguagem de configuração e o workflow de deployment, mas tem zero conhecimento hardcoded de qualquer API cloud específica. Em vez disso, o Terraform usa plugins chamados providers. Um provider é uma peça de software standalone que entende os endpoints, os métodos de autenticação e os comportamentos dos recursos para uma plataforma específica. Existe um provider para o Microsoft Azure, um para a Amazon Web Services e outros para plataformas software as a service, como o GitHub ou o Datadog. Estes plugins são publicados e alojados num diretório central chamado Terraform Registry. Quando começas um novo projeto de infraestrutura, tens de declarar explicitamente quais os providers que o teu código vai usar. Também especificas a versão exata do provider que queres. Fazer o lock de uma versão é uma prática crítica. Isto garante que, se a API da cloud mudar ou se o plugin do provider receber um major update amanhã, o teu deployment não vai quebrar inesperadamente. Tu controlas exatamente quando fazer o upgrade. Simplesmente declarar o provider no teu ficheiro de texto não o instala. Tens de correr um comando de inicialização no teu terminal. Este passo de inicialização acede ativamente ao Terraform Registry, faz o download dos plugins do provider necessários e guarda-os em cache num diretório local oculto. Até correres este passo, o teu projeto Terraform não consegue interagir com nenhum sistema externo. Vamos ver como configurar isto para um novo projeto que se liga a uma subscrição enterprise do Azure. Vais usar o provider oficial do Azure Resource Manager, conhecido como azurerm. Depois de declarares a versão de que precisas, tens de configurar o comportamento específico do provider. Cada provider tem os seus próprios requisitos de configuração com base na API subjacente. Para o Azure, o plugin exige que declares explicitamente como deve lidar com determinados comportamentos dos recursos. Por exemplo, tens de dizer ao provider se deve apagar permanentemente os discos de storage anexados quando uma Virtual Machine é destruída. O provider exige esta configuração à partida para que as ações destrutivas sejam sempre intencionais. Uma vez inicializado e configurado, o provider atua como uma camada de tradução plug-and-play. Quando executas o teu código, o engine core do Terraform calcula a diferença entre a tua infraestrutura atual e o teu state desejado. De seguida, passa essas instruções genéricas para o plugin do provider do Azure. O plugin assume o controlo, traduzindo a tua intenção em pedidos HTTP autenticados enviados diretamente para a API do Azure Resource Manager. O plugin espera que o Azure termine de criar ou modificar os recursos, traduz a resposta da API de volta para um formato que o Terraform entende e devolve os dados finais ao engine core. O próprio Terraform nunca comunica diretamente com o teu ambiente cloud; ele delega cada chamada de API ao plugin do provider, tornando o provider a verdadeira ponte entre o teu código e a tua infraestrutura live. É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
4

Declarar Infraestrutura com Resources

3m 13s

O bloco Resource é o elemento de construção fundamental de qualquer configuração de Terraform. Aprenda a escrever código que aprovisiona um Azure Resource Group do mundo real.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. Fundamentos de Terraform, episódio 4 de 13. Olhas para o teu código e vês uma base de dados com a label primary, mas quando fazes login na tua cloud console, essa mesma base de dados tem um nome completamente diferente, como db-cluster-node-one. Se queres que algo exista fisicamente no teu ambiente cloud, tens de o pedir usando a construct mais importante do Terraform, mas também tens de perceber como o Terraform nomeia as coisas. Hoje vamos falar sobre declarar infraestrutura com resources. Os resources são os componentes fundamentais da tua infraestrutura. Sempre que queres criar, atualizar ou destruir um objeto, escreves um resource block. Este objeto pode ser um componente físico, como uma compute instance ou uma storage drive, ou uma construct lógica, como um DNS record ou um role assignment. O resource block é a forma como traduzes a ideia de um componente de infraestrutura num API request que o teu cloud provider realmente percebe. Quando declaras um resource block, defines a sua identidade usando duas labels distintas. Primeiro, declaras o resource type. Isto diz ao Terraform exatamente que tipo de objeto queres construir e qual o provider que o vai construir. O type começa sempre com o namespace do provider, como Azure ou AWS, seguido pelo serviço específico. Estás essencialmente a dizer ao Terraform que precisas de um resource group do Azure, ou que precisas de um storage bucket da AWS. Imediatamente a seguir ao resource type, defines o local identifier. Isto é simplesmente um nickname. Ele existe apenas dentro da tua configuração de Terraform. Usas este nickname para referenciar o objeto a partir de outras partes do teu código. Não tem absolutamente nenhum efeito naquilo que o teu cloud provider vê. Isto leva-nos ao configuration block em si. Depois de declarares o type e o nickname local, defines os arguments para esse resource. Os arguments são as settings e os valores específicos que configuram o objeto. É aqui que passas os parâmetros reais exigidos pela API do cloud provider. Para juntar tudo isto, imagina que estás a fazer deploy de um resource group do Azure. Declaras o resource type para um resource group do Azure, e dás-lhe um nickname local como main. Dentro do configuration block, forneces os arguments reais. Defines um argument name e dás-lhe o valor rg-enterprise-prod, e defines um argument location, configurando-o para uma região específica. Quando corres o teu deploy, o Terraform usa o resource type para saber qual a API do provider a chamar. Ele usa os teus arguments para dizer à API exatamente como configurar o resource. No portal do Azure, o teu resource group vai aparecer como rg-enterprise-prod. O Azure não sabe nada sobre o nickname main. Mas de volta ao teu código, sempre que precisares de ir buscar o ID ou a location desse resource group para passar a uma virtual machine ou a uma base de dados, simplesmente pedes ao Terraform os dados guardados pelo resource local chamado main. Cada resource type tem o seu próprio conjunto único de arguments. Alguns são obrigatórios, como a location para um resource group ou o instance size para um virtual server. Outros são opcionais, como tags ou routing rules específicas. A documentação do provider dita exatamente quais os arguments que podes usar. Só mapeias os valores de que precisas para o resource block, e o Terraform trata da tradução para as API calls que realmente provisionam a tua infraestrutura. O teu local identifier pertence ao Terraform para manter o teu código legível, mas os teus arguments pertencem à cloud para definir a realidade. Obrigado por ouvires. Até à próxima!
5

Relações e Dependências de Resources

3m 33s

Os componentes da infraestrutura dependem uns dos outros. Explicamos como o Terraform calcula automaticamente a ordem de execução utilizando dependências implícitas, e quando forçar a ordenação com dependências explícitas.

Download
Olá, daqui é o Alex do DEV STORIES DOT EU. Fundamentos de Terraform, episódio 5 de 13. Se uma base de dados tem de existir antes que um web server se possa ligar a ela, como é que uma tool de infraestrutura sabe qual construir primeiro sem scripts sequenciais? Se vens de um background de scripting imperativo como Bash ou Python, podes procurar formas de forçar a execução linha a linha. Mas em Terraform, a ordem das linhas no teu ficheiro não importa de todo. A única coisa que importa são as relações e dependências entre resources. O Terraform é um execution engine altamente inteligente. Antes de criar o que quer que seja, ele analisa a tua configuração e constrói um directed acyclic graph. Este graph mapeia exatamente como cada peça de infraestrutura se liga às outras. Ele usa este mapa para determinar a ordem de criação mais eficiente, construindo resources não relacionados em paralelo e sequenciando os que dependem uns dos outros. Nunca tens de escrever scripts manuais de wait ou sleep. Na maioria das vezes, o Terraform descobre este sequenciamento automaticamente através de implicit dependencies. Uma implicit dependency acontece quando um resource referencia um attribute de outro resource. Considera um cenário em que estás a criar uma Virtual Network no Azure e uma Subnet. Uma subnet não pode existir sem uma virtual network. Na tua configuração, defines o block da virtual network e, a seguir, defines o block da subnet. Dentro do block da subnet, defines o argument do nome da virtual network para apontar diretamente para o attribute name do resource da virtual network que acabaste de definir. Quando o Terraform faz o parse disto, ele vê a ligação. Ele sabe intrinsecamente que tem de acabar de criar a virtual network e ir buscar o seu nome gerado antes sequer de começar a criar a subnet. Não tens de lhe dizer o que fazer. Só tens de passar os dados, e o Terraform trata do timing. Esta é a parte que importa. Usa sempre implicit dependencies, se puderes. Ao referenciar attributes diretamente, dás ao Terraform a informação exata de que ele precisa para otimizar os teus deploys em segurança. Às vezes, a relação entre dois resources não é visível no código. Podes ter uma situação em que um resource precisa que outro resource esteja totalmente ativo, mas não precisa, de facto, de extrair quaisquer dados dele. Considera fazer o deploy de uma virtual machine que corre uma aplicação, enquanto também fazes o provision de uma managed database. A aplicação precisa que a database acabe de fazer o boot antes de poder arrancar. No entanto, a configuração da virtual machine não faz referência a nenhuns attributes do resource da database. Como não há um data link, o Terraform assume que estes dois resources não têm qualquer relação e vai tentar construí-los ao mesmo tempo. A aplicação vai fazer o boot, procurar uma database que ainda não existe, e falhar. Para corrigir isto, usas explicit dependencies. O Terraform fornece um meta-argument chamado depends on. Adicionas este argument ao block da virtual machine e passas-lhe uma lista que contém o resource da database. Isto diz explicitamente ao Terraform para pausar a criação da virtual machine até que a database acabe completamente o provisioning. Deves tratar as explicit dependencies como último recurso. Elas forçam o Terraform a ser mais conservador na sua execução, o que atrasa os teus deploys. Também podem tornar a tua configuração mais difícil de manter ao longo do tempo, já que a verdadeira razão para a dependência nem sempre é óbvia para o próximo engineer que ler o ficheiro. Deixar o execution graph fazer o trabalho pesado é o que separa a infraestrutura declarativa dos procedural scripts, por isso para de tentar microgerir a ordem de execução e deixa o data flow ditar a sequência. Obrigado por passares uns minutos comigo. Até à próxima, fica bem.
6

Compreender o State do Terraform

4m 05s

O State é a fonte absoluta de verdade para o Terraform. Aprenda por que razão o ficheiro de state é obrigatório, como mapeia o seu código para o mundo real e por que nunca o deve editar manualmente.

Download
Olá, daqui fala o Alex da DEV STORIES DOT EU. Fundamentos do Terraform, episódio 6 de 13. Escreves o teu código de infraestrutura, corres o apply, e os teus servidores arrancam na perfeição. Mas se correres o apply outra vez cinco minutos depois, não acontece nada. O Terraform sabe que o trabalho já está feito. Ao contrário de scripts de automação simples que executam comandos às cegas, o Terraform tem uma memória. Sem ela, seria completamente cego à infraestrutura que acabou de construir. Essa memória chama-se Terraform State. Quando corres o Terraform, ele cria um ficheiro local chamado terraform ponto tfstate. Muitos engenheiros inicialmente veem este ficheiro como um estorvo. Parece um artefacto extra para gerir e proteger. Mas este ficheiro é o coração da forma como o Terraform opera. O Terraform precisa de um mecanismo para mapear os resources lógicos definidos nos teus ficheiros de configuração para os objetos físicos remotos que vivem no teu ambiente cloud. Um equívoco comum é achar que o Terraform apenas olha para as tags do cloud provider para descobrir o que gere. Podes pensar que ele coloca uma tag num servidor durante a criação e, mais tarde, pesquisa na cloud por essa tag específica para saber o que atualizar. Esta abordagem cai por terra rapidamente. Nem todos os recursos cloud suportam tags. Além disso, alguém poderia editar ou apagar uma tag manualmente, quebrando a ligação. Por fim, pesquisar por tags específicas numa enorme conta cloud corporativa sempre que corres um plan seria incrivelmente lento. Como as tags não são fiáveis, o Terraform usa um state file dedicado e altamente estruturado. O state file funciona como uma base de dados de mapeamento privada. Quando declaras um resource no teu código, o Terraform cria-o através da API do provider. O provider devolve um identificador físico único para esse objeto recém-criado. O Terraform pega no nome do teu resource lógico a partir do código, associa-o a esse ID único da cloud, e escreve o par no state file. Imagina um cenário prático. Decides alterar o tamanho de uma máquina virtual do Azure no teu código. Quando corres o apply, o Terraform não tenta adivinhar qual máquina modificar. Ele verifica o state file, procura o nome do teu resource lógico, e recupera o ID exato da instância do Azure. De seguida, envia um pedido de atualização direcionado a esse ID específico. Sem o state file, o Terraform não saberia se deveria atualizar uma máquina existente ou simplesmente criar uma duplicada. Para além do mapeamento, o state lida com o rastreamento de metadados. O Terraform precisa de saber a ordem exata em que os resources foram criados para poder atualizá-los ou destruí-los com segurança. Se um servidor web precisa de uma base de dados, essa dependência está escrita no teu código. No entanto, se apagares todo esse bloco de código para destruir o ambiente, o Terraform já não consegue ler o código para encontrar a dependência. O state file retém uma cópia destes metadados históricos, garantindo que o Terraform destrói o servidor web antes da base de dados. O state também fornece uma cache de desempenho crucial. Consultar a API de um cloud provider para obter o estado atual de milhares de regras de rede, storage buckets e compute nodes leva um tempo considerável. Os cloud providers também impõem API rate limits rigorosos. O state file atua como uma cache dos atributos da tua infraestrutura. Ao referenciar esta cache, o Terraform minimiza o número de API calls lentas e caras necessárias para calcular um plan. Aqui está o ponto-chave. A tua configuração descreve o que queres, o cloud provider detém o que realmente existe, e o state file é a única ponte definitiva que liga os dois. Ficamos por aqui neste episódio. Até à próxima!
7

Parametrizar com Input Variables

3m 43s

Fazer hardcode de valores de infraestrutura não é escalável. Descubra como utilizar input variables para criar configurações dinâmicas e reutilizáveis em diferentes ambientes empresariais.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. Fundamentos de Terraform, episódio 7 de 13. Fazer hardcoding de valores não tem problema para um teste rápido, mas o que acontece quando precisas de fazer deploy dessa mesma configuração tanto para um ambiente de desenvolvimento como para produção? Não podes duplicar e reescrever o teu código para cada novo deploy. O mecanismo que resolve isto é a parametrização com input variables. As input variables servem de parâmetros para um módulo de Terraform. Permitem-te personalizar aspetos da tua infraestrutura sem alterar o source code subjacente. Este é o passo exato em que o teu código passa de uma proof of concept para um template production-ready. Ao usar variáveis, escreves a configuração uma vez e reutilizas em todo o lado. Antes de entrarmos na mecânica da coisa, precisamos de esclarecer uma confusão comum. Existe uma diferença estrita entre declarar uma variável e atribuir-lhe um valor. Declarar uma variável simplesmente diz ao Terraform que um parâmetro existe e define as suas regras. Atribuir um valor é o ato de lhe dar efetivamente dados durante um deploy. Declaras uma variável usando um bloco variable seguido de um nome único. Dentro deste bloco, defines o data type esperado. O Terraform suporta vários tipos. Uma string é apenas texto normal. Uma list é uma sequência ordenada de valores, como múltiplas availability zones. Um map é uma coleção de pares key-value, o que é perfeito para aplicar tags standard aos recursos. Dentro do bloco variable, também podes definir um valor default. Se forneceres um default, a variável torna-se opcional. Se o utilizador não fornecer um valor durante o deploy, o Terraform simplesmente usa o default. Se não definires um default, o Terraform vai forçar o utilizador a fornecer um valor antes de prosseguir. Vamos ancorar isto a um cenário prático. Supõe que tens um deploy no Azure. Neste momento, a tua configuração pede explicitamente uma virtual machine de tamanho pequeno chamada Standard B2s, e faz hardcode de uma tag de environment como dev. Para tornar isto reutilizável, substituis esse texto em hardcode por uma referência. No Terraform, referencias uma input variable escrevendo var dot seguido do nome da variável. Portanto, em vez de escreveres Standard B2s, escreves var dot vm size. Em vez de dev, escreves var dot environment. Agora o teu código é flexível, mas o Terraform ainda precisa de saber que valores usar quando for efetivamente executado. É aqui que entram os ficheiros de definição de variáveis. Estes são ficheiros terminados em dot tfvars. Um ficheiro tfvars é simplesmente uma lista de nomes de variáveis e os seus respetivos valores. Para o teu deploy de produção, crias um ficheiro chamado prod dot tfvars. Lá dentro, defines a variável environment para prod, e a variável vm size para uma instance maior, como Standard D4s. Quando corres o Terraform, apontas para este ficheiro. O Terraform lê o ficheiro tfvars, injeta esses valores nas tuas referências var dot, e provisiona o ambiente de produção. Amanhã, podes apontar exatamente o mesmo código de Terraform para um ficheiro dev dot tfvars para levantar um pequeno ambiente de testes. Aqui está o ponto chave. Manter a tua lógica completamente separada dos teus dados específicos de environment é o que torna a infraestrutura verdadeiramente repetível. Se estás a achar estes episódios úteis e queres apoiar o programa, podes procurar por DevStoriesEU no Patreon. É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
8

Expor Dados com Output Values

3m 49s

Assim que a sua infraestrutura estiver construída, precisa de saber como se ligar a ela. Aprenda a utilizar blocos Output para extrair dados críticos, como IDs gerados automaticamente e endereços IP, dos seus deployments.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. Fundamentos de Terraform, episódio 8 de 13. A tua infraestrutura cloud termina o deploy na perfeição, mas ainda tens um grande problema: precisas de saber o seu endereço IP público para te ligares a ela. Vasculhar os dashboards do cloud provider anula o propósito da automação. Precisas de uma forma de extrair esse dado específico diretamente do Terraform. É aí que entra a exposição de dados com output values. Os output values são essencialmente os return values de uma configuração de Terraform. Quando defines e crias um resource, o cloud provider gera certos atributos dinamicamente. São coisas que não consegues saber antes do deploy, como um endereço IP atribuído, uma password de base de dados gerada, ou um nome de domínio específico. Usas output blocks para capturar esses atributos gerados dinamicamente e expô-los ao mundo exterior. Para definires um, escreves um output block seguido de uma label. Esta label é simplesmente o nome que queres atribuir ao output. Dentro do bloco, defines um único argumento obrigatório chamado value. Este argumento aponta para o dado específico que queres extrair. Por exemplo, se criares uma máquina virtual, podes definir o argumento value para apontar diretamente para o atributo de IP público desse resource específico da máquina. Pensa num cenário concreto. Tens uma pipeline automatizada que faz o deploy de um novo cluster de Azure Kubernetes Service. Quando o deploy termina, os teus developers precisam do endpoint raw de Kubernetes gerado automaticamente para configurarem as suas ferramentas de ligação locais. Sem um output, alguém teria de aceder ao portal da cloud, encontrar o cluster e copiar o URL manualmente. Em vez disso, escreves um output block chamado cluster endpoint. Defines o seu value para referenciar o atributo de fully qualified domain name do cluster de Kubernetes recém-criado. Quando o Terraform termina de aplicar a tua configuração, ele recolhe todos os output values definidos e imprime-os diretamente na command line interface. A tua pipeline de automação pode então ler esse texto e passar o endpoint diretamente para os developers. Também podes recuperar estes valores mais tarde sem executares um novo deploy. Basta executares o comando terraform output no teu terminal. Para scripts de automação, podes até dizer a esse comando para retornar os dados como raw text ou em formato JSON, facilitando o parse por outras ferramentas de software. Às vezes, os dados que precisas de fazer output são confidenciais, como uma password de base de dados ou uma private key. Não queres que essas strings passem no ecrã de um terminal partilhado ou fiquem permanentemente nos build logs da tua continuous integration. Para evitar isto, adicionas o argumento sensitive dentro do output block e defines o seu valor como true. O Terraform vai então ocultar o valor real no ecrã da consola, substituindo-o por uma placeholder tag a indicar que o valor é sensitive. Aqui está o ponto-chave. Definir um output como sensitive apenas o oculta do ecrã do terminal. Isto não encripta nem oculta os dados dentro do state file do Terraform. A password ou key continua armazenada em plain text nos teus state data no disco ou no teu remote backend. A flag sensitive é puramente um filtro de visualização para a command line interface, não um mecanismo de segurança para o teu storage. Os output values funcionam, em última análise, como a tua API de configuração. São a forma estruturada e previsível de devolveres informações críticas a humanos ou a ferramentas de automação no momento em que uma run termina. Por este episódio é tudo. Obrigado por ouvires, e continua a desenvolver!
9

Consultar com Data Sources

3m 34s

Nem todos os recursos cloud são geridos pelo seu projeto atual. As Data Sources permitem ao Terraform ler e utilizar dinamicamente infraestruturas existentes, como uma rede core gerida por outra equipa.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. Fundamentos de Terraform, episódio 9 de 13. Nem toda a infraestrutura do teu ambiente cloud foi criada pelo código Terraform que estás a escrever agora. Ainda assim, o teu código precisa de uma forma de se ligar a esses sistemas existentes com segurança, sem os alterar acidentalmente. Fazer queries com Data Sources é exatamente como resolves isto. Um grande ponto de confusão ao aprender Terraform é a diferença entre um resource block e um data block. Vamos esclarecer isso agora mesmo. Um resource block diz ao Terraform para criar, atualizar e ser o dono de um objeto de infraestrutura. Um data block faz apenas um lookup read-only. Ele pede à API do provider para encontrar um objeto existente e devolver os seus detalhes, para que a tua configuração os possa ler. Esta capacidade read-only é a base de uma arquitetura de infraestrutura desacoplada. Considera um setup empresarial standard. Uma equipa de networking centralizada cria e gere a Virtual Network corporativa. Como developer de aplicações, precisas de fazer o deploy de uma Virtual Machine no Azure e ligá-la a essa mesma rede. Tu não és o dono do código da rede. Também não deves fazer hardcode do ID único da rede nos teus ficheiros Terraform, porque IDs em hardcode falham facilmente se os ambientes alguma vez forem recriados. Em vez disso, fazes apenas um lookup da rede. Fazes isto definindo um data block. A sintaxe é muito parecida com a de um resource block. Começas com a keyword data. A seguir, especificas o tipo de data source, como azurerm virtual network. Depois, dás-lhe um nome local, como corporate, que vais usar para a referenciar mais tarde no teu código. Dentro do bloco, defines os argumentos de pesquisa. Estes funcionam como filtros rigorosos. Podes passar o nome legível da virtual network e o resource group a que ela pertence. O Terraform usa estes argumentos para construir uma query. Quando corres um Terraform plan, o Terraform liga-se à API do Azure e procura uma virtual network que corresponda aos teus filtros. Se a API devolver exatamente um match, o Terraform faz o download das propriedades dessa rede para a memória. Se a query devolver zero matches, ou se os filtros forem demasiado abrangentes e devolverem múltiplos matches, o Terraform para imediatamente e lança um erro. Este rigor é intencional. Isto impede-te de fazer o deploy acidental da tua aplicação na subnet ou ambiente errado. Assim que o data source obtiver a informação com sucesso, podes extrair qualquer atributo exportado dele. A sintaxe para referenciar um data source é altamente estruturada. Começas com a palavra data, seguida de um ponto, o tipo de data source, um ponto, o teu nome local e, finalmente, o atributo específico de que precisas. No nosso cenário, escreverias data ponto azurerm virtual network ponto corporate ponto id. Passas essa string específica diretamente para o resource block da tua virtual machine, contornando totalmente a necessidade de fazer hardcode de um valor estático. Aqui está a parte que interessa. Os data sources permitem-te tratar a tua infraestrutura envolvente como um serviço dinâmico. Não precisas de construir o ambiente para interagir com ele, e podes ligar workspaces independentes com segurança, simplesmente fazendo uma query aos identificadores exatos de que precisas em runtime. Obrigado por estares aí. Espero que tenhas aprendido algo novo.
10

Escalar com Count e For_Each

3m 38s

Pare de copiar e colar os seus blocos resource. Aprenda a utilizar os meta-argumentos count e for_each para escalar dinamicamente a sua infraestrutura para cima e para baixo com facilidade.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. Fundamentos de Terraform, episódio 10 de 13. Se precisas de fazer deploy de cinquenta web servers idênticos, a última coisa que queres fazer é copiar e colar o mesmo bloco de código cinquenta vezes. Podes procurar por um while-loop ou um for-loop tradicional, mas o Terraform não funciona dessa forma. Em vez disso, geres a escala ao nível do bloco usando Count e For Each. Por defeito, um resource block configura exatamente um objeto de infraestrutura. Para provisionar múltiplos objetos, adicionas o meta-argument count dentro desse bloco. Ele aceita um número inteiro. Se definires o count para três, o Terraform provisiona três objetos a partir desse único configuration block. Estes objetos geralmente não podem ser estritamente idênticos no mundo real. Precisam de nomes ou endereços IP únicos. Para lidar com isto, o Terraform fornece o objeto count dot index. Esta é uma variável especial disponível apenas dentro de blocos que tenham um argumento count. Imagina que estás a fazer deploy de três Azure Virtual Machines. Escreves um resource block para a virtual machine e defines o count para três. Dentro do bloco, atribuis o nome da máquina combinando a palavra web, um hífen, e o valor do count dot index. Como o index começa em zero, o Terraform avalia este bloco e gera três máquinas separadas chamadas web-zero, web-one e web-two. Adicionar o count altera a forma como o Terraform controla o resource internamente. Um único resource é endereçado simplesmente pelo seu tipo e nome atribuído. Assim que adicionas o count, esse endereço torna-se num array. Agora referencias instâncias específicas noutras partes do teu código usando os seus números de index entre parênteses retos. O count é altamente eficiente, mas apresenta um risco mecânico específico ligado à ordem da lista. Aqui está o ponto chave. O count identifica os resources inteiramente pela sua posição de número inteiro. Se usares uma lista de valores para configurar um bloco com count, a posição do index é a única coisa que interessa ao Terraform. Se tiveres três itens e alterares o count para dois, o Terraform destrói o último item no array, o index dois. Se injetares uma nova string no meio da tua source list, todas as posições de index subsequentes movem-se para baixo. O Terraform vai notar que a configuração para o index um mudou, o index dois mudou, e por aí fora. É provável que destrua e recrie infraestrutura perfeitamente saudável apenas porque a ordem da source list mudou. Para resolver esta vulnerabilidade, usas antes o meta-argument for each. Enquanto o count aceita um número inteiro, o for each aceita um map ou um set de strings. Em vez de criar um array de objetos indexados por números sequenciais, o for each cria um map de objetos controlados por string keys explícitas. Se lhe passares um set contendo as strings frontend e backend, o Terraform cria resources endereçados por esses nomes exatos. Se adicionares uma nova string mais tarde, ou removeres uma, o Terraform apenas adiciona ou destrói esse resource específico. Os restantes ficam intocados porque os seus identificadores são string keys fixas, e não posições numéricas frágeis. Usa o count quando os objetos de infraestrutura forem realmente intercambiáveis, mas muda para o for each no momento em que esses objetos exigirem identidades distintas que têm de sobreviver a alterações na tua configuration list. Obrigado por ouvires. Até à próxima!
11

Construir Componentes Reutilizáveis com Modules

3m 55s

Os Modules permitem-lhe empacotar arquiteturas complexas em blocos de código únicos e reutilizáveis. Aprenda a construir child modules e a chamá-los a partir da sua configuração root para manter a sua empresa DRY.

Download
Olá, daqui é o Alex do DEV STORIES DOT EU. Fundamentos de Terraform, episódio 11 de 13. O teu único ficheiro de configuração de Terraform servia bem para um servidor web simples, mas à medida que a tua infraestrutura cresce, está rapidamente a tornar-se num monólito confuso e ilegível. Estás a copiar e a colar os mesmos resource blocks vezes sem conta, apenas para alterar uma única string de nome ou uma tag de ambiente. Está na hora de parares de te repetires e começares a construir componentes reutilizáveis com modules. Um module é um contentor para múltiplos resources que são usados em conjunto. Se estás familiarizado com alguma linguagem de programação, podes pensar num module como uma função. Escreves a lógica complexa uma vez, encapsulas, e depois chamas várias vezes a partir de outros locais. Em Terraform, todas as configurações já têm pelo menos um module. Os ficheiros que estão no teu diretório de trabalho principal formam o que é chamado de root module. Quando o teu root module referencia outro conjunto de ficheiros de configuração, esse segundo conjunto é conhecido como child module. Considera um cenário específico. Uma equipa centralizada de DevOps quer garantir que todas as storage accounts criadas na empresa são seguras por omissão, com encriptação, private endpoints e diagnostic logging rigorosamente aplicados. Em vez de confiar que cada developer de aplicações configure corretamente dez resources complexos diferentes, a equipa de DevOps cria um module standard de Secure Azure Storage. Quando uma equipa de aplicações precisa de storage, não escreve um bloco enorme de definições de resources. Escreve simplesmente um module block na sua root configuration. Dentro desse module block, a primeira coisa que definem é um argumento source. O source diz ao Terraform exatamente onde encontrar os ficheiros do child module, quer seja o caminho de um diretório local ou um repositório remoto. Abaixo do source, a equipa de aplicações passa arguments. Tal como passar arguments para uma função, eles fornecem os dados específicos que o child module precisa para correr, como um nome de aplicação único ou um identificador de ambiente. Estes arguments mapeiam diretamente para as input variables definidas dentro do child module. O child module recebe esses inputs, executa as configurações de resources subjacentes e constrói a infraestrutura. A equipa de aplicações obtém storage compliant automaticamente, completamente isolada da complexidade subjacente. Aqui está o ponto-chave. As pessoas muitas vezes confundem-se sobre como o Terraform lida com o scope entre estes modules. Quando chamas um child module, os resources lá dentro são estritamente encapsulados. O teu root module não pode ler diretamente um endereço IP, uma connection string ou um storage ID gerado dentro desse child module. O child module é uma caixa negra. Se o teu root module precisar de um dado que foi gerado dentro do child module, o child module tem de o exportar explicitamente usando um output block. As variables atuam como parâmetros de input, e os outputs atuam como return values. Formam uma interface estrita. Assim que o child module exporta esses dados como um output, o root module pode finalmente lê-los. Acedes a esses dados referenciando a palavra module, seguida do nome específico que atribuíste ao teu module block, e depois o nome do output. Se o child module fizer output de um storage account ID gerado, o teu root module pode agarrá-lo usando essa sintaxe e passá-lo a uma base de dados ou a uma virtual machine que precise de se ligar a ele. O verdadeiro poder dos modules não é apenas poupar linhas de código. É a capacidade de definir um standard de arquitetura uma vez, isolar a complexidade, e apresentar uma interface limpa e previsível ao resto da tua organização. Obrigado por ouvirem. Fiquem bem, pessoal.
12

Preparação Empresarial: Remote State e Locking

3m 43s

Um ficheiro de state local é aceitável para um developer a trabalhar sozinho, mas desastroso para uma equipa. Aprenda a configurar remote state backends e a implementar state locking para colaborar com segurança na infraestrutura empresarial.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. Fundamentos de Terraform, episódio 12 de 13. Um ficheiro de state local no teu disco rígido funciona perfeitamente quando estás a desenvolver sozinho. Mas no momento em que dois engenheiros tentam atualizar a mesma infraestrutura exatamente ao mesmo segundo, tens aí a receita para um ambiente corrompido. Esta é a fronteira entre a experimentação individual e a colaboração em equipa, e leva-nos à preparação para o nível enterprise: remote state e locking. Por omissão, o Terraform grava a sua visão atual da tua infraestrutura num ficheiro local chamado terraform dot tfstate. Este ficheiro é a source of truth crítica que mapeia o teu código de configuração para os recursos do mundo real. O problema surge quando adicionas mais pessoas ao teu projeto. Se um colega fizer uma alteração na máquina dele, o teu portátil não faz ideia de que o ambiente acabou de mudar. Estás a operar com informações desatualizadas. Às vezes, as equipas tentam resolver isto fazendo commit do ficheiro de state para o seu sistema de controlo de versões. Isto é um risco de segurança grave. Os ficheiros de state armazenam rotineiramente dados sensíveis, como passwords de bases de dados ou chaves privadas, em plain text. A abordagem correta é configurar um remote backend. Em vez de guardar o ficheiro de state numa máquina local, o Terraform lê e escreve estes dados a partir de um data store centralizado e seguro. Normalmente, trata-se de um serviço de object storage, como um bucket do Amazon S3, um container do Azure Blob Storage ou um bucket do Google Cloud Storage. Quando usas um remote backend, sempre que alguém corre um comando, o Terraform consulta esse storage central para ir buscar a imagem mais precisa e atualizada da infraestrutura. A transição para este setup requer a adição de um bloco de configuração de backend ao teu código, para definir onde o state deve viver. Presta atenção a esta parte. Um erro muito comum é escrever essa configuração, guardar o ficheiro e assumir que o state agora é remoto. Não é. Depois de adicionares o bloco de backend, tens de correr terraform init novamente. Correr este comando de inicialização é o trigger que diz ao Terraform para copiar fisicamente o teu ficheiro de state local existente e migrá-lo para o cloud backend. Mover o ficheiro de state para um local partilhado resolve o problema de visibilidade, mas expõe-te a modificações concorrentes. Se duas pipelines de deployment fizerem trigger a um update em simultâneo, ambas podem tentar escrever no ficheiro de remote state ao mesmo tempo, corrompendo-o completamente. É por isso que os remote backends suportam state locking. Considera um ambiente que usa o Azure Blob Storage para o seu remote state. Dois engenheiros estão a trabalhar em updates diferentes. O Engenheiro A corre um apply. Antes de fazer qualquer alteração aos recursos reais na cloud, o Terraform acede ao container de storage do Azure e coloca um lock no ficheiro de remote state. Uma fração de segundo depois, o Engenheiro B tenta correr o seu próprio apply. O Terraform verifica o remote backend, deteta o lock ativo e interceta imediatamente a run do Engenheiro B. Em vez de colidir, o Terraform para em segurança e devolve um erro, a explicar que outro processo está a segurar o lock. Assim que a primeira run for concluída com sucesso, o Terraform liberta o lock automaticamente. Implementar um remote backend com lock é o passo decisivo para infrastructure as code a nível enterprise. Protege os teus dados sensíveis e elimina race conditions perigosas. O remote state garante que, independentemente de quem corra o código, ou de onde, toda a tua equipa esteja firmemente ancorada à exata mesma realidade. Obrigado por ouvirem, happy coding a todos!
13

Workflows Empresariais e CI/CD

4m 11s

Tire o Terraform do seu terminal e leve-o para a automação. Concluímos a série explorando pipelines de CI/CD, revisões automatizadas de PR e modelos de infraestrutura self-service.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. Fundamentos de Terraform, episódio 13 de 13. Escreveste a tua configuração, testaste-a localmente e fizeste o deploy dos teus recursos. Mas executar alterações de infraestrutura a partir do portátil de um developer é um gargalo, não uma estratégia. Applies manuais levam a states conflituosos, alterações não revistas e riscos de segurança. A verdadeira automação corre de forma segura num pipeline, acionada automaticamente pelo version control. Isso leva-nos aos Enterprise Workflows e CI/CD. Quando passas de um operador individual para uma equipa, o workflow principal de Write, Plan e Apply sai completamente da tua máquina local. O version control torna-se a source of truth absoluta. Paras de correr comandos diretamente, e começas a deixar que os pipelines de continuous integration orquestrem as mudanças de state. Aqui está a ideia principal. O pipeline divide a fase tradicional de plan em dois conceitos distintos: speculative plans e concrete plans. Perceber a diferença é crucial para o design do pipeline. Imagina um developer que precisa de aumentar o tamanho de uma virtual machine no Azure. Ele atualiza o tamanho da instância na configuração, faz commit do código e abre um Pull Request. Neste exato momento, o pipeline aciona automaticamente um speculative plan. Um speculative plan mostra simplesmente o que o Terraform pretende fazer. Ele verifica o código proposto contra o remote state para calcular o delta, mas é estritamente read-only. Não se pode fazer o apply sob nenhuma circunstância. O pipeline pega no output deste speculative plan e publica-o diretamente como um comentário de texto no Pull Request. Quando um senior engineer revê o código, não vê apenas a mudança de sintaxe. Vê o impacto exato na infraestrutura. Sabe precisamente quais os recursos do Azure que serão modificados, criados ou destruídos antes de dar a aprovação. Assim que o Pull Request é aprovado e é feito o merge para a main branch, o pipeline aciona a segunda fase. Ele gera um concrete plan contra essa main branch. Este é um ficheiro de plan executável. Como a main branch é a source of truth confiável, o pipeline pega neste concrete plan e faz o apply imediatamente. A infraestrutura live é atualizada automaticamente pelo robô, não pelo humano. Correr o Terraform em automação abre as portas para controlos empresariais avançados. Policy-as-code, usando frameworks como o Sentinel, integra-se diretamente neste pipeline. O Sentinel avalia o plan antes mesmo de o apply acontecer. Se um developer pedir acidentalmente uma instância de base de dados que viole restrições de custo ou regras de compliance, o policy engine sinaliza o problema e interrompe o pipeline imediatamente. Este workflow automatizado é o que possibilita um modelo de infraestrutura self-service. Os platform engineers criam e testam módulos reutilizáveis, enquanto os application developers simplesmente submetem um Pull Request a pedir os recursos de que precisam. O pipeline faz o plan da alteração, o policy-as-code verifica a compliance, e um peer revê a intenção. A equipa de aplicações obtém a sua infraestrutura rapidamente, e a equipa de plataforma reforça a segurança sem atuar como um roadblock manual. Isto conclui a nossa série de fundamentos. Agora já sabes como o Terraform escala de um único comando local para um motor empresarial automatizado. A melhor maneira de consolidar este conhecimento é construíres algo, leres a documentação oficial e experimentares estes pipelines por ti mesmo. Se tiveres ideias para tópicos futuros, visita devstories dot eu. Gostaria de tirar um momento para te agradecer por ouvires — ajuda-nos imenso. Tem um ótimo dia!