🇵🇸
Terraform Intensivo
  • Introdução
  • Sumário
    • 1. O que é o Terraform?
    • 2. O state file do Terraform
  • 3. Construindo e Reutilizando Módulos
  • 4. O que é um module source?
  • 5. O uso de for loop no Terraform
Fornecido por GitBook
Nesta página
  • O que é um module source?
  • Tipos de module source
  • Utilizando condicionais no código
  • Utilizando for_each em seu módulo

4. O que é um module source?

O que é um module source?

Um module source é um arquivo que contém um ou mais módulos. Um módulo é um conjunto de funções, classes e variáveis que podem ser importadas e utilizadas em outros arquivos.

Tipos de module source

É possível importar módulos de diversas fontes, como:

Local paths

Normalmente são diretórios locais que contém os módulos. Para importar um módulo de um diretório local, basta informar o caminho do diretório no arquivo que deseja importar o módulo.

module "module_name" {
  source = "./path/to/module"
}

Terraform Registry

No Terraform Registry é possível encontrar módulos prontos para serem utilizados. Para importar um módulo do Terraform Registry, basta informar o nome do módulo no arquivo que deseja importar o módulo.

module "module_name" {
  source = "namespace/module_name/registry"
}

Git repositories

São repositórios Git que contém módulos. Para importar um módulo de um repositório Git, basta informar o URL do repositório no arquivo que deseja importar o módulo.

module "module_name" {
  source = "git@github.com:nataliagranato/terraform-aws-ec2-module.git"
}   

HTTP URLs

São URLs que contém módulos. Para importar um módulo de um URL, basta informar o URL no arquivo que deseja importar o módulo.

module "module_name" {
  source = "https://example.com/path/to/module"
}

S3 buckets

É possível importar módulos de buckets S3. Para importar um módulo de um bucket S3, basta informar o caminho do bucket no arquivo que deseja importar o módulo.

module "module_name" {
  source = "s3::https://s3.amazonaws.com/bucket/path/to/module"
}

Modules in package directories

Por fim é possível importar módulos de diretórios de pacotes. Para importar um módulo de um diretório de pacote, basta informar o caminho do diretório no arquivo que deseja importar o módulo.

module "module_name" {
  source = "package::/path/to/module"
}

Em ambientes de produção, é recomendado utilizar módulos de fontes confiáveis, como o Terraform Registry, para garantir a segurança e a qualidade dos módulos utilizados.

Versionamento semântico

Para garantir a compatibilidade entre os módulos, é recomendado utilizar o versionamento semântico. O versionamento semântico é um padrão de versionamento que define como as versões de um software devem ser incrementadas.

O versionamento semântico é composto por três números, separados por pontos, que representam a versão do software. Os números são incrementados da seguinte forma:

  • O primeiro número representa a versão principal (major). Deve ser incrementado quando são feitas alterações incompatíveis com versões anteriores.

  • O segundo número representa a versão secundária (minor). Deve ser incrementado quando são adicionadas funcionalidades de forma compatível com versões anteriores.

  • O terceiro número representa a versão de correção (patch). Deve ser incrementado quando são feitas correções de bugs de forma compatível com versões anteriores.

Ao utilizar o Github como repositório de módulos, é possível utilizar tags para versionar os módulos. As tags devem seguir o padrão vX.Y.Z, onde X, Y e Z são os números da versão. Por exemplo, a tag v0.1.0 representa a versão 0.1.0 do módulo.

module "aws-ec2" {
  source      = "git@github.com:nataliagranato/terraform-aws-ec2-module.git?ref=v0.1.0"
  nome        = "ec2-teste1"
  region      = "us-east-1"
  environment = "prd"
}

Criando uma release especificando tags, é possível garantir a compatibilidade entre os módulos e evitar problemas de dependências. Além disso, o versionamento semântico facilita a identificação das versões dos módulos e permite que os desenvolvedores saibam exatamente quais versões estão sendo utilizadas em seus projetos, caso você realize alterações em seu módulo, o versionamento garante que os usuários do módulo possam utilizar aquela versão específica, evitando quebras em seus projetos.

Outra forma de versionamento é utilizando o hash do commit, porém, essa forma não é recomendada, pois o hash do commit pode ser alterado a qualquer momento, o que pode causar problemas de compatibilidade entre os módulos. Um exemplo de utilização do hash do commit é:

module "aws-ec2" {
  source      = "git@github.com:nataliagranato/terraform-aws-ec2-module.git?ref=119c58f6a98cf71a1e5195a32f72fc400ecff8ef"
  nome        = "ec2-teste2"
  region      = "us-east-2"
  environment = "dev"
}

Ao executar o comando terraform init, o Terraform irá baixar o módulo especificado no arquivo main.tf e armazená-lo no diretório .terraform. Caso o módulo já tenha sido baixado anteriormente, o Terraform irá verificar se a versão do módulo é a mesma especificada no arquivo main.tf. Se a versão do módulo for diferente, o Terraform irá baixar a versão correta do módulo e substituir a versão antiga.

O output do comando terraform init irá exibir a versão do módulo baixado e o caminho do diretório onde o módulo foi armazenado.

Initializing the backend...

Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.
Initializing modules...
Downloading git::ssh://git@github.com/nataliagranato/terraform-aws-ec2-module.git?ref=v0.1.0 for aws-ec2...

Você pode ver diversos desenvolvedores que utilizam monorepo para armazenar todos os módulos em um único repositório. Um exemplo de utilização de monorepo é:

Modules em subdiretórios
module "aws-ec2" {
  source      = "git@github.com:nataliagranato/terraform-aws-ec2-module.git//modules/instances?ref=main"
  nome        = "ec2-teste2"
  region      = "us-east-2"
  environment = "dev"
}

Utilizando condicionais no código

É possível utilizar condicionais no código para controlar o fluxo de execução do Terraform. As condicionais permitem executar blocos de código com base em condições específicas.

Operadores de comparação

Os operadores de comparação são utilizados para comparar valores e retornar um resultado booleano. Os operadores de comparação mais comuns são:

  • == (igual a): Retorna verdadeiro se os valores comparados forem iguais.

  • != (diferente de): Retorna verdadeiro se os valores comparados forem diferentes.

  • > (maior que): Retorna verdadeiro se o valor da esquerda for maior que o valor da direita.

Um exemplo de condição

resource "aws_instance" "web" {
  count                   = var.environment == "prod" ? 2 : 1
  ami                     = data.aws_ami.ubuntu.id
  instance_type           = "t3.micro"
  disable_api_termination = true
  metadata_options {
    http_tokens = "required"

  }

  root_block_device {
    encrypted = true

  }

  tags = {
    Name       = var.nome
    Env        = var.environment
    Plataforma = data.aws_ami.ubuntu.platform_details
  }
}

A linha count = var.environment == "prod" ? 2 : 1 usa uma expressão condicional para determinar quantas instâncias serão criadas. Se a variável environment for igual a "prod", então count será 2, criando duas instâncias; caso contrário, será 1, criando apenas uma instância. Isso permite flexibilidade na alocação de recursos com base no ambiente de implantação.

Utilizando condicionais com módulos

É possível utilizar condicionais com módulos para controlar a criação de recursos com base em condições específicas. Por exemplo, é possível criar um módulo que cria um recurso apenas se uma variável específica for verdadeira.

# Definição de uma variável para controlar a criação do recurso
variable "criar_recurso" {
  description = "Um booleano que determina se o recurso deve ser criado"
  type        = bool
}

# Módulo condicional
module "meu_recurso_condicional" {
  source = "./caminho/do/modulo"

  count = var.criar_recurso ? 1 : 0

  # Argumentos do módulo aqui
}

# Exemplo de uso do módulo com a variável
# Para criar o recurso, defina a variável criar_recurso como true
# terraform apply -var "criar_recurso=true"

Neste exemplo, o módulo meu_recurso_condicional será criado apenas se a variável criar_recurso for verdadeira. Isso permite controlar a criação de recursos com base em condições específicas, tornando o código mais flexível e reutilizável.

Utilizando for_each em seu módulo

O for_each é uma função que permite iterar sobre uma coleção de valores e criar recursos dinamicamente com base nesses valores. Isso é útil quando você deseja criar vários recursos com base em uma lista de valores.

Um exemplo de uso do for_each

# Definição de uma variável contendo uma lista de valores
variable "instancias" {
  description = "Uma lista de instâncias a serem criadas"
  type        = list(object({
    nome        = string
    environment = string
    region      = string
  }))
  default = [
    {
      nome        = "instancia1"
      environment = "dev"
      region      = "us-east-1"
    },
    {
      nome        = "instancia2"
      environment = "prod"
      region      = "us-west-2"
    },
  ]
}

O código HCL (HashiCorp Configuration Language) abaixo define uma variável no Terraform chamada instancias. Esta variável é usada para armazenar uma lista de objetos, onde cada objeto representa uma instância com atributos específicos. Vamos detalhar cada parte do código:

# Definição de uma variável contendo uma lista de valores
variable "instancias" {
  description = "Uma lista de instâncias a serem criadas"
  type        = list(object({
    nome        = string
    environment = string
    region      = string
  }))
  default = [
    {
      nome        = "instancia1"
      environment = "dev"
      region      = "us-east-1"
    },
    {
      nome        = "instancia2"
      environment = "prod"
      region      = "us-west-2"
    },
  ]
}

Explicação do Código

  • variable "instancias": Declara uma nova variável chamada instancias.

  • description: Fornece uma descrição para a variável, explicando que ela armazena uma lista de instâncias que serão criadas.

  • type: Define o tipo da variável como uma lista (list) de objetos (object). Cada objeto na lista deve seguir uma estrutura específica, que inclui três atributos: nome, environment, e region, todos do tipo string.

  • default: Estabelece um valor padrão para a variável instancias. Neste caso, o valor padrão é uma lista contendo dois objetos, cada um representando uma instância com valores específicos para nome, environment, e region:

    • O primeiro objeto define uma instância chamada instancia1, marcada como um ambiente de desenvolvimento (dev), e localizada na região us-east-1.

    • O segundo objeto define uma instância chamada instancia2, marcada como um ambiente de produção (prod), e localizada na região us-west-2.

Este código facilita a configuração de múltiplas instâncias em diferentes ambientes e regiões, permitindo uma abordagem declarativa e reutilizável para definir recursos no Terraform.

Anterior3. Construindo e Reutilizando MódulosPróximo5. O uso de for loop no Terraform

Atualizado há 2 meses