By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
(AWS, Azure, GCP, Kubernetes)
Terraform providers are the bridge between your IaC (Infrastructure as Code) and the cloud platforms (AWS, Azure, GCP) or services (Kubernetes, Datadog, etc.) you manage. Think of them like drivers for your infrastructure—without them, Terraform can’t talk to AWS to create an EC2 instance or to Kubernetes to deploy a pod.
Why this matters in production: - No provider = no infrastructure. If you misconfigure a provider, Terraform fails silently or deploys resources in the wrong region/account. - Multi-cloud chaos. If you’re managing AWS, Azure, and GCP in the same repo, providers let you isolate credentials, regions, and permissions per environment. - Security nightmares. Hardcoded AWS keys in Terraform files? That’s how breaches happen. Providers let you inject secrets safely via environment variables or Vault. - Legacy migration. You inherit a Terraform repo with 500 resources, but the AWS provider is pinned to v2.0.0 (from 2019). Upgrading without breaking everything? That’s provider management.
Real-world scenario: You’re a cloud engineer at a fintech startup. Your team uses AWS for production, Azure for compliance backups, and Kubernetes for microservices. You need to:1. Deploy a private EKS cluster in us-east-1 with IAM roles for service accounts (IRSA).2. Mirror the same Kubernetes manifests to Azure AKS for disaster recovery.3. Ensure no hardcoded secrets leak into Git.4. Pin provider versions so a teammate’s terraform apply doesn’t accidentally upgrade AWS from v4 to v5 and break everything.
us-east-1
terraform apply
This guide will show you how.
provider
version = "~> 4.0"
aws_s3_bucket
aws_s3_bucket_v2
eu-west-1
region
profile
assume_role
skip_credentials_validation
AWS_PROFILE
AWS_WEB_IDENTITY_TOKEN_FILE
required_providers
terraform {}
hcl terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 4.0" } kubernetes = { source = "hashicorp/kubernetes" version = "~> 2.10" } } }
s3:*
.terraform/providers/
aws_vpc
azurerm_resource_group
depends_on
count
for_each
terraform destroy
vpc_id = aws_vpc.main.id
hcl provider "aws" { default_tags { tags = { Environment = "prod" Owner = "platform-team" } } }
hcl provider "aws" { alias = "staging" region = "us-west-2" }
kubectl
aws-cli
az-cli
terraform
Deploy:1. An AWS EKS cluster in us-east-1 with IRSA (IAM Roles for Service Accounts).2. An Azure AKS cluster in eastus with managed identity.3. A Kubernetes Nginx deployment that works on both clusters (using provider aliases).
eastus
Why? IRSA lets Kubernetes pods assume IAM roles without hardcoded credentials.
Create an OIDC provider for GitHub Actions (or your CI/CD): bash aws iam create-open-id-connect-provider \ --url https://token.actions.githubusercontent.com \ --client-id-list sts.amazonaws.com \ --thumbprint-list $(openssl s_client -connect token.actions.githubusercontent.com:443 -showcerts </dev/null 2>/dev/null | openssl x509 -fingerprint -noout | sed 's/SHA1 Fingerprint=//g' | sed 's/://g')
bash aws iam create-open-id-connect-provider \ --url https://token.actions.githubusercontent.com \ --client-id-list sts.amazonaws.com \ --thumbprint-list $(openssl s_client -connect token.actions.githubusercontent.com:443 -showcerts </dev/null 2>/dev/null | openssl x509 -fingerprint -noout | sed 's/SHA1 Fingerprint=//g' | sed 's/://g')
Create an IAM role for Terraform: bash aws iam create-role --role-name terraform-irsa --assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::YOUR_ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "token.actions.githubusercontent.com:aud": "sts.amazonaws.com" } } }] }'
bash aws iam create-role --role-name terraform-irsa --assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::YOUR_ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "token.actions.githubusercontent.com:aud": "sts.amazonaws.com" } } }] }'
Attach admin policy (for demo only—restrict in prod!): bash aws iam attach-role-policy --role-name terraform-irsa --policy-arn arn:aws:iam::aws:policy/AdministratorAccess
bash aws iam attach-role-policy --role-name terraform-irsa --policy-arn arn:aws:iam::aws:policy/AdministratorAccess
Configure the AWS provider in main.tf: ```hcl terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 4.0" } kubernetes = { source = "hashicorp/kubernetes" version = "~> 2.10" } } }
main.tf
provider "aws" { region = "us-east-1" assume_role { role_arn = "arn:aws:iam::YOUR_ACCOUNT_ID:role/terraform-irsa" } } ```
Define the EKS cluster: ```hcl module "eks" { source = "terraform-aws-modules/eks/aws" version = "~> 19.0" cluster_name = "prod-eks" cluster_version = "1.27" subnets = module.vpc.private_subnets vpc_id = module.vpc.vpc_id
# Enable IRSA enable_irsa = true
# Node groups eks_managed_node_groups = { default = { min_size = 1 max_size = 3 desired_size = 2 instance_types = ["t3.medium"] } } } ```
Configure the Kubernetes provider to use the EKS cluster: ```hcl data "aws_eks_cluster" "cluster" { name = module.eks.cluster_name }
data "aws_eks_cluster_auth" "cluster" { name = module.eks.cluster_name }
provider "kubernetes" { alias = "aws" host = data.aws_eks_cluster.cluster.endpoint cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority[0].data) token = data.aws_eks_cluster_auth.cluster.token } ```
bash terraform init terraform plan terraform apply
Log in to Azure CLI: bash az login
bash az login
Create a service principal (or use managed identity): bash az ad sp create-for-rbac --name terraform-sp --role Contributor --scopes /subscriptions/YOUR_SUBSCRIPTION_ID Save the output (appId, password, tenant).
bash az ad sp create-for-rbac --name terraform-sp --role Contributor --scopes /subscriptions/YOUR_SUBSCRIPTION_ID
appId
password
tenant
Configure the Azure provider in main.tf: hcl provider "azurerm" { features {} subscription_id = "YOUR_SUBSCRIPTION_ID" client_id = "YOUR_APP_ID" client_secret = "YOUR_PASSWORD" tenant_id = "YOUR_TENANT_ID" }
hcl provider "azurerm" { features {} subscription_id = "YOUR_SUBSCRIPTION_ID" client_id = "YOUR_APP_ID" client_secret = "YOUR_PASSWORD" tenant_id = "YOUR_TENANT_ID" }
Deploy AKS: ```hcl resource "azurerm_resource_group" "aks" { name = "prod-aks-rg" location = "eastus" }
resource "azurerm_kubernetes_cluster" "aks" { name = "prod-aks" location = azurerm_resource_group.aks.location resource_group_name = azurerm_resource_group.aks.name dns_prefix = "prodaks"
default_node_pool { name = "default" node_count = 2 vm_size = "Standard_D2_v2" } identity { type = "SystemAssigned" }
} ```
hcl provider "kubernetes" { alias = "azure" host = azurerm_kubernetes_cluster.aks.kube_config[0].host client_certificate = base64decode(azurerm_kubernetes_cluster.aks.kube_config[0].client_certificate) client_key = base64decode(azurerm_kubernetes_cluster.aks.kube_config[0].client_key) cluster_ca_certificate = base64decode(azurerm_kubernetes_cluster.aks.kube_config[0].cluster_ca_certificate) }
resource "kubernetes_deployment" "nginx_azure" { provider = kubernetes.azure # ... (same as above) } ```
Apply: bash terraform apply
bash terraform apply
Verify: ```bash # For AWS EKS aws eks --region us-east-1 update-kubeconfig --name prod-eks kubectl get pods
# For Azure AKS az aks get-credentials --resource-group prod-aks-rg --name prod-aks kubectl get pods ```
ARM_CLIENT_ID
ARM_CLIENT_SECRET
GOOGLE_APPLICATION_CREDENTIALS
json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:*", "eks:*", "iam:PassRole" ], "Resource": "*" } ] }
default_tags
terraform providers
~> 4.0
alias
kubeconfig
aws eks update-kubeconfig
az aks get-credentials
kubernetes.aws
kubernetes.azure
azurerm
azure
host
token
cluster_ca_certificate
Challenge: Deploy a private S3 bucket in AWS using Terraform, but:1. Use IRSA (IAM Roles for Service Accounts) for authentication.2. Tag the bucket with Environment=staging and Owner=devops.3. Block all public access by default.
Environment=staging
Owner=devops
Solution:
provider "aws" { region = "us-east-1" assume_role { role_arn = "arn:aws:iam::YOUR_ACCOUNT_ID:role/terraform-irsa" } default_tags { tags = { Environment = "staging" Owner = "devops" } } } resource "aws_s3_bucket" "private" { bucket = "my-private-bucket-${random_id.bucket_suffix.hex}" } resource "aws_s3_bucket_public_access_block" "private" { bucket = aws_s3_bucket.private.id block_public_acls = true block_public_policy = true ignore_public_acls = true restrict_public_buckets = true } resource "random_id" "bucket_suffix" { byte_length = 4 }
Why it works: - IRSA avoids hardcoded keys. - default_tags applies tags to all resources. - aws_s3_bucket_public_access_block enforces private access.
aws_s3_bucket_public_access_block
provider "aws" { region = "us-east-1" }
region = "us-east-1"
alias = "staging"
provider "aws" { alias = "staging" }
AWS_PROFILE=dev terraform apply
AWS_PROFILE=dev
--name prod-eks
--name prod-aks
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.