Introdução
A estruturação apropriada de projetos Terraform de acordo com os casos de uso e a complexidade percebida é fundamental para garantir sua manutenibilidade e extensibilidade nas operações diárias. Uma abordagem sistemática para a organização adequada de arquivos de código é necessária para garantir que o projeto permaneça escalável durante a implantação e útil para você e sua equipe.
Neste tutorial, você aprenderá a estruturar projetos Terraform de acordo com seu propósito geral e complexidade. Em seguida, você criará um projeto com uma estrutura simples usando as funcionalidades mais comuns do Terraform: variáveis, locais, fontes de dados e fornecedores. No final, seu projeto implantará um servidor Ubuntu 20.04 (Droplet) no DigitalOcean, instalará um servidor web Apache e apontará seu domínio para o servidor web.
Pré-requisitos
-
Um token de acesso pessoal do DigitalOcean, que você pode criar através do painel de controle do DigitalOcean. Você pode encontrar instruções no documento do produto do DigitalOcean, Como Criar um Token de Acesso Pessoal.
-
Uma chave SSH sem senha adicionada à sua conta DigitalOceano, que você pode criar seguindo as instruções de Como Usar Chaves SSH com Dropletse DigitalOcean.
-
Terraform instalado na máquina local. Para instruções de acordo com o sistema operativo, veja Passo 1 do tutorial Como Usar Terraform com DigitalOcean.
-
Python 3 instalado no seu computador local. Você pode concluir Step 1 de Como Instalar e Configurar um Ambiente de Programação Local para Python 3 para o seu Sistema Operacional.
-
Um nome de domínio totalmente registrado adicionado à sua conta do DigitalOcean. Para instruções sobre como fazer isso, visite as documentações oficiais.
Nota: Este tutorial foi testado especificamente com Terraform 1.0.2
.
Compreensão da Estrutura de um Projeto Terraform
Neste seção, você aprenderá o que o Terraform considera um projeto, como organizar o código da infraestrutura e quando escolher uma determinada abordagem. Você também aprenderá sobre espaços de trabalho do Terraform, o que eles fazem e como o Terraform está armazenando estado.
Um recurso é uma entidade de um serviço na nuvem (como um Droploan DigitalOcean) declarada no código do Terraform que é criada conforme propriedades especificadas e inferidas. Múltiplos recursos formam infraestrutura com suas conexões mutuais. Vários recursos formam infraestrutura com suas conexões mutuais.
O Terraform usa uma linguagem de programação especializada para definir infraestrutura, chamada de Linguagem de Configuração Hashicorp (HCL). O código HCL é usualmente armazenado em arquivos com extensão tf
. Um projeto do Terraform é qualquer diretório que contém arquivos tf
e que foi inicializado usando o comando init
, o qual estabelece cache e estado local padrão.
O Terraform estado é o mecanismo por meio do qual ele manteve rastreio das instâncias realmente deployadas na nuvem. O estado é armazenado em backends (localmente no disco ou remotamente em um serviço de armazenamento de arquivos na nuvem ou software especializado em gerenciamento de estado). Você pode levar mais tempo lendo sobre diferentes backends na documentação do Terraform.
Projetos de espaços de trabalho permitem que você tenha múltiplas estratégias em uma mesma configuração de back-end, ligadas à mesma configuração. Isso permite que você deploy multiple instâncias distintas da mesma infraestrutura. Cada projeto começa com um espaço de trabalho chamado default
. Este será usado se você não criar ou mudar para outro explicitamente.
Módulos em Terraform (semelhantes a bibliotecas em outras linguagens de programação) são containers de código parametrizados que envolvem declarações de recursos múltiplos. Elas permitem abstrair parte comum da sua infraestrutura e reusá-la mais tarde com entradas diferentes.
Um projeto Terraform também pode incluir arquivos de código externos para uso com entradas dinamicas, que podem interpretar o output JSON de um comando de linha de comandos e oferecer para uso nas declarações de recursos. Neste tutorial, você faz isso com um script Python.
Após saber o que constitui um projeto Terraform, vamos revisar duas abordagens gerais para estruturar projetos.
Estrutura Simples
Uma estrutura simples é adequada para pequenos projetos e de teste, com alguns recursos de tipos variados e variáveis. Possui alguns arquivos de configuração, geralmente um por tipo de recurso (ou mais arquivos auxiliares juntamente com um principal) e nenhum módulo personalizado, pois a maioria dos recursos são únicos e não há suficientes para serem generalizados e reutilizados. Seguindo isso, a maioria do código é armazenada no mesmo diretório, um ao lado do outro. Esses projetos frequentemente têm algumas variáveis (como uma chave de API para acessar a nuvem) e podem usar entradas de dados dinâmicas e outros recursos do Terraform e HCL, embora não de maneira prominente.
Como exemplo da estrutura de arquivos dessa abordagem, é assim que o projeto que você construirá neste tutorial ficará no final:
.
└── tf/
├── versions.tf
├── variables.tf
├── provider.tf
├── droplets.tf
├── dns.tf
├── data-sources.tf
└── external/
└── name-generator.py
Como este projeto déploiará um Droplet de servidor web Apache e configurará registros DNS, as definições de variáveis do projeto, o provedor Terraform do DigitalOcean, o Droplet e os registros DNS serão armazenados em seus respectivos arquivos. As versões mínimas necessárias do Terraform e do provedor DigitalOcean serão especificadas em versions.tf
, enquanto o script Python que gerará um nome para o Droplet (e será usado como fonte de dados dinâmica em data-sources.tf
) será armazenado na pasta external
, para separá-lo do código HCL.
Estrutura Complexa
Contrário à estrutura simples, este método é apropriado para projetos grandes, com estruturas de subdiretórios claramente definidas contendo múltiplos módulos de diferentes níveis de complexidade, além do código usual. esses módulos podem depender uns dos outros. Com o uso de sistemas de controle de versão, esses projetos podem fazer uso extensivo de ambientes de trabalho. Este método é adequado a projetos maiores que gerenciam várias aplicações, reutilizando o código tanto quanto possível.
Instâncias de infraestrutura de desenvolvimento, produção, validação de qualidade e produção também podem ser hospedadas no mesmo projeto em diretórios diferentes, com base em módulos comuns, eliminando assim código duplicado e tornando o projeto a fonte central de verdade. Aqui está a estrutura de arquivo de um exemplo de projeto com uma estrutura mais complexa, contendo múltiplas aplicações de implantação, módulos Terraform e ambientes cloud alvo:
.
└── tf/
├── modules/
│ ├── network/
│ │ ├── main.tf
│ │ ├── dns.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ └── spaces/
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
└── applications/
├── backend-app/
│ ├── env/
│ │ ├── dev.tfvars
│ │ ├── staging.tfvars
│ │ ├── qa.tfvars
│ │ └── production.tfvars
│ └── main.tf
└── frontend-app/
├── env/
│ ├── dev.tfvars
│ ├── staging.tfvars
│ ├── qa.tfvars
│ └── production.tfvars
└── main.tf
Este método é explorado em mais detalhe na série Como Gerenciar Infraestrutura com Terraform.
Você agora sabe o que é um projeto Terraform, como melhor structurá-lo de acordo com a complexidade percebida e qual papel servem os ambientes de trabalho Terraform. Nas próximas etapas, você criará um projeto com uma estrutura simples que provisionará um Droplet com um servidor web Apache instalado e registros DNS configurados para seu domínio. Você começará criando seu projeto com o fornecedor DigitalOcean e variáveis, e em seguida, definirá o Droplet, um provedor de dados dinâmico para fornecer seu nome e um registro DNS para a implantação.
Passo 1 — Configurando seu Projeto Inicial
Nesta seção, você adicionará o provedor DigitalOcean Terraform ao seu projeto, definirá as variáveis do projeto e declarará uma instância do provedor DigitalOcean, para que o Terraform possa se conectar à sua conta.
Comece criando um diretório para seu projeto Terraform com o seguinte comando:
Navegue até ele:
Como este projeto seguirá a abordagem de estruturação simples, você armazenará o provedor, variáveis, Droplet e o código do registro DNS em arquivos separados, conforme a estrutura de arquivos da seção anterior. Primeiro, você precisará adicionar o provedor DigitalOcean Terraform ao seu projeto como um provedor necessário.
Crie um arquivo chamado versions.tf
e abra-o para edição executando:
Adicione as seguintes linhas:
Neste bloco terraform
, você lista os provedores necessários (DigitalOcean, versão 2.x
). Quando terminar, salve e feche o arquivo.
Então, defina as variáveis que seu projeto exibirá no arquivo variables.tf
, seguindo a abordagem de armazenar diferentes tipos de recursos em arquivos de código separados:
Adicione as seguintes variáveis:
Salve e feche o arquivo.
A variável do_token
手臂 o seu Token de Acesso Pessoal da DigitalOcean e domain_name
especificará o nome de domínio desejado. O Droplet implantado terá a chave SSH, identificada pelo impressão digital SSH, instalada automaticamente.
Agora, vamos definir a instância do provedor DigitalOcean para este projeto. Você a armazenará em um arquivo chamado provider.tf
. Crie e abra-o para edição executando:
Adicione o provedor:
Salve e saia quando terminar. Você definiu o provedor digitalocean
, que corresponde ao provedor necessário que você especificou anteriormente em provider.tf
, e definiu seu token para o valor da variável, que será fornecido durante a execução.
Nesta etapa, você criou um diretório para o seu projeto, solicitou que o provedor DigitalOcean fosse disponibilizado, declarou variáveis de projeto e configurou a conexão a uma instância do provedor DigitalOcean para usar um token de autenticação que será fornecido mais tarde. Agora, você escreverá um script que gerará dados dinâmicos para suas definições de projeto.
Passo 2 — Criando um Script Python para Dados Dinâmicos
Antes de continuar para definir o Droplet, você criará um script Python que gerará o nome do Droplet dinamicamente e declarará um recurso de fonte de dados para analisá-lo. O nome será gerado concatenando uma string constante (web
) com a hora atual da máquina local, expressa no formato UNIX epoch. Um script de nomenclatura pode ser útil quando múltiplos Droplets são gerados de acordo com um esquema de nomenclatura, a fim de diferenciá-los facilmente.
Você armazenará o script em um arquivo chamado name-generator.py
, em um diretório chamado external
. Primeiro, crie o diretório executando:
O diretório external
reside na raiz do seu projeto e armazenará arquivos de código não-HCL, como o script Python que você escreverá.
Crie o name-generator.py
sob external
e abra-o para edição:
Adicione o seguinte código:
Este script Python importa os módulos json
e time
, declara um dicionário chamado result
e define o valor da chave name
como uma string interpolada, que combina o fixed_name
com a hora UNIX atual da máquina na qual ele é executado. Em seguida, o result
é convertido em JSON e exibido na stdout
. A saída será diferente cada vez que o script for executado:
Quando você estiver pronto, salve e fechar o arquivo.
Observação: Projetos de alto nível e complexos exigem mais pensamento sobre como os fontes de dados externos são criados e usados, especialmente em termos de portabilidade e manejo de erros. O Terraform espera que o programa executado escreva uma mensagem de erro humano-legível na stderr
e saia com um estatus não zero, o que não é mostrado neste passo por causa da simplicidade do trabalho. Além disso, ele espera que o programa não tenha efeitos colaterais, permitindo que seja executado quantas vezes forem necessárias.
Para mais informações sobre o que o Terraform espera, visite os documentos oficiais sobre fontes de dados.
Agora que o script está pronto, você pode definir a fonte de dados, que irá extrair dados do script. Você armazenará a fonte no arquivo chamado data-sources.tf
na raiz do seu projeto de acordo com a abordagem de estruturamento simples.
Crie-lo para edição executando:
Adicione o seguinte definição:
Salve e fecha o arquivo.
Esta fonte é chamada droplet_name
e executa o script name-generator.py
usando Python 3, que reside no diretório external
que você acabou de criar. Ele automaticamente analisa sua saída e disponibiliza os dados deserializados sob seu atributo result
.
Com a fonte agora declarada, você pode definir o Dropletto que o Apache irá rodar.
Passo 3 — Definindo o Pérola
Neste passo, você escreverá a definição da recurso de Pérola e armazenará-la em um arquivo de código dedicado às Pérolas, conforme a abordagem de estruturação simples. O nome desta pérola será diferente cada vez que seja deployada, derivando do conjunto de dados dinâmicos que acabou de ser criado.
Crie e abra o arquivo droplets.tf
para edição:
Adicione a seguinte definição de recurso de Pérola:
Você primeiro declara uma chave SSH DigitalOcean chamada ssh_key
, que irá buscar uma chave de sua conta por seu nome. Certifique-se de substituir o código destacado com o seu nome de chave SSH.
Então, declara um recurso de Pérola chamado web
. Seu nome real na nuvem será diferente, pois é solicitado a partir do droplet_name
dos dados externos. Para inicializar a Pérola com uma chave SSH cada vez que seja deployada, o ID da ssh_key
é passado como parâmetro para ssh_keys
, assim o DigitalOcean saberá qual chave aplicar.
Por enquanto, isso é tudo que você precisa configurar relacionado ao droplet.tf
, então salve e fecha o arquivo quando terminar.
Agora você escreverá a configuração para o registro DNS que apontará seu domínio para a pérola declarada recentemente.
Passo 4 — Definindo Registros DNS
O último passo no processo é configurar o registro de DNS que aponta para o Droplets de seu domínio.
Você armazenará a configuração do DNS em um arquivo chamado dns.tf
, porque é um tipo de recurso diferente dos outros que você criou nas etapas anteriores. Crie e abra-o para editar:
Adicione as seguintes linhas:
Este código declara um registro DigitalOcean DNS na sua domínio (passado usando a variável), do tipo A
. O registro tem um nome de @
, que é um alias para o próprio domínio e com a adressa IP do Droplet como seu valor
. Você pode substituir o valor de nome
por algo outro, o que resultará em uma subdomínio sendo criado.
Quando você estiver terminado, salve e fecha o arquivo.
Agora que você configurou o Droplet, a fonte de dados do gerador de nomes e um registro DNS, vai passar ao projeto de deploy no clúster.
Passo 5 — Planejamento e Aplicação da Configuração
Neste seção, você inicializará seu projeto de terraforma, depois disso, ele será implantado na nuvem e verificado se tudo foi provisionado corretamente.
Agora que o infraestrutura do projeto está definida completamente, o último passo antes de implantar é iniciar o projeto do Terraforma. Faça isso executando o comando seguinte:
Você receberá a seguinte saída:
OutputInitializing the backend...
Initializing provider plugins...
- Finding digitalocean/digitalocean versions matching "~> 2.0"...
- Finding latest version of hashicorp/external...
- Installing digitalocean/digitalocean v2.10.1...
- Installed digitalocean/digitalocean v2.10.1 (signed by a HashiCorp partner, key ID F82037E524B9C0E8)
- Installing hashicorp/external v2.1.0...
- Installed hashicorp/external v2.1.0 (signed by HashiCorp)
Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
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ê agora pode implantar seu Dropletto com um nome dinâmico gerado e um domínio associado à sua conta do DigitalOcean.
Comece definindo o nome do domínio, a impressão digitada da chave SSH e sua chave de acesso personalizada como variáveis de ambiente, para que não tenha que copiar os valores cada vez que execute o Terraforma. Executar os seguintes comandos, substituindo os valores destacados:
Você pode encontrar sua chave de acesso API no Painel de Controle do DigitalOcean.
Executar o comando plan
com as variáveis passadas para ver quais etapas o Terraforma iria tomar para implantar seu projeto:
A saída será semelhante a seguinte:
OutputTerraform used the selected providers to generate the following execution plan. Resource
actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# digitalocean_droplet.web será criado
+ resource "digitalocean_droplet" "web" {
+ backups = false
+ created_at = (known after apply)
+ disk = (known after apply)
+ id = (known after apply)
+ image = "ubuntu-20-04-x64"
+ ipv4_address = (known after apply)
+ ipv4_address_private = (known after apply)
+ ipv6 = false
+ ipv6_address = (known after apply)
+ locked = (known after apply)
+ memory = (known after apply)
+ monitoring = false
+ name = "web-1625908814"
+ price_hourly = (known after apply)
+ price_monthly = (known after apply)
+ private_networking = (known after apply)
+ region = "fra1"
+ resize_disk = true
+ size = "s-1vcpu-1gb"
+ ssh_keys = [
+ "...",
]
+ status = (known after apply)
+ urn = (known after apply)
+ vcpus = (known after apply)
+ volume_ids = (known after apply)
+ vpc_uuid = (known after apply)
}
# digitalocean_record.www será criado
+ resource "digitalocean_record" "www" {
+ domain = "your_domain'"
+ fqdn = (known after apply)
+ id = (known after apply)
+ name = "@"
+ ttl = (known after apply)
+ type = "A"
+ value = (known after apply)
}
Plan: 2 to add, 0 to change, 0 to destroy.
...
As linhas começando com uma marca +
significam que o Terraforma irá criar cada recurso que veja em seguida após aplicar a configuração:
O apply
do comando será semelhante ao anterior, mas esta vez você será solicitado a confirmar:
OutputPlan: 2 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: `yes`
Digite yes
, e o Terraforma provisionará seu Dropletto e o registro DNS:
Outputdigitalocean_droplet.web: Creating...
...
digitalocean_droplet.web: Creation complete after 33s [id=204432105]
digitalocean_record.www: Creating...
digitalocean_record.www: Creation complete after 1s [id=110657456]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Terraform agora registrou as suas ressourçes deployadas em seu estado. Para confirmar que os registros de DNS e o Droplets se conectaram com sucesso, você pode extrair o endereço IP do Droplet da sua estate local e verificar se ele corresponde às recordes públicos de DNS para seu domínio. Executar o seguinte comando para obter o endereço IP do Droplet:
Você receberá o endereço IP do Droplet:
Outputipv4_address = "your_Droplet_IP"
...
Você pode checar os registros públicos A executando:
A saída mostrará o endereço IP para o qual o registro A está apontando:
OutputAddress: your_Droplet_IP
Eles são o mesmo, como devem ser, significando que o Droplet e o registro DNS foram provisionados com sucesso.
Para as alterações no próximo passo a tomar lugar, destruir as recursos implantados executando:
Quando solicitado, digite yes
para continuar.
Neste passo, você criou sua infraestrutura e a aplicou ao seu conta DigitalOcean. Agora você modificará para instalar o servidor Web Apache na Droplet provisionada usando provisioners do Terraform.
Passo 6 — Executando Código Usando Provisioners
Agora você configurará a instalação do servidor Apache no seu Droplet implantado usando o provisioner remote-exec
para executar comandos personalizados.
Os provisioners do Terraform podem ser usados para executar ações específicas sobre os recursos remotos criados (usando o provisionador remote-exec
) ou na máquina local onde o código está sendo executado (usando o provisionador local-exec
). Se um provisionador falhar, o nó será marcado como tainted no estado atual, o que significa que ele será excluído e recriado durante a próxima execução.
Para conectar-se à instância de uma Dropleta provisionada pelo Terraform, o Terraform precisa da chave privada SSH do Droplet configurado. O melhor caminho é passar a localização da chave privada por meio de variáveis, então abra variables.tf
para editar:
Adicione a linha destacada:
Você agora adicionou uma nova variável, chamada private_key
, ao seu projeto. Salve e fecha o arquivo.
Agora, você adicionará as declarações de dados de conexão e de provisionador remoto à configuração do Droplet. Abra droplets.tf
para editar, executando:
Expanda o bloco existente com as linhas destacadas:
O bloco connection
especifica como o Terraform deve se conectar ao alvo do Droplet. O bloco provisioner
contém o array de comandos, dentro do parâmetro inline
, que ele executará após a provisionação. Isso é, atualizando o cache do gerenciador de pacotes e instalando o Apache. Salve e saia quando você estiver pronto.
Você pode criar uma variável de ambiente temporária para a pasta da chave privada também:
Anotação: A chave privada e outros arquivos que você deseja carregar dentro do Terraform devem ser colocados dentro do projeto. Consulte o tutorial Como Configurar Autenticação Baseada em Chaves SSH no Servidor Linux para obter mais informações sobre a configuração da chave SSH no Ubuntu 20.04 ou outras distribuições.
Tente aplicar a configuração novamente:
Digite yes
quando solicitado. Você receberá saída semelhante à anterior, mas seguida por uma saída longa proveniente do provisor remote-exec
.
Outputdigitalocean_droplet.web: Creating...
digitalocean_droplet.web: Still creating... [10s elapsed]
digitalocean_droplet.web: Still creating... [20s elapsed]
digitalocean_droplet.web: Still creating... [30s elapsed]
digitalocean_droplet.web: Provisioning with 'remote-exec'...
digitalocean_droplet.web (remote-exec): Connecting to remote host via SSH...
digitalocean_droplet.web (remote-exec): Host: ...
digitalocean_droplet.web (remote-exec): User: root
digitalocean_droplet.web (remote-exec): Password: false
digitalocean_droplet.web (remote-exec): Private key: true
digitalocean_droplet.web (remote-exec): Certificate: false
digitalocean_droplet.web (remote-exec): SSH Agent: false
digitalocean_droplet.web (remote-exec): Checking Host Key: false
digitalocean_droplet.web (remote-exec): Connected!
...
digitalocean_droplet.web: Creation complete after 1m5s [id=204442200]
digitalocean_record.www: Creating...
digitalocean_record.www: Creation complete after 1s [id=110666268]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Você pode agora navegar até sua domínio na web usando um navegador. Voulez-vous voir la page d’accueil par défaut Apache. Cela signifie que Apache a été installé avec succès et que Terraform a fourni tout correctement.
Vous pouvez maintenant naviguer vers votre domaine dans un navigateur Web. Vous verrez la page d’accueil par défaut Apache. Cela signifie que Apache a été installé avec succès et que Terraform a fourni tous les éléments correctement.
Pour détruire les ressources déployées, exécutez la commande suivante et entrez yes
lorsque vous le soyez invité :
Vous avez maintenant terminé un petit projet Terraform avec une structure simple qui déploie le serveur Web Apache sur un Droplet et configure les enregistres DNS pour le domaine souhaité.
Conclusão
Você aprendeu sobre duas abordagens gerais para estruturar seus projetos Terraform, de acordo com sua complexidade. Seguindo a abordagem simples de estruturação e usando o provisionador remote-exec
para executar comandos, você então implantou um Droplet executando o Apache com registros de DNS para seu domínio.
Para referência, aqui está a estrutura de arquivos do projeto que você criou neste tutorial:
.
└── tf/
├── versions.tf
├── variables.tf
├── provider.tf
├── droplets.tf
├── dns.tf
├── data-sources.tf
└── external/
└── name-generator.py
As recursos que você definiu (o Droplet, o registro de DNS e a fonte de dados dinâmica, o fornecedor DigitalOcean e as variáveis) estão armazenados cada um em seu próprio arquivo separado, de acordo com a estrutura simples de projeto descrita na primeira seção deste tutorial.
Para obter mais informações sobre provisionadores Terraform e seus parâmetros, visite a documentação oficial.
Este tutorial é parte da série Como Gerenciar Infraestrutura com Terraform. A série abrange vários tópicos de Terraform, desde instalar Terraform pela primeira vez até gerenciar projetos complexos.
Source:
https://www.digitalocean.com/community/tutorials/how-to-structure-a-terraform-project