Neste tutorial, explicamos como gerenciar a infraestrutura como código com o Terraform e o Cloud Build usando a conhecida metodologia GitOps. O termo GitOps foi cunhado pela primeira vez pela Weaveworks, e o conceito principal é usar um repositório Git para armazenar o estado do ambiente pretendido. O Terraform é uma ferramenta da HashiCorp que permite criar, alterar e melhorar de maneira previsível a infraestrutura de nuvem usando códigos. Neste tutorial, você usa o Cloud Build, um serviço de integração contínua do Google Cloud , para aplicar automaticamente os manifestos do Terraform ao ambiente.
Este tutorial é destinado a desenvolvedores e operadores que procuram uma estratégia elegante para fazer alterações previsíveis na infraestrutura. Para acompanhar este artigo, é necessário ter familiaridade com o Google Cloud, o Linux e o GitHub.
Os relatórios State of DevOps identificaram recursos que impulsionam o desempenho da entrega de software. Este tutorial vai ajudar você com os seguintes recursos:
Arquitetura
Para demonstrar como este tutorial aplica as práticas do GitOps para gerenciar execuções do Terraform, considere o diagrama de arquitetura a seguir. Ele usa
ramificações do GitHub (dev
e prod
) para representar ambientes reais. Esses
ambientes são definidos pelas redes VPC (nuvem privada virtual) dev
e prod
, respectivamente,
em um projeto do Google Cloud .
O processo começa quando você envia o código do Terraform para a ramificação dev
ou prod
. Nesse cenário, o Cloud Build aciona e aplica
manifestos do Terraform para atingir o estado pretendido no respectivo ambiente.
Por outro lado, quando você aplica o código do Terraform a qualquer outra ramificação, como uma
ramificação de recurso, o Cloud Build é iniciado para executar terraform plan
, mas
nada é aplicado a ambiente algum.
O ideal é que desenvolvedores ou operadores façam propostas de infraestrutura para
ramificações não protegidas
e as enviem usando
solicitações de pull.
O
app GitHub do Cloud Build,
discutido posteriormente neste tutorial, aciona automaticamente os jobs de build e
vincula os relatórios terraform plan
a essas solicitações de pull. Dessa forma, é possível discutir e analisar as possíveis alterações com os colaboradores e adicionar confirmações de acompanhamento antes que as alterações sejam mescladas no branch básico.
Se não houver preocupações, mescle as alterações no branch dev
. Essa mescla aciona uma implantação de infraestrutura para o ambiente dev
, o que permite testá-lo. Depois de testar e ter certeza do que foi implantado, mescle o branch dev
no branch prod
para acionar a instalação da infraestrutura no ambiente de produção.
Objetivos
- Configurar seu repositório GitHub.
- Configurar o Terraform para armazenar o estado em um bucket do Cloud Storage.
- Conceder permissões à conta de serviço do Cloud Build.
- Conectar o Cloud Build ao seu repositório GitHub.
- Alterar a configuração do ambiente em uma ramificação de recurso.
- Promover mudanças no ambiente de desenvolvimento.
- Promover mudanças no ambiente de produção.
Custos
Neste documento, você vai usar os seguintes componentes faturáveis do Google Cloud:
Para gerar uma estimativa de custo baseada na sua projeção de uso,
use a calculadora de preços.
Ao concluir as tarefas descritas neste documento, é possível evitar o faturamento contínuo excluindo os recursos criados. Para mais informações, consulte Limpeza.
Pré-requisitos
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Verify that billing is enabled for your Google Cloud project.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Verify that billing is enabled for your Google Cloud project.
-
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
- No Cloud Shell, confira o ID do projeto que você acabou de selecionar:
Se esse comando não retornar o ID, configure o Cloud Shell para usar seu projeto. Substituagcloud config get-value project
PROJECT_ID
pelo ID do projeto.gcloud config set project PROJECT_ID
- Ative as APIs necessárias:
Essa etapa pode levar alguns minutos.gcloud services enable cloudbuild.googleapis.com compute.googleapis.com
- Se você nunca usou o Git no Cloud Shell, configure-o com seu
nome e endereço de e-mail:
O Git usa essas informações para identificar você como autor dos commits criados no Cloud Shell.git config --global user.email "YOUR_EMAIL_ADDRESS" git config --global user.name "YOUR_NAME"
- A ramificação
dev
contém as alterações mais recentes aplicadas ao ambiente de desenvolvimento. - A ramificação
prod
contém as últimas alterações que são aplicadas ao ambiente de produção. - No GitHub, acesse https://github.com/GoogleCloudPlatform/solutions-terraform-cloudbuild-gitops.git.
No canto superior direito da página, clique em Bifurcar.
Agora você tem uma cópia do repositório
solutions-terraform-cloudbuild-gitops
com arquivos de origem.No Cloud Shell, clone o repositório bifurcado, substituindo
YOUR_GITHUB_USERNAME
pelo seu nome de usuário do GitHub:cd ~ git clone https://github.com/YOUR_GITHUB_USERNAME/solutions-terraform-cloudbuild-gitops.git cd ~/solutions-terraform-cloudbuild-gitops
A pasta
environments/
contém subpastas que representam ambientes, comodev
eprod
, que fornecem separação lógica entre cargas de trabalho em diferentes estágios de maturidade, desenvolvimento e produção, respectivamente. É uma boa prática que esses ambientes sejam os mais semelhantes possíveis, mas cada subpasta tem a própria configuração do Terraform para garantir que possam ter configurações únicas, conforme necessário.A pasta
modules/
contém módulos in-line do Terraform. Esses módulos representam agrupamentos lógicos de recursos relacionados e são usados para compartilhar código em diferentes ambientes.O
cloudbuild.yaml
é um arquivo de configuração de build que contém instruções para o Cloud Build, por exemplo, como executar tarefas com base em um conjunto de etapas. Esse arquivo especifica uma execução condicional, dependendo do branch em que o Cloud Build está buscando o código. Por exemplo:Para ramificações
dev
eprod
, as seguintes etapas são executadas:terraform init
terraform plan
terraform apply
Para qualquer outra ramificação, as etapas a seguir são executadas:
terraform init
para todas as subpastasenvironments
terraform plan
para todas as subpastasenvironments
No Cloud Shell, crie o bucket do Cloud Storage:
1. Ative o controle de versões de objeto para manter o histórico das implantações:PROJECT_ID=$(gcloud config get-value project) gcloud storage buckets create gs://${PROJECT_ID}-tfstate
```sh gcloud storage buckets update gs://${PROJECT_ID}-tfstate --versioning ``` Enabling Object Versioning increases [storage costs](/storage/pricing){: track-type="tutorial" track-name="internalLink" track-metadata-position="body" }, which you can mitigate by configuring [Object Lifecycle Management](/storage/docs/lifecycle){: track-type="tutorial" track-name="internalLink" track-metadata-position="body" } to delete old state versions.
Substitua o marcador de posição
PROJECT_ID
pelo ID do projeto nos arquivosterraform.tfvars
ebackend.tf
:cd ~/solutions-terraform-cloudbuild-gitops sed -i s/PROJECT_ID/$PROJECT_ID/g environments/*/terraform.tfvars sed -i s/PROJECT_ID/$PROJECT_ID/g environments/*/backend.tf
No SO X/MacOS, talvez seja necessário adicionar duas aspas (
""
) depois desed -i
, da seguinte maneira:cd ~/solutions-terraform-cloudbuild-gitops sed -i "" s/PROJECT_ID/$PROJECT_ID/g environments/*/terraform.tfvars sed -i "" s/PROJECT_ID/$PROJECT_ID/g environments/*/backend.tf
Verifique se todos os arquivos foram atualizados:
git status
O resultado será semelhante ao seguinte:
On branch dev Your branch is up-to-date with 'origin/dev'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: environments/dev/backend.tf modified: environments/dev/terraform.tfvars modified: environments/prod/backend.tf modified: environments/prod/terraform.tfvars no changes added to commit (use "git add" and/or "git commit -a")
Confirme e envie suas alterações por push:
git add --all git commit -m "Update project IDs and buckets" git push origin dev
Dependendo da sua configuração do GitHub, será preciso se autenticar para enviar as alterações anteriores.
Como conceder permissões à conta de serviço do Cloud Build
Para permitir que a conta de serviço do Cloud Build execute scripts do Terraform para gerenciar os recursos do Google Cloud , você precisa conceder acesso adequado ao projeto. Para simplificar, o acesso de editor do projeto é concedido neste tutorial. No entanto, quando o papel de editor do projeto tem uma permissão ampla em ambientes de produção, siga as práticas recomendadas de segurança de TI da sua empresa, que geralmente indicam para fornecer acessos com menos privilégios. Para conferir as práticas recomendadas de segurança, consulte Verificar explicitamente todas as tentativas de acesso.
No Cloud Shell, recupere o e-mail da conta de serviço do Cloud Build no projeto:
CLOUDBUILD_SA="$(gcloud projects describe $PROJECT_ID \ --format 'value(projectNumber)')@cloudbuild.gserviceaccount.com"
Conceda o acesso necessário à sua conta de serviço do Cloud Build:
gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:$CLOUDBUILD_SA --role roles/editor
Como conectar diretamente o Cloud Build ao repositório do GitHub
Esta seção mostra como instalar o app GitHub do Cloud Build. Essa instalação permite que você conecte o repositório do GitHub ao projeto doGoogle Cloud para que o Cloud Build possa aplicar automaticamente seus manifestos do Terraform toda vez que você criar uma nova ramificação ou enviar um código ao GitHub.
As etapas a seguir só fornecem instruções para instalar o app para o repositório
solutions-terraform-cloudbuild-gitops
, mas você pode optar por instalar o app para mais repositórios ou todos eles.Acesse a página do Marketplace do GitHub para o app Cloud Build:
Abrir a página do app Cloud Build
- Se esta for a primeira vez que você configura um app no GitHub, clique em Configurar com o Google Cloud Build na parte inferior da página. Em seguida, clique em Conceder acesso à sua conta do GitHub para o app.
- Se esta não for a primeira vez que você configura um app no GitHub, clique em Configurar acesso. A página Aplicativos da sua conta pessoal é aberta.
Clique em Configurar na linha do Cloud Build.
Selecione Somente repositórios selecionados e clique em
solutions-terraform-cloudbuild-gitops
para se conectar ao repositório.Clique em Salvar ou em Instalar. O rótulo do botão muda dependendo do fluxo de trabalho. Você vai acessar o Google Cloud para continuar a instalação.
Faça login com sua conta do Google Cloud . Se solicitado, autorize a integração do Cloud Build com o GitHub.
Na página Cloud Build, selecione o projeto. Um assistente será exibido.
Na seção Selecionar repositório, escolha sua conta do GitHub e o repositório
solutions-terraform-cloudbuild-gitops
.Se você concordar com os termos e condições, marque a caixa de seleção e clique em Conectar.
Na seção Criar gatilho, clique em Criar gatilho:
- Adicione um nome para o gatilho, como
push-to-branch
. Anote esse nome do gatilho porque você vai precisar dele mais tarde. - Na seção Evento, selecione Enviar para uma ramificação.
- Na seção Origem, selecione
.*
no campo Ramificação. - Clique em Criar.
- Adicione um nome para o gatilho, como
O app GitHub do Cloud Build agora está configurado e seu repositório do GitHub está vinculado ao projeto do Google Cloud . A partir de agora, as alterações feitas no repositório do GitHub acionam execuções do Cloud Build, que informam os resultados ao GitHub usando as verificações do GitHub.
Como alterar a configuração do ambiente em um novo branch de recurso
Até agora, você configurou a maior parte do seu ambiente. Portanto, é hora de fazer algumas alterações no código do seu ambiente de desenvolvimento.
No GitHub, acesse a página principal do seu repositório bifurcado.
https://github.com/YOUR_GITHUB_USERNAME/solutions-terraform-cloudbuild-gitops
Verifique se você está na ramificação
dev
.Para abrir o arquivo
modules/firewall/main.tf
para edição, acesse-o e clique no ícone de lápis.Na linha 30, corrija o erro de digitação
"http-server2"
no campotarget_tags
.O valor precisa ser
"http-server"
.Adicione uma mensagem de commit na parte inferior da página, como "Corrigindo o destino do firewall HTTP" e selecione Criar nova ramificação para esse commit e iniciar uma solicitação de pull.
Clique em Propor alterações.
Na página a seguir, clique em Criar solicitação de pull para abrir uma nova solicitação com sua alteração.
Depois que a solicitação de pull é aberta, um job do Cloud Build é iniciado automaticamente.
Clique em Mostrar todas as verificações e aguarde a verificação ficar verde.
Clique em Detalhes para conferir mais informações, incluindo a saída de
terraform plan
no link Conferir mais detalhes no Google Cloud Build.
Não mescle sua solicitação de pull ainda.
O job do Cloud Build executou o pipeline definido no arquivo
cloudbuild.yaml
. Como discutido anteriormente, esse pipeline tem comportamentos diferentes, dependendo do branch que está sendo buscado. A construção verifica se a variável$BRANCH_NAME
corresponde a alguma pasta do ambiente. Nesse caso, o Cloud Build executaterraform plan
para esse ambiente. Caso contrário, ele executaterraform plan
para todos os ambientes, de modo a garantir que a alteração proposta seja apropriada para todos eles. Se a execução de algum desses planos falhar, o build vai falhar.Da mesma forma, o comando
terraform apply
é executado para ramificações do ambiente, mas é completamente ignorado em qualquer outro caso. Nesta seção, como você enviou uma mudança de código para uma nova ramificação, nenhuma implantação de infraestrutura foi aplicada ao projeto do Google Cloud .Como aplicar com sucesso a execução do Cloud Build antes de mesclar ramificações
Para garantir que as mesclagens possam ser aplicadas apenas quando as respectivas execuções do Cloud Build forem bem-sucedidas, continue com as seguintes etapas:
No GitHub, acesse a página principal do seu repositório bifurcado.
https://github.com/YOUR_GITHUB_USERNAME/solutions-terraform-cloudbuild-gitops
No nome do repositório, clique em Configurações.
No menu esquerdo, clique em Ramificações.
Em Regras de proteção de ramificação, clique em Adicionar regra.
Em Padrão de nome de ramificação, digite
dev
.Na seção Proteger ramificações correspondentes, selecione Exigir que as verificações de status sejam aprovadas antes da mesclagem.
Pesquise o nome do gatilho do Cloud Build criado anteriormente.
Clique em Criar.
Repita as etapas 3 a 7, definindo Padrão de nome de ramificação como
prod
.
Essa configuração é importante para proteger as ramificações
dev
eprod
. Isso significa que os commits precisam ser enviados para outra ramificação antes de serem mesclados à ramificação protegida. Neste tutorial, a proteção exige que a execução do Cloud Build seja bem-sucedida para que a mesclagem seja permitida.Como promover alterações no ambiente de desenvolvimento
Há uma solicitação de pull aguardando para ser mesclada. É hora de aplicar o estado que você quer ao seu ambiente
dev
.No GitHub, acesse a página principal do seu repositório bifurcado.
https://github.com/YOUR_GITHUB_USERNAME/solutions-terraform-cloudbuild-gitops
Abaixo do nome do repositório, clique em Solicitações de pull.
Clique na solicitação de pull que você acabou de criar.
Clique em Mesclar solicitação de pull e em Confirmar mesclagem.
Verifique se um novo Cloud Build foi acionado:
Abra a compilação e verifique os registros.
Quando a compilação terminar, você verá algo assim:
Step #3 - "tf apply": external_ip = EXTERNAL_IP_VALUE Step #3 - "tf apply": firewall_rule = dev-allow-http Step #3 - "tf apply": instance_name = dev-apache2-instance Step #3 - "tf apply": network = dev Step #3 - "tf apply": subnet = dev-subnet-01
Copie
EXTERNAL_IP_VALUE
e abra o endereço em um navegador da Web.http://EXTERNAL_IP_VALUE
Esse provisionamento pode levar alguns segundos para inicializar a VM e propagar a regra de firewall. Por fim, Ambiente: dev será exibido no navegador da Web.
Acesse o arquivo de estado do Terraform no bucket do Cloud Storage.
https://storage.cloud.google.com/PROJECT_ID-tfstate/env/dev/default.tfstate
Como promover alterações no ambiente de produção
Agora que seu ambiente de desenvolvimento foi totalmente testado, promova seu código de infraestrutura para produção.
No GitHub, acesse a página principal do seu repositório bifurcado.
https://github.com/YOUR_GITHUB_USERNAME/solutions-terraform-cloudbuild-gitops
Abaixo do nome do repositório, clique em Solicitações de pull.
Clique em Nova solicitação de pull.
Para Repositório base, selecione seu repositório bifurcado.
Para Base, selecione
prod
no seu repositório base. Para Comparar, selecionedev
.Clique em Criar solicitação de pull.
Para Título, digite um título como
Promoting networking changes
e clique em Criar solicitação de pull.Revise as alterações propostas, incluindo os detalhes do
terraform plan
do Cloud Build e clique em Mesclar solicitação de pull.Clique em Confirmar mesclagem.
No console do Google Cloud , abra a página Histórico de builds para conferir o progresso da aplicação das alterações no ambiente de produção:
Aguarde o término da compilação e verifique os registros.
No final dos registros, você verá algo assim:
Step #3 - "tf apply": external_ip = EXTERNAL_IP_VALUE Step #3 - "tf apply": firewall_rule = prod-allow-http Step #3 - "tf apply": instance_name = prod-apache2-instance Step #3 - "tf apply": network = prod Step #3 - "tf apply": subnet = prod-subnet-01
Copie
EXTERNAL_IP_VALUE
e abra o endereço em um navegador da Web.http://EXTERNAL_IP_VALUE
Esse provisionamento pode levar alguns segundos para inicializar a VM e propagar a regra de firewall. Eventualmente, Ambiente: prod será exibido no navegador da Web.
Acesse o arquivo de estado do Terraform no bucket do Cloud Storage.
https://storage.cloud.google.com/PROJECT_ID-tfstate/env/prod/default.tfstate
Você configurou um pipeline de infraestrutura como código sem servidor no Cloud Build. No futuro, tente realizar as ações a seguir:
- Adicione implantações para casos de uso separados.
- Crie ambientes adicionais para refletir suas necessidades.
- Use um projeto por ambiente em vez de uma VPC por ambiente.
Limpeza
Depois de concluir este tutorial, limpe os recursos que você criou no Google Cloud para não receber cobranças no futuro.
Excluir o projeto
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
Excluir o repositório do GitHub
Para evitar o bloqueio de novas solicitações de pull no repositório do GitHub, exclua as regras de proteção da ramificação:
- No GitHub, acesse a página principal do repositório bifurcado.
- No nome do repositório, clique em Configurações.
- No menu esquerdo, clique em Ramificações.
- Na seção Regras de proteção da ramificação, clique no botão Excluir
das linhas
dev
eprod
.
Se preferir, desinstale completamente o app Cloud Build do GitHub:
Acesse as configurações de Aplicativos do GitHub.
Na guia Apps instalados do GitHub, clique em Configurar na linha Cloud Build. Em seguida, na seção Zona de perigo, clique no botão Desinstalar na linha Desinstalar o Google Cloud Builder.
Na parte superior da página, uma mensagem é exibida: Tudo pronto. Um job foi colocado na fila para desinstalar o Google Cloud Build.
Na guia Apps autorizados do GitHub, clique no botão Revogar na linha Google Cloud Build e em Entendo, revogar acesso no pop-up.
Se você não quiser manter o repositório do GitHub, faça o seguinte:
- No GitHub, acesse a página principal do repositório bifurcado.
- No nome do repositório, clique em Configurações.
- Role para baixo até Zona de perigo.
- Clique em Excluir este repositório e siga as etapas de confirmação.
A seguir
- Considere usar os modelos do Cloud Foundation Toolkit para criar rapidamente uma base empresarial replicável no Google Cloud.
- Assista a Ambientes replicáveis do Google Cloud em escala com pipelines de infraestrutura como código do Cloud Build, produzido pela Next' 19, sobre o fluxo de trabalho de GitOps descrito neste tutorial.
- Confira o tutorial Entrega contínua no estilo GitOps com o Cloud Build.
- Confira os recursos mais avançados do Cloud Build: Como configurar a ordem das etapas de build, Como criar, testar e implantar artefatos e Como criar etapas personalizadas de build.
- Confira o blog sobre Como garantir a escala e a conformidade da implantação do Terraform com o Cloud Build.
- Leia nossos recursos sobre DevOps.
- Saiba mais sobre os recursos de DevOps relacionados a este tutorial:
- Faça a verificação rápida de DevOps para entender sua posição em relação ao restante do setor.
Como configurar seu repositório do GitHub
Neste tutorial, você usa um único repositório Git para definir a infraestrutura em nuvem. Você orquestra essa infraestrutura ao ter branches diferentes correspondentes a ambientes diferentes:
Com essa infraestrutura, sempre é possível fazer referência ao repositório para saber qual configuração é esperada em cada ambiente e propor novas alterações, primeiro fundindo-as ao ambiente dev
. Em seguida, você promove as alterações
mesclando a ramificação dev
na ramificação prod
.
Para começar, bifurque o repositório solutions-terraform-cloudbuild-gitops.
O código nesse repositório está estruturado da seguinte maneira:
Para garantir que as alterações propostas sejam adequadas para todos os ambientes,
terraform init
e terraform plan
são executados para todas as
subpastas environments
. Antes de mesclar a solicitação de pull, é possível analisar os planos
para garantir que o acesso não seja concedido, por exemplo, a uma entidade
não autorizada.
Como configurar o Terraform para armazenar o estado em um bucket do Cloud Storage
Por padrão, o Terraform armazena o
estado
localmente em um arquivo chamado terraform.tfstate
. Essa configuração padrão pode
dificultar o uso do Terraform para as equipes, especialmente quando muitos usuários o executam
ao mesmo tempo e cada máquina tem o próprio entendimento da
infraestrutura atual.
Para ajudar a evitar esses problemas, esta seção configura um
estado remoto
que aponta para um bucket do Cloud Storage. O estado remoto é um recurso de
back-ends
e, neste tutorial, é configurado nos arquivos backend.tf
, por exemplo:
Nas etapas a seguir, você cria um bucket do Cloud Storage e muda alguns arquivos para apontar para ele e para o projeto do Google Cloud .