O livro "Terraform: infraestrutura no nível do código"

imagemOlá, habrozhiteli! O livro é destinado a todos os responsáveis ​​pelo código já escrito. Isso se aplica a administradores de sistemas, especialistas em operações, engenheiros de release, SR, DevOps, desenvolvedores de infraestrutura, desenvolvedores de ciclo completo, líderes de equipes de engenharia e diretores técnicos. Qualquer que seja sua posição, se você estiver envolvido em infraestrutura, implantar código, configurar servidores, dimensionar clusters, fazer backup de dados, monitorar aplicativos e atender chamadas às três da manhã, este livro é para você.

Juntas, essas responsabilidades são comumente referidas como atividades operacionais (ou administração do sistema). Anteriormente, os desenvolvedores que sabiam escrever código, mas não entendiam a administração do sistema eram frequentemente atendidos; os administradores de sistema geralmente se deparavam sem a capacidade de escrever código. Uma vez que essa separação era aceitável, mas no mundo moderno, que não pode mais ser imaginado sem a computação em nuvem e o movimento DevOps, quase todo desenvolvedor precisa de habilidades administrativas, e qualquer administrador de sistema deve poder programar.

Você não apenas aprenderá como gerenciar a infraestrutura na forma de código usando o Terraform, mas também aprenderá como ela se encaixa no conceito geral do DevOps. Aqui estão algumas perguntas que você pode responder lendo este livro.

  • Por que usar IaC?
  • , , ?
  • Terraform, Chef, Ansible, Puppet, Salt, CloudFormation, Docker, Packer Kubernetes?
  • Terraform ?
  • Terraform, ?
  • Terraform, ?
  • Terraform?
  • Terraform ?
  • Terraform ?

2017 . 2019- , ! . , .

, , , Terraform, .

  • Terraform. , Terraform 0.8. Terraform 0.12. , . , !
  • . Terraform. , , , , , , , .
  • . Terraform . , , — , .
  • . 8 , Terraform . , , , : , .
  • HCL2. Terraform 0.12 HCL HCL2. ( ${…}!), , , null, for_each for, . HCL2, 5 6.
  • . Terraform 0.9 . Terraform . Terraform 0.9 , ; 0.10 . 3.
  • Terraform. Terraform 0.10 ( AWS, GCP, Azure . .). , . terraform init , . 2 7.
  • . 2016 Terraform (AWS, GCP Azure). 100, , , 1. (, Alicloud, Oracle Cloud Infrastructure, VMware vSphere .), , (GitHub, GitLab BitBucket), (MySQL, PostreSQL InfluxDB), ( DataDog, New Relic Grafana), Kubernetes, Helm, Heroku, Rundeck Rightscale . , : , AWS , , CloudFormation!
  • Terraform. 2017 HashiCorp Terraform (registry.terraform.io) — , Terraform, . 2018 . Terraform 0.11 . « » . 153.
  • . Terraform 0.9 : , , errored.tfstate. Terraform 0.12 . , , .
  • . , (. « » . 144), « » (, « Terraform» . 242), plan apply (. « » . 64), create_before_destroy, count, (. «» . 160), , provider .

. Terraform


(muito mais atenção será dada às questões dos testes automáticos no livro posteriormente)

O mundo do DevOps está cheio de medos diferentes: todo mundo tem medo de permitir que as coisas funcionem, percam dados ou sejam invadidas. Ao fazer qualquer alteração, você sempre se pergunta quais as consequências que ela terá. Comportará o mesmo em todos os ambientes? Causará outra interrupção? E, se isso acontecer, quanto você precisará permanecer no trabalho dessa vez para consertá-lo? À medida que a empresa cresce, há mais em risco, tornando o processo de implantação ainda pior e aumentando o risco de erros. Muitas empresas tentam minimizar esse risco por meio de implantações menos frequentes, mas, como resultado, cada implantação individual se torna maior e mais propensa a erros.

Se você gerencia sua infraestrutura na forma de código, tem uma maneira melhor de minimizar os riscos: testes. O objetivo deles é dar a você confiança suficiente para fazer alterações. A palavra-chave aqui é confiança: nenhum teste pode garantir nenhum erro; portanto, é mais provável que você lide com a probabilidade. Se você pode capturar toda a sua infraestrutura e processos de implantação como código, pode testá-lo em um ambiente de teste. Se for bem-sucedido, há uma grande chance de que o mesmo código funcione em um ambiente industrial. Em um mundo de medo e incerteza, alta probabilidade e confiança são caras.

Neste capítulo, passaremos pelo processo de teste do código de infraestrutura, manual e automático, com ênfase no último.

Testes manuais:

  • noções básicas de teste manual;
  • limpando recursos após testes.

Testes automatizados:

  • testes de unidade;
  • testes de integração;
  • testes de ponta a ponta;
  • outras abordagens de teste.

Testes manuais


Ao pensar em como testar o código do Terraform, é útil traçar alguns paralelos com o código de teste escrito em linguagens de programação de uso geral, como Ruby. Imagine que você está escrevendo um servidor Web Ruby simples no arquivo web-server.rb:

class WebServer < WEBrick::HTTPServlet::AbstractServlet
  def do_GET(request, response)
     case request.path
     when "/"
         response.status = 200
         response['Content-Type'] = 'text/plain'
         response.body = 'Hello, World'
     else
         response.status = 404
         response['Content-Type'] = 'text/plain'
         response.body = 'Not Found'
     end
  end
end

Este código retornará uma resposta 200 OK com o corpo Hello, World para a URL /; para qualquer outro endereço, a resposta será 404. Como você testaria esse código manualmente? Normalmente, mais algum código é adicionado para executar o servidor da web localmente:

#   ,      
#  ,       
if __FILE__ == $0
  #      8000
  server = WEBrick::HTTPServer.new :Port => 8000
  server.mount '/', WebServer

  #    Ctrl+C
  trap 'INT' do server.shutdown end

  #  
  server.start
end

Se você executar este arquivo no terminal, ele carregará o servidor web na porta 8000:

$ ruby web-server.rb
[2019-05-25 14:11:52] INFO WEBrick 1.3.1
[2019-05-25 14:11:52] INFO ruby 2.3.7 (2018-03-28) [universal.x86_64-darwin17]
[2019-05-25 14:11:52] INFO WEBrick::HTTPServer#start: pid=19767 port=8000

Para verificar a operação deste servidor, você pode usar o navegador ou fazer uma espiral:

$ curl localhost:8000/
Hello, World

$ curl localhost:8000/invalid-path
Not Found

Agora imagine que alteramos esse código adicionando um ponto de entrada / api que retorna 201 Created e um corpo no formato JSON:

class WebServer < WEBrick::HTTPServlet::AbstractServlet
  def do_GET(request, response)
     case request.path
     when "/"
         response.status = 200
         response['Content-Type'] = 'text/plain'
         response.body = 'Hello, World'
     when "/api"
         response.status = 201
         response['Content-Type'] = 'application/json'
         response.body = '{"foo":"bar"}'
     else
         response.status = 404
         response['Content-Type'] = 'text/plain'
         response.body = 'Not Found'
     end
  end
end

Para testar manualmente esse código atualizado, pressione Ctrl + C e reinicie o servidor da Web executando o script novamente:

$ ruby web-server.rb
[2019-05-25 14:11:52] INFO WEBrick 1.3.1
[2019-05-25 14:11:52] INFO ruby 2.3.7 (2018-03-28) [universal.x86_64-darwin17]
[2019-05-25 14:11:52] INFO WEBrick::HTTPServer#start: pid=19767 port=8000
^C
[2019-05-25 14:15:54] INFO going to shutdown ...
[2019-05-25 14:15:54] INFO WEBrick::HTTPServer#start done.

$ ruby web-server.rb
[2019-05-25 14:11:52] INFO WEBrick 1.3.1
[2019-05-25 14:11:52] INFO ruby 2.3.7 (2018-03-28) [universal.x86_64-darwin17]
[2019-05-25 14:11:52] INFO WEBrick::HTTPServer#start: pid=19767 port=8000

Para verificar a nova versão, você pode novamente usar o comando curl:

$ curl localhost:8000/api
{"foo":"bar"}

Noções básicas de teste manual


Como será esse tipo de teste manual no Terraform? Por exemplo, dos capítulos anteriores, você ainda tem o código para implantar o ALB. Aqui está um trecho do arquivo modules / networking / alb / main.tf:

resource "aws_lb" "example" {
   name                     = var.alb_name
   load_balancer_type = "application"
   subnets                  = var.subnet_ids
   security_groups      = [aws_security_group.alb.id]
}

resource "aws_lb_listener" "http" {
   load_balancer_arn = aws_lb.example.arn
   port                      = local.http_port
   protocol                = "HTTP"

   #      404
   default_action {
      type = "fixed-response"

      fixed_response {
        content_type = "text/plain"
        message_body = "404: page not found"
        status_code = 404
      }
    }
}

resource "aws_security_group" "alb" {
   name = var.alb_name
}

# (...)

Se você comparar essa listagem com o código Ruby, poderá ver uma diferença bastante óbvia: o AWS ALB, grupos de destino, ouvintes, grupos de segurança e outros recursos não podem ser implantados em seu próprio computador.

A principal conclusão sobre o teste número 1 segue a partir disso: o teste de código Terraform não pode ser realizado localmente.

Isso se aplica não apenas ao Terraform, mas também à maioria das ferramentas de IaC. A única maneira prática de fazer testes manuais no Terraform é implantar o código em um ambiente real (ou seja, na AWS). Em outras palavras, iniciar de forma independente os comandos aplicar e destruir terraform que você trabalhou durante a leitura do livro é um teste manual no Terraform.

Esse é um dos motivos pelos quais é tão importante ter exemplos fáceis de implantar na pasta de exemplos de cada módulo (consulte o capítulo 6). Para testar o módulo alb, a maneira mais fácil é usar o código de demonstração que você criou nos exemplos / alb:

provider "aws" {
   region = "us-east-2"

   #     AWS  2.x
   version = "~> 2.0"
}

module "alb" {
    source = "../../modules/networking/alb"

    alb_name = "terraform-up-and-running"
    subnet_ids = data.aws_subnet_ids.default.ids
}

Para implantar este exemplo, você precisa executar o comando terraform apply, como fez repetidamente:

$ terraform apply

(...)

Apply complete! Resources: 5 added, 0 changed, 0 destroyed.

Outputs:

alb_dns_name = hello-world-stage-477699288.us-east-2.elb.amazonaws.com

No final da implantação, você pode usar uma ferramenta como curl para, por exemplo, garantir que o ALB retorne 404 por padrão:

$ curl \
   -s \
   -o /dev/null \
   -w "%{http_code}" \
hello-world-stage-477699288.us-east-2.elb.amazonaws.com

404

Verificação de infraestrutura

, HTTP, , , curl HTTP-. . , MySQL, MySQL. VPN-, VPN. , , SSH - . . , , . , .

Deixe-me lembrá-lo: O ALB retorna 404 devido à ausência de outras regras do ouvinte na configuração, e a ação padrão no módulo alb tem uma resposta 404:

resource "aws_lb_listener" "http" {
   load_balancer_arn = aws_lb.example.arn
   port                      = local.http_port
   protocol                = "HTTP"

   #      404
   default_action {
      type = "fixed-response"

      fixed_response {
       content_type = "text/plain"
       message_body = "404: page not found"
       status_code = 404
      }
   }
}

Então, você já sabe como executar e testar seu código. Agora você pode começar a fazer alterações. Toda vez que você altera algo (para que, por exemplo, a ação padrão retorne 401), você precisa usar o comando terraform apply para implantar o novo código:

$ terraform apply

(...)

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

Outputs:

alb_dns_name = hello-world-stage-477699288.us-east-2.elb.amazonaws.com

Para verificar a nova versão, você pode reiniciar o curl:

$ curl \
   -s \
   -o /dev/null \
   -w "%{http_code}" \
   hello-world-stage-477699288.us-east-2.elb.amazonaws.com
401

Quando terminar, execute o comando terraform destroy para remover os recursos:

$ terraform destroy

(...)

Apply complete! Resources: 0 added, 0 changed, 5 destroyed.

Em outras palavras, ao trabalhar com o Terraform, todo desenvolvedor precisa de boas amostras de código para testes e um ambiente de desenvolvimento real (como uma conta da AWS), que serve como o equivalente a um computador local e é usado para executar testes. No processo de teste manual, você provavelmente precisará criar e remover um grande número de componentes de infraestrutura, e isso pode levar a muitos erros. Nesse sentido, o ambiente deve ser completamente isolado de ambientes mais estáveis, destinados ao teste final e, em particular, para aplicações industriais.

Dado o exposto, recomendo vivamente que cada equipe de desenvolvimento prepare um ambiente isolado no qual você possa criar e remover qualquer infraestrutura sem consequências. Para minimizar a probabilidade de conflitos entre diferentes desenvolvedores (imagine que dois desenvolvedores estejam tentando criar um balanceador de carga com o mesmo nome), a solução ideal seria fornecer a cada membro da equipe um ambiente separado e completamente isolado. Por exemplo, se você usa o Terraform em conjunto com a AWS, cada desenvolvedor deve idealmente ter sua própria conta, onde pode testar tudo o que deseja.

Limpeza de recursos após testes


A presença de muitos ambientes isolados é necessária para a alta produtividade dos desenvolvedores, mas se você não tomar cuidado, poderá acumular muitos recursos extras que atrapalharão todos os seus ambientes e custarão uma soma redonda.
Para manter os custos sob controle, limpe regularmente sua mídia isolada. Esta é a principal conclusão sobre o teste número 2 .

Você deve, no mínimo, criar essa cultura na equipe quando, após o teste, os desenvolvedores excluírem tudo o que implementaram usando o comando terraform destroy. Pode ser possível encontrar ferramentas para limpar recursos em excesso ou antigos que podem ser executados regularmente (por exemplo, usando cron). Aqui estão alguns exemplos para diferentes ambientes de implementação.

  • cloud-nuke (http://bit.ly/2OIgM9r). , . AWS ( Amazon EC2 Instances, ASG, ELB . .). (Google Cloud, Azure) . — , . , cloud-nuke cron, . , , , :

    $ cloud-nuke aws --older-than 48h
  • Janitor Monkey (http://bit.ly/2M4GoLB). , AWS , ( — ). , , , . Netflix Simian Army, Chaos Monkey . , Simian Army , : , Janitor Monkey Swabbie (http://bit.ly/2OLrOLb).
  • aws-nuke (http://bit.ly/2ZB8lOe). Esta é uma ferramenta de código aberto para excluir todo o conteúdo de uma conta da AWS. As contas e os recursos a serem excluídos são especificados no arquivo de configuração no formato YAML:

    #   
    regions:
    - us-east-2
    
    #    
    accounts:
       "111111111111": {}
    
    #    
    resource-types:
       targets:
       - S3Object
       - S3Bucket
       - IAMRole

    O Aws-nuke começa da seguinte maneira:

    $ aws-nuke -5c config.yml

Testes automatizados


O conceito de teste automático é que os testes são escritos para testar o comportamento do código real. No Capítulo 8, você aprenderá que, usando o servidor de IC, esses testes podem ser executados após cada confirmação individual. Se não forem concluídas, a fixação pode ser desfeita ou corrigida imediatamente. Assim, seu código estará sempre operacional.

Existem três tipos de testes automatizados.

  • . — . , . (, , - ) mock-. (, mock- , ) , .
  • . . , . mock-: , , , , , , , mock-.
  • . (, , , ) . : , Selenium . - mock-, ( , ).

Cada tipo de teste tem seu próprio objetivo e, com a ajuda deles, você pode identificar todos os tipos de erros, portanto eles devem ser usados ​​juntos. Os testes de unidade são rápidos e permitem que você tenha uma idéia imediata das alterações feitas e verifique uma variedade de combinações. Isso lhe dá confiança de que os componentes elementares do seu código (módulos individuais) se comportam conforme o esperado. No entanto, o fato de os módulos funcionarem corretamente separadamente não significa que eles possam trabalhar juntos; portanto, para garantir que seus componentes elementares sejam compatíveis, são necessários testes de integração. Por outro lado, o comportamento correto de diferentes partes do sistema não garante que esse sistema funcione como deveria após a implantação em um ambiente industrial; portanto, são necessários testes para testar seu código em condições próximas às reais.

»Mais informações sobre o livro podem ser encontradas no site da editora
» Conteúdo
» Trecho

Para Khabrozhiteley desconto de 25% no cupom - Terraform

Após o pagamento da versão impressa do livro, um livro eletrônico é enviado por e-mail.

All Articles