Link da apresentação deste artigo: slides

Agenda

Fundamentos de IaC

Infrastructure as Code

Infraestrutura como código (em inglês: infrastructure as code, ou IaC) é o processo de gerenciamento e provisionamento de centros de processamentos dados usando arquivos de configuração ao invés de configurações físicas de hardware ou ferramentas de configuração interativas.

Dry - Don’t repeat yourself

Quando dizemos “como código”, queremos dizer que todas as boas práticas que aprendemos no mundo do software devem ser aplicadas à infraestrutura.

Uso do controle de versão, adesão ao princípio DRY, modularização, manutenção e uso de testes e implantação automatizados são práticas fundamentais.

Casos de Uso

Terraform

Terraform é uma ferramenta open source de provisionamento de infraestrutura, criada pela HashiCorp, que permite que definamos nossa infraestrutura como código(IaC), usando uma linguagem simples e declarativa (HCL - HashiCorp Configuration Language).

O terraform é desenvolvido em GO e é OpenSource

Terraform Workflow

O Workflow do terraform consiste em basicamente 3 etapas:

  • Write - Author infrastructure as code.
  • Plan - Preview changes before applying.
  • Apply - Provision reproducible infrastructure.

IaC

A ideia por trás do terraform é ele gerenciar o estado de uma infraestrutura, ou seja, o estado de cada recurso com base na interação com o seu provider.

Interacao Api

Arquivos

Para começarmos com o Terraform, nós temos que identificar as extensões dos arquivos utilizados por por ele.

  • .tf - Arquivo de declaração do terraform. (variáveis, recursos, datasources, outputs, etc)
  • .tfvars - Arquivo de valor das variáveis, sendo que se o arquivo for .auto.tfvars, o terraform irá automaticamente carregar o arquivo .tfvars.
  • .plan - Arquivo de plano de ação que será executado pelo terraform apply.
  • .TFSTATE - Arquivo de estado do terraform. Onde ele escreve o que foi realizado.

Básico do Terraform

Variables

Variáveis são parametros para um módulo de Terraform, permitem que aspectos da implementação seja customizado sem que seu codigo seja alterado.

Temos 3 tipos de uso de variáveis:

  • Input variables are like function arguments
  • Output values are like function return values
  • Local values are like a function’s temporary local variables.

Declarando uma variável de input

variable "image_id" {
  type = string
}
variable "availability_zone_names" {
  type    = list(string)
  default = ["us-west-1a"]
}
variable "docker_ports" {
  type = list(object({
    internal = number
    external = number
    protocol = string
  }))
  default = [
    {
      internal = 8300
      external = 8300
      protocol = "tcp"
    }
  ]
}
variable "image_id" {
  type        = string
  description = "The id of the machine image (AMI) to use for the server."

  validation {
    condition     = length(var.image_id) > 4 && substr(var.image_id, 0, 4) == "ami-"
    error_message = "The image_id value must be a valid AMI id, starting with \"ami-\"."
  }
}

Precedência de carregamento

  • Environment variables
  • The terraform.tfvars file, if present.
  • The terraform.tfvars.json file, if present.
  • Any -.auto.tfvars or -.auto.tfvars.json files, processed in lexical order of their filenames.
  • Any -var and -var-file options on the command line, in the order they are provided. (This includes variables set by a Terraform Cloud workspace.)

Locals

Um Local é um valor que recebe um nome a partir de uma expressão ou valor.

locals {
  # Ids for multiple sets of EC2 instances, merged together
  instance_ids = concat(aws_instance.blue.-.id, aws_instance.green.-.id)
}

locals {
  # Common tags to be assigned to all resources
  common_tags = {
    Service = local.service_name
    Owner   = local.owner
  }
}

Output

Output é uma forma de expor o valor, seja como retorno de um módulo ou imprimindo como retorno do root.

output "instance_ip_addr" {
  value = aws_instance.server.private_ip
}
output "instance_ip_addr" {
  value       = aws_instance.server.private_ip
  description = "The private IP address of the main server instance."
}
output "db_password" {
  value       = aws_db_instance.db.password
  description = "The password for logging in to the database."
  sensitive   = true
}
output "instance_ip_addr" {
  value       = aws_instance.server.private_ip
  description = "The private IP address of the main server instance."

  depends_on = [
    # Security group rule must be created before this IP address could
    # actually be used, otherwise the services will be unreachable.
    aws_security_group_rule.local_access,
  ]
}

Type Constraints

São os tipos que as variáveis podem declarados como argumentos na declaração e que podem ser customizados. Veja elas como uma Classe na programação ou uma estrutura de dados.

Simples

  • string
  • number
  • bool

Complexos

  • list(<TYPE>)
  • set(<TYPE>)
  • map(<TYPE>)
  • object({<ATTR NAME> = <TYPE>, … })
  • tuple([<TYPE>, …])

Functions

  • Numeric Functions
  • String Functions
  • Collection Functions
  • Encoding Functions
  • Filesystem Functions
  • Date and Time Functions
  • Hash and Crypto Functions
  • IP Network Functions
  • Type Conversion Functions

Principais funções

Format

format(spec, values...)

> format("Hello, %s!", "Ander")
Hello, Ander!
> format("There are %d lights", 4)
There are 4 lights
> format("Hello, %s!", var.name)
Hello, Valentina!
> "Hello, ${var.name}!"
Hello, Valentina!
Join

join(separator, list)

> join(", ", ["foo", "bar", "baz"])
foo, bar, baz
> join(", ", ["foo"])
foo
Split

split(separator, string)

> split(",", "foo,bar,baz")
[
  "foo",
  "bar",
  "baz",
]
> split(",", "foo")
[
  "foo",
]
> split(",", "")
[
  "",
]
Upper, lower, title
> upper("hello")
HELLO
> upper("алло!")
АЛЛО!
> lower("HELLO")
hello
> lower("АЛЛО!")
алло!
> title("hello world")
Hello World
Element Index

element(list, index)

> element(["a", "b", "c"], 1)
b

index(list, value)

> index(["a", "b", "c"], "b")
1
Map
  • The map function is no longer available. Prior to Terraform v0.12 it was the only available syntax for writing a literal map inside an expression, but Terraform v0.12 introduced a new first-class syntax.
tomap({
  a = "b"
  c = "d"
})
File

file(path)

> file("${path.module}/hello.txt")
Hello World

Providers

É a estrutura resposavel por comunicar com a API da estrutura desejada.

# The default provider configuration; resources that begin with `aws_` will use
# it as the default, and it can be referenced as `aws`.
provider "aws" {
  region = "us-east-1"
}

# Additional provider configuration for west coast region; resources can
# reference this as `aws.west`.
provider "aws" {
  alias  = "west"
  region = "us-west-2"
}

Terraform Registry

O registry do terrarform é uma coleção de providers, Módulos e policies que podem ser usados em qualquer projeto. Os principais providers são:

  • AWS
  • Azure
  • Google Cloud Platform (GCP)
  • Kubernetes
  • Alibaba Cloud
  • Oracle Cloud Infrastructure

Resources

Item mais importante do Terraform, ele informa o recurso que será criado/gerenciado.

resource "aws_instance" "web" {
  ami           = "ami-a1b2c3d4"
  instance_type = "t2.micro"
}

Data Sources

Data recupera informações de recursos já criados no ambiente sem precisar de gerenciar o mesmo. Ou seja, sem precisar de importar o recurso e gerenciar ele.

data "aws_ami" "example" {
  most_recent = true

  owners = ["self"]
  tags = {
    Name   = "app-server"
    Tested = "true"
  }
}

Módulos

É como uma abstração de um conjunto de recursos para reaproveitamento do mesmo.

module "servers" {
  source = "./app-cluster"

  servers = 5
}

Backend - TFSTATE

O backend é a estrutrua que define onde o terraform irá guardar o estado (TFSTATE) do seu ambiente.

backend "s3" {
  bucket = "terraform-state"
  key    = "terraform.tfstate"
  region = "us-east-1"
}

Algo legal de utilizarmos é que os atributos do backend podem ser definidos dinamicamente no terraform init, isso trás uma maior flexibilidade podendo ser definido em tempo de execução.

terraform init \
    -backend-config="address=demo.consul.io" \
    -backend-config="path=example_app/terraform_state" \
    -backend-config="scheme=https"

Algumas opções de backend:

Workspaces

Workspaces é uma forma de gerenciar múltiplos ambientes de forma independente. Onde você pode associar cada ambiente com um conjunto de variáveis.

Workspaces

HashiCorp Certified Terraform Associate

A certificação Terraform é uma excelente opção para comprovar seu conhecimento sobre o Terraform. Ela não vai cobrir todos os aspectos do dia-a-dia, mas vai guiar você para entender o que é Terraform e como ele funciona.

A Hashicorp está atualizando o exame Terraform Associate 002 para a 003. A recomendação é que quem tem a Terraform Associate 002, faça o upgrade para a 003 quando for lançada, e quem não tem a 002 espere até o 003 ser lançada.

Timeline dos exames Terraform

Características

  • Prova multiplica escolha
  • Formato online
  • Duração 1 hora
  • Preço: $70.50 USD retake não incluído
  • Idioma: Inglês
  • Expiração: 2 Anos

Objetivos do exame

  • Entendimento dos conceitos de IaC
  • Entendimento da proposta do Terraform (vs outros IaC)
  • Entendimento das bases do Terraform
  • Uso do Terraform fora do Workflow principal
  • Interação com Terraform modules
  • Uso do Terraform Workflow principal
  • Implementação e manutenção do estado
  • Leitura, geração e modificação de configuração
  • Entendimento das características e funcionalidades do Terraform Cloud

Simulados

Dicas para a prova

  • Pratique as questões da prova com simulados e exercícios
  • Crie um repositório ou um projeto pequeno só para testar a CLI e o proprio terraform
  • Leia o Guia do Terraform Associate
  • Leia a documentação do terraform e entenda o que é o que é
  • Crie uma conta gratuita no Terraform Cloud e faça alguns testes
  • Durma cedo
  • Tenha uma alimentação tranquila no dia anterior
  • Marque a prova para um horário cedo