Utilizando módulos com outros módulos
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 e outro repositório chamado gcp-subnetworks
.
Faça o clone dos repositórios.
$ 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: