Skip to main content

Terraform Providers


Chapter objectives

  • Understand the role of providers
  • Configure the main providers
  • Manage multiple providers
  • Use provider aliases

1 - What is a provider?

Definition

A provider is a plugin that allows Terraform to communicate with an external API.

Types of providers

TypeExamplesUse
Cloudaws, azurerm, googleCloud infrastructure
Infrastructurekubernetes, helm, dockerOrchestration
SaaSgithub, gitlab, datadogThird-party services
Utilityrandom, local, nullHelpers

2 - Terraform Registry

Provider sources

Source format

terraform {
required_providers {
# Format: namespace/name
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}

# Provider partenaire
datadog = {
source = "DataDog/datadog"
version = "~> 3.0"
}

# Provider communautaire
github = {
source = "integrations/github"
version = "~> 5.0"
}
}
}

3 - Configuring the AWS provider

Basic configuration

terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

provider "aws" {
region = "eu-west-1"
}

Authentication methods

Advanced configuration

provider "aws" {
region = "eu-west-1"

# Profil AWS CLI
profile = "production"

# Assume role
assume_role {
role_arn = "arn:aws:iam::123456789012:role/TerraformRole"
session_name = "terraform"
}

# Tags par défaut
default_tags {
tags = {
Environment = "Production"
ManagedBy = "Terraform"
}
}

# Ignorer certains tags
ignore_tags {
keys = ["LastModified", "CreatedBy"]
}
}

4 - Configuring the Azure provider

Basic configuration

terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
}
}
}

provider "azurerm" {
features {}
}

Authentication

# Via Service Principal
provider "azurerm" {
features {}

subscription_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
client_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
client_secret = var.client_secret
tenant_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

# Ou via variables d'environnement
# ARM_SUBSCRIPTION_ID
# ARM_CLIENT_ID
# ARM_CLIENT_SECRET
# ARM_TENANT_ID

The features block

provider "azurerm" {
features {
resource_group {
prevent_deletion_if_contains_resources = false
}

virtual_machine {
delete_os_disk_on_deletion = true
graceful_shutdown = true
skip_shutdown_and_force_delete = false
}

key_vault {
purge_soft_delete_on_destroy = true
}
}
}

5 - Configuring the GCP provider

Basic configuration

terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
}
}

provider "google" {
project = "my-project-id"
region = "europe-west1"
}

Authentication

# Via fichier de credentials
provider "google" {
credentials = file("service-account-key.json")
project = "my-project-id"
region = "europe-west1"
}

# Ou via variable d'environnement
# GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json

6 - Multiple providers and aliases

Multiple regions

# Provider par défaut
provider "aws" {
region = "eu-west-1"
}

# Provider avec alias pour une autre région
provider "aws" {
alias = "us_east"
region = "us-east-1"
}

# Utilisation
resource "aws_instance" "eu_server" {
# Utilise le provider par défaut
ami = "ami-12345678"
instance_type = "t2.micro"
}

resource "aws_instance" "us_server" {
# Utilise le provider avec alias
provider = aws.us_east
ami = "ami-87654321"
instance_type = "t2.micro"
}

Multi-cloud

# AWS
provider "aws" {
region = "eu-west-1"
}

# Azure
provider "azurerm" {
features {}
}

# GCP
provider "google" {
project = "my-project"
region = "europe-west1"
}

# Ressources dans chaque cloud
resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t2.micro"
}

resource "azurerm_linux_virtual_machine" "web" {
# ...
}

resource "google_compute_instance" "web" {
# ...
}

Multiple accounts

provider "aws" {
alias = "production"
profile = "prod"
region = "eu-west-1"
}

provider "aws" {
alias = "development"
profile = "dev"
region = "eu-west-1"
}

# Prod resources
resource "aws_instance" "prod_server" {
provider = aws.production
# ...
}

# Dev resources
resource "aws_instance" "dev_server" {
provider = aws.development
# ...
}

7 - Utility providers

Random

provider "random" {}

resource "random_id" "bucket_suffix" {
byte_length = 4
}

resource "random_password" "db" {
length = 16
special = true
}

resource "random_pet" "server" {
length = 2
}

# Utilisation
resource "aws_s3_bucket" "example" {
bucket = "my-bucket-${random_id.bucket_suffix.hex}"
}

Local

provider "local" {}

# Créer un fichier local
resource "local_file" "config" {
filename = "${path.module}/config.json"
content = jsonencode({
server = aws_instance.web.public_ip
port = 8080
})
}

Null

provider "null" {}

# Provisioner sans ressource réelle
resource "null_resource" "setup" {
triggers = {
instance_id = aws_instance.web.id
}

provisioner "local-exec" {
command = "echo 'Instance ${aws_instance.web.id} created'"
}
}

8 - Kubernetes and Docker providers

Kubernetes

terraform {
required_providers {
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.0"
}
}
}

provider "kubernetes" {
config_path = "~/.kube/config"
}

resource "kubernetes_namespace" "example" {
metadata {
name = "my-namespace"
}
}

resource "kubernetes_deployment" "nginx" {
metadata {
name = "nginx"
namespace = kubernetes_namespace.example.metadata[0].name
}

spec {
replicas = 3

selector {
match_labels = {
app = "nginx"
}
}

template {
metadata {
labels = {
app = "nginx"
}
}

spec {
container {
image = "nginx:latest"
name = "nginx"

port {
container_port = 80
}
}
}
}
}
}

Docker

terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0"
}
}
}

provider "docker" {
host = "unix:///var/run/docker.sock"
}

resource "docker_image" "nginx" {
name = "nginx:latest"
keep_locally = false
}

resource "docker_container" "nginx" {
image = docker_image.nginx.image_id
name = "nginx-server"

ports {
internal = 80
external = 8080
}
}

9 - Version locking

Lock file

# .terraform.lock.hcl (généré automatiquement)
provider "registry.terraform.io/hashicorp/aws" {
version = "5.31.0"
constraints = "~> 5.0"
hashes = [
"h1:abcdef...",
"zh:123456...",
]
}

Commands

# Mettre à jour le lock file
terraform init -upgrade

# Vérifier les providers
terraform providers

# Afficher les versions
terraform version

10 - Best practices

Versions

# ✅ Toujours spécifier les versions
terraform {
required_version = ">= 1.5.0"

required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

# ❌ Éviter
provider "aws" {}

Security

# ✅ Ne jamais hardcoder les credentials
provider "aws" {
region = "eu-west-1"
# Utilise les env vars ou profil par défaut
}

# ❌ Éviter
provider "aws" {
access_key = "AKIAIOSFODNN7EXAMPLE"
secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}

Summary

Key points
  • Providers are plugins to communicate with APIs
  • Always use pinned versions
  • Never hardcode credentials
  • Use aliases for multi-region/account
  • The .terraform.lock.hcl file locks the versions

Practical exercises

  1. Configure the AWS provider with a profile
  2. Create two AWS providers for two regions
  3. Use the random provider to generate names
  4. Configure a Kubernetes provider

← HCL syntax | Resources →