Terraform

Introduction to Terraform Providers: What They Are and How They Work

AGAnurag Gupta04 Apr 2025 · Updated 04 Oct 2026 · 6 min read
Introduction to Terraform Providers: What They Are and How They Work

Quick answer: A Terraform provider is a plugin that teaches Terraform how to talk to a specific platform — AWS, Azure, Google Cloud, Kubernetes, GitHub, even Cloudflare. You declare the provider once, Terraform downloads it, and from then on every resource block in your code is translated into real API calls behind the scenes.

If you have ever wondered how one tool can create an EC2 instance, an Azure SQL database and a Kubernetes namespace from the same .tf file, the answer is providers. This guide explains what they are, how they work under the hood, how to configure them properly, and the mistakes almost every beginner makes.

What is a Terraform provider?

Terraform itself does not know anything about clouds. The core binary only understands HCL (HashiCorp Configuration Language), builds a dependency graph, and figures out what needs to change. Everything that is platform-specific — “how do I create an S3 bucket?”, “what fields does a Virtual Machine accept?” — lives inside a provider.

Think of it like a printer driver. Your operating system can “print”, but it needs a driver for your exact printer to actually produce a page. Terraform can “create infrastructure”, but it needs the AWS provider to actually create something on AWS.

Each provider ships two things:

  • Resources – things Terraform can create, update and destroy (for example aws_instance, azurerm_storage_account, google_compute_network).
  • Data sources – read-only lookups of things that already exist (for example aws_ami to find the latest Ubuntu image, or azurerm_client_config to get your tenant ID).

How providers work under the hood

When you run terraform init, Terraform reads the required_providers block, downloads the matching provider binaries from the Terraform Registry, and stores them in .terraform/providers/. It also writes a .terraform.lock.hcl file that pins the exact versions so your whole team gets identical plugins.

At terraform plan and terraform apply time, Terraform starts each provider as a separate process and talks to it over gRPC. The provider validates your configuration, calls the cloud’s API, and reports back the real state of each resource. That is why a provider upgrade can change behaviour even when your .tf files have not changed — the “driver” was swapped.

Declaring and configuring a provider

A production-ready provider setup has two parts: the requirement (which provider and which version) and the configuration (region, credentials, defaults).

terraform {
  required_version = ">= 1.5.0"

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

provider "aws" {
  region = "ap-south-1"   # Mumbai

  default_tags {
    tags = {
      Project   = "tkh-demo"
      ManagedBy = "terraform"
    }
  }
}

resource "aws_s3_bucket" "logs" {
  bucket = "tkh-demo-logs-2025"
}

A few things worth noticing:

  • source = "hashicorp/aws" tells Terraform where to download the plugin. Official providers live under hashicorp/; partner and community providers use the publisher’s namespace, such as cloudflare/cloudflare or integrations/github.
  • version = "~> 5.0" allows any 5.x release but blocks 6.0, which may contain breaking changes. Never leave the version unpinned in real projects.
  • Credentials are not in the file. The AWS provider reads them from environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY), the shared ~/.aws/credentials file, or an IAM role. Hard-coding keys in .tf files is the fastest way to leak them to GitHub.

Types of providers you will meet

Tier Who maintains it Examples
Official HashiCorp aws, azurerm, google, kubernetes, helm, random, null, tls
Partner The vendor, verified by HashiCorp cloudflare, datadog, mongodbatlas, digitalocean
Community Open-source contributors Hundreds of niche providers for SaaS tools and internal APIs

Utility providers such as random, null, local and time do not touch any cloud at all. They exist to generate passwords, run local scripts, or add delays — small helpers that make real-world modules work.

Using more than one provider

You can declare as many providers as you like in one configuration. Two patterns are extremely common:

1. Different platforms in the same project — for example AWS for compute and Cloudflare for DNS:

provider "aws"        { region = "ap-south-1" }
provider "cloudflare" { api_token = var.cloudflare_token }

2. The same provider, multiple regions or accounts — using an alias:

provider "aws" {
  region = "ap-south-1"
}

provider "aws" {
  alias  = "virginia"
  region = "us-east-1"
}

# CloudFront certificates must live in us-east-1
resource "aws_acm_certificate" "cdn" {
  provider    = aws.virginia
  domain_name = "techknowledgehub.org"
  validation_method = "DNS"
}

We cover the full multi-cloud setup in Configuring and Using Multiple Providers in Terraform (AWS, Azure and GCP).

Five provider mistakes beginners make

  1. No version constraint. A teammate runs terraform init six months later, gets a newer major version, and the plan suddenly wants to replace 40 resources. Always pin with ~>.
  2. Not committing .terraform.lock.hcl. The lock file is what guarantees everyone (and your CI pipeline) uses the same provider build. Commit it; ignore only the .terraform/ directory.
  3. Credentials in code. Use environment variables, a credentials file, OIDC in CI, or a secrets manager — never literal keys in .tf or .tfvars files that get committed.
  4. Running init once and forgetting -upgrade. Changing the version constraint does nothing until you run terraform init -upgrade.
  5. Configuring providers inside child modules. Modules should receive providers from the root module (via the providers argument), not define their own. Otherwise you cannot destroy the module cleanly later.

Frequently asked questions

Is a provider the same as a module?

No. A provider is a plugin that connects Terraform to an API. A module is a reusable bundle of your own .tf files. Modules use providers; they do not replace them.

Where does Terraform download providers from?

From the public Terraform Registry by default. Enterprises often mirror providers to an internal registry or use provider_installation settings in the CLI config so air-gapped servers can still run init.

Do I need a provider for every resource?

Yes. Every resource type is prefixed by its provider name — aws_, azurerm_, google_, kubernetes_ — so Terraform always knows which plugin to hand it to.

Can I write my own provider?

Yes, using the Terraform Plugin Framework in Go. Teams do this to manage internal tools that expose a REST API, so the whole platform can be treated as code.

Key takeaways

  • Providers are the bridge between Terraform and real infrastructure APIs.
  • Declare them in required_providers, pin versions, and commit the lock file.
  • Keep credentials out of code; use aliases for multi-region and multi-account setups.
  • Master providers and the rest of Terraform — state, modules, workspaces — becomes far easier.

Ready to go from reading about Terraform to deploying real infrastructure on AWS and Azure? Our DevOps course covers Terraform end to end with live projects, mentor support and placement assistance. Prefer video? Follow along on our YouTube channel.

AG
Written byAnurag Gupta

Part of the Techknowledgehub team of industry mentors, writing practical guides to help you build a job-ready tech career.

More articles by Anurag Gupta →
Keep reading

Related articles

Leave a Reply