Getting Started with Multiple Providers in Terraform
Today, we'll look about how to interact with numerous Terraform providers. Providers serve as an intermediary between Terraform and infrastructure platforms such as AWS, Azure, GCP, Docker, and Kubernetes. As multi-cloud architectures gain appeal, understanding how to manage several providers becomes crucial for developing scalable and efficient infrastructure.
This session also covers how to use multiple copies of the same provider, which is important for delivering resources across several accounts or regions.
Providers in Terraform
Providers in Terraform are plugins that allow it to communicate with external APIs. Each provider identifies resources and data sources, making it easier to administer individual platforms. For example, Terraform may use the aws
provider to build, edit, and remove AWS resources.
Required Providers
The required_providers
block is used in Terraform to specify which providers your configuration depends on, including their source and version.
It provides stability and predictability by locking provider versions in your Terraform setup. This eliminates unexpected changes or incompatibilities when providers update, making your deployments more dependable across environments.
It also increases security by identifying a provider's legitimate source (for example, "hashicorp/aws") and ensuring that the right provider is installed during Terraform init. This is critical in production to prevent the unintended usage of unverified providers or mismatched versions, which might result in deployment problems or security issues.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
required_version = ">= 3.5.0"
}
Providers Aliases
Provider aliases allow you to set up several instances of the same provider in a single Terraform configuration. This is particularly handy for managing resources across several AWS regions or accounts or even clouds using the same provider. With aliases, you can ensure that resources are provisioned where they are needed, without needing separate provider configurations.
provider "aws" {
alias = "east"
region = "us-east-1"
}
# Alias for another provider instance in us-west-2
provider "aws" {
alias = "west"
region = "us-west-2"
}
# Define an output for each region's name
output "region_east" {
value = "Region: ${provider.aws.region}"
}
output "region_west" {
value = "Region: ${provider.aws.west.region}"
}
Use the Aliases in Resources
When defining resources, specify which provider to use by referencing the alias with the provider
argument.
resource "aws_instance" "east_instance" {
provider = aws.east
ami = "ami-123456"
instance_type = "t2.micro"
}
resource "aws_instance" "west_instance" {
provider = aws.west
ami = "ami-654321"
instance_type = "t2.micro"
}
Using Multiple Accounts
Using Assume Role
To manage infrastructure across multiple AWS accounts, IAM Assume Role is essential. This allows secure cross-account access without needing multiple user credentials. Here’s how to set it up:
Step 1: Create a New AWS Account
Use AWS Organizations to create a child account.
Leave the default IAM Role Name as
OrganizationAccountAccessRole
.
Step 2: Set Up IAM Role in the Child Account
AWS Organizations automatically creates the role OrganizationAccountAccessRole
in the child account, allowing the parent account to assume this role. If needed, manually create an IAM role in the child account:
Create a role with the trusted entity as the parent account:
jsonCopy code{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111111111111:root" }, "Action": "sts:AssumeRole" } ] }
Attach policies to define permissions (e.g.,
AdministratorAccess
or custom policies).
Step 3: Configure Terraform Providers
In your Terraform configuration, define two providers—one for the parent account and one for the child account with an assume_role
block.
provider "aws" {
alias = "parent"
region = "us-east-1"
}
provider "aws" {
alias = "child"
region = "us-east-1"
assume_role {
role_arn = "arn:aws:iam::222222222222:role/OrganizationAccountAccessRole"
session_name = "AssumeRoleSession"
}
}
- Replace
222222222222
with the child account ID.
Step 4: Deploy Resources
Use the provider aliases to target resources in the respective accounts:
resource "aws_s3_bucket" "parent_bucket" {
provider = aws.parent
bucket = "parent-account-bucket"
}
resource "aws_s3_bucket" "child_bucket" {
provider = aws.child
bucket = "child-account-bucket"
}
Step 5: Verify Configuration
Use the aws_caller_identity
data source to verify access:
data "aws_caller_identity" "parent" {
provider = aws.parent
}
data "aws_caller_identity" "child" {
provider = aws.child
}
output "parent_account" {
value = data.aws_caller_identity.parent.account_id
}
output "child_account" {
value = data.aws_caller_identity.child.account_id
}
Conclusion
We looked at how to utilize provider aliases in Terraform to manage resources across various Amazon Web Services accounts. We can safely and efficiently isolate environments, enhance resource organization, and speed multi-account installations by defining aliases and relying on cross-account role assumptions. In complicated settings, this method guarantees improved compartmentalization, increased security, and simpler infrastructure administration.