O que são módulos Terraform e como eles funcionam?

O que são módulos Terraform e como eles funcionam?

9 de September, 2020 0 By António César de Andrade
Click to rate this post!
[Total: 0 Average: 0]


Surpreendentemente, muitos iniciantes pulam os módulos do Terraform por uma questão de simplicidade, ou assim eles pensam.

Mais tarde, eles se veem passando por centenas de linhas de código de configuração.

Presumo que você já conheça algumas noções básicas sobre o Terraform e até já tenha tentado usá-lo antes. Se não, verifique este visão geral do Terraform e isto vídeo tutorial antes de continuar lendo.

Observação: eu não uso exemplos de código reais com algum provedor específico como AWS ou Google intencionalmente, apenas por uma questão de simplicidade.

Módulos Terraform

Você já escreve módulos

Mesmo quando você não cria um módulo intencionalmente, se você usa o Terraform, já está escrevendo um módulo – o chamado “raiz“módulo.

Qualquer arquivo de configuração Terraform (.tf) em um diretório, mesmo que seja apenas um, forma um módulo.

O que um módulo faz?

Um módulo Terraform permite que você crie uma abstração lógica no topo de algum conjunto de recursos. Em outras palavras, um módulo permite agrupar recursos e reutilizar esse grupo posteriormente, possivelmente muitas vezes.

Vamos supor que temos um servidor virtual com alguns recursos hospedados na nuvem. Que conjunto de recursos pode descrever esse servidor? Por exemplo:

  • a própria máquina virtual, criada a partir de alguma imagem
  • um dispositivo de bloco anexado de um tamanho especificado para armazenamento adicional
  • um IP público estático mapeado para a interface de rede virtual do servidor
  • um conjunto de regras de firewall a serem anexadas ao servidor
  • outras coisas como outro dispositivo de bloco, interface de rede adicional e assim por diante

Agora vamos supor que você precise criar esse servidor com um conjunto de recursos muitas vezes. É aqui que os módulos são realmente úteis – você não quer repetir o mesmo código de configuração indefinidamente, quer?

Aqui está um exemplo que ilustra como nosso módulo “servidor” pode ser chamado.
Para chamar um módulo“significa usá-lo no arquivo de configuração.

Aqui, criamos 5 instâncias do “servidor” usando um único conjunto de configurações (no módulo):

module "server" {
    
    count         = 5
    
    source        = "./module_server"
    some_variable = some_value
}
Terraform suporta “contagem” para módulos a partir da versão 0.13

Organização do módulo: filho e raiz

Claro, você provavelmente desejaria criar mais de um módulo. Aqui estão alguns exemplos comuns:

  • uma rede como uma nuvem privada virtual (VPC)
  • hospedagem de conteúdo estático (ou seja, buckets)
  • um balanceador de carga e seus recursos relacionados
  • uma configuração de registro
  • ou qualquer outra coisa que você considere um componente lógico distinto da infraestrutura

Digamos que temos dois módulos diferentes: um módulo de “servidor” e um módulo de “rede”. O módulo chamado “rede” é onde definimos e configuramos nossa rede virtual e colocamos os servidores nela:

module "server" {
    source        = "./module_server"
    some_variable = some_value
}

module "network" {  
    source              = "./module_network"
    some_other_variable = some_other_value
}
Dois módulos filhos diferentes chamados no módulo raiz

Assim que tivermos alguns módulos personalizados, podemos nos referir a eles como módulos “filhos”. E o arquivo de configuração onde chamamos de módulos filhos está relacionado ao módulo raiz.

Um módulo filho pode ser obtido de vários lugares:

  • caminhos locais
  • o Terraform Registry oficial – se você está familiarizado com outros registros como o Docker Registry, então você já entendeu a ideia
  • um repositório Git (personalizado ou GitHub / BitBucket)
  • um URL HTTP para um arquivo .zip com o módulo

Mas como você pode passar detalhes de recursos entre módulos?

Em nosso exemplo, os servidores devem ser criados em uma rede. Então, como podemos dizer ao módulo “servidor” para criar VMs em uma rede que foi criada em um módulo chamado “rede”?

Aqui é onde encapsulamento entra.

Encapsulamento de módulo

O encapsulamento no Terraform consiste em dois conceitos básicos: escopo do módulo e exposição explícita de recursos.

Escopo do Módulo

Todas as instâncias de recursos, nomes e, portanto, visibilidade de recursos são isolados no escopo de um módulo. Por exemplo, o módulo “A” não pode ver e não conhece os recursos do módulo “B” por padrão.

A visibilidade do recurso, às vezes chamada de isolamento de recurso, garante que os recursos terão nomes exclusivos dentro do namespace de um módulo. Por exemplo, com nossas 5 instâncias do módulo “servidor”:

module.server[0].resource_type.resource_name
module.server[1].resource_type.resource_name
module.server[2].resource_type.resource_name
...
Endereços de recurso de módulo criados com o meta-argumento de contagem

Por outro lado, poderíamos criar duas instâncias do mesmo módulo com nomes diferentes:

module "server-alpha" {    
    source        = "./module_server"
    some_variable = some_value
}
module "server-beta" {
    source        = "./module_server"
    some_variable = some_value
}
Preste atenção ao argumento de origem – ele permanece o mesmo, é o mesmo módulo de origem

Nesse caso, a nomenclatura ou endereço dos recursos seria a seguinte:

module.server-alpha.resource_type.resource_name

module.server-beta.resource_type.resource_name

Exposição explícita de recursos

Se você deseja acessar alguns detalhes para os recursos em outro módulo, você precisará configurar isso explicitamente.

Por padrão, nosso módulo “servidor” não conhece a rede que foi criada no módulo “rede”.

Portanto, devemos declarar um output valor no módulo “rede” para exportar seu recurso, ou um atributo de um recurso, para outros módulos.

O módulo “servidor” deve declarar um variable para ser usado posteriormente como entrada:

Os nomes output e variable pode ser diferente, mas sugiro usar os mesmos nomes para maior clareza.

Esta declaração explícita da saída é a maneira de expor algum recurso (ou informação sobre ele) fora – para o escopo do módulo ‘raiz’, portanto, para torná-lo disponível para outros módulos.

Em seguida, quando chamamos o módulo filho de “servidor” no módulo raiz, devemos atribuir a saída do módulo “rede” à variável do módulo “servidor”:

network_id = module.network.network_id
Preste atenção ao endereço de saída ‘network_id’ aqui – dizemos explicitamente onde ele reside

Aqui está a aparência do código final para chamar nossos módulos filhos:

module "server" {
    count         = 5
    source        = "./module_server"
    some_variable = some_value
    network_id    = module.network.network_id
}

module "network" {  
    source              = "./module_network"
    some_other_variable = some_other_value
}

Esta configuração de exemplo criaria 5 instâncias do mesmo servidor, com todos os recursos necessários, na rede que criamos como um módulo separado.

Empacotando

Agora você deve entender o que são módulos e o que eles fazem.

Se você está no início de sua jornada do Terraform, aqui estão algumas sugestões para as próximas etapas.

Eu encorajo você a fazer este breve tutorial da HashiCorp, os criadores do Terraform, sobre módulos: “Organizar configuração

Além disso, há um excelente guia de estudo abrangente que cobre tudo, desde conceitos básicos a avançados sobre o Terraform: “Guia de estudo – Certificação de Associado do Terraform

A estrutura de código modular torna sua configuração mais flexível e fácil de ser entendida por outras pessoas. Este último é especialmente útil para uma equipe.

Se você gostou do artigo, siga-me no Twitter (@vasylenko) onde ocasionalmente compartilho minhas descobertas e dicas sobre Terraform, AWS, Ansible e outras tecnologias relacionadas ao DevOps.





Fonte