Guia definitivo: Como gerenciar sua infraestrutura com Terraform
Em meio ao caos que o Corona Vírus tem causado em todo o globo, chegamos ao último post da nossa série de postagens sobre Terraform.
Caso tenha perdido os 5 primeiros posts desta série, recomendo ler para entaão retornar neste ponto:
#parte1 #parte2 #parte3 #parte4 #parte5
Hands-On
De cara já vamos iniciar o post com um preview de como nossa infraestrutura deverá rodar ao final deste post:
Primeira coisa que devemos fazer é destruir toda sua infraestrutura (caso ainda não tenha feito) com o comando:
$ terraform destroy -auto-approve
Crie um novo repositório chamado gcp-networks no GitLab (detalhes foram explicados no post 5) e outro repositório chamado gcp-subnetworks.
Faça o clone dos repositórios.
Repositório gcp-networks.
$ git clone git@gitlab.com:rd-public/blog-blog-tf-modules/4linux/gcp-networks.git
Você receberá mensagem para cada um dos repositórios que está clonando um repositório em branco.
Entre no diretório do gcp-networks e vamos iniciar a criação deste módulo com algumas coisas novas, como o arquivo outputs.tf que será explicado em breve.
Crie o arquivo main.tf:
resource "google_compute_network" "this" { name = var.name description = var.description auto_create_subnetworks = var.auto_create_subnetworks }
Arquivo variables.tf
variable "name" { description = "Nome para sua rede" type = string } variable "description" { description = "Descrição para sua rede" type = string } variable "auto_create_subnetworks" { description = "Redes devem criar automaticamente subredes?" type = bool default = true }
Arquivo outputs.tf
output "gateway_ipv4" { value = google_compute_network.this.gateway_ipv4 } output "self_link" { value = google_compute_network.this.self_link }
O arquivo outputs é responsável por basicamente imprimir no seu terminal a saída do recurso criado, porém ele também é o ponto de ligação quando você precisa fazer o vínculo de um módulo com outro módulo, que é o nosso caso pra ligar instâncias com as redes.
Antes de enviarmos o código para o repositório devemos fazer um teste local para verificar se ele está funcionando corretamente e para isso precisamos primeiro fazer uma outra alteração em nosso módulo que gerencia as instâncias.
Vá até seu módulo que gerencia instâncias e abra o arquivo main.tf alterando para:
resource "google_compute_instance" "this" { count = var.amount name = format("%s-%d", var.name, count.index) machine_type = var.machine_type zone = var.zone boot_disk { initialize_params { image = var.image } } network_interface { network = var.network } }
Altere o arquivo variables.tf adicionando no fim do arquivo mais um bloco para a variável de rede:
variable "network" { description = "Qual rede deseja utilizar" type = string default = "default" }
Abra o arquivo instances.tf (que consome os módulos), adicione a rede e faça o apontamento do módulo de instâncias também para local:
# Instâncias Linux module "network-linux" { source = "./tf-modules/gcp-networks" name = "network-linux" description = "Rede para o grupo de máquinas linux" } module "instances" { source = "./tf-modules/gcp-instances" amount = 2 name = "linux-vm-1" network = module.network-linux.self_link } # Instâncias Web module "network-web" { source = "./tf-modules/gcp-networks" name = "network-web" description = "Rede para o grupo de máquinas web" } module "group-web" { source = "./tf-modules/gcp-instances" amount = 3 name = "linux-web" image = "centos-cloud/centos-8" network = module.network-web.self_link } # Instâncias Gitlab module "network-gitlab" { source = "./tf-modules/gcp-networks" name = "network-gitlab" description = "Rede para o grupo de máquinas gitlab" } module "group-gitlab" { source = "./tf-modules/gcp-instances" amount = 2 name = "linux-gitlab" image = "centos-cloud/centos-7" network = module.network-gitlab.self_link }
Faça a inicialização dos módulos:
$ terraform init
Com a seguinte saída:
Initializing modules... - group-gitlab in ../../tf-modules/gcp-instances - group-web in ../../tf-modules/gcp-instances - instances in ../../tf-modules/gcp-instances - network-gitlab in ../../tf-modules/gcp-networks - network-linux in ../../tf-modules/gcp-networks - network-web in ../../tf-modules/gcp-networks Initializing the backend... ...... ...... ...... ......
Faça o plano de execução e verifique a criação das redes:
...... ...... ...... ...... # module.network-gitlab.google_compute_network.this will be created + resource "google_compute_network" "this" { + auto_create_subnetworks = false + delete_default_routes_on_create = false + description = "Rede para o grupo de máquinas gitlab" + gateway_ipv4 = (known after apply) + id = (known after apply) + ipv4_range = (known after apply) + name = "network-gitlab" + project = (known after apply) + routing_mode = (known after apply) + self_link = (known after apply) } # module.network-linux.google_compute_network.this will be created + resource "google_compute_network" "this" { + auto_create_subnetworks = false + delete_default_routes_on_create = false + description = "Rede para o grupo de máquinas linux" + gateway_ipv4 = (known after apply) + id = (known after apply) + ipv4_range = (known after apply) + name = "network-linux" + project = (known after apply) + routing_mode = (known after apply) + self_link = (known after apply) } # module.network-web.google_compute_network.this will be created + resource "google_compute_network" "this" { + auto_create_subnetworks = false + delete_default_routes_on_create = false + description = "Rede para o grupo de máquinas web" + gateway_ipv4 = (known after apply) + id = (known after apply) + ipv4_range = (known after apply) + name = "network-web" + project = (known after apply) + routing_mode = (known after apply) + self_link = (known after apply) } Plan: 10 to add, 0 to change, 0 to destroy.
Crie esta infraestrutura:
$ terraform apply -auto-approve
Com a saída:
...... ...... ...... ...... ...... module.group-web.google_compute_instance.this[1]: Still creating... [10s elapsed] module.group-web.google_compute_instance.this[0]: Still creating... [10s elapsed] module.group-web.google_compute_instance.this[2]: Creation complete after 10s [id=projects/projeto-1-265222/zones/us-central1-a/instances/linux-web-2] module.group-web.google_compute_instance.this[0]: Creation complete after 10s [id=projects/projeto-1-265222/zones/us-central1-a/instances/linux-web-0] module.group-gitlab.google_compute_instance.this[0]: Still creating... [10s elapsed] module.group-gitlab.google_compute_instance.this[1]: Still creating... [10s elapsed] module.group-web.google_compute_instance.this[1]: Creation complete after 10s [id=projects/projeto-1-265222/zones/us-central1-a/instances/linux-web-1] module.group-gitlab.google_compute_instance.this[1]: Creation complete after 11s [id=projects/projeto-1-265222/zones/us-central1-a/instances/linux-gitlab-1] module.group-gitlab.google_compute_instance.this[0]: Creation complete after 11s [id=projects/projeto-1-265222/zones/us-central1-a/instances/linux-gitlab-0] Apply complete! Resources: 10 added, 0 changed, 3 destroyed.
Okay, tudo funcionando, hora de versionarmos nossos módulos. Primeiro vamos versionar o módulo de instâncias:
Adicione os dois arquivos que foram modificados.
$ git add main.tf variables.tf
Faça o commit das alterações.
$ git commit -m 'Adição de rede para o modulo'
Envie para o repositório:
$ git push origin master
Crie uma nova tag:
$ git tag -a v1.1 -m 'Adição de rede'
Envie a tag para o repositório:
$ git push --tags
Vamos para o módulo de rede e fazer o versionamento.
Adicione os 3 arquivos.
$ git add main.tf variables.tf outputs.tf
Faça o commit:
$ git commit -m 'Envio de módulo'
Envie para o repositório:
$ git push origin master
Crie a primeira tag:
$ git tag -a v1.0 -m 'Versão 1.0 do módulo'
Envie a tag para o repositório:
$ git push --tags
Perfeito! todos os módulos versionados, agora é hora de novamente alterar o arquivo instances.tf para suportar o novo código.
Arquivo instances.tf:
# Instâncias Linux module "network-linux" { source = "git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-networks.git?ref=v1.0" name = "network-linux" description = "Rede para o grupo de máquinas linux" } module "instances" { source = "git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-instances.git?ref=v1.1" amount = 2 name = "linux-vm-1" network = module.network-linux.self_link } # Instâncias Web module "network-web" { source = "git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-networks.git?ref=v1.0" name = "network-web" description = "Rede para o grupo de máquinas web" } module "group-web" { source = "git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-instances.git?ref=v1.1" amount = 3 name = "linux-web" image = "centos-cloud/centos-8" network = module.network-web.self_link } # Instâncias Gitlab module "network-gitlab" { source = "git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-networks.git?ref=v1.0" name = "network-gitlab" description = "Rede para o grupo de máquinas gitlab" } module "group-gitlab" { source = "git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-instances.git?ref=v1.1" amount = 2 name = "linux-gitlab" image = "centos-cloud/centos-7" network = module.network-gitlab.self_link }
Faça a inicialização do Terraform para buscar o novo código:
$ terraform init
Com o resultado:
Initializing modules... Downloading git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-instances.git?ref=v1.1 for group-gitlab... - group-gitlab in .terraform/modules/group-gitlab Downloading git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-instances.git?ref=v1.1 for group-web... - group-web in .terraform/modules/group-web Downloading git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-instances.git?ref=v1.1 for instances... - instances in .terraform/modules/instances Downloading git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-networks.git?ref=v1.0 for network-gitlab... - network-gitlab in .terraform/modules/network-gitlab Downloading git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-networks.git?ref=v1.0 for network-linux... - network-linux in .terraform/modules/network-linux Downloading git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-networks.git?ref=v1.0 for network-web... - network-web in .terraform/modules/network-web ...... ...... ...... ...... ......
Verifique no seu painel do GCP todas instâncias criadas assim como todas redes que foram criadas.
Estas redes estão com o atributo para criar automaticamente subredes. Estas subredes são criadas automaticamente pelo nosso atributo auto_create_subnetworks = var.auto_create_subnetworks onde nossa variável está setada como true.
Nós não queremos que seja gerada automaticamente mas sim gerenciada por nós e pra isso precisamos alterar este atributo na nossa chamada e passar ela para false, mas este atributo podemos agora setar na chamada de nosso módulo e faremos isso em breve.
Por fim, nosso último módulo que irá gerenciar subredes.
Crie um diretório chamado gcp-subnetworks e dentro deste diretório:
Crie um arquivo chamado main.tf com o seguinte conteúdo:
resource "google_compute_subnetwork" "this" { name = var.name ip_cidr_range = var.ip_cidr_range region = var.region network = var.network }
Arquivo variables.tf
variable "name" { type = string description = "Nome para a subrede" } variable "ip_cidr_range" { type = string description = "IP CIDR" } variable "region" { type = string description = "Nome da região que será utilizada" default = "us-central1" } variable "network" { type = string description = "Nome da rede que será conectada com esta subrede" }
Arquivo outputs.tf
output "creation_timestamp" { value = google_compute_subnetwork.this.creation_timestamp } output "gateway_address" { value = google_compute_subnetwork.this.gateway_address } output "self_link" { value = google_compute_subnetwork.this.self_link }
Também devemos criar uma nova versão do nosso módulo que gerencia as instâncias para que passe a suportar as subredes:
Altere o arquivo main.tf e altere o bloco de network de:
network_interface { network = var.network }
para:
network_interface { network = var.network subnetwork = var.subnetwork } Altere também o arquivo variables.tf com um novo bloco no fim do arquivo:
variable "subnetwork" { description = "Qual subrede deseja utilizar" type = string }
Altere o arquivo do instances.tf mais uma vez para fazer o teste local com o novo módulo.
# Instâncias Linux module "network-linux" { source = "git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-networks.git?ref=v1.0" name = "network-linux" description = "Rede para o grupo de máquinas linux" } module "subnetwork-linux" { source = "./tf-modules/gcp-subnetworks" name = "subnetwork-linux" ip_cidr_range = "10.10.1.0/24" network = module.network-linux.self_link } module "instances" { source = "./tf-modules/gcp-instances" amount = 2 name = "linux-vm-1" network = module.network-linux.self_link subnetwork = module.subnetwork-linux.self_link } # Instâncias Web module "network-web" { source = "git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-networks.git?ref=v1.0" name = "network-web" description = "Rede para o grupo de máquinas web" } module "subnetwork-web" { source = "./tf-modules/gcp-subnetworks" name = "subnetwork-web" ip_cidr_range = "10.10.2.0/24" network = module.network-web.self_link } module "group-web" { source = "./tf-modules/gcp-instances" amount = 3 name = "linux-web" image = "centos-cloud/centos-8" network = module.network-web.self_link subnetwork = module.subnetwork-web.self_link } # Instâncias Gitlab module "network-gitlab" { source = "git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-networks.git?ref=v1.0" name = "network-gitlab" description = "Rede para o grupo de máquinas gitlab" } module "subnetwork-gitlab" { source = "./tf-modules/gcp-subnetworks" name = "subnetwork-gitlab" ip_cidr_range = "10.10.3.0/24" network = module.network-gitlab.self_link } module "group-gitlab" { source = "./tf-modules/gcp-instances" amount = 2 name = "linux-gitlab" image = "centos-cloud/centos-7" network = module.network-gitlab.self_link subnetwork = module.subnetwork-gitlab.self_link }
Funcionando? então devemos enviar nosso módulo de instâncias com suas devidas modificações para serem versionadas.
$ git add .
Faça o commit:
$ git commit -m 'Suporte a subredes'
Envie para o repositório:
$ git push origin master
Crie a tag:
$ git tag -a v1.2 -m 'Suporte a subredes'
Envie a tag para o repositório:
$ git push --tags
Agora no novo novo módulo gcp-subnetworks faça o processo de envio de código e crie a tag (processo já é conhecido, certo?)
Finalmente altere o arquivo instances.tf para a versão final.
# Instâncias Linux module "network-linux" { source = "git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-networks.git?ref=v1.0" name = "network-linux" description = "Rede para o grupo de máquinas linux" } module "subnetwork-linux" { source = "git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-subnetworks.git?ref=v1.0" name = "subnetwork-linux" ip_cidr_range = "10.10.1.0/24" network = module.network-linux.self_link } module "instances" { source = "git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-instances.git?ref=v1.2" amount = 2 name = "linux-vm-1" network = module.network-linux.self_link subnetwork = module.subnetwork-linux.self_link } # Instâncias Web module "network-web" { source = "git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-networks.git?ref=v1.0" name = "network-web" description = "Rede para o grupo de máquinas web" } module "subnetwork-web" { source = "git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-subnetworks.git?ref=v1.0" name = "subnetwork-web" ip_cidr_range = "10.10.2.0/24" network = module.network-web.self_link } module "group-web" { source = "git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-instances.git?ref=v1.2" amount = 3 name = "linux-web" image = "centos-cloud/centos-8" network = module.network-web.self_link subnetwork = module.subnetwork-web.self_link } # Instâncias Gitlab module "network-gitlab" { source = "git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-networks.git?ref=v1.0" name = "network-gitlab" description = "Rede para o grupo de máquinas gitlab" } module "subnetwork-gitlab" { source = "git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-subnetworks.git?ref=v1.0" name = "subnetwork-gitlab" ip_cidr_range = "10.10.3.0/24" network = module.network-gitlab.self_link } module "group-gitlab" { source = "git@gitlab.com:rd-public/4linux/blog-tf-modules/gcp-instances.git?ref=v1.2" amount = 2 name = "linux-gitlab" image = "centos-cloud/centos-7" network = module.network-gitlab.self_link subnetwork = module.subnetwork-gitlab.self_link }
Estes módulos estão disponíveis em:
https://gitlab.com/rd-public/4linux/blog-blog-tf-modules/gcp-networks
https://gitlab.com/rd-public/4linux/blog-blog-tf-modules/gcp-subnetworks
É isso aí galera!
Finalizamos aqui nossa série de posts sobre Terraform, agradeço por terem me acompanhado até aqui! Espero que tenham gostado e aproveitado para tirar algumas dúvidas iniciais de como utilizar Terraform e que isso possa servir para estimulá-los à usar essa poderosa ferramenta.
Qualquer dúvida ou sugestão, por favor, me contatem pelo Linkedin.
Sucesso na jornada que irão percorrer para construir sua infraestrutura como código.
Grande abraço!
Líder em Treinamento e serviços de Consultoria, Suporte e Implantação para o mundo open source. Conheça nossas soluções:
About author
Você pode gostar também
Prometheus: A revolução do monitoramento open source em TI
Conheça o Prometheus, ferramenta open source de monitoramento adaptada ao atual modelo de TI focada em serviços e opção aos tradicionais Zabbix/Nagios. Compartilhe este post: Share on X (Twitter) Share
Guia completo para instalar e personalizar o Arch Linux
Introdução Arch Linux é um sistema operacional rolling release baseado em Linux com arquitetura x86_64 ( suportada oficialmente), desenvolvido pelo programador canadense Judd Vinet em 2002, que se inspirou
Descubra como a estratégia DevOps pode transformar sua empresa
DevOps é um termo que tem ganhado destaque no mundo corporativo. Considerado uma poderosa estratégia, surgiu da necessidade de agilizar entregas na área de tecnologia da informação, sempre buscando ações