Providers
Providers are plugins that enable Terraform to interact with cloud platforms, SaaS providers, and other APIs. Each provider adds a set of resource types and data sources that Terraform can manage.
Provider Configuration
Provider blocks configure the named provider:
provider "<PROVIDER_NAME>" {
# Configuration options
}
Example
provider "aws" {
region = "us-west-2"
default_tags {
tags = {
Environment = "production"
ManagedBy = "Terraform"
}
}
}
Provider Requirements
Declare required providers in a terraform block:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.0"
}
}
}
Source Addresses
Provider source addresses have the format:
<HOSTNAME>/<NAMESPACE>/<TYPE>
Examples:
hashicorp/aws - Official AWS provider
terraform-providers/azurerm - Azure provider
example.com/custom/provider - Third-party provider
The hostname defaults to registry.terraform.io if omitted.
Version Constraints
Specify acceptable provider versions:
version = "~> 5.0" # >= 5.0, < 6.0
version = ">= 5.0" # 5.0 or higher
version = ">= 5.0, < 6.0" # Between 5.0 and 6.0
version = "= 5.1.0" # Exactly 5.1.0
Multiple Provider Configurations
Use aliases for multiple configurations of the same provider:
provider "aws" {
region = "us-west-2"
}
provider "aws" {
alias = "east"
region = "us-east-1"
}
provider "aws" {
alias = "europe"
region = "eu-west-1"
}
Using Aliased Providers
Reference aliased providers in resources:
resource "aws_instance" "west" {
provider = aws
ami = "ami-12345678"
instance_type = "t2.micro"
}
resource "aws_instance" "east" {
provider = aws . east
ami = "ami-87654321"
instance_type = "t2.micro"
}
Provider Configuration Reference
Resources can reference provider configurations:
variable "aws_region" {
type = string
}
provider "aws" {
region = var . aws_region
}
Provider configurations cannot use resource outputs. Providers are configured before resources are created.
Default Provider Configuration
Terraform uses the default (unaliased) provider configuration when:
No provider argument is specified in a resource
The resource type matches the provider name
provider "aws" {
region = "us-west-2"
}
# Uses the default aws provider
resource "aws_instance" "web" {
ami = "ami-12345678"
}
Provider Configuration in Modules
Modules can declare which provider configurations they accept:
Child Module
# modules/web-app/main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
}
}
}
resource "aws_instance" "app" {
ami = var . ami_id
}
Root Module
provider "aws" {
region = "us-west-2"
}
provider "aws" {
alias = "east"
region = "us-east-1"
}
module "web_app_west" {
source = "./modules/web-app"
providers = {
aws = aws
}
}
module "web_app_east" {
source = "./modules/web-app"
providers = {
aws = aws.east
}
}
Access provider metadata in resources:
resource "aws_instance" "web" {
ami = "ami-12345678"
tags = {
Provider = "aws"
}
}
Provider Functions
Some providers offer built-in functions:
# Using a provider-contributed function
locals {
encoded = provider::aws::encode_secret (var . password )
}
Provider functions are namespaced under provider::<PROVIDER>::<FUNCTION>.
Provider Configuration Files
Organize provider configurations:
# providers.tf
provider "aws" {
region = var . aws_region
}
provider "random" {}
provider "tls" {}
Authentication
Providers support various authentication methods:
Static Credentials
provider "aws" {
access_key = "AKIAIOSFODNN7EXAMPLE"
secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
region = "us-west-2"
}
Never commit credentials to version control. Use environment variables or credential files instead.
Environment Variables
export AWS_ACCESS_KEY_ID = "AKIAIOSFODNN7EXAMPLE"
export AWS_SECRET_ACCESS_KEY = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
export AWS_DEFAULT_REGION = "us-west-2"
provider "aws" {
# Credentials from environment variables
}
Credential Files
provider "aws" {
shared_credentials_files = [ "~/.aws/credentials" ]
profile = "production"
}
Provider Validation
Providers validate their configuration during terraform init:
Common validation errors:
Invalid region names
Missing required configuration
Unsupported provider versions
Provider Development
The provider implementation defines:
Resource types
Data source types
Configuration schema
Authentication logic
From the source code (internal/configs/provider.go:20-52):
type Provider struct {
Name string
NameRange hcl . Range
Alias string
AliasRange * hcl . Range
Version VersionConstraint
Config hcl . Body
DeclRange hcl . Range
}
Provider Naming
Provider names must be normalized and valid:
provider "aws" { } # Valid
provider "aws-custom" { } # Valid
provider "AWS" { } # Invalid - must be lowercase
provider "2nd-aws" { } # Invalid - cannot start with digit
From internal/configs/provider.go:286-312, provider names are validated to ensure they conform to the naming standards.
Deprecated Provider Version Constraints
Provider version constraints inside provider blocks are deprecated. Use required_providers instead: Deprecated: provider "aws" {
version = "~> 5.0"
}
Recommended: terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
Provider Installation
Terraform downloads providers during initialization:
Providers are installed to:
.terraform/providers/ (local cache)
~/.terraform.d/plugins/ (global cache)
Provider Mirroring
Use a local mirror for air-gapped environments:
provider_installation {
filesystem_mirror {
path = "/usr/local/share/terraform/providers"
include = [ "example.com/*/*" ]
}
direct {
exclude = [ "example.com/*/*" ]
}
}
Best Practices
Pin Versions Always specify provider version constraints to ensure consistent behavior.
Separate Files Keep provider configurations in providers.tf for clarity.
Use Variables Parameterize provider configurations for flexibility across environments.
Secure Credentials Never hardcode credentials. Use environment variables or credential files.
Common Provider Blocks
AWS
provider "aws" {
region = "us-west-2"
profile = "production"
assume_role {
role_arn = "arn:aws:iam::123456789012:role/TerraformRole"
}
}
Azure
provider "azurerm" {
features {}
subscription_id = var . subscription_id
tenant_id = var . tenant_id
}
Google Cloud
provider "google" {
project = var . project_id
region = "us-central1"
zone = "us-central1-a"
}
Next Steps
Resources Use providers to create resources
Modules Pass providers to child modules