Implementação de Módulos Terraform

LinuxBeginner
Pratique Agora

Introdução

Módulos Terraform são um conceito central em Infraestrutura como Código (IaC) que permitem criar componentes reutilizáveis, configuráveis e organizados. Em vez de escrever o mesmo bloco de código em vários locais, você pode encapsulá-lo em um módulo e chamá-lo sempre que necessário. Essa prática melhora significativamente a manutenibilidade e a consistência do código em seus projetos.

Neste laboratório, você aprenderá os fundamentos da implementação de módulos Terraform. Você começará criando uma estrutura de diretórios de módulo padrão. Em seguida, definirá um módulo simples que cria um arquivo local. Você tornará este módulo configurável usando variáveis e exporá seus resultados usando outputs (saídas). Finalmente, você chamará este módulo a partir da sua configuração Terraform raiz para implantar o recurso.

Ao final deste laboratório, você terá uma compreensão prática de como construir e usar seus próprios módulos Terraform.

Criar o diretório 'modules' na raiz do projeto

Nesta etapa, você criará a estrutura de diretórios padrão para um módulo Terraform local. É uma convenção comum colocar todos os módulos locais dentro de um diretório modules na raiz do seu projeto. Cada subdiretório dentro de modules representa então um módulo único e autônomo.

Primeiro, vamos criar um diretório para nossos módulos e um subdiretório específico para um módulo que chamaremos de localfile_creator. Todas as operações serão realizadas no diretório ~/project.

Execute o seguinte comando para criar a estrutura de diretórios aninhada:

mkdir -p modules/localfile_creator

O flag -p garante que o mkdir crie o diretório pai modules caso ele ainda não exista.

Agora, você pode verificar se os diretórios foram criados corretamente usando o comando tree. Se o tree não estiver instalado, você pode usar ls -R.

tree

Você deverá ver a seguinte saída, confirmando sua nova estrutura de diretórios:

.
└── modules
    └── localfile_creator

2 directories, 0 files

Esta estrutura separa claramente o código do seu módulo reutilizável da configuração raiz que o utilizará.

Criar o arquivo main.tf no módulo para o recurso local_file

Nesta etapa, você criará o arquivo de configuração principal para seu novo módulo. Cada módulo é um projeto Terraform autônomo, portanto, possui seu próprio conjunto de arquivos .tf. O arquivo main.tf é tipicamente onde os recursos centrais do módulo são definidos.

Definiremos um recurso local_file, que faz parte do provedor hashicorp/local. Este recurso é excelente para fins de aprendizado, pois simplesmente gerencia arquivos no sistema de arquivos local sem a necessidade de credenciais de provedor de nuvem.

Primeiro, crie o arquivo main.tf dentro do diretório do seu módulo usando o editor nano:

nano modules/localfile_creator/main.tf

Agora, adicione o seguinte código HCL (HashiCorp Configuration Language) ao arquivo. Este código define um recurso do tipo local_file chamado example.

resource "local_file" "example" {
  content  = "This is a file created by a Terraform module."
  filename = "${path.module}/module_output.txt"
}

Vamos analisar este código:

  • resource "local_file" "example": Isso declara um recurso do tipo local_file e lhe dá um nome local example.
  • content: Este argumento define o conteúdo que será escrito no arquivo.
  • filename: Este argumento especifica o caminho e o nome do arquivo a ser criado. Usamos a variável embutida path.module, que sempre se refere ao caminho do sistema de arquivos do módulo onde a expressão está localizada. Isso torna o caminho do arquivo relativo ao próprio módulo.

Salve o arquivo e saia do nano pressionando Ctrl+X, seguido por Y e, em seguida, Enter.

Definir variáveis e saídas (outputs) do módulo

Nesta etapa, você tornará seu módulo configurável e capaz de retornar informações. Codificar valores como nomes de arquivos e conteúdo limita a reutilização de um módulo. Usaremos variáveis de entrada (input variables) para passar valores personalizados e valores de saída (output values) para expor informações sobre os recursos que o módulo cria.

Por convenção, as variáveis são definidas em um arquivo variables.tf e as saídas em um arquivo outputs.tf.

Primeiro, crie o arquivo variables.tf para o seu módulo:

nano modules/localfile_creator/variables.tf

Adicione o seguinte código para definir duas variáveis de entrada: file_content e file_name.

variable "file_content" {
  description = "The content of the file."
  type        = string
  default     = "Default content."
}

variable "file_name" {
  description = "The name of the file to create."
  type        = string
}

Em seguida, crie o arquivo outputs.tf para declarar quais informações o módulo retornará:

nano modules/localfile_creator/outputs.tf

Adicione o seguinte código para retornar o caminho completo do arquivo criado:

output "filename" {
  description = "The full path to the created file."
  value       = local_file.example.filename
}

Finalmente, você precisa atualizar o main.tf do módulo para usar essas novas variáveis em vez dos valores codificados. Abra o arquivo novamente:

nano modules/localfile_creator/main.tf

Modifique o arquivo para que fique assim. Estamos substituindo as strings codificadas por var.file_content e var.file_name.

resource "local_file" "example" {
  content  = var.file_content
  filename = "${path.module}/${var.file_name}"
}

Salve e saia do editor. Seu módulo agora está flexível e pronto para ser usado com diferentes entradas.

Chamar o módulo no arquivo main.tf raiz

Nesta etapa, você criará um arquivo de configuração raiz que chama o módulo que você acabou de construir. O main.tf raiz é o ponto de entrada para sua execução Terraform. É onde você compõe sua infraestrutura chamando um ou mais módulos.

Você trabalhará agora no diretório raiz do seu projeto, ~/project. Crie um arquivo main.tf aqui:

nano main.tf

Adicione o seguinte código a este arquivo. Esta configuração usará o módulo localfile_creator.

terraform {
  required_providers {
    local = {
      source  = "hashicorp/local"
      version = "2.4.0"
    }
  }
}

module "file_creator_instance" {
  source = "./modules/localfile_creator"

  file_content = "Hello from the root module!"
  file_name    = "my_test_file.txt"
}

output "created_file_path" {
  description = "Path of the file created by the module."
  value       = module.file_creator_instance.filename
}

Vamos analisar esta configuração raiz:

  • terraform { ... }: Este bloco define os requisitos de provedor (provider requirements). Como nosso módulo usa o provedor local, o módulo raiz que o chama também deve declará-lo.
  • module "file_creator_instance" { ... }: Este é o bloco do módulo. file_creator_instance é um nome local para esta instância específica do módulo.
  • source = "./modules/localfile_creator": Isso informa ao Terraform onde encontrar o código-fonte do módulo. Neste caso, é um caminho local.
  • file_content = "..." e file_name = "...": Aqui, você está passando valores para as variáveis de entrada definidas no variables.tf do módulo.
  • output "created_file_path" { ... }: Este bloco de saída (output) de nível raiz recupera um valor do módulo. A sintaxe é module.<NOME_DA_INSTANCIA_DO_MODULO>.<NOME_DA_SAIDA>.

Salve o arquivo e saia do nano. Seu projeto agora está totalmente configurado para usar o módulo.

Executar terraform apply para implantar via módulo

Nesta etapa final, você usará comandos Terraform padrão para inicializar, planejar e aplicar sua configuração. Isso executará o código no seu módulo e criará o arquivo local.

Primeiro, inicialize o diretório de trabalho do Terraform. Este comando baixa os plugins de provedor necessários (neste caso, hashicorp/local).

terraform init

Você deverá ver uma mensagem de sucesso indicando que o Terraform foi inicializado.

Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/local versions matching "2.4.0"...
- Installing hashicorp/local v2.4.0...
- Installed hashicorp/local v2.4.0 (signed by HashiCorp)

Terraform has been successfully initialized!
...

Em seguida, execute terraform plan para ver quais alterações o Terraform fará. Este é um teste (dry run) que não altera nada, mas mostra o plano de execução.

terraform plan

A saída mostrará que um recurso (o local_file dentro do seu módulo) será criado.

...
Plan: 1 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + created_file_path = (known after apply)
...

Agora, aplique a configuração para criar o arquivo. Usaremos a flag -auto-approve para pular o prompt de confirmação interativo.

terraform apply -auto-approve

O Terraform executará o plano e criará o arquivo. A saída confirmará a criação e exibirá o valor de saída que você definiu.

...
module.file_creator_instance.local_file.example: Creating...
module.file_creator_instance.local_file.example: Creation complete after 0s [id=f73598097552a798110a31388c54c1194b539a53]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

created_file_path = "./modules/localfile_creator/my_test_file.txt"

Finalmente, verifique se o arquivo foi criado com o conteúdo correto. Liste os arquivos no diretório do módulo e, em seguida, exiba o conteúdo do novo arquivo.

ls -l modules/localfile_creator/
cat modules/localfile_creator/my_test_file.txt

A saída do comando cat deve ser:

Hello from the root module!

Parabéns, você criou e usou com sucesso um módulo Terraform!

Resumo

Neste laboratório (lab), você aprendeu os fundamentos da criação e uso de módulos Terraform. Você percorreu todo o processo, desde a configuração de uma estrutura de diretórios adequada até a implantação de um recurso por meio de um módulo reutilizável.

Você aprendeu a:

  • Criar uma estrutura de diretórios padrão para módulos locais.
  • Definir recursos no arquivo main.tf de um módulo.
  • Usar variables.tf para tornar seu módulo configurável e reutilizável.
  • Usar outputs.tf para expor dados do seu módulo para a configuração chamadora.
  • Chamar um módulo local a partir de um arquivo main.tf raiz, passando variáveis de entrada e acessando valores de saída.
  • Aplicar a configuração para ver o módulo em ação.

Ao dominar os módulos, você pode escrever Infraestrutura como Código (Infrastructure as Code) mais limpa, organizada e escalável. Parabéns por completar este laboratório!