O autor selecionou o Fundo Livre e de Código Aberto para receber uma doação como parte do programa Escreva por Doações.
Introdução
Módulos do Terraform permitem que você agrupe recursos distintos de sua infraestrutura em um único recurso unificado. Você pode reutilizá-los posteriormente com personalizações possíveis, sem repetir as definições de recursos toda vez que precisar deles, o que é benéfico para projetos grandes e estruturados de forma complexa. Você pode personalizar instâncias de módulos usando variáveis de entrada que você define, bem como extrair informações deles usando saídas. Além de criar seus próprios módulos personalizados, você também pode usar os módulos pré-fabricados publicados publicamente no Registro do Terraform. Desenvolvedores podem usá-los e personalizá-los usando entradas como os módulos que você cria, mas seu código-fonte é armazenado e puxado da nuvem.
Neste tutorial, você criará um módulo Terraform que configurará múltiplos Droplets atrás de um Balanceador de Carga para redundância. Você também usará os recursos de looping for_each
e count
da Linguagem de Configuração HashiCorp (HCL) para implantar múltiplas instâncias personalizadas do módulo ao mesmo tempo.
Pré-requisitos
- A DigitalOcean Personal Access Token, which you can create via the DigitalOcean control panel. You can find instructions in the DigitalOcean product document, How to Create a Personal Access Token.
- Terraform instalado na sua máquina local e um projeto configurado com o provedor DO. Conclua o Passo 1 e o Passo 2 do tutorial Como Usar o Terraform com DigitalOcean, e certifique-se de nomear a pasta do projeto como
terraform-modules
, em vez deloadbalance
. Durante o Passo 2, não inclua a variávelpvt_key
e o recurso de chave SSH. - Familiaridade com os tipos de dados e loops do HCL. Para mais informações, consulte o tutorial Como Melhorar a Flexibilidade Usando Variáveis, Dependências e Condições no Terraform.
- Familiaridade com as saídas do Terraform e seu uso. Você pode seguir o tutorial Como Gerenciar Dados de Infraestrutura com as Saídas do Terraform para aprender sobre elas.
Observação: Este tutorial foi especificamente testado com o Terraform 1.1.3
.
Estrutura e Benefícios do Módulo
Nesta seção, você aprenderá quais são os benefícios dos módulos, onde eles costumam ser colocados no projeto e como devem ser estruturados.
Os módulos personalizados do Terraform são criados para encapsular componentes conectados que são usados e implantados juntos com frequência em projetos maiores. Eles são autocontidos, agrupando apenas os recursos, variáveis e provedores de que precisam.
Os módulos geralmente são armazenados em uma pasta central na raiz do projeto, cada um em sua subpasta respectiva abaixo. Para manter uma separação limpa entre os módulos, sempre os arquitete de forma a terem um único propósito e certifique-se de que nunca contenham submódulos.
É útil criar módulos a partir de seus esquemas de recursos quando você se vê repetindo-os com customizações infrequentes. Empacotar um único recurso como um módulo pode ser supérfluo e gradualmente remover a simplicidade da arquitetura geral.
Para pequenos projetos de desenvolvimento e teste, incorporar módulos não é necessário porque eles não trazem muita melhoria nesses casos. Com sua capacidade de personalização, os módulos são o elemento de construção de projetos complexamente estruturados. Os desenvolvedores usam módulos para projetos maiores devido às vantagens significativas em evitar a duplicação de código. Os módulos também oferecem o benefício de que as definições só precisam ser modificadas em um único local, o que será então propagado pelo restante da infraestrutura.
A seguir, você definirá, usará e personalizará módulos em seus projetos Terraform.
Criando um Módulo
Nesta seção, você definirá múltiplos Droplets e um Balanceador de Carga como recursos do Terraform e os empacotará em um módulo. Você também tornará o módulo resultante personalizável usando entradas de módulo.
Você armazenará o módulo em um diretório chamado droplet-lb
, sob um diretório chamado módulos
. Supondo que você esteja no diretório terraform-modules
que você criou como parte dos pré-requisitos, crie ambos de uma vez executando:
O argumento -p
instrui o mkdir
a criar todos os diretórios no caminho fornecido.
Navegue até ele:
Como foi observado na seção anterior, os módulos contêm os recursos e variáveis que eles usam. A partir do Terraform 0.13
, eles também devem incluir definições dos provedores que utilizam. Módulos não requerem nenhuma configuração especial para observar que o código representa um módulo, pois o Terraform considera cada diretório contendo código HCL como um módulo, até mesmo o diretório raiz do projeto.
As variáveis definidas em um módulo são expostas como suas entradas e podem ser usadas em definições de recursos para personalizá-los. O módulo que você criará terá duas entradas: o número de Droplets a serem criados e o nome de seu grupo. Crie e abra para edição um arquivo chamado variables.tf
onde você armazenará as variáveis:
Adicione as seguintes linhas:
Salve e feche o arquivo.
Você irá armazenar a definição do Droplet em um arquivo chamado droplets.tf
. Crie e abra-o para edição:
Adicione as seguintes linhas:
Para o parâmetro count
, que especifica quantas instâncias de um recurso criar, você passa a variável droplet_count
. Seu valor será especificado quando o módulo for chamado a partir do código do projeto principal. O nome de cada um dos Droplets implantados será diferente, o que você alcança anexando o índice do Droplet atual ao nome do grupo fornecido. O deployment dos Droplets será na região fra1
e eles serão executados no Ubuntu 20.04.
Quando terminar, salve e feche o arquivo.
Com os Droplets agora definidos, você pode prosseguir para a criação do Balanceador de Carga. Você irá armazenar a definição de recurso dele em um arquivo chamado lb.tf
. Crie e abra-o para edição executando:
Adicione a definição do recurso:
Você define o Balanceador de Carga com o nome do grupo em seu nome para torná-lo distinguível. Você o implanta na região fra1
junto com os Droplets. As duas seções seguintes especificam as portas e protocolos de destino e monitoramento.
O bloco droplet_ids
destacado recebe os IDs dos Droplets, que devem ser gerenciados pelo Balanceador de Carga. Como existem vários Droplets, e sua quantidade não é conhecida antecipadamente, você usa um loop for
para percorrer a coleção de Droplets (digitalocean_droplet.droplets
) e obter seus IDs. Você envolve o loop for
com colchetes ([]
) para que a coleção resultante seja uma lista.
Salve e feche o arquivo.
Agora você definiu o Droplet, o Balanceador de Carga e as variáveis para o seu módulo. Você precisará definir os requisitos do provedor, especificando quais provedores o módulo utiliza, incluindo sua versão e onde estão localizados. Desde o Terraform 0.13
, os módulos devem definir explicitamente as fontes dos provedores não mantidos pela HashiCorp que eles utilizam; isso ocorre porque eles não os herdam do projeto pai.
Você irá armazenar os requisitos do provedor em um arquivo chamado provider.tf
. Crie-o para edição executando:
Adicione as seguintes linhas para requerer o provedor digitalocean
:
Salve e feche o arquivo quando terminar. O módulo droplet-lb
agora requer o provedor digitalocean
.
Os módulos também suportam saídas, que você pode usar para extrair informações internas sobre o estado de seus recursos. Você definirá uma saída que expõe o endereço IP do Balanceador de Carga e a armazenará em um arquivo chamado outputs.tf
. Crie-o para edição:
Adicione a seguinte definição:
Esta saída recupera o endereço IP do Balanceador de Carga. Salve e feche o arquivo.
O módulo droplet-lb
está agora funcionalmente completo e pronto para implantação. Você irá chamá-lo a partir do código principal, que você irá armazenar na raiz do projeto. Primeiro, navegue até lá indo para cima através do diretório do arquivo duas vezes:
Em seguida, crie e abra para edição um arquivo chamado main.tf
, no qual você irá usar o módulo:
Adicione as seguintes linhas:
Nesta declaração, você invoca o módulo droplet-lb
localizado no diretório especificado como source
. Você configura a entrada que ele fornece, droplet_count
e group_name
, que é definido como group1
para que você possa distinguir entre as instâncias mais tarde.
Como a saída do IP do Balanceador de Carga é definida em um módulo, ela não será mostrada automaticamente quando você aplicar o projeto. A solução para isso é criar outra saída recuperando seu valor (loadbalancer_ip
).
Salve e feche o arquivo quando terminar.
Inicialize o módulo executando:
A saída será semelhante a esta:
OutputInitializing modules...
- groups in modules/droplet-lb
Initializing the backend...
Initializing provider plugins...
- Finding digitalocean/digitalocean versions matching "~> 2.0"...
- Installing digitalocean/digitalocean v2.19.0...
- Installed digitalocean/digitalocean v2.19.0 (signed by a HashiCorp partner, key ID F82037E524B9C0E8)
...
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
Você pode tentar planejar o projeto para ver quais ações o Terraform tomaria executando:
A saída será semelhante a esta:
Este output detalha que o Terraform criaria três Droplets, nomeados group1-0
, group1-1
e group1-2
, e também criaria um Balanceador de Carga chamado group1-lb
, que gerenciará o tráfego de e para os três Droplets.
Você pode tentar aplicar o projeto na nuvem executando:
Digite yes
quando solicitado. O output mostrará todas as ações e o endereço IP do Balanceador de Carga também será mostrado:
Você criou um módulo contendo um número personalizável de Droplets e um Balanceador de Carga que será automaticamente configurado para gerenciar o tráfego de entrada e saída deles.
Renomeando Recursos Implentados
Na seção anterior, você implantou o módulo que definiu e o chamou de groups
. Se você deseja alterar seu nome, simplesmente renomear a chamada do módulo não produzirá os resultados esperados. Renomear a chamada fará com que o Terraform destrua e recrie os recursos, causando tempo de inatividade excessivo.
Por exemplo, abra main.tf
para edição executando:
Renomeie o módulo groups
para groups_renamed
, conforme destacado:
Salve e feche o arquivo. Em seguida, inicialize o projeto novamente:
Agora você pode planejar o projeto:
A saída será longa, mas parecerá semelhante a isto:
Output...
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
- destroy
Terraform will perform the following actions:
# module.groups.digitalocean_droplet.droplets[0] será destruído
...
# module.groups_renamed.digitalocean_droplet.droplets[0] será criado
...
O Terraform solicitará que você destrua as instâncias existentes e crie novas. Isso é destrutivo e desnecessário, e pode resultar em tempo de inatividade indesejado.
Em vez disso, usando o bloco moved
, você pode instruir o Terraform a mover os recursos antigos sob o novo nome. Abra main.tf
para edição e adicione as seguintes linhas ao final do arquivo:
Quando terminar, salve e feche o arquivo.
Agora você pode planejar o projeto:
Ao planejar com o bloco moved
presente em main.tf
, o Terraform quer mover os recursos, em vez de recriá-los:
OutputTerraform will perform the following actions:
# O módulo .groups.digitalocean_droplet.droplets[0] foi movido para .groups_renamed.digitalocean_droplet.droplets[0]
...
# O módulo .groups.digitalocean_droplet.droplets[1] foi movido para .groups_renamed.digitalocean_droplet.droplets[1]
...
A movimentação de recursos altera sua posição no estado do Terraform, o que significa que os recursos reais na nuvem não serão modificados, destruídos ou recriados.
Como você modificará significativamente a configuração no próximo passo, destrua os recursos implantados executando:
Digite sim
quando solicitado. A saída terminará em:
Output...
Destroy complete! Resources: 4 destroyed.
Nesta seção, você renomeou recursos em seu projeto Terraform sem destruí-los no processo. Agora, você implantará várias instâncias de um módulo a partir do mesmo código usando for_each
e count
.
Implantando Múltiplas Instâncias de Módulo
Nesta seção, você usará count
e for_each
para implantar o módulo droplet-lb
várias vezes com personalizações.
Usando count
Uma maneira de implantar várias instâncias do mesmo módulo de uma vez é passar o número para o parâmetro count
, que está automaticamente disponível para cada módulo. Abra main.tf
para edição:
Modifique-o para se parecer com isso, removendo a definição de saída existente e o bloco moved
:
Ao definir count
como 3
, você instrui o Terraform a implantar o módulo três vezes, cada um com um nome de grupo diferente. Quando terminar, salve e feche o arquivo.
Planeje a implantação executando:
A saída será longa e parecerá com isso:
Detalhes do Terraform na saída que cada uma das três instâncias do módulo teria três Droplets e um Balanceador de Carga associado a elas.
Usando for_each
Você pode usar for_each
para módulos quando você necessita de uma personalização mais complexa da instância, ou quando o número de instâncias depende de dados de terceiros (frequentemente apresentados como mapas) que não são conhecidos durante a escrita do código.
Agora você vai definir um mapa que associa nomes de grupos a contagens de Droplets e implantar instâncias de droplet-lb
de acordo com ele. Abra o arquivo main.tf
para edição executando:
Modifique o arquivo para ficar assim:
Primeiro, você define um mapa chamado group_counts
que contém quantos Droplets um determinado grupo deve ter. Então, você invoca o módulo droplet-lb
, mas especifica que o loop for_each
deve operar em var.group_counts
, o mapa que você definiu logo antes. droplet_count
recebe each.value
, o valor do par atual, que é a contagem de Droplets para o grupo atual. group_name
recebe o nome do grupo.
Salve e feche o arquivo quando terminar.
Tente aplicar a configuração executando:
A saída detalhará as ações que o Terraform executaria para criar os dois grupos com seus Droplets e Balanceadores de Carga:
Neste passo, você utilizou count
e for_each
para implantar várias instâncias personalizadas do mesmo módulo a partir do mesmo código central.
Conclusão
Neste tutorial, você criou e implantou módulos do Terraform. Você utilizou módulos para agrupar recursos logicamente vinculados e personalizou-os para implantar várias instâncias diferentes a partir de uma definição de código central. Você também utilizou saídas para mostrar atributos dos recursos contidos no módulo.
Se você gostaria de aprender mais sobre o Terraform, confira nossa série Como Gerenciar Infraestrutura com Terraform.
Source:
https://www.digitalocean.com/community/tutorials/how-to-build-a-custom-terraform-module