Skip to main content

Terraform Provider Basics

·572 words·3 mins
Jack Warner
Author
Jack Warner
A little blog by me

Terraform Provider Basics
#

Overview
#

The very first command we run is terraform init. This installs all the requirements and plugins needed for your configuration, such as the AWS, GCP, or Azure providers.


Provider Types
#

There are three types of providers available:

  1. Official — Owned and maintained by HashiCorp (e.g., AWS, GCP, Azure).
  2. Partner — Owned and maintained by a third party, but vetted by HashiCorp.
  3. Community — Owned and maintained by a third party, not vetted by HashiCorp.

Multiple Providers
#

resource "local_file" "pet" {
    filename = "/root/pets.txt"
    content  = "We love pets!"
}

resource "random_pet" "name" {
    length    = 2
    prefix    = "Mrs"
    separator = "."
}

When running terraform init, it sees that the local provider is already installed, but the random provider will need to be installed.

Resource Attribute References
#

resource "random_string" "server-suffix" {
    length  = 6
    upper   = false
    special = false
}

resource "aws_instance" "web" {
    ami           = "ami-0c55b159cbfafe1f0"
    instance_type = "t2.micro"
    tags = {
        Name = "web-${random_string.server-suffix.id}"
    }
}

Here is another example using two different providers. The random_string resource creates a random string, and the aws_instance resource uses the AWS provider.

The expression ${random_string.server-suffix.id} is called a resource attribute reference. It is used to reference the output of one resource as an input to another resource. When terraform apply is run, two resources will be created — the random string is created first, and then the AWS instance is created with the random string as part of its Name tag.


Version Constraints
#

By default, terraform init downloads the latest version of each provider. You can pin or constrain versions in the terraform block:

terraform {
    required_providers {
        local = {
            source  = "hashicorp/local"
            version = "~> 1.4.0"
        }
    }
}

resource "local_file" "pet" {
    filename = "/root/pets.txt"
    content  = "We love pets!"
}

Now when terraform init runs, it will download version 1.4.0 of the local provider.

Pessimistic Constraint Operator (~>)
#

The ~> operator allows for flexible version matching:

Minor version constraint (~> 1.4):

terraform {
    required_providers {
        local = {
            source  = "hashicorp/local"
            version = "~> 1.4"
        }
    }
}

This will allow any version >= 1.4.0 but < 2.0.0.

Patch version constraint (~> 1.4.0):

terraform {
    required_providers {
        local = {
            source  = "hashicorp/local"
            version = "~> 1.4.0"
        }
    }
}

This will allow any version >= 1.4.0 but < 1.5.0.


Provider Aliases
#

resource "aws_key_pair" "alpha" {
    key_name   = "alpha"
    public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3……alpha@a-server"
}

resource "aws_key_pair" "beta" {
    key_name   = "beta"
    public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3………beta@b-server"
}

These two resource blocks need a provider block. Say this is the provider block in provider.tf:

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

If you create the above resources, both key pairs will be created in the us-east-1 region. But what if we want to create one key pair in us-east-1 and another in us-west-2? We can use provider aliases to achieve this.

Defining Aliases
#

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

provider "aws" {
    region = "us-west-2"
    alias  = "west"
}

Using Aliases in Resources
#

resource "aws_key_pair" "alpha" {
    key_name   = "alpha"
    public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3……alpha@a-server"
}

resource "aws_key_pair" "beta" {
    key_name   = "beta"
    public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3………beta@b-server"
    provider   = aws.west
}

Now when you run terraform show, you will see that the alpha key pair is created in the us-east-1 region and the beta key pair is created in the us-west-2 region.

Related