InSpec-Iggy permet de générer des règles de compliances InSpec pour les cloud AWS, Azure et GCP à partir de tfstate
Terraform.
Il est possible de générer des règles de compliances incluant le tfstate
Terraform ou l'excluant. Ce derniers cas est intéressant pour vérifier que rien n'est provisionné dans le cloud en dehors de Terraform.
Procedure pour installer differentes versions d'un logiciel avec brew:
$ git clone git@github.com:Homebrew/homebrew-core.git
$ cd homebrew-core
$ git log master -- Formula/terraform.rb
# retrouver le commit de la version qu'on souhaite installer
$ git checkout <commitid>
$ cd Formula
$ brew unpin terraform
$ brew unlink terraform
$ brew install terraform.rb
$ brew pin terraform
$ brew switch terraform <version>
Pour gérer les versions de Terraform, je préfère utiliser tfenv, mais la procédure est valable pour n'importe quel logiciel installable avec brew.
AWS EKS gère désormais les node groups de workers en tant que ressources managées (avant il fallait gérer soit même les ASG de workers nodes).
En plus c'est déjà géré par la nouvelle version du provider terraform-aws
Le getting started officiel Hashicorp pour déployer un cluster EKS avec Terraform.
Le code est ici: https://github.com/terraform-providers/terraform-provider-aws/tree/master/examples/eks-getting-started
EDIT:
NOTE: The usage of the specific kubernetes.io/cluster/ resource tags below are required for EKS and Kubernetes to discover and manage networking resources.
NOTE: The usage of the specific kubernetes.io/cluster/ resource tag below is required for EKS and Kubernetes to discover and manage compute resources.
voir également: https://github.com/kubernetes/cloud-provider-aws/blob/8f6e1e3d2cfa20a0deac088b9c4022d433500369/pkg/cloudprovider/providers/aws/tags.go#L30-L52
Je n'ai pas trouvé de doc officielle claire indiquant les tags à mettre en place sur les ressources AWS, mais après avoir passé 2 jours à débugguer pourquoi mes ELB ne se provisionnaient pas, puis pourquoi mes Nodes n'arrivaient pas à joindre le cluster EKS, je confirme que ces tags sont très importants à ajouter sur les ressources suivantes:
- VPC
- Subnets
- Security Groups
- Instances EC2
Une bonne introduction au déploiement d'infra sur Azure avec Ansible et Terraform. A noter l'utilisation du module Ansible pour Terraform.
Un petit tuto pour créer un cluster AKS (K8S managé Azure) avec Terraform.
Terratest est un framework de test en Go pour automatiser les tests d'infrastructure Terraform, mais aussi Packer et Docker build.
Atlantis permet d'orchestrer la planification et l'application topologies Terraform depuis des pull requests GitHub, GitLab où BitBucket.
Atlantis fait désormais partie d'Hashicorm (cf. https://medium.com/runatlantis/joining-hashicorp-200ee9572dc5)
Un tuto pour provisioner des ressources sur GCP avec Terraform
Topologies Terraform pour déployer la configurations IAM nécessaire pour accéder à un compte AWS depuis un autre compte (assume-role) dans une architecture AWS multi-comptes.
terraform-docs génère une doc au format markdown ou json à partir des templates terraform
Terraform propose désormais une registry de modules Terraform prêts à l'emploi (ex: vpc, autoscaling, rds, elb, ...)
Pour installer un cluster Kubernetes privé avec KOPS sur une infra AWS déjà existante (DNS, VPC, Subnets, ...)
EDIT
en complement un tuto qui permet de faire quasimment la même chose mais en utilisant KOPS pour exporter une configuration Terraform pour ceux qui utilisent déjà Terraform pour le reste de leur infrastructure:
https://ryaneschinger.com/blog/kubernetes-aws-vpc-kops-terraform/
Kops permet de créer un cluster Kubernetes complet et haute-dispo sur AWS.
Parmi les nombreuses features intéressantes:
- instances EC2 basées sur Debian
- instances dans des ASG (master et nodes)
- possibilité de créer un VPC dédié ou d'en utiliser un existant
- possibilité d'exporter la config au format terraform pour provisionner le cluster avec terraform
Depuis Terragrunt v0.10.0, la configuration S3 et DynamoDB permettant de gérer les states et lock Terraform se trouve dans terraform.tfvars
au lieu de .terragrunt
.
Exemple de configuration avec un repo de configuration et un repos module:
- arborescence:
* terraform-configuration-repo
|- dev
|- test
|- prod
|- application
| |- terraform.tfvars
| |- main.tfvars (symlink -> ../main.tfvars)
|- terraform.tfvars
|- main.tfvars
* terraform-module-application-repo
|- main.tf
|- vars.tf
|- ...
- terragrunt configuration spécifique to
application
:
# terraform-configuration/prod/application/terraform.tfvars
terragrunt = {
terraform {
source = "git@github.com:myuser/tf-modules-application-repo.git///ref=1.0.0"
extra_arguments "main" {
arguments = [
"-var-file=main.tfvars",
"-var-file=terraform.tfvars"
]
commands = [
"plan",
"apply"
]
}
}
include {
path = "${find_in_parent_folders()}"
}
}
# variables specifics to application module
var1 = "XXX"
var2 = "YYY"
# var3 can override var3 from main.tfvars environment variables
var3 = "BBB"
...
- terragrunt configuration spécifique to
prod
environnement:
# terraform-configuration/prod/terraform.tfvars
terragrunt = {
# Configure Terragrunt to use DynamoDB for locking
lock = {
backend = "dynamodb"
config {
state_file_id = "prod"
}
}
# Configure Terragrunt to automatically store tfstate files in an S3 bucket
remote_state = {
backend = "s3"
config {
encrypt = "true"
bucket = "s3-terraform-states"
key = "prod/${path_relative_to_include()}/terraform.tfstate"
}
}
}
- global variables for
prod
environment:
# terraform-configuration/prod/main.tfvars
# variables specifics to prod environment
var3 = "ZZZ"
var4 = "AAA"
Les slides de Gruntwork qui résument toutes les bonnes pratiques Terraform présentés dans leur série d'article
Cf. liens précédents:
Workflow proposé par Gruntwork pour les changements d'infrastructure avec Terraform:
- Vérifier les effets du changements avec
terraform plan
- Appliquer le changement en environnement de test avec
terraform apply
- Pusher le changement sur une branche et soumettre une pull-request à reviewer
- Merger la PR sur master après la code review
- Appliquer le changement en environnement de production avec
terraform apply
Des astuces pour utiliser des boucles et des conditions avec Terraform en utilisant le paramètre count
au sein des ressources:
- comme un compteur pour les boucles
- comme un booléen (0=false, 1=true) pour les conditions
On peut ensuite utiliser la fonction element
pour récupérer l'élément d'une liste correspondant à l'indice de count
ou utiliser la fonction replace
pour remplacer 0 ou 1 par des valeurs différentes par exemple.
C'est plutôt tricky mais ça à l'air de faire le job.
Best practices pour Terraform:
- utiliser des modules contenant le code nécessaire au provisinning des services
- appeler les modules depuis les répertoires de configuration spécifiques aux environnements en passant en variables les données spécifiques aux environnements
- séparer les modules et la configuration spécifique aux environnements dans 2 repos git différents afin de pouvoir appeler des versions du module différent selon les environnements (en utilisant les tags git)
ex:
- infrastructure-live-repo
| - dev
| | - app1
| | - app2
| | - db1
| | - vpc
| - test
| | - ...
| - prod
| | - ...
| - mgmt
| | - bastion
| | - ...
| - global
| | - iam
| | - route53
| | - ...
- infrastructure-modules-repo (tags v0.0.1, v0.0.2, ...)
| - app1
| - app2
| - db1
| - vpc
| - bastion
| - ...
Terraform 0.8 est sorti.
Au menu:
- une amélioration de la gestion des conditions (même s'il reste encore énormément de chemin à faire de ce côté)
- Le mode console permettant d'interroger les states et de tester les interpolations
- les ressources peuvent maintenant être dépendantes d'un module
Attention, certains changements provoquent des incompatibilités avec les versions précédentes. Lire la partie upgrade de la release note pour vérifier les changements nécessaires.