Qu’est-ce que du IaC?

Faire de l’Infrastructure as Code (IaC) veut dire que notre infrastructure est gérée par du code plutôt que manuellement. Le but est d’écrire les spécifications de notre infrastructure dans des fichiers de configuration. De cette façon, nous pouvons facilement modifier l’infrastructure tout en ayant une trace et il est plus facile de partager l’information.

Pourquoi faire du IaC?

  1. Transparence et traçabilité: On suppose ici que les bonnes pratiques de développement sont en place, mais si notre configuration est versionnée (sous git, par exemple), il sera toujours possible d’avoir un timeline de notre infrastructure. On ne cherche pas à blâmer ou chercher un coupable, nous préconisons la transparence.

  2. Réduction du nombre d’erreurs: Si les modifications à la configuration passent par des revues de code et du testing, nous mettons toutes les chances de notre côté et prenons confiance en ce que nous faisons.

  3. Déploiements plus rapides: Une modification est soumise en revue de code. Si l’équipe l’approuve et que les tests passent avec succès, la mise en production d’une modification d’infrastructure n’est qu’une question d’appuyer sur un bouton. On s’éloigne grandement du temps où il fallait soumettre des plans de déploiements et attendre qu’un sysadmin effectue la modification voulue. L’overhead est réduit au maximum.

  4. Amélioration de la cohérence de l’infrastructure: Avec une bonne configuration, il est possible de faire de la réutilisation de code et faire en sorte que chaque composante de notre infrastructure soit “standard” avec ce que nous avons.

  5. Facilité de réplication: En cas de sinistre dans votre région ou availability zone, une configuration IaC bien montée devrait permettre de relancer votre environnement dans une autre région en ne changeant que quelques variables.

Est-ce une solution magique?

Non. La pratique du IaC vient avec son lot de défis.

  1. Courbe d’apprentissage: L’apprentissage d’une nouvelle technologie tant au niveau du langage utilisé, les concepts de développement qui peuvent être tout nouveaux ou l’écosystème du IaC peuvent être un obstacle à l’implantation de IaC pour gérer une infrastructure.

  2. Debug: Lorsque l’exécution échoue, il peut être difficile de reprendre là où le problème a eu lieu. De plus, il m’est arrivé d’avoir des frustrations par rapport à des cas d’erreurs qui aurait été plus facile à gérer à la main.

  3. Demande de la discipline: Ce n’est pas agréable de gérer du code et une infrastructure qui ne concordent pas. Nous verrons plus tard comment gérer cela automatiquement, mais dans les premiers jours, si vous avez le malheur de faire des changements manuels et ensuite vous relancez votre projet IaC, vous pourriez avoir des surprises.

Comment cela a été fait pour ce blog?

TLDR: Tout est dans ce repo: https://github.com/nylo-andry/tf-rahonasydevops.com. J’expliquerai les points importants si vous souhaitez plus d’informations.

Nous utiliserons terraform comme technologie. Ce post n’a pas pour but de vous apprendre terraform, je vous recommanderais plutôt leurs excellents tutoriels

S3

Si vous vous souvenez du post précédent, nous avons créé un bucket S3 qui héberge notre blog avec quelques cliques et en entrant de l’information. Voici la manière de faire exactement la même chose:

Pour le bucket:

resource "aws_s3_bucket" "rahonasydevops_com" {
  bucket = "rahonasydevops.com"

  force_destroy = true

  tags = {
    Name = "rahonasydevops.com"
  }
}

Pour la configuration de site web:

resource "aws_s3_bucket_website_configuration" "rahonasydevops_com" {
  bucket = aws_s3_bucket.rahonasydevops_com.bucket

  index_document {
    suffix = "index.html"
  }
}

Et nous allons définir en sortie l’endpoint du site web pour la passer à Cloudflare

output "rahonasydevops_com_endpoint" {
  value = aws_s3_bucket_website_configuration.rahonasydevops_com.website_endpoint
}

Cloudflare

Pour le côté Cloudflare, j’ai volontairement décidé de gérer la zone manuellement pour un faux sentiment de sécurité.

Cette zone peut donc être obtenue comme une data dans Terraform:

data "cloudflare_zone" "rahonasydevops_com" {
  name = "rahonasydevops.com"
}

La seule ressource créé par Terraform dans Cloudflare est donc l’entrée DNS qui va vers le site:

resource "cloudflare_record" "apex_rahonasydevops_com" {
  zone_id = data.cloudflare_zone.rahonasydevops_com.id
  name    = "rahonasydevops.com"
  value   = var.rahonasydevops_com_endpoint
  type    = "CNAME"
  proxied = true
  ttl     = 1
}

Note: La valeur pour l’entrée DNS est une var car nous avons passé la valeur d’un module terraform à un autre.

Et la policy?

Le provider Cloudflare expose une data source qui retournes les IPs de Cloudflare.

Nous pouvons donc déclarer la sources comme ceci:

data "cloudflare_ip_ranges" "cloudflare" {}

Du côté de S3, voici comment définir la policy ne donnant accès au bucket qu’à Cloudflare:

resource "aws_s3_bucket_policy" "allow_access_from_cloudflare" {
  bucket = aws_s3_bucket.rahonasydevops_com.id
  policy = data.aws_iam_policy_document.allow_access_from_cloudflare.json
}

data "aws_iam_policy_document" "allow_access_from_cloudflare" {
  statement {
    sid = "AllowCloudflareAccessOnly"

    principals {
      type        = "*"
      identifiers = ["*"]
    }

    condition {
      test     = "IpAddress"
      variable = "aws:SourceIp"
      values   = var.cloudflare_ip_ranges
    }

    actions = [
      "s3:GetObject"
    ]

    resources = [
      "${aws_s3_bucket.rahonasydevops_com.arn}/*",
    ]
  }
}

Vous pouvez voir l’exemple complet du code dans ce repo.

Et ensuite?

Dans un monde idéal, le contenu d’un repository IaC ne se lance pas sur un poste en local. Nous poursuivrons dans le prochain post en utilisant les GitHub Actions pour déployer notre infrastructure automatiquement.