Gostaria de saber o que é Terraform? Vamos explorar!
Infraestrutura como código (IaC) é um conceito amplamente adotado por profissionais de DevOps. Refere-se ao processo de gerenciar e provisionar toda a infraestrutura de TI, tanto física quanto virtual, por meio de arquivos de configuração legíveis por máquina. Essencialmente, é uma abordagem de engenharia de software aplicada às operações, facilitando a automação completa de data centers por meio de scripts de programação.
Apesar das vantagens que a Infraestrutura como Código oferece, ela apresenta alguns desafios:
- Curva de aprendizado em programação.
- Dificuldade em prever o impacto de alterações.
- Necessidade de reverter mudanças.
- Complexidade em monitorar alterações.
- Obstáculos na automação de recursos específicos.
- Gerenciamento de múltiplos ambientes de infraestrutura.
Terraform surgiu como uma solução para esses desafios.
O que é Terraform?
Terraform é uma ferramenta de código aberto para Infraestrutura como Código, desenvolvida pela HashiCorp. Ele permite definir e provisionar infraestruturas completas utilizando uma linguagem declarativa de fácil compreensão. Terraform armazena a configuração da infraestrutura em nuvem como código, semelhante a ferramentas como CloudFormation, utilizada para automatizar infraestruturas AWS, porém, o Terraform se destaca por sua capacidade de operar em diversas plataformas de nuvem.
Confira alguns benefícios do uso do Terraform:
- Realiza orquestração, indo além do simples gerenciamento de configurações.
- Compatível com diversos provedores, como AWS, Azure, GCP, DigitalOcean e outros.
- Proporciona infraestrutura imutável, onde as mudanças são aplicadas de forma suave.
- Utiliza HCL (Linguagem de Configuração HashiCorp), uma linguagem intuitiva.
- Facilmente portável para diferentes provedores.
- Adota uma arquitetura somente cliente, dispensando gerenciamento adicional em servidores.
Conceitos Essenciais do Terraform
A seguir, os principais conceitos e terminologias utilizadas no Terraform:
- Variáveis: Também conhecidas como variáveis de entrada, são pares chave-valor que permitem a personalização de módulos do Terraform.
- Provider (Provedor): É um plugin que possibilita a interação com APIs de serviços, permitindo acesso aos seus recursos.
- Módulo: Uma pasta contendo templates do Terraform, onde as configurações são definidas.
- Estado: Informações em cache sobre a infraestrutura gerenciada pelo Terraform e suas configurações.
- Recursos: Blocos que representam um ou mais objetos de infraestrutura, como instâncias computacionais ou redes virtuais, utilizados para configuração e gerenciamento.
- Data Source (Fonte de Dados): Permite aos provedores retornar informações sobre objetos externos ao Terraform.
- Valores de Saída: Valores de um módulo Terraform que podem ser utilizados por outras configurações.
- Plano: Etapa que define o que precisa ser criado, alterado ou removido para que a infraestrutura alcance o estado desejado.
- Aplicar: Etapa onde as alterações são aplicadas para mover a infraestrutura do estado atual para o desejado.
Ciclo de Vida do Terraform
O ciclo de vida do Terraform abrange quatro etapas: inicialização, planejamento, aplicação e destruição.
- Inicialização (init): Configura o diretório de trabalho e seus arquivos de configuração.
- Planejamento (plan): Elabora um plano de execução para alcançar o estado desejado da infraestrutura, com base nas alterações nos arquivos de configuração.
- Aplicação (apply): Implementa as mudanças na infraestrutura conforme o plano definido, levando-a ao estado desejado.
- Destruição (destroy): Remove todos os recursos de infraestrutura que se tornaram obsoletos após a fase de aplicação.
Como o Terraform Funciona?
O Terraform possui dois componentes principais:
Núcleo do Terraform
O núcleo do Terraform opera com base em duas fontes de entrada:
Primeiramente, uma configuração definida pelo usuário, que especifica os recursos a serem criados ou provisionados. Em segundo lugar, o estado, que armazena informações atualizadas sobre a configuração atual da infraestrutura. O núcleo do Terraform processa essas entradas e cria um plano de execução. Ele compara o estado atual com a configuração desejada, e identifica as ações necessárias para alcançar o resultado final, seja criação, atualização ou exclusão de recursos.
Provedores
Os provedores são o segundo componente essencial. Eles são específicos para tecnologias como plataformas de nuvem (AWS, Azure, GCP) ou outras ferramentas de infraestrutura como serviço, Kubernetes, e até mesmo softwares de autoatendimento. Essa abordagem flexível permite a criação de infraestruturas em diversos níveis, por exemplo, construindo uma infraestrutura na AWS, implementando Kubernetes sobre ela e, em seguida, criando serviços dentro do cluster.
O Terraform oferece suporte a mais de uma centena de provedores, cada um dando acesso aos seus recursos específicos. Por exemplo, o provedor da AWS possibilita o uso de instâncias EC2, usuários IAM, enquanto o provedor do Kubernetes dá acesso a serviços, deployments e namespaces.
Dessa forma, o Terraform busca auxiliar no provisionamento e configuração completa de aplicações, desde a infraestrutura até o nível de aplicação.
Vamos agora para alguns exemplos práticos.
Vamos instalar o Terraform no Ubuntu e provisionar uma infraestrutura básica.
Instalação do Terraform
Baixe o pacote do Terraform mais recente.
Acesse a página oficial de download e baixe a versão adequada para seu sistema operacional.
[email protected]:~$ wget https://releases.hashicorp.com/terraform/0.13.0/terraform_0.13.0_linux_amd64.zip
--2020-08-14 16:55:38--
https://releases.hashicorp.com/terraform/0.13.0/terraform_0.13.0_linux_amd64.zip
Resolving releases.hashicorp.com (releases.hashicorp.com)... 151.101.153.183, 2a04:4e42:24::439
Connecting to releases.hashicorp.com (releases.hashicorp.com)|151.101.153.183|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 34851622 (33M) [application/zip]
Saving to: ‘terraform_0.13.0_linux_amd64.zip’
terraform_0.13.0_linux_amd64.zip
100%[=================================================================>] 33.24M
90.3KB/s in 5m 28s
2020-08-14 17:01:06 (104 KB/s) - ‘terraform_0.13.0_linux_amd64.zip’ saved [34851622/34851622]
Extraia o pacote baixado:
[email protected]:~$ unzip terraform_0.13.0_linux_amd64.zip
Archive: terraform_0.13.0_linux_amd64.zip
inflating: terraform
Mova o executável do Terraform para o caminho indicado abaixo. Verifique a versão do Terraform:
[email protected]:~$ sudo mv terraform /usr/local/bin/
[sudo] password for etechpt.com:
[email protected]:~$ terraform -v
Terraform v0.13.0
Estes são os comandos disponíveis para execução no Terraform:
[email protected]:~$ terraform
Usage: terraform [-version] [-help] <command> [args]
The available commands for execution are listed below.
The most common, useful commands are shown first, followed by
less common or more advanced commands. If you're just getting
started with Terraform, stick with the common commands. For the
other commands, please read the help and docs before usage.
Common commands:
apply Builds or changes infrastructure
console Interactive console for Terraform interpolations
destroy Destroy Terraform-managed infrastructure
env Workspace management
fmt Rewrites config files to canonical format
get Download and install modules for the configuration
graph Create a visual graph of Terraform resources
import Import existing infrastructure into Terraform
init Initialize a Terraform working directory
login Obtain and save credentials for a remote host
logout Remove locally-stored credentials for a remote host
output Read an output from a state file
plan Generate and show an execution plan
providers Prints a tree of the providers used in the configuration
refresh Update local state file against real resources
show Inspect Terraform state or plan
taint Manually mark a resource for recreation
untaint Manually unmark a resource as tainted
validate Validates the Terraform files
version Prints the Terraform version
workspace Workspace management
All other commands:
0.12upgrade Rewrites pre-0.12 module source code for v0.12
0.13upgrade Rewrites pre-0.13 module source code for v0.13
debug Debug output management (experimental)
force-unlock Manually unlock the terraform state
push Obsolete command for Terraform Enterprise legacy (v1)
state Advanced state management
Provisionar Instância AWS EC2 usando Terraform
Nesta demonstração, vamos iniciar uma nova instância AWS EC2 com o Terraform.
Crie um diretório de trabalho para esta demonstração:
[email protected]:~$ mkdir terraform_demo
Acesse o diretório e crie um arquivo de configuração do Terraform onde definiremos o provedor e os recursos para uma instância AWS EC2:
[email protected]:~$ cd terraform_demo/
[email protected]:~/terraform_demo$ gedit awsec2.tf
provider "aws" {
access_key = "B5KG6Fe5GUKIATUF5UD"
secret_key = "R4gb65y56GBF6765ejYSJA4YtaZ+T6GY7H"
region = "us-west-2"
}
resource "aws_instance" "terraform_demo" {
ami = "ami-0a634ae95e11c6f91"
instance_type = "t2.micro"
}
Atenção: altere as chaves de acesso e secretas para suas credenciais.
Na configuração acima, o provedor definido é a AWS, com as credenciais do usuário e região. Em seguida, os detalhes da AMI (ami-0a634ae95e11c6f91) e tipo de instância t2.micro.
Observe como a configuração é simples e fácil de ler, mesmo para quem não tem experiência em programação.
Inicialização do Terraform
Inicialize o Terraform:
[email protected]:~/terraform_demo$ terraform init
Initializing the backend...
Initializing provider plugins...
- Using previously-installed hashicorp/aws v3.2.0
The following providers do not have any version constraints in configuration,
so the latest version was installed.
To prevent automatic upgrades to new major versions that may contain breaking
changes, we recommend adding version constraints in a required_providers block
in your configuration, with the constraint strings suggested below.
* hashicorp/aws: version = "~> 3.2.0"
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.
Planejamento do Terraform
Em seguida, o plano: ele cria o gráfico de execução para construir e provisionar a infraestrutura:
[email protected]:~/terraform_demo$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_instance.terraform_demo will be created
+ resource "aws_instance" "terraform_demo" {
+ ami = "ami-0a634ae95e11c6f91"
+ arn = (known after apply)
+ associate_public_ip_address = (known after apply)
+ availability_zone = (known after apply)
+ cpu_core_count = (known after apply)
+ cpu_threads_per_core = (known after apply)
+ get_password_data = false
+ host_id = (known after apply)
+ id = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t2.micro"
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = (known after apply)
+ outpost_arn = (known after apply)
+ password_data = (known after apply)
+ placement_group = (known after apply)
+ primary_network_interface_id = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ secondary_private_ips = (known after apply)
+ security_groups = (known after apply)
+ source_dest_check = true
+ subnet_id = (known after apply)
+ tenancy = (known after apply)
+ volume_tags = (known after apply)
+ vpc_security_group_ids = (known after apply)
+ ebs_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ snapshot_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
+ ephemeral_block_device {
+ device_name = (known after apply)
+ no_device = (known after apply)
+ virtual_name = (known after apply)
}
+ metadata_options {
+ http_endpoint = (known after apply)
+ http_put_response_hop_limit = (known after apply)
+ http_tokens = (known after apply)
}
+ network_interface {
+ delete_on_termination = (known after apply)
+ device_index = (known after apply)
+ network_interface_id = (known after apply)
}
+ root_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
Aplicação do Terraform
A etapa de aplicação executa a configuração e inicia uma instância AWS EC2. Ao executar, o comando perguntará se você deseja realizar as ações, digite “sim” e pressione enter:
[email protected]:~/terraform_demo$ terraform apply
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_instance.terraform_demo will be created
+ resource "aws_instance" "terraform_demo" {
+ ami = "ami-0a634ae95e11c6f91"
+ arn = (known after apply)
+ associate_public_ip_address = (known after apply)
+ availability_zone = (known after apply)
+ cpu_core_count = (known after apply)
+ cpu_threads_per_core = (known after apply)
+ get_password_data = false
+ host_id = (known after apply)
+ id = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t2.micro"
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = (known after apply)
+ outpost_arn = (known after apply)
+ password_data = (known after apply)
+ placement_group = (known after apply)
+ primary_network_interface_id = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ secondary_private_ips = (known after apply)
+ security_groups = (known after apply)
+ source_dest_check = true
+ subnet_id = (known after apply)
+ tenancy = (known after apply)
+ volume_tags = (known after apply)
+ vpc_security_group_ids = (known after apply)
+ ebs_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ snapshot_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
+ ephemeral_block_device {
+ device_name = (known after apply)
+ no_device = (known after apply)
+ virtual_name = (known after apply)
}
+ metadata_options {
+ http_endpoint = (known after apply)
+ http_put_response_hop_limit = (known after apply)
+ http_tokens = (known after apply)
}
+ network_interface {
+ delete_on_termination = (known after apply)
+ device_index = (known after apply)
+ network_interface_id = (known after apply)
}
+ root_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
}
Plan: 1 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
aws_instance.terraform_demo: Creating...
aws_instance.terraform_demo: Still creating... [10s elapsed]
aws_instance.terraform_demo: Still creating... [20s elapsed]
aws_instance.terraform_demo: Still creating... [30s elapsed]
aws_instance.terraform_demo: Still creating... [40s elapsed]
aws_instance.terraform_demo: Creation complete after 44s [id=i-0eec33286ea4b0740]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Acesse o painel do AWS EC2 e observe a nova instância criada, com o ID de instância exibido no final do comando apply.
Parabéns! Você executou uma instância AWS EC2 com sucesso usando o Terraform.
Destruição com Terraform
Por fim, para remover a infraestrutura, use o comando destroy:
[email protected]:~/terraform_demo$ terraform destroy
aws_instance.terraform_demo: Refreshing state... [id=i-0eec33286ea4b0740]
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# aws_instance.terraform_demo will be destroyed
- resource "aws_instance" "terraform_demo" {
- ami = "ami-0a634ae95e11c6f91" -> null
- arn = "arn:aws:ec2:us-west-2:259212389929:instance/i-0eec33286ea4b0740" -> null
- associate_public_ip_address = true -> null
- availability_zone = "us-west-2c" -> null
- cpu_core_count = 1 -> null
- cpu_threads_per_core = 1 -> null
- disable_api_termination = false -> null
- ebs_optimized = false -> null
- get_password_data = false -> null
- hibernation = false -> null
- id = "i-0eec33286ea4b0740" -> null
- instance_state = "running" -> null
- instance_type = "t2.micro" -> null
- ipv6_address_count = 0 -> null
- ipv6_addresses = [] -> null
- monitoring = false -> null
- primary_network_interface_id = "eni-02a46f2802fd15634" -> null
- private_dns = "ip-172-31-13-160.us-west-2.compute.internal" -> null
- private_ip = "172.31.13.160" -> null
- public_dns = "ec2-34-221-77-94.us-west-2.compute.amazonaws.com" -> null
- public_ip = "34.221.77.94" -> null
- secondary_private_ips = [] -> null
- security_groups = [
- "default",
] -> null
- source_dest_check = true -> null
- subnet_id = "subnet-5551200c" -> null
- tags = {} -> null
- tenancy = "default" -> null
- volume_tags = {} -> null
- vpc_security_group_ids = [
- "sg-b5b480d1",
] -> null
- credit_specification {
- cpu_credits = "standard" -> null
}
- metadata_options {
- http_endpoint = "enabled" -> null
- http_put_response_hop_limit = 1 -> null
- http_tokens = "optional" -> null
}
- root_block_device {
- delete_on_termination = true -> null
- device_name = "/dev/sda1" -> null
- encrypted = false -> null
- iops = 100 -> null
- volume_id = "vol-0be2673afff6b1a86" -> null
- volume_size = 8 -> null
- volume_type = "gp2" -> null
}
}
Plan: 0 to add, 0 to change, 1 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
aws_instance.terraform_demo: Destroying... [id=i-0eec33286ea4b0740]
aws_instance.terraform_demo: Still destroying... [id=i-0eec33286ea4b0740, 10s elapsed]
aws_instance.terraform_demo: Still destroying... [id=i-0eec33286ea4b0740, 20s elapsed]
aws_instance.terraform_demo: Still destroying... [id=i-0eec33286ea4b0740, 30s elapsed]
aws_instance.terraform_demo: Destruction complete after 34s
Destroy complete! Resources: 1 destroyed.
Verificando o painel do EC2, a instância estará encerrada.
Conclusão
Espero que esta explicação tenha lhe dado uma base sólida para começar a usar o Terraform. Recomendo que você tente reproduzir o exemplo apresentado.
Considere também explorar outras ferramentas de automação de infraestrutura.
Para aprofundar seus conhecimentos, sugiro o Curso Aprendendo DevOps com Terraform.