Este tutorial explica como gerir a infraestrutura como código com o Terraform e o Cloud Build através da popular metodologia GitOps. O termo GitOps foi cunhado pela primeira vez pela Weaveworks, e o seu conceito principal é usar um repositório Git para armazenar o estado do ambiente que quer. O Terraform é uma ferramenta da HashiCorp que lhe permite criar, alterar e melhorar de forma previsível a sua infraestrutura na nuvem através de código. Neste tutorial, vai usar o Cloud Build (um serviço de integração contínua) para aplicar automaticamente manifestos do Terraform ao seu ambiente. Google Cloud
Este tutorial destina-se a programadores e operadores que procuram uma estratégia elegante para fazer alterações previsíveis à infraestrutura. O artigo pressupõe que tem conhecimentos sobre o Google Cloud, o Linux e o GitHub. Google Cloud
Os relatórios State of DevOps identificaram capacidades que impulsionam o desempenho da entrega de software. Este tutorial vai ajudar com as seguintes capacidades:
Arquitetura
Para demonstrar como este tutorial aplica as práticas de GitOps para gerir as execuções do Terraform, considere o seguinte diagrama de arquitetura. Tenha em atenção que usa ramificações do GitHub, dev
e prod
, para representar ambientes reais. Estes ambientes são definidos por redes da nuvem virtual privada (VPC), dev
e prod
, respetivamente, num projeto. Google Cloud
O processo começa quando envia código do Terraform para o ramo dev
ou prod
. Neste cenário, o Cloud Build aciona e, em seguida, aplica os manifestos do Terraform para alcançar o estado pretendido no ambiente respetivo.
Por outro lado, quando envia código Terraform para qualquer outro ramo, por exemplo, para um ramo de funcionalidade, o Cloud Build é executado para executar terraform plan
, mas não é aplicado nada a nenhum ambiente.
Idealmente, os programadores ou os operadores têm de fazer propostas de infraestrutura para
ramificações não protegidas
e, em seguida, enviá-las através de
pedidos de obtenção.
A
app GitHub do Cloud Build,
abordada mais adiante neste tutorial, aciona automaticamente as tarefas de compilação e
associa os relatórios terraform plan
a estes pedidos de envio. Desta forma, pode discutir e rever as potenciais alterações com os colaboradores e adicionar commits de seguimento antes de as alterações serem unidas no ramo base.
Se não forem levantadas preocupações, tem de unir primeiro as alterações ao ramo dev
Esta união aciona uma implementação de infraestrutura no ambiente dev
, o que lhe permite testar este ambiente. Depois de testar e ter a certeza do que foi implementado, tem de unir a ramificação dev
à ramificação prod
para acionar a instalação da infraestrutura no ambiente de produção.
Objetivos
- Configure o seu repositório do GitHub.
- Configure o Terraform para armazenar o estado num contentor do Cloud Storage.
- Conceda autorizações à sua conta de serviço do Cloud Build.
- Associe o Cloud Build ao seu repositório do GitHub.
- Altere a configuração do ambiente numa ramificação de funcionalidades.
- Promova alterações para o ambiente de desenvolvimento.
- Promova alterações para o ambiente de produção.
Custos
Neste documento, usa os seguintes componentes faturáveis do Google Cloud:
Para gerar uma estimativa de custos com base na sua utilização projetada,
use a calculadora de preços.
Quando terminar as tarefas descritas neste documento, pode evitar a faturação contínua eliminando os recursos que criou. Para mais informações, consulte o artigo Limpe.
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.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator
(
roles/resourcemanager.projectCreator
), which contains theresourcemanager.projects.create
permission. Learn how to grant roles.
-
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.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator
(
roles/resourcemanager.projectCreator
), which contains theresourcemanager.projects.create
permission. Learn how to grant roles.
-
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, obtenha o ID do projeto que acabou de selecionar:
Se este comando não devolver o ID do projeto, configure o Cloud Shell para usar o seu projeto. Substituagcloud config get-value project
PROJECT_ID
pelo ID do seu projeto.gcloud config set project PROJECT_ID
- Ative as APIs necessárias:
Este passo pode demorar alguns minutos a ser concluído.gcloud services enable cloudbuild.googleapis.com compute.googleapis.com
- Se nunca usou o Git no Cloud Shell, configure-o com o seu nome e endereço de email:
O Git usa estas informações para identificar o utilizador como o autor das confirmações que cria na Cloud Shell.git config --global user.email "YOUR_EMAIL_ADDRESS" git config --global user.name "YOUR_NAME"
- O ramo
dev
contém as alterações mais recentes que são aplicadas ao ambiente de desenvolvimento. - O ramo
prod
contém as alterações mais recentes que são aplicadas ao ambiente de produção. - No GitHub, navegue para https://github.com/GoogleCloudPlatform/solutions-terraform-cloudbuild-gitops.git.
No canto superior direito da página, clique em Criar fork.
Agora, tem uma cópia do repositório com os ficheiros de origem.
solutions-terraform-cloudbuild-gitops
No Cloud Shell, clone este repositório bifurcado, substituindo
YOUR_GITHUB_USERNAME
pelo seu nome de utilizador 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 oferecem uma separação lógica entre cargas de trabalho em diferentes fases de maturidade, desenvolvimento e produção, respetivamente. Embora seja uma boa prática ter estes ambientes o mais semelhantes possível, cada subpasta tem a sua própria configuração do Terraform para garantir que podem ter definições únicas, conforme necessário.A pasta
modules/
contém módulos Terraform incorporados. Estes módulos representam agrupamentos lógicos de recursos relacionados e são usados para partilhar código em diferentes ambientes.O ficheiro
cloudbuild.yaml
é um ficheiro de configuração de compilação que contém instruções para o Cloud Build, como a forma de realizar tarefas com base num conjunto de passos. Este ficheiro especifica uma execução condicional consoante o ramo do qual o Cloud Build está a obter o código, por exemplo:Para os ramos
dev
eprod
, são executados os seguintes passos:terraform init
terraform plan
terraform apply
Para qualquer outro ramo, são executados os seguintes passos:
terraform init
para todas asenvironments
subpastasterraform plan
para todas asenvironments
subpastas
No Cloud Shell, crie o contentor do Cloud Storage:
1. Ative a opção Object Versioning para manter o histórico das suas implementaçõ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 ficheirosterraform.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 OS X/MacOS, pode ter de adicionar duas aspas (
""
) apóssed -i
, da seguinte forma: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 ficheiros foram atualizados:
git status
O resultado tem o seguinte aspeto:
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 as alterações:
git add --all git commit -m "Update project IDs and buckets" git push origin dev
Consoante a sua configuração do GitHub, tem de se autenticar para enviar as alterações anteriores.
Conceder autorizações à sua conta de serviço do Cloud Build
Para permitir que a conta de serviço do Cloud Build execute scripts do Terraform com o objetivo de gerir recursos, tem de lhe conceder o acesso adequado ao seu projeto. Google Cloud Para simplificar, o acesso de editor do projeto é concedido neste tutorial. No entanto, quando a função de editor do projeto tem uma autorização de grande alcance, nos ambientes de produção, tem de seguir as práticas recomendadas de segurança de TI da sua empresa, normalmente fornecendo acesso com privilégios mínimos. Para ver as práticas recomendadas de segurança, consulte o artigo Valide explicitamente todas as tentativas de acesso.
No Cloud Shell, obtenha o email da conta de serviço do Cloud Build do seu 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
Associar diretamente o Cloud Build ao seu repositório do GitHub
Esta secção mostra como instalar a app GitHub do Cloud Build. Esta instalação permite-lhe associar o seu repositório do GitHub ao seu Google Cloud projeto para que o Cloud Build possa aplicar automaticamente os seus manifestos do Terraform sempre que criar um novo ramo ou enviar código para o GitHub.
Os passos seguintes fornecem instruções para instalar a app apenas para o repositório
solutions-terraform-cloudbuild-gitops
, mas pode optar por instalar a app para mais ou todos os seus repositórios.Aceda à página do GitHub Marketplace para a app Cloud Build:
Abra a página da app Cloud Build
- Se for a primeira vez que configura uma app no GitHub: clique em Configurar com o Google Cloud Build na parte inferior da página. Em seguida, clique em Conceder acesso desta app à sua conta do GitHub.
- Se não for a primeira vez que configura uma app no GitHub: clique em Configurar acesso. É aberta a página Aplicações da sua conta pessoal.
Clique em Configurar na linha do Cloud Build.
Selecione Selecionar apenas repositórios e, de seguida, selecione
solutions-terraform-cloudbuild-gitops
para estabelecer ligação ao repositório.Clique em Guardar ou Instalar. A etiqueta do botão muda consoante o seu fluxo de trabalho. É feito o redirecionamento para Google Cloud para continuar a instalação.
Inicie sessão com a sua conta do Google Cloud . Se lhe for pedido, autorize a integração do Cloud Build com o GitHub.
Na página Cloud Build, selecione o seu projeto. É apresentado um assistente.
Na secção Selecionar repositório, selecione a sua conta do GitHub e o repositório
solutions-terraform-cloudbuild-gitops
.Se concordar com os termos de utilização, selecione a caixa de verificação e, de seguida, clique em Associar.
Na secção Crie um acionador, clique em Crie um acionador:
- Adicione um nome do acionador, como
push-to-branch
. Tome nota do nome deste acionador, pois vai precisar dele mais tarde. - Na secção Evento, selecione Enviar para uma ramificação.
- Na secção Origem, selecione
.*
no campo Filial. - Clique em Criar.
- Adicione um nome do acionador, como
A app GitHub do Cloud Build está agora configurada e o seu repositório do GitHub está associado ao seu Google Cloud projeto. A partir de agora, as alterações ao repositório do GitHub acionam execuções do Cloud Build, que comunicam os resultados ao GitHub através do GitHub Checks.
Alterar a configuração do ambiente num novo ramo de funcionalidades
Neste momento, já tem a maior parte do ambiente configurada. Por isso, está na altura de fazer algumas alterações ao código no seu ambiente de programação.
No GitHub, navegue para a página principal do repositório bifurcado.
https://github.com/YOUR_GITHUB_USERNAME/solutions-terraform-cloudbuild-gitops
Certifique-se de que está na ramificação
dev
.Para abrir o ficheiro para edição, aceda ao ficheiro
modules/firewall/main.tf
e clique no ícone de lápis.Na linha 30, corrija o erro ortográfico
"http-server2"
no campotarget_tags
.O valor tem de ser
"http-server"
.Adicione uma mensagem de confirmação na parte inferior da página, como "Fixing http firewall target", e selecione Criar um novo ramo para esta confirmação e iniciar um pedido de obtenção.
Clique em Propor alterações.
Na página seguinte, clique em Criar pedido de obtenção para abrir um novo pedido de obtenção com a sua alteração.
Depois de o pedido de obtenção estar aberto, é iniciado automaticamente um trabalho do Cloud Build.
Clique em Mostrar todas as verificações e aguarde até que a verificação fique verde.
Clique em Detalhes para ver mais informações, incluindo o resultado do
terraform plan
no link Ver mais detalhes no Google Cloud Build.
Não associe o seu pedido de envio já.
Tenha em atenção que a tarefa do Cloud Build executou o pipeline definido no ficheiro
cloudbuild.yaml
. Conforme abordado anteriormente, este pipeline tem comportamentos diferentes consoante a ramificação que está a ser obtida. A compilação verifica se a variável$BRANCH_NAME
corresponde a alguma pasta de ambiente. Se for o caso, o Cloud Build executaterraform plan
para esse ambiente. Caso contrário, o Cloud Build executaterraform plan
para todos os ambientes para garantir que a alteração proposta é adequada para todos eles. Se algum destes planos não for executado, a compilação falha.Da mesma forma, o comando
terraform apply
é executado para ramificações do ambiente, mas é completamente ignorado em qualquer outro caso. Nesta secção, enviou uma alteração de código para um novo ramo, pelo que não foram aplicadas implementações de infraestrutura ao seu Google Cloud projeto.Impor o sucesso da execução do Cloud Build antes de unir ramificações
Para garantir que as unificações só podem ser aplicadas quando as respetivas execuções do Cloud Build forem bem-sucedidas, avance com os seguintes passos:
No GitHub, navegue para a página principal do repositório bifurcado.
https://github.com/YOUR_GITHUB_USERNAME/solutions-terraform-cloudbuild-gitops
Abaixo do nome do repositório, clique em Definições.
No menu do lado esquerdo, clique em Ramos.
Em Regras de proteção de ramificações, clique em Adicionar regra.
Em Padrão do nome da ramificação, escreva
dev
.Na secção Proteger ramos correspondentes, selecione Exigir que as verificações de estado sejam aprovadas antes da união.
Pesquise o nome do acionador do Cloud Build criado anteriormente.
Clique em Criar.
Repita os passos 3 a 7, definindo o Padrão do nome da ramificação como
prod
.
Esta configuração é importante para proteger os ramos
dev
eprod
. Isto significa que os commits têm de ser enviados primeiro para outro ramo e só depois podem ser unidos ao ramo protegido. Neste tutorial, a proteção requer que a execução do Cloud Build seja bem-sucedida para permitir a união.Promover alterações para o ambiente de programação
Tem um pedido de obtenção a aguardar a união. Está na altura de aplicar o estado que quer ao seu ambiente
dev
.No GitHub, navegue para a página principal do repositório bifurcado.
https://github.com/YOUR_GITHUB_USERNAME/solutions-terraform-cloudbuild-gitops
Abaixo do nome do repositório, clique em Pedidos de obtenção.
Clique no pedido de obtenção que acabou de criar.
Clique em Unir pedido de envio e, de seguida, em Confirmar união.
Verifique se foi acionado um novo Cloud Build:
Abra a compilação e verifique os registos.
Quando a compilação terminar, vê algo semelhante ao seguinte:
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 num navegador de Internet.http://EXTERNAL_IP_VALUE
Este aprovisionamento pode demorar alguns segundos a arrancar a VM e a propagar a regra de firewall. Eventualmente, vê Environment: dev no navegador de Internet.
Navegue para o ficheiro de estado do Terraform no contentor do Cloud Storage.
https://storage.cloud.google.com/PROJECT_ID-tfstate/env/dev/default.tfstate
Promover alterações para o ambiente de produção
Agora que tem o ambiente de desenvolvimento totalmente testado, pode promover o código de infraestrutura para produção.
No GitHub, navegue para a página principal do repositório bifurcado.
https://github.com/YOUR_GITHUB_USERNAME/solutions-terraform-cloudbuild-gitops
Abaixo do nome do repositório, clique em Pedidos de obtenção.
Clique em Novo pedido de envio.
Para o repositório base, selecione o repositório que acabou de criar.
Para base, selecione
prod
no seu próprio repositório base. Para comparar, selecionedev
.Clique em Criar pedido de obtenção.
Para título, introduza um título, como
Promoting networking changes
, e, em seguida, clique em Criar pedido de envio.Reveja as alterações propostas, incluindo os detalhes do
terraform plan
Cloud Build, e, de seguida, clique em Unir pedido de obtenção.Clique em Confirmar união.
Na Google Cloud consola, abra a página Histórico de compilações para ver as alterações aplicadas ao ambiente de produção:
Aguarde a conclusão da compilação e, em seguida, verifique os registos.
No final dos registos, vê algo semelhante ao seguinte:
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 num navegador de Internet.http://EXTERNAL_IP_VALUE
Este aprovisionamento pode demorar alguns segundos a arrancar a VM e a propagar a regra de firewall. Eventualmente, vê Environment: prod no navegador de Internet.
Navegue para o ficheiro de estado do Terraform no contentor do Cloud Storage.
https://storage.cloud.google.com/PROJECT_ID-tfstate/env/prod/default.tfstate
Configurou com êxito um pipeline de infraestrutura como código sem servidores no Cloud Build. No futuro, pode experimentar o seguinte:
- Adicione implementações para exemplos de utilização separados.
- Crie ambientes adicionais para refletir as suas necessidades.
- Use um projeto por ambiente em vez de uma VPC por ambiente.
Limpeza
Depois de concluir o tutorial, limpe os recursos que criou no Google Cloud para que não lhe sejam faturados no futuro.
Eliminar 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.
Eliminar o repositório do GitHub
Para evitar o bloqueio de novos pedidos de obtenção no seu repositório do GitHub, pode eliminar as regras de proteção de ramos:
- No GitHub, navegue para a página principal do repositório criado a partir de outro.
- Abaixo do nome do repositório, clique em Definições.
- No menu do lado esquerdo, clique em Ramos.
- Na secção Regras de proteção de ramificações, clique no botão Eliminar
para as linhas
dev
eprod
.
Opcionalmente, pode desinstalar completamente a app Cloud Build do GitHub:
Aceda às definições de Aplicações do GitHub.
No separador Apps GitHub instaladas, clique em Configurar na linha Cloud Build. Em seguida, na secção Zona de perigo, clique no botão Desinstalar na linha Desinstalar o Google Cloud Builder.
Na parte superior da página, é apresentada a mensagem "Está tudo pronto. Uma tarefa foi colocada em fila para desinstalar o Google Cloud Build."
No separador Apps GitHub autorizadas, clique no botão Revogar na linha Google Cloud Build e, de seguida, em Compreendo, revogar acesso no pop-up.
Se não quiser manter o seu repositório do GitHub:
- No GitHub, aceda à página principal do repositório bifurcado.
- Abaixo do nome do repositório, clique em Definições.
- Desloque a página para baixo até à Zona de perigo.
- Clique em Eliminar este repositório e siga os passos de confirmação.
O que se segue?
- Considere usar os modelos do Cloud Foundation Toolkit para criar rapidamente uma base repetível pronta para a empresa no Google Cloud.
- Veja o vídeo Repeatable Google Cloud Environments at Scale With Cloud Build Infra-As-Code Pipelines do Next' 19 sobre o fluxo de trabalho do GitOps descrito neste tutorial.
- Consulte o tutorial Fornecimento contínuo ao estilo GitOps com o Cloud Build.
- Veja mais funcionalidades avançadas do Cloud Build: configurar a ordem dos passos de compilação, criar, testar e implementar artefactos e criar passos de compilação personalizados.
- Consulte o blogue sobre como garantir a escala e a conformidade da sua implementação do Terraform com o Cloud Build.
- Leia os nossos recursos sobre DevOps.
- Saiba mais sobre as capacidades de DevOps relacionadas com este tutorial:
- Faça a verificação rápida de DevOps para saber a sua posição em comparação com o resto da indústria.
Configurar o seu repositório do GitHub
Neste tutorial, usa um único repositório Git para definir a sua infraestrutura na nuvem. Orquestra esta infraestrutura com diferentes ramificações correspondentes a diferentes ambientes:
Com esta infraestrutura, pode sempre consultar o repositório para saber que configuração é esperada em cada ambiente e propor novas alterações, primeiro, ao juntá-las ao ambiente dev
. Em seguida, promove as alterações ao
unir a ramificação dev
à ramificação prod
subsequente.
Para começar, bifurque o repositório solutions-terraform-cloudbuild-gitops.
O código neste repositório está estruturado da seguinte forma:
Para garantir que as alterações propostas são adequadas para todos os ambientes, os comandos terraform init
e terraform plan
são executados para todas as environments
subpastas. Antes de unir o pedido de envio, pode rever os planos para se certificar de que o acesso não está a ser concedido a uma entidade não autorizada, por exemplo.
Configurar o Terraform para armazenar o estado num contentor do Cloud Storage
Por predefinição, o Terraform armazena o
estado
localmente num ficheiro denominado terraform.tfstate
. Esta configuração predefinida pode dificultar a utilização do Terraform para as equipas, especialmente quando muitos utilizadores executam o Terraform ao mesmo tempo e cada máquina tem a sua própria compreensão da infraestrutura atual.
Para ajudar a evitar estes problemas, esta secção configura um estado remoto que aponta para um contentor do Cloud Storage. O estado remoto é uma funcionalidade dos
servidores de back-end
e, neste tutorial, é configurado nos ficheiros backend.tf
, por exemplo:
Nos passos seguintes, cria um contentor do Cloud Storage e altera alguns ficheiros para apontarem para o novo contentor e o seu Google Cloud projeto.