
GCP
Engineering Handbook · Capitulo 03
Google Cloud Master Journey 2026
Engineering Handbook · Capitulo 03
Como usei Terraform para provisionar uma VPC, criar maquinas virtuais, configurar IP estatico, modelar dependencias e entender o ciclo de vida da infraestrutura no Google Cloud.
Este artigo faz parte da serie Google Cloud Master Journey 2026, em que estou documentando minha jornada pratica com Google Cloud, Arcade, laboratorios da trilha de certificacao e preparacao para a Associate Cloud Engineer.
A ideia nao e apenas registrar badges ou comandos executados. Quero transformar cada laboratorio em um material que responda perguntas de engenharia:
Neste capitulo, o tema e Infrastructure as Code com Terraform.
O laboratorio usado como base foi Infrastructure as Code with Terraform, executado em um ambiente temporario do Google Cloud.
Durante a pratica, a infraestrutura evoluiu por etapas:
Apesar de pequena, essa infraestrutura apresenta conceitos que aparecem em ambientes corporativos maiores: estado desejado, revisao de mudancas, dependencias, substituicao de recursos e automacao.
E possivel criar todos esses recursos pelo Console do Google Cloud. Para um teste isolado, clicar no painel pode funcionar.
O problema aparece quando precisamos repetir o processo:
Infraestrutura manual tende a gerar configuracoes inconsistentes, pouca auditoria, dependencia de conhecimento individual e maior chance de erro humano.
Infrastructure as Code muda a pergunta principal.
Em vez de perguntar:
Quais passos preciso executar no Console?
Passamos a perguntar:
Qual estado minha infraestrutura precisa possuir?
Essa diferenca e o centro do Terraform.
Terraform e uma ferramenta de Infrastructure as Code criada pela HashiCorp. Ela usa uma linguagem declarativa chamada HCL, ou HashiCorp Configuration Language.
Em uma configuracao declarativa, descrevemos o estado desejado. O Terraform compara esse estado com o que ele conhece da infraestrutura e calcula as acoes necessarias.
resource "google_compute_network" "vpc_network" {
name = "terraform-network"
}
Esse bloco nao diz "abra o Console, clique em redes e confirme". Ele declara:
Deve existir uma rede do Google Cloud chamada
terraform-network.
O provider do Google Cloud faz a ponte entre o Terraform e a API da plataforma.
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "3.5.0"
}
}
}
Em um projeto novo eu avaliaria uma versao mais atual do provider, mas no laboratorio a versao fixa ajuda a manter previsibilidade.
O fluxo basico do Terraform e simples, mas cada etapa tem uma responsabilidade importante.
terraform initInicializa o diretorio de trabalho, baixa providers e prepara o ambiente local.
No laboratorio, ele tambem criou o arquivo .terraform.lock.hcl, que registra as versoes selecionadas dos providers e ajuda a manter execucoes consistentes.
terraform planCompara configuracao desejada, state e infraestrutura real.
Ele nao altera nada. Serve para revisar impacto antes da execucao.
Simbolos importantes:
| Simbolo | Significado |
|---|---|
+ |
criar recurso |
~ |
alterar em lugar |
- |
destruir recurso |
-/+ |
destruir e recriar |
Em ambiente real, o plan deveria ser revisado em Pull Request ou pipeline antes de qualquer alteracao chegar em producao.
terraform applyExecuta as mudancas planejadas. No primeiro passo do laboratorio, o resultado foi a criacao da VPC:
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
terraform destroyRemove os recursos administrados pela configuracao.
Esse comando e util em laboratorios, ambientes efemeros, testes automatizados e demonstracoes. Em producao, destruicao exige controles adicionais: aprovacao, backup, politicas e janelas de execucao.
A configuracao inicial tinha uma VPC e uma VM.
resource "google_compute_network" "vpc_network" {
name = "terraform-network"
}
resource "google_compute_instance" "vm_instance" {
name = "terraform-instance"
machine_type = "e2-micro"
boot_disk {
initialize_params {
image = "debian-cloud/debian-12"
}
}
network_interface {
network = google_compute_network.vpc_network.name
access_config {
}
}
}
A linha abaixo ja cria uma relacao entre VM e rede:
network = google_compute_network.vpc_network.name
Essa relacao e uma dependencia implicita.
Uma parte importante do laboratorio foi observar como o Terraform reage a mudancas diferentes.
Ao adicionar uma VM nova, o plano mostra criacao:
+ create
Ao adicionar tags na instancia, o plano mostra alteracao em lugar:
~ update in-place
A diferenca no codigo era pequena:
resource "google_compute_instance" "vm_instance" {
name = "terraform-instance"
machine_type = "e2-micro"
}resource "google_compute_instance" "vm_instance" {
name = "terraform-instance"
machine_type = "e2-micro"
tags = ["web", "dev"]
}Mas quando a imagem do disco de boot muda, a instancia precisa ser substituida:
-/+ destroy and then create replacement
Esse e um aprendizado fundamental: uma mudanca pequena no codigo pode representar uma substituicao completa na infraestrutura.
Por isso, terraform plan nao e burocracia. E etapa de engenharia.
O Terraform precisa saber quais recursos ele administra, quais IDs reais foram criados e como os recursos se relacionam. Para isso, ele mantem um state.
No laboratorio, o state ficou local. Em equipe, eu usaria backend remoto com:
O state pode conter informacoes sensiveis e deve ser tratado como parte critica da infraestrutura.
Depois da VM, adicionei um IP estatico:
resource "google_compute_address" "vm_static_ip" {
name = "terraform-static-ip"
}
E associei esse IP na interface de rede:
network_interface {
network = google_compute_network.vpc_network.self_link
access_config {
nat_ip = google_compute_address.vm_static_ip.address
}
}
A referencia google_compute_address.vm_static_ip.address cria uma dependencia implicita. O Terraform entende que o IP precisa existir antes da VM consumir esse valor.
Sempre que a dependencia aparece por uma referencia real entre recursos, prefiro deixa-la implicita. O codigo fica mais expressivo.

Nem toda dependencia aparece em uma propriedade do recurso.
Imagine uma aplicacao que roda em uma VM e espera encontrar um bucket durante a inicializacao. A VM pode nao referenciar o bucket em nenhum atributo, mas a aplicacao depende dele.
Nesse caso, usamos depends_on.
resource "google_compute_instance" "another_instance" {
depends_on = [google_storage_bucket.example_bucket]
name = "terraform-instance-2"
machine_type = "e2-micro"
}
A ordem dos blocos no arquivo nao determina a ordem de criacao. O Terraform usa o grafo de dependencias.
Uma forma simples de visualizar o processo:
Esse grafo permite criar recursos dependentes na ordem correta, destruir em ordem inversa, executar operacoes independentes em paralelo e evitar remover recursos ainda utilizados.
O laboratorio tambem mostrou:
terraform plan -out static_ip
terraform apply "static_ip"
Salvar o plano permite aplicar exatamente aquilo que foi revisado. Em pipeline, isso ajuda a reduzir diferenca entre revisao e execucao.
Na ultima etapa, adicionei um provisioner:
provisioner "local-exec" {
command = "echo ${self.name}: ${self.network_interface[0].access_config[0].nat_ip} >> ip_address.txt"
}
O local-exec roda na maquina onde o Terraform esta sendo executado. No laboratorio, isso significa o Cloud Shell. Ele nao roda dentro da VM criada.
Um detalhe importante: depois de adicionar o provisioner, o Terraform informou que nao havia mudancas. Isso acontece porque provisioners normalmente executam na criacao do recurso.
Para forcar a recriacao no laboratorio, foi usado:
terraform taint google_compute_instance.vm_instance
Em fluxos mais modernos, eu preferiria:
terraform apply -replace="google_compute_instance.vm_instance"
Provisioners sao uteis, mas eu evitaria trata-los como primeira opcao. Em producao, avaliaria alternativas como startup scripts, cloud-init, Packer, imagens pre-configuradas, containers ou servicos gerenciados.
O bucket e a segunda VM foram recursos temporarios para demonstrar dependencia explicita. Depois da validacao, eles foram removidos.
Como eu ja venho de experiencia com AWS, comparar os conceitos ajuda a consolidar.
| Conceito | Google Cloud | AWS |
|---|---|---|
| Provider Terraform | hashicorp/google |
hashicorp/aws |
| Rede virtual | google_compute_network |
aws_vpc |
| Maquina virtual | google_compute_instance |
aws_instance |
| IP estatico | google_compute_address |
aws_eip |
| Armazenamento de objetos | google_storage_bucket |
aws_s3_bucket |
| Terminal gerenciado | Cloud Shell | AWS CloudShell |
| Imagem de VM | Compute Engine Image | AMI |
| Escopo principal | Google Cloud Project | AWS Account |
As equivalencias nao sao perfeitas, mas ajudam a transferir intuicoes entre nuvens.
Eu nao deixaria toda a infraestrutura em um unico main.tf.
Uma estrutura inicial poderia ser:
Cada ambiente consumiria modulos reutilizaveis, mantendo padroes e reduzindo duplicacao.
Em uma plataforma real, o fluxo deveria ser:
O laboratorio e bom para aprender, mas producao pede mais cuidado.
project_id, regiao, zona e nomes por variaveis.output.terraform fmt e terraform validate no pipeline.terraform plan antes de aplicar.apply manualmente do notebook de um desenvolvedor para producao.Registrar erros tambem faz parte da jornada.
Durante a instalacao, um arquivo de chave ja existia e o processo entrou em modo interativo. A solucao foi interromper, revisar o bloco e executar corretamente.
Ao adicionar o IP estatico, uma chave do HCL ficou aberta e o Terraform retornou:
Error: Unclosed configuration block
Isso reforcou o valor de rodar:
terraform fmt
terraform validate
Tambem aprendi na pratica que adicionar um provisioner nao forca execucao em recurso ja criado. O comportamento estava correto, mas era facil interpretar como erro se eu nao entendesse o ciclo de vida do recurso.
terraform plan e etapa de engenharia, nao uma formalidade.depends_on deve ser usado com intencao.Esse laboratorio reforca habilidades importantes para a certificacao:
A certificacao nao exige apenas decorar comandos. Ela exige entender qual recurso usar, como configura-lo e qual impacto uma decisao pode causar.
Este laboratorio comecou com uma VPC simples e terminou mostrando conceitos centrais do Terraform: estado desejado, plano de execucao, dependencias, substituicao de recursos, provisionamento e infraestrutura declarativa.
O aprendizado principal nao foi executar terraform apply.
Foi entender que o Terraform constroi uma representacao da infraestrutura, calcula dependencias e executa mudancas para alcancar o estado declarado.
Essa mudanca de mentalidade e o que torna Infrastructure as Code tao poderosa.
Nos proximos capitulos da Google Cloud Master Journey 2026, quero continuar conectando os laboratorios do Arcade com preparacao real para Cloud Engineering:
gcloud;A jornada esta apenas comecando.
As respostas da comunidade chegam em breve.