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.
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.
Terraform propose désormais une registry de modules Terraform prêts à l'emploi (ex: vpc, autoscaling, rds, elb, ...)
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.
Des bonnes pratiques pour gérer son infrastructure avec terraform:
- utiliser un bucket s3 versionné et chiffré plutôt qu'un repo git comme datastore
- isoler chaque environnements dans des states séparés
- isoler chaque rôle (network, database, application, ...) dans des states séparés