

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Entendendo os módulos do Terraform
<a name="modules"></a>

No reino da infraestrutura como código (IaC), um *módulo* é um bloco de código independente que é isolado e empacotado para reutilização. O conceito de módulos é um aspecto inevitável do desenvolvimento do Terraform. Para obter mais informações, consulte [Módulos](https://developer.hashicorp.com/terraform/language/modules) na documentação do Terraform. AWS CloudFormation também suporta módulos. Para obter mais informações, consulte [Introdução aos AWS CloudFormation módulos](https://aws.amazon.com/blogs/mt/introducing-aws-cloudformation-modules/) no blog de operações e migrações na AWS nuvem.

A principal diferença entre os módulos no Terraform CloudFormation é que os CloudFormation módulos são importados usando um tipo de recurso especial (`AWS::CloudFormation::ModuleVersion`). No Terraform, cada configuração tem pelo menos um módulo, conhecido como [módulo raiz](https://developer.hashicorp.com/terraform/language/modules#the-root-module). Os recursos do Terraform que estão no arquivo **main.tf** ou arquivos em um arquivo de configuração do Terraform são considerados como estando no módulo raiz. O módulo raiz pode então chamar outros módulos para inclusão na pilha. [O exemplo a seguir mostra um módulo raiz provisionando um cluster do Amazon Elastic Kubernetes Service (Amazon EKS) usando o módulo eks de código aberto.](https://registry.terraform.io/modules/terraform-aws-modules/eks/aws/latest)

```
terraform {
  required_providers {
    helm = {
      source  = "hashicorp/helm"
      version = "2.12.1"
    }
  }
  required_version = ">= 1.2.0"
}

module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "20.2.1"
  vpc_id  = var.vpc_id
}

provider "helm" {
  kubernetes {
    host                   = module.eks.cluster_endpoint
    cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
  }
}
```

Você deve ter notado que o arquivo de configuração acima não inclui o AWS provedor. Isso porque os módulos são independentes e podem incluir seus próprios fornecedores. Como os provedores do Terraform são globais, os provedores de um módulo filho podem ser usados no módulo raiz. No entanto, isso não é verdade para todos os valores do módulo. Outros valores internos em um módulo têm como escopo definido, por padrão, somente esse módulo e precisam ser declarados como saídas para serem acessíveis no módulo raiz. Você pode aproveitar os módulos de código aberto para simplificar a criação de recursos em sua pilha. Por exemplo, o módulo eks faz mais do que provisionar um cluster EKS — ele provisiona um ambiente Kubernetes totalmente funcional. Usá-lo pode evitar que você escreva dezenas de linhas extras de código, desde que a configuração do módulo eks atenda às suas necessidades.

## Módulos de chamada
<a name="calling-modules"></a>

[Dois dos principais comandos da CLI do Terraform que você executa durante a implantação do Terraform [são terraform init e terraform apply](https://developer.hashicorp.com/terraform/cli/commands/init).](https://developer.hashicorp.com/terraform/cli/commands/apply) Uma das etapas padrão que o `terraform init` comando executa é localizar todos os módulos secundários e importá-los como dependências para o `.terraform/modules` diretório. Durante o desenvolvimento, sempre que você adiciona um novo módulo de origem externa, é necessário reinicializar antes de usar o comando. `apply` Quando você ouve uma referência a um *módulo* do Terraform, ela está se referindo aos pacotes nesse diretório. Estritamente falando, o módulo que você declara em seu código é o *módulo de chamada*, então, na prática, a palavra-chave module chama o módulo real, que é armazenado como uma dependência.

Dessa forma, o módulo de chamada serve como um representante mais sucinto do módulo completo a ser substituído quando a implantação ocorrer. Você pode aproveitar essa ideia criando seus próprios módulos em suas pilhas para impor separações lógicas de recursos usando os critérios que desejar. Lembre-se de que o objetivo final de fazer isso deve ser reduzir a complexidade da pilha. Como o compartilhamento de dados entre módulos exige que você produza esses dados de dentro do módulo, às vezes confiar demais nos módulos pode complicar demais as coisas.

## O módulo raiz
<a name="the-root-module"></a>

Como cada configuração do Terraform tem pelo menos um módulo, pode ser útil examinar as propriedades do módulo com o qual você mais lidará: o módulo raiz. Sempre que você estiver trabalhando em um projeto do Terraform, o módulo raiz consiste em todos os `.tf` (ou`.tf.json`) arquivos em seu diretório de nível superior. Quando você executa `terraform apply` nesse diretório de nível superior, o Terraform tenta executar todos os `.tf` arquivos que encontra lá. Todos os arquivos nos subdiretórios são ignorados, a menos que sejam chamados em um desses arquivos de configuração de nível superior.

Isso fornece alguma flexibilidade na forma como você estrutura seu código. Também é por isso que é mais preciso se referir à implantação do Terraform como um módulo do que como um arquivo, pois vários arquivos podem estar envolvidos em um único processo. Há uma [estrutura de módulo padrão](https://developer.hashicorp.com/terraform/language/modules/develop/structure) que o Terraform recomenda para as melhores práticas. No entanto, se você colocasse qualquer `.tf` arquivo em seu diretório de nível superior, ele será executado junto com o resto dos arquivos. Na verdade, todos os `.tf` arquivos de nível superior em um módulo são implantados quando você executa. `terraform apply` Então, qual arquivo o Terraform executa primeiro? A resposta a essa pergunta é muito importante.

Há uma série de etapas que o Terraform executa após a inicialização e antes da implantação da pilha. Primeiro, as configurações existentes são analisadas e, em seguida, um [gráfico de dependências é criado](https://developer.hashicorp.com/terraform/internals/graph). O gráfico de dependências determina quais recursos são necessários e em que ordem eles devem ser tratados. Recursos que contêm propriedades referenciadas em outros recursos, por exemplo, seriam tratados antes dos recursos dependentes. Da mesma forma, os recursos que declaram explicitamente a dependência usando o `depends_on` parâmetro seriam tratados após os recursos que eles especificam. Quando possível, o Terraform pode implementar paralelismo e lidar com recursos não dependentes simultaneamente. Você pode ver o gráfico de dependências antes da implantação usando o comando [terraform](https://developer.hashicorp.com/terraform/cli/commands/graph) graph.

Depois que o gráfico de dependências é criado, o Terraform determina o que precisa ser feito durante a implantação. Ele compara o gráfico de dependências com o arquivo de estado mais recente. O resultado desse processo é chamado de *plano* e é muito parecido com um [conjunto de CloudFormation mudanças](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-changesets-create.html). Você pode ver o plano atual usando o comando [terraform plan](https://developer.hashicorp.com/terraform/cli/commands/plan).

Como prática recomendada, é recomendável ficar o mais próximo possível da estrutura padrão do módulo. Nos casos em que seus arquivos de configuração estão ficando muito longos para serem gerenciados com eficiência e as separações lógicas podem simplificar o gerenciamento, você pode distribuir seu código em vários arquivos. Lembre-se de como o gráfico de dependências e o processo de planejamento funcionam para que suas pilhas funcionem da forma mais eficiente possível.