Le livre "Terraform: infrastructure au niveau du code"

imageBonjour, habrozhiteli! Le livre est destiné à tous ceux qui sont responsables du code déjà écrit. Cela s'applique aux administrateurs système, aux spécialistes des opérations, aux ingénieurs des versions, SR, DevOps, aux développeurs d'infrastructure, aux développeurs à cycle complet, aux chefs d'équipe d'ingénierie et aux directeurs techniques. Quelle que soit votre position, si vous êtes impliqué dans l'infrastructure, déployez du code, configurez des serveurs, mettez à l'échelle des clusters, sauvegardez des données, surveillez des applications et répondez à des appels à trois heures du matin, ce livre est pour vous.

Ensemble, ces responsabilités sont communément appelées activités opérationnelles (ou administration du système). Auparavant, les développeurs qui savaient écrire du code mais ne comprenaient pas l'administration système étaient souvent rencontrés; les administrateurs système ont souvent rencontré sans la possibilité d'écrire du code. Une fois que cette séparation était acceptable, mais dans le monde moderne, qui ne peut plus être imaginé sans le cloud computing et le mouvement DevOps, presque tous les développeurs ont besoin de compétences administratives et tout administrateur système doit pouvoir programmer.

Vous apprendrez non seulement comment gérer l'infrastructure sous forme de code à l'aide de Terraform, mais aussi comment elle s'intègre dans le concept global de DevOps. Voici quelques questions auxquelles vous pouvez répondre en lisant ce livre.

  • Pourquoi utiliser 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


(beaucoup plus d'attention est accordée aux questions des tests automatiques dans le livre plus tard)

Le monde DevOps est plein de peurs différentes: tout le monde a peur de permettre aux choses de fonctionner, de perdre des données ou d'être piraté. Lorsque vous effectuez un changement, vous vous demandez toujours quelles conséquences cela aura. Se comportera-t-il de la même manière dans tous les environnements? Cela provoquera-t-il une autre panne? Et, si cela se produit, combien devrez-vous rester au travail cette fois pour y remédier? Au fur et à mesure que l'entreprise grandit, de nouveaux enjeux sont en jeu, ce qui aggrave le processus de déploiement et augmente le risque d'erreurs. De nombreuses entreprises tentent de minimiser ce risque par des déploiements moins fréquents, mais en conséquence, chaque déploiement individuel devient plus important et plus sujet aux erreurs.

Si vous gérez votre infrastructure sous forme de code, vous avez un meilleur moyen de minimiser les risques: les tests. Leur objectif est de vous donner suffisamment confiance pour apporter des changements. Le mot clé ici est la confiance: aucun test ne peut garantir aucune erreur, vous êtes donc plus susceptible de gérer la probabilité. Si vous pouvez capturer tous vos processus d'infrastructure et de déploiement sous forme de code, vous pouvez tester ce code dans un environnement de test. En cas de succès, il y a de grandes chances que le même code fonctionne dans un environnement industriel. Dans un monde de peur et d'incertitude, une probabilité et une confiance élevées coûtent cher.

Dans ce chapitre, nous allons passer en revue le processus de test du code d'infrastructure, à la fois manuel et automatique, en mettant l'accent sur ce dernier.

Tests manuels:

  • bases des tests manuels;
  • nettoyage des ressources après les tests.

Tests automatisés:

  • tests unitaires;
  • tests d'intégration;
  • tests de bout en bout;
  • d'autres approches de test.

Tests manuels


Lorsque vous réfléchissez à la façon de tester le code Terraform, il est utile de faire des parallèles avec le code de test écrit dans des langages de programmation à usage général comme Ruby. Imaginez que vous écrivez un simple serveur Web Ruby dans le fichier 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

Ce code renverra une réponse 200 OK avec le corps Hello, World pour l'URL /; pour toute autre adresse, la réponse sera 404. Comment testeriez-vous ce code manuellement? En règle générale, un peu plus de code est ajouté pour exécuter le serveur Web localement:

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

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

  #  
  server.start
end

Si vous exécutez ce fichier dans le terminal, il chargera le serveur Web sur le port 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

Pour vérifier le fonctionnement de ce serveur, vous pouvez utiliser le navigateur ou curl:

$ curl localhost:8000/
Hello, World

$ curl localhost:8000/invalid-path
Not Found

Imaginez maintenant que nous avons changé ce code en y ajoutant un point d'entrée / api qui renvoie 201 Created et un corps au format 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

Pour tester manuellement ce code mis à jour, appuyez sur Ctrl + C et redémarrez le serveur Web en exécutant à nouveau le script:

$ 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

Pour vérifier la nouvelle version, vous pouvez à nouveau utiliser la commande curl:

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

Bases des tests manuels


À quoi ressemblera ce type de test manuel dans Terraform? Par exemple, dans les chapitres précédents, vous avez toujours le code pour déployer ALB. Voici un extrait du fichier 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
}

# (...)

Si vous comparez cette liste avec le code Ruby, vous pouvez voir une différence assez évidente: AWS ALB, les groupes cibles, les écouteurs, les groupes de sécurité et toutes les autres ressources ne peuvent pas être déployés sur votre propre ordinateur.

La principale conclusion concernant le test n ° 1 en découle: le test de code Terraform ne peut pas avoir lieu localement.

Cela s'applique non seulement à Terraform, mais aussi à la plupart des outils IaC. Le seul moyen pratique de faire des tests manuels dans Terraform est de déployer le code dans un environnement réel (c'est-à-dire dans AWS). En d'autres termes, le lancement indépendant des commandes terraform apply et terraform destroy sur lesquelles vous avez travaillé pendant la lecture du livre est un test manuel dans Terraform.

C'est l'une des raisons pour lesquelles il est si important d'avoir des exemples faciles à déployer dans le dossier d'exemples de chaque module (voir chapitre 6). Pour tester le module alb, la façon la plus simple est d'utiliser le code de démonstration que vous avez créé dans examples / 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
}

Pour déployer cet exemple, vous devez exécuter la commande terraform apply, comme vous l'avez fait à plusieurs reprises:

$ 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

À la fin du déploiement, vous pouvez utiliser un outil tel que curl pour, par exemple, vous assurer que ALB renvoie 404 par défaut:

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

404

Vérification de l'infrastructure

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

Permettez-moi de vous rappeler: ALB renvoie 404 en raison de l'absence d'autres règles d'écoute dans la configuration, et l'action par défaut dans le module alb a une réponse de 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
      }
   }
}

Donc, vous savez déjà comment exécuter et tester votre code. Vous pouvez maintenant commencer à apporter des modifications. Chaque fois que vous modifiez quelque chose (pour que, par exemple, l'action par défaut renvoie 401), vous devez utiliser la commande terraform apply pour déployer le nouveau code:

$ 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

Pour vérifier la nouvelle version, vous pouvez redémarrer curl:

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

Une fois terminé, exécutez la commande terraform destroy pour supprimer les ressources:

$ terraform destroy

(...)

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

En d'autres termes, lorsque vous travaillez avec Terraform, chaque développeur a besoin de bons exemples de code pour les tests et d'un environnement de développement réel (comme un compte AWS), qui sert d'équivalent à un ordinateur local et est utilisé pour exécuter des tests. Dans le processus de test manuel, vous devrez probablement créer et supprimer un grand nombre de composants d'infrastructure, ce qui peut entraîner de nombreuses erreurs. À cet égard, l'environnement doit être complètement isolé des environnements plus stables destinés aux tests finaux et en particulier aux applications industrielles.

Compte tenu de ce qui précède, je recommande fortement à chaque équipe de développement de préparer un environnement isolé dans lequel vous pouvez créer et supprimer toute infrastructure sans conséquences. Pour minimiser la probabilité de conflits entre différents développeurs (imaginez que deux développeurs tentent de créer un équilibreur de charge avec le même nom), la solution idéale serait de donner à chaque membre de l'équipe un environnement séparé et complètement isolé. Par exemple, si vous utilisez Terraform en conjonction avec AWS, chaque développeur devrait idéalement avoir son propre compte où il peut tester tout ce qu'il veut.

Nettoyage des ressources après les tests


La présence de nombreux environnements isolés est nécessaire pour la haute productivité des développeurs, mais si vous ne faites pas attention, vous pouvez accumuler beaucoup de ressources supplémentaires qui encombreront tous vos environnements et vous coûteront une somme ronde.
Pour maîtriser les coûts, nettoyez régulièrement vos supports isolés. Telle est la principale conclusion concernant le test numéro 2 .

Au minimum, vous devez créer une telle culture dans l'équipe lorsque, après les tests, les développeurs suppriment tout ce qu'ils ont déployé à l'aide de la commande terraform destroy. Il peut être possible de trouver des outils pour nettoyer les ressources excédentaires ou anciennes qui peuvent être exécutées régulièrement (par exemple, en utilisant cron). Voici quelques exemples pour différents environnements de déploiement.

  • 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). Il s'agit d'un outil open source pour supprimer tout le contenu d'un compte AWS. Les comptes et ressources à supprimer sont spécifiés dans le fichier de configuration au format YAML:

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

    Aws-nuke commence comme suit:

    $ aws-nuke -5c config.yml

Tests automatisés


Le concept du test automatique est que les tests sont écrits pour tester le comportement du code réel. Au chapitre 8, vous apprendrez qu'en utilisant le serveur CI, ces tests peuvent être exécutés après chaque validation individuelle. S'ils ne sont pas terminés, la fixation peut être immédiatement annulée ou corrigée. Ainsi, votre code sera toujours opérationnel.

Il existe trois types de tests automatisés.

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

Chaque type de test a son propre objectif, et avec leur aide, vous pouvez identifier toutes sortes d'erreurs, elles doivent donc être utilisées ensemble. Les tests unitaires sont rapides et vous permettent de vous faire une idée immédiate des modifications apportées et de vérifier une variété de combinaisons. Cela vous donne la certitude que les composants élémentaires de votre code (modules individuels) se comportent comme prévu. Cependant, le fait que les modules fonctionnent correctement séparément ne signifie pas du tout qu'ils peuvent fonctionner ensemble, par conséquent, pour vous assurer que vos composants élémentaires sont compatibles, des tests d'intégration sont nécessaires. D'un autre côté, le comportement correct des différentes parties du système ne garantit pas que ce système fonctionnera comme il se doit après le déploiement dans un environnement industriel.Par conséquent, des tests sont nécessaires pour tester votre code dans des conditions proches des conditions réelles.

»Plus d'informations sur le livre peuvent être trouvées sur le site Web de l'éditeur
» Contenu
» Extrait

pour Khabrozhiteley 25% de réduction sur le coupon - Terraform

Lors du paiement de la version papier du livre, un livre électronique est envoyé par e-mail.

All Articles