Updating from terraform v0.14 to v1.3 having issues trying to work out what the correct provider statements

Hello,
I’m working on upgrading from terraform v0.14 to v1.3. My current terraform version is v0.14.11.
While I am trying to upgrade the terraform version,
having issues trying to work out what the correct provider statements should be for the main module and the child module.
Below are couple of warnings :-

Warning: Reference to undefined provider

  on main.tf line 99, in module "encryption":
  99:     aws = aws

There is no explicit declaration for local provider name "aws" in
module.encryption, so Terraform is assuming you mean to pass a configuration
for "hashicorp/aws".

If you also control the child module, add a required_providers entry named
"aws" with the source address "hashicorp/aws".

(and one more similar warning elsewhere)

Warning: Redundant empty provider block

  on dns/dns.tf line 22:
  22: provider "aws" {

Earlier versions of Terraform used empty provider blocks ("proxy provider
configurations") for child modules to declare their need to be passed a
provider configuration by their callers. That approach was ambiguous and is
now deprecated.

I was able to rectify the above warnings by modifying my versions.tf file.

terraform {
  required_version = ">= 1.3"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
      configuration_aliases = [ 
        aws.route53,
       ]
    }
    template = {
      source  = "hashicorp/template"
      version = "~> 2.0"
    }
  }
}

But now, we have got the below warning.

on main.tf line 110, in module "dns":
 110:     aws.route53 = aws.route53

There is no explicit declaration for local provider name "aws.route53" in
module.dns, so Terraform is assuming you mean to pass a configuration for
"hashicorp/aws".

If you also control the child module, add a required_providers entry named
"aws.route53" with the source address "hashicorp/aws".

I googled and found that we can declare couple of required_variables in the single block, hence updated the versions.tf to look like :-

terraform {
  required_version = ">= 1.3"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
      configuration_aliases = [ 
        aws.route53,
        aws,
       ]
    }
    template = {
      source  = "hashicorp/template"
      version = "~> 2.0"
    }
  }
}

Below are the configurations that we are having for upgrading it to v1.3.
But still it didn’t worked.

versions.tf
terraform {
  required_version = ">= 1.3"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
      configuration_aliases = [ aws.route53 ]
    }
    template = {
      source  = "hashicorp/template"
      version = "~> 2.0"
    }
  }
}

Part of the main.tf $ dns.tf where we are getting the error :-

main.tf
# Route53 deployment provider
provider "aws" {
  alias  = "route53"
  region = var.aws_region
}


module "dns" {
  source = "./dns"

  providers = {
    aws.route53 = aws.route53
  }

dns.tf
# Create R53 alias records for all fileservers
resource "aws_route53_record" "fileserver" {
  for_each = var.map_uid_dns__instances

  provider = aws.route53
  provider = aws
  zone_id  = data.aws_route53_zone.dns_zone.id
  name     = format("%s%s", each.key, var.dns_env_suffix)
  type     = "A"
  ttl      = "300"
  records = [
    each.value,
  ]
}

The Current configuration where the code is working without the warnings. {v0.14}

versions.tf
terraform {
  required_version = ">= 0.14.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
    template = {
      source  = "hashicorp/template"
      version = "~> 2.0"
    }
  }
}

Part of the main.tf $ dns.tf
main.tf
# Route53 deployment provider (management account)
provider "aws" {
  alias  = "route53"
  region = var.aws_region
}

module "dns" {
  source = "./dns"
  providers = {
    aws         = aws
    aws.route53 = aws.route53
  }

dns.tf
# Create R53 alias records for all fileservers
resource "aws_route53_record" "fileserver" {
  for_each = var.map_uid_dns__instances

  provider = aws.route53
  zone_id  = data.aws_route53_zone.dns_zone.id
  name     = format("%s%s", each.key, var.dns_env_suffix)
  type     = "A"
  ttl      = "300"
  records = [
    each.value,
  ]
}

Can anyone please let me know what I need to change for my required_providers block, my module block, and the child module file?

It seems you have multiple modules with different provider configs.
It would be helpful if you shared your directory tree structure and mentioned which of the versions.tf you’re referring to.
Also note that versions.tf is just a file name, it does not imply anything about the content of the file. It could as well be called providers.tf or be part of main.tf

Hello @macmiranda !!

Thanks for the reply.

main.tf is the main file which defines all our child modules, versions.tf contains main version strings and required_providers, dns.tf is a child module.

Ok, it would be easier to look at the directory structure, but I’ll try to guess.

In general, you would have a directory /module_A with the following files inside of it:

  • providers.tf (where you have you module’s required providers)
  • variables.tf (self-explanatory)
  • main.tf (where you create the module’s resources)
  • locals.tf (for local variables)
  • outputs.tf (self-explanatory)
  • data.tf (for data sources)

(this is not a requirement but it’s a common practice)

This would then be sourced in your root module’s main.tf or any other .tf file that wants to make use of that module, like so:

module "module_A" {
   source = "./module_A"

  input_A = var.input_A
  input_B = var.input_B
  ... 
}

Now, both the parent module and the child module will have a file where they declare their required_providers, be it providers.tf or versions.tf but only in the root module will you declare specific provider and aliases configuration.

If you do use multiple provider configs in your module, you need to use the configuration_aliases in the required_providers section of your child module (or explicitly assign the providers in the providers {} section of the module instantiation.

I’d guess then, from the error

There is no explicit declaration for local provider name "aws.route53" in
module.dns, so Terraform is assuming you mean to pass a configuration for
"hashicorp/aws".

that you need to declare a required_providers section for your child module.

More about it, here.

Thanks for the update @macmiranda.