Abril 12, 2020

Terraform 101 - Instalando e fazendo deploy de EC2 na AWS

Terraform 101 -  Instalando e fazendo deploy de EC2 na AWS

Terraform é uma ferramenta da Hashicorp para construir, modificar e versionar a infraestrutura de maneira segura e eficiente.

Através do terraform adicionamos camadas de abstração a serviços de cloud como Google Cloud Platform, Amazon Web Services, Microsoft Azure, Digital Ocean, dentre outros serviços não somente de cloud.

Primeiramente precisamos entender dois recursos chaves do Terraform para gerenciar nossa infraestrutura: Providers e Provisioners.

Providers são responsáveis por interagir com a API e expor os recursos. Geralmente quando falamos de providers estamos falando de IaaS (Infrastructure as a Service), PaaS (Platform as a Service) ou Saas (Softwares as a Service)

Alguns exemplos de providers:

  • IaaS: GCP, AWS, Azure, Digital Ocean, Alibaba Cloud, Openstack.
  • PaaS: Heroku.
  • SaaS: Cloudflare, DNSSimple, DNSMadeEasy.

Provisioners são responsáveis por provisionar o ambiente, podemos dizer que provisioners são o ultimo recurso e devem ser utilizados apenas se a API do provider não fornecer todos os recursos que precisamos.

Alguns exemplos de provisioners:

  • file
  • local-exec
  • remote-exec
  • chef
  • puppet
  • salt

O Terraform utiliza a linguagem HCL (Hashicorp Configuration Language) que é uma linguagem declarativa de fácil entendimento e compatível com JSON.

Vamos a prática

Em todos os laboratórios deste blog utilizamos distribuições de linux, também utilizamos os comandos como super user, em ambientes de produção lembre-se de tomar as precauções de segurança.
ATENÇÃO: Como estamos trabalhando em um ambiente de Cloud, lembre-se de destruir o laboratório quando terminar o mesmo para evitar dores de cabeça com cobrança, uma vez que os provedores de Cloud irão cobrar pelos recursos que estiverem na infraestrutura.

Para rodar o terraform não precisamos mais do que uma máquina linux e terminal. Caso esteja utilizando outro sistema operacional, verifique no site do terraform na seção de downloads o binário correto para seu sistema.

Amazon Web Services

Primeiramente precisamos da nossa conta na AWS, pode ser inclusive a conta FreeTier pra quem ainda não tem uma conta na mesma.

Não irei cobrir o passo a passo da criação da conta uma vez que já possúo minha conta da AWS e existem diversos outros blogs explicando o passo a passo de como criar uma e inclusive o próprio site da AWS <link>

Acesse o console da AWS e faça o login com sua conta e pesquise pelo produto IAM (Identity and Access Management)

AWS Services Console 

Iremos criar um usuário para interagir com a AWS, clique em USERS e em seguida em ADD USER

Add User

Digite um nome para o usuário, selecione programatic access para que seja criado um ID e Senha para a chave de acesso e clique em Next.

Programatic Access

Adicione a politica AmazonEC2FullAccess ao usuário, o que dará permissão total ao usuário apenas a recursos da EC2, e clique em Next.

Attaching Policies

Tags são utilizadas para adicionar informações relevantes ao usuario, clique em Next.

Verifique os dados e clique em Create user

Create User

Clique em show e copie o Access key ID e Secret access key

Access Key and Secret Access Key 
O usuário criado e chave de acesso não devem ser compartilhados, uma vez que quem tiver acesso a estes dados terá controle sobre os recursos adicionados como política, por questões de segurança este usuário não existe mais em minha conta.

Instalando o AWS CLI

Iremos instalar o AWS CLI (Command Line Interface) para autenticarmos via terminal e possibilitar nosso acesso via terraform.

$ cd /tmp
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install

Verifique a instalação através do comando aws --version que deve retornar a versão atual do aws cli instalado, agora iremos configurar nosso cli com o ID e chave de acesso criadas anteriormente, execute o comando aws configure e em seguida digite o ID e Chave (para região e output format apenas tecle <ENTER>).

$ aws configure

Isso vai configurar o arquivo ~/.aws/credentials com suas credenciais

file: ~/.aws/credentials

Instalando o Terraform

Iremos fazer o download da versão do terraform 0.12.24 no momento da escrita deste post.

$ cd /tmp 
$ curl https://releases.hashicorp.com/terraform/0.12.24/terraform_0.12.24_linux_amd64.zip -o terraform.zip
$ unzip terraform.zip
$ sudo mv terraform /usr/local/bin
$ terraform --version

Caso o comando terraform --version retorne a versão correta, no nosso caso Terraform v0.12.24 , significa que a instalação ocorreu com sucesso.

Criando o código HCL

Os arquivos utilizados pelo terraform tem a terminação .tf , eu particularmente gosto de separar em diversos arquivos para que fique mais fácil a manutenção do mesmo, então vamos criar nosso primeiro código para criar uma instância na AWS.

Criaremos o diretório para armazenar nosso código bem como um arquivo para configurar nosso backend.

$ mkdir ~/terraform-101
$ cd ~/terraform-101
$ vim backend.tf

No arquivo backend.tf iremos adicionar o conteúdo para informar qual será o provider utilizado, no nosso caso aws, bem como a região que será aplicada.

file: ~/terraform-101/backend.tf

provider "aws" {
   region = var.region
}

Declaramos um conteudo proveniente de uma variavel chamada region através do parâmetro var.<nome_variavel> , iremos definir o conteúdo desta variável posteriormente.

O uso de variáveis não é necessário, podemos simplesmente declarar os valores diretamente no arquivo, porém ao utilizar as variáveis a manutenção e o reaproveitamento do código é feito de maneira mais simples

Vamos criar um arquivo ec2.tf que será responsável pela definição da nossa instância ec2.

$ vim ec2.tf
resource "aws_instance" "server" {
  ami           = var.ami
  instance_type = var.instance_type

  tags = {
    Name        = var.name
    Environment = var.env
    Provisioner = "Terraform"
  }
}

Novamente estamos declarando diversas variáveis e precisamos definilas em um arquivo para que seja utilizada. Criaremos então o arquivo variables.tf onde definiremos estas variáveis.

$ vim variables.tf
variable "region" {
  description = "Define what region the instance will be deployed"
  default = "us-east-1"
}

variable "name" {
  description = "Name of the Application"
  default = "server01"
}

variable "env" {
  description = "Environment of the Application"
  default = "prod"
}

variable "ami" {
  description = "AWS AMI to be used "
  default = "ami-07ebfd5b3428b6f4d"
}

variable "instance_type" {
  description = "AWS Instance type defines the hardware configuration of the machine"
  default = "t2.micro"
}
O campo description informa a descrição de cada variável, é uma boa prática dizer o que cada variável significa e/ou para que é utilizada.
O campo default informa o valor padrão da variável.

Agora que ja criamos nosso arquivo precisamos executar o comando terraform init para que seja feito download dos providers do terraform em nosso diretório.

$ terraform init

Agora que iniciamos o provider teremos uma pasta oculta .terraform em nosso diretório com os plugins necessários.

Terraform 101 Directory Structure

Podemos agora efetuar o planejamento da nossa infraestrutura através do comando terraform plan , que será responsável por nos mostrar qual seria o resultado após a aplicação do nosso código.

$ terraform plan

No final da saída do comando é exibido quantos planos serão aplicados, modificados ou destruídos.

$ terraform plan

Para aplicar o plano utilizaremos o comando terraform apply que nos mostrará o resultado do plan e perguntando se queremos aplicar o recurso, digite yes para iniciar a aplicação.

$ terraform apply

Após isto é exibida a informação dos recursos que estão sendo criados bem como o estado final após execução

$ terraform apply

No painel da AWS podemos ir em EC2 e verificar a instância que foi criada conforme as configurações listadas.

AWS EC2

Ao executar um terraform, é criado um arquivo terraform.tfstate no diretório com o conteúdo do que foi criado/modificado para que o terraform possa efetuar ações de modificação na infraestrutura sabendo seu estado anterior.

Vamos alterar o nome da variável name para server02 e executar novamente o terraform apply.

vim variables.tf
variable "region" {
  description = "Define what region the instance will be deployed"
  default = "us-east-1"
}

variable "name" {
  description = "Name of the Application"
  default = "server02"
}

variable "env" {
  description = "Environment of the Application"
  default = "prod"
}

variable "ami" {
  description = "AWS AMI to be used "
  default = "ami-07ebfd5b3428b6f4d"
}

variable "instance_type" {
  description = "AWS Instance type defines the hardware configuration of the machine"
  default = "t2.micro"
}

Execute o terraform plan e verifique que o nome da instância será modificado, porém ela não será destruida e recriada.

$ terraform plan

Podemos executar o terraform apply para aplicar a configuração.

$ terraform apply

Note que agora é exibido que um componente foi atualizado.

$ terraform apply

Podemos também verificar na EC2 da AWS que a modificação foi efetuada com sucesso.

AWS EC2

Para destruir a instância podemos executar o comando terraform destroy

$ terraform destroy 

Digite yes para destruir a instância, note que o processo todo levará um tempo para ser executado, aguarde o retorno pelo terminal.

$ terraform destroy

Verifique também no EC2 da AWS  que a instância foi terminada.

AWS EC2

Irei continuar uma série de posts sobre Terraform e gradativamente aumentando a complexidade com outros recursos e inclusive integrando com ansible e outras ferramentas. Não deixe de acompanhar o blog!

O código deste post encontra-se no repositório: https://github.com/caiodelgadonew/blog-terraform-101  

Ficamos por aqui com esse post e nos vemos em uma próxima!