Table des matières
Terraform
Télécharger du site de Terraform, décompresser et copier dans un répertoire du PATH:
$ sudo mv ./terraform /usr/local/bin
Sur macOS, peut être installé avec Brew:
$ brew install terraform
Commandes
Initialiser terraform:
$ terraform init
Validation (non garantie):
$ terraform validate
Plan:
$ terraform plan $ terraform plan -out file.tfplan
Apply:
$ terraform apply "file.tfplan"
Destroy:
$ terraform destroy $ terraform destroy -auto-approve
Configuration
Backend
Créer un fichier dans le home directory nommé .terraformrc
:
credentials "app.terraform.io" { token = "xxxxxx.atlasv1.zzzzzzzzzzzzz" }
Dans le répertoire de travail de Terraform, créer un fichier de configuration main.tf
.
terraform { backend "remote" { hostname = "app.terraform.io" organization = "company" workspaces { name = "workspace-name" } } }
Faire l'initialisation par la suite.
$ terraform init
Sources : CLI Configuration File et Backend - Remote.
Variables
On peut spécifier le nom, le type et la valeur par défaut d'une variable.
# Spécifier la valeur par défaut et le type (les deux sont facultatifs) variable "environment_name" { type = string default = "development" } # Spécifier la valeur de la variable environment_name = "uat"
On peut déclarer des variables de plusieurs sources, celles-ci on une précédence:
- Variable d'environnement
- Fichier
- Ligne de commande
Cela signifie qu'une variable qui est initialisée dans un fichier écrasera la valeur de cette variable initialisé depuis une variable d'environnement.
Spécifier une valeur in-line en ligne de commande:
$ terraform -plan -var 'environment_name=production'
Exemples
Avec map:
variable "cidr" { type = map(string) default = { development = "10.0.0.0/16" uat = "10.1.0.0/16" production = "10.2.0.0/16" } }
Utilisation:
cidr_block = lookup(var.cidr, var.environment_name)
Datasources
Ressources
Random provider:
resource "random_integer" "rand" { min = 10000 max = 99999 }
Resource Arguments
depends_on
: nommer explicitement une dépendance à une autre ressourcecount
:for_each
:provider
: utilisation explicite d'un provider quand on en utilise plusieurs
Exemple de count
et depends_on
:
resource "aws_instance" "taco_servers" { count = 2 tags { Name = "customer-${count.index}" # Commence à 0 } depends_on = [aws_iam_role_policy.allow_s3] }
Exemple de for-each
:
resource "aws_s3_bucket" "taco_toppings" { for_each { food = "public-read" cash = "private" } bucket = "${each.key}-${var.bucket_suffix}" acl = each.value }
Provisioner
File
Simple:
provisioner "file" { source = "/local/path/to/file.txt" destination = "/path/to/file.txt" }
Avec connection
:
provisioner "file" { connection { type = "ssh" user = "root" private_key = "${var.private_key}" host = "${var.hostname}" } source = "/local/path/to/file.txt" destination = "/path/to/file.txt" }
Avec content
:
provisioner { content = <<EOF access_key = secret_key = security_token = use_https = True bucket_location = US EOF destination = "/home/ec2-user/.s3cfg" }
Remote
Inline:
provisioner "remote-exec" { inline = [ "puppet apply", "consul join ${aws_instance.web.private_ip}", ] }
Script:
provisioner "remote-exec" { scripts = [ "./scripts/01_post-install.sh", ] }
Syntaxe
Utilise le HCL, qui est un langage de HashiCorp.
Types de données:
string = "taco" number = 5 bool = true list = ["Montréal", "New York"] map = {name = "Ned", age = 42, loves_tacos = true}
Références:
var.taco_day aws_instance.taco_truck.name local.taco_toppings.cheeses module.taco_hut.locations
Référencer une chaîne, nombre et booléen:
local.taco_count # retourne le nombre
Référencer un élément d'une liste ou une map:
local.taco_toppings[2] # retourne l'élément 3 local.taco_map["likes_tacos"] # retourne la valeur à cette clé
Valeurs des ressources:
var.region # us-east-1 data.aws_availability_zones.azs.names[1] # retourne la deuxième zone de disponibilité
Interpolation:
taco_name = "neds-${var.taco_type}"
Locals
locals { common_tags = { BillingCode = var.billing_code_tag Environment = var.environment_tag } s3_bucket_name = "${var.bucket_name_prefix}-${var.environment_tag}-${random_integer.rand.result}" }
Fonctions
Exemples de fonctions communes:
min(42, 8, 13) # Numérique lower("TACOS") # Chaine merge(map1, map2) # Collection file(path) # Filesystem cidrsubnet("10.1.2.0/24", 4, 15) # IP Network timestamp() # Date and time
# Configure networking variable network_info { default = "10.1.0.0/16" } cidr_block = cidrsubnet(var.network_info, 8, 0) # retourne 10.1.0.0/24 host_ip = cidrhost(var.network_info, 5) # retourne 10.1.0.5
On peut utiliser terraform console
pour évaluer et tester les fonctions.
⇒ Référence: Functions
Gérer les environnements
On peut gérer les environnements de différentes façons. On peut le faire avec les Workspaces, mais aussi en indiquant les fichiers à utiliser.
|-- /dev | |-- dev.state | |-- dev.tfvars |-- /uat | |-- uat.state | |-- uat.tfvars |-- /prod | |-- prod.state | |-- prod.tfvars |-- main_config.tf |-- common.tfvars
La commande à utiliser:
$ terraform plan -state=".\dev\dev.state" -var-file="common.tfvars" -var-file=".\dev\dev.tfvars"
Workspaces
$ terraform workspace new dev $ terraform plan
Modules
- Réutilisation du code
- Remote ou local source
- Root module
- Versioning
- Provider inheritance
Composantes:
- Variables d'entrée
- Ressources
- Variables de sortie
Example d'utilisation:
# Créer le module module "bucket" { name = "taco-bucket" source = ".\\Modules\\s3" } # L'utiliser ressource "aws_s3_bucket_object" { bucket = module.bucket.bucket_id [...] }
Autres examples
provider "aws" { #Virginia, USA region = "us-east-1" } resource "aws_instance" "example" { #Ubuntu 14.04 AMI (Amazon Machine Image) ami = "ami-2d39803a" instance_type = "t2.micro" tags { #tags WILL CHANGE the state of previous runnings resources. Name = "My Instance Name" } }
Sources
- PluralSight Terraform Getting started.