DEV Community

quixoticmonk
quixoticmonk

Posted on

Terraform AWS Provider V6.0.0-beta1

v6.0.0-beta1 of AWS provider has landed this morning. The multi-region support without having to create provider blocks with aliases is much appreciated. Along with that comes some deprecations which you may be impacted by (though only v7 should remove them completely).

Below are some of very preliminary notes based on what I read.

Enhanced multi region support

So what does this enhanced multi region support look like ? Lets take an example of an S3 bucket deployment in a primary and secondary region.

Till v5.x.y ( v5.97.0 as of today)

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

provider "aws" {
  region = "us-east-2" # secondary region
  alias = "secondary"
}

# Random suffix to ensure bucket names are globally unique
resource "random_string" "bucket_suffix" {
  length  = 8
  special = false
  upper   = false
}

# Primary S3 bucket
resource "aws_s3_bucket" "primary" {
  bucket = "primary-bucket-${random_string.bucket_suffix.result}"

  tags = {
    Name = "Primary Bucket"
  }
}

# Secondary S3 bucket 
resource "aws_s3_bucket" "secondary" {
  provider = aws.secondary
  bucket = "replica-bucket-${random_string.bucket_suffix.result}"

  tags = {
    Name = "Replication Bucket"
  }
}

Enter fullscreen mode Exit fullscreen mode

With v6.0.0-beta1 onwards.

  • A region override is introduced as part of this version. You can read more about the proposal here

Configuration

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "= 6.0.0-beta1" # Setting this explicitly to ensure init picks up the beta version.
    }
        random = {
      source  = "hashicorp/random"
      version = "~> 3.0"
    }
  }
}

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

# Random suffix to ensure bucket names are globally unique
resource "random_string" "bucket_suffix" {
  length  = 8
  special = false
  upper   = false
}

# Primary S3 bucket
resource "aws_s3_bucket" "primary" {
  bucket = "primary-bucket-${random_string.bucket_suffix.result}"

  tags = {
    Name = "Primary Bucket"
  }
}

# Secondary S3 bucket 
resource "aws_s3_bucket" "secondary" {
  region = "us-east-2"
  bucket = "replica-bucket-${random_string.bucket_suffix.result}"

  tags = {
    Name = "Replication Bucket"
  }
}

Enter fullscreen mode Exit fullscreen mode

Importing resources

Lets say I have two S3 buckets by the names below.

  • cf-templates-1xfr5l1bee3rm-us-east-1
  • cf-templates-1xfr5l1bee3rm-us-west-2

With us-east-1 as my default, terraform import aws_s3_bucket.this cf-templates-1xfr5l1bee3rm-us-east-1 runs successfully

aws_s3_bucket.this: Importing from ID "cf-templates-1xfr5l1bee3rm-us-east-1"...
aws_s3_bucket.this: Import prepared!
  Prepared aws_s3_bucket for import
aws_s3_bucket.this: Refreshing state... [id=cf-templates-1xfr5l1bee3rm-us-east-1]

Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.

Enter fullscreen mode Exit fullscreen mode

Lets try that with us-west-2 bucket. Keep in mind that AWS_DEFAUL_REGION is still set to us-east-1

  • command : terraform import aws_s3_bucket.this cf-templates-1xfr5l1bee3rm-us-west-2
aws_s3_bucket.this: Importing from ID "cf-templates-1xfr5l1bee3rm-us-west-2"...
aws_s3_bucket.this: Import prepared!
  Prepared aws_s3_bucket for import
aws_s3_bucket.this: Refreshing state... [id=cf-templates-1xfr5l1bee3rm-us-west-2]
╷
│ Error: Cannot import non-existent remote object
│
│ While attempting to import an existing object to "aws_s3_bucket.this", the provider detected that no object exists with the given id. Only pre-existing objects can be imported;
│ check that the id is correct and that it is associated with the provider's configured region or endpoint, or use "terraform apply" to create a new remote object for this
│ resource.

Enter fullscreen mode Exit fullscreen mode

You can fix this import using the env var prefixed to the command or setting your provider to use us-west-2

  • command : AWS_DEFAULT_REGION=us-west-2 terraform import aws_s3_bucket.this cf-templates-1xfr5l1bee3rm-us-west-2
aws_s3_bucket.this: Importing from ID "cf-templates-1xfr5l1bee3rm-us-west-2"...
aws_s3_bucket.this: Import prepared!
  Prepared aws_s3_bucket for import
aws_s3_bucket.this: Refreshing state... [id=cf-templates-1xfr5l1bee3rm-us-west-2]

Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.
Enter fullscreen mode Exit fullscreen mode

With the multi region support, you can do this with a @<region_name> suffix for the resource identifier to be imported.

  • command : terraform import aws_s3_bucket.this cf-templates-1xfr5l1bee3rm-us-west-2@us-west-2

aws_s3_bucket.this: Importing from ID "cf-templates-1xfr5l1bee3rm-us-west-2@us-west-2"...
aws_s3_bucket.this: Import prepared!
  Prepared aws_s3_bucket for import
aws_s3_bucket.this: Refreshing state... [id=cf-templates-1xfr5l1bee3rm-us-west-2]

Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.

Enter fullscreen mode Exit fullscreen mode

There is an open proposal to infer the region for resources where the identifier is an arn from the ARN itself.

Noteable deprecations which you should look at

aws_region datasource

One of most common datasources used in any module I write are the aws_caller_identity and aws_region. These peculiar datasources solves the problem of not having to hard code the AWS account id and region you are deploying to as they are inferrred.

A local block in most of my modules would have the following:

data "aws_region" "current" {}

locals {
    region=data.aws_region.current.name
}
Enter fullscreen mode Exit fullscreen mode
  • Even the provider documentation references the data.aws_region.current.name in many examples.
  • AWSCC provider examples which we autogenerated as part of the Bedrock based automation had a prompt to use aws_region datasource to avoid hardcoding regions. That is another mass update I am looking at( unless you pin the AWS provider versions in the examples too)

  • Related issue : https://github.com/hashicorp/terraform-provider-aws/issues/42468

The change here involves removing the .name attribute in a version v7 in favor of the .region attribute. The change is simple, but something you can be caught offguard if you switch from an earlier version to v7 later this year or next.

data "aws_region" "current" {}

locals {
    region=data.aws_region.current.region
}
Enter fullscreen mode Exit fullscreen mode

aws_s3_bucket

The attribute reference of S3 bucket has region field modified to bucket_region. This may not be an attribute a lot of people use, but I do seem to see them in the wild.

For additional deprecations and updates, take a look at the changelog and the v6.0.0-beta1 release notes.

The big question

Will the AI models which have been trained on all alias based references from Terraform examples and value deprecations keep up ? :)

If you do play around with the beta and have some feedback, please consider submitting them via Beta Feedback Form.

Top comments (0)