Skip to main content

Terraform Ep 2: Providers, Plugins, and Secure Authentication

Rachmat Hidayat
Author
Rachmat Hidayat
Learn & sharing insights on TypeScript, Go, Kubernetes, DevOps, DevSecOps, SRE, Platform Engineering, AI/ML Engineering, and MLOps.
terraform - This article is part of a series.
Part 2: This Article
By itself, the core Terraform binary cannot communicate with AWS, GCP, Azure, or Kubernetes. It is simply an engine that parses HCL (HashiCorp Configuration Language). To interact with the physical world, it requires Providers.

1. The Provider Architecture
#

A Terraform Provider is a logical plugin that understands API interactions and exposes resources. For example, the aws provider knows how to call the AWS API to create an EC2 instance, while the kubernetes provider knows how to call the Kube-APIServer to create a Pod.

When you run terraform init, the core Terraform engine reads your code, determines which providers you requested, and downloads the corresponding compiled Go binaries (plugins) from the Terraform Registry into your hidden .terraform/ directory.

Why is this architecture brilliant?
#

This decoupled architecture allows HashiCorp (the creators of Terraform) to release updates to the core engine independently of the cloud providers. If AWS releases a brand new service tomorrow (e.g., AWS Quantum Computing), HashiCorp does not need to release a new version of Terraform. The AWS team simply updates the aws provider plugin, and you can start using it immediately by pulling the latest provider version.


2. Practice: Configuring the AWS Provider
#

Let’s write the code to instruct Terraform to download the AWS plugin and target a specific AWS region.

Create a new directory named terraform-aws-auth and create a main.tf file:

mkdir terraform-aws-auth
cd terraform-aws-auth

Open main.tf and paste the following configuration:

# main.tf

# 1. The Terraform Block (Core Engine Configuration)
terraform {
  required_providers {
    # We are declaring that we need the "aws" provider
    aws = {
      source  = "hashicorp/aws" # Download from the official HashiCorp namespace
      version = "~> 5.0"        # Use version 5.x.x (do not upgrade to 6.x.x automatically)
    }
  }
}

# 2. The Provider Block (Plugin Configuration)
provider "aws" {
  region = "us-east-1"
  
  # DO NOT DO THIS (See Section 3 for why):
  # access_key = "AKIAIOSFODNN7EXAMPLE"
  # secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}

Now, force Terraform to download the AWS plugin:

terraform init

Expected Terminal Output:

Initializing the backend...

Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.0"...
- Installing hashicorp/aws v5.15.0...
- Installed hashicorp/aws v5.15.0 (signed by HashiCorp)

Terraform has been successfully initialized!

Terraform has successfully downloaded a massive binary (usually >300MB) containing the API logic for every single service that AWS offers.


3. The Danger of Hardcoded Credentials
#

Notice the commented-out access_key and secret_key in the provider "aws" block above.

You must NEVER hardcode your AWS Access Keys directly inside your Terraform files.

If you commit a main.tf file containing hardcoded keys to a public GitHub repository, automated bots scanning GitHub will detect those keys in under 3 seconds. They will immediately use your keys to spin up hundreds of Bitcoin mining servers in your AWS account. You will wake up to a $50,000 AWS bill. This is a very common and very real catastrophe.


4. Secure Authentication (The Industry Standard)
#

To authenticate securely, we rely on environmental contexts outside of the Terraform code. Terraform’s AWS Provider is exceptionally smart; if it does not find keys in the main.tf, it will automatically hunt for credentials in your operating system in a specific order.

The most standard and secure approach for local development is using the AWS CLI Shared Credentials File.

Step 4.1: Install the AWS CLI
#

If you haven’t already, ensure the AWS CLI is installed.

aws --version
# Expected: aws-cli/2.x.x Python/3.x.x Linux/x86_64

Step 4.2: Configure your IAM User
#

Run the configure command. It will prompt you for your keys.

aws configure

Terminal Prompt:

AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: us-east-1
Default output format [None]: json

(Note: The keys provided here are saved locally on your hard drive at ~/.aws/credentials, completely outside of your Git repository).

Step 4.3: Verifying the Connection
#

Let’s test if Terraform can successfully authenticate to AWS using our newly configured AWS CLI profile. We will use a Data Source (which we will cover deeply in Episode 5) just to read our own account ID.

Append the following to your main.tf:

# Read the current caller identity (Who am I?)
data "aws_caller_identity" "current" {}

# Print the Account ID to the terminal
output "my_aws_account_id" {
  value = data.aws_caller_identity.current.account_id
}

Now, ask Terraform to evaluate the configuration:

terraform plan

Expected Terminal Output:

Changes to Outputs:
  + my_aws_account_id = "123456789012"

You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure.

If you see your 12-digit AWS Account ID printed on the screen, Congratulations! Terraform has successfully established a secure, authenticated connection to the AWS API without a single hardcoded secret in your code.


Troubleshooting & Common Errors
#

  1. No valid credential sources found for AWS Provider.

    • Root Cause: Terraform looked in your main.tf, your environment variables, and your ~/.aws/credentials file, but could not find any AWS keys.
    • Solution: You missed Step 4.2. Run aws configure and ensure you input valid keys.
  2. Error: InvalidClientTokenId: The security token included in the request is invalid.

    • Root Cause: The keys you provided to aws configure are incorrect, expired, or deactivated in the AWS IAM Console.
    • Solution: Generate a new Access Key in the AWS IAM Console and run aws configure again.
  3. Error: error configuring Terraform AWS Provider: error validating provider credentials: error calling sts:GetCallerIdentity

    • Root Cause: Your network might be blocking API calls to AWS, or you have a clock skew issue (your laptop’s clock is drastically out of sync with actual time, which invalidates AWS API signatures).
    • Solution: Check your corporate VPN/Firewall, and sync your OS time with an NTP server.

Conclusion & Next Steps
#

You have now mastered the Provider architecture and secured your authentication pipeline against credential leaks. Your local environment is now fully primed and authorized to manipulate cloud infrastructure.

In Episode 3: Declaring Resources and Dependency Management, we will finally start building real infrastructure. We will deploy an AWS Virtual Private Cloud (VPC) and a Subnet, and learn how Terraform automatically resolves the dependencies between them using the Implicit Dependency Graph.

terraform - This article is part of a series.
Part 2: This Article