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.
