Search code examples
terraformterraform-aws-modules

How to pass several aws providers to one module?


I have a module that combines two resources, an rds instance and a secret that each need their own provider.

.
├── environments
│   └── myenv
│       ├── locals.tf
│       ├── main.tf
│       └── variables.tf
└── modules
    └── db
        ├── main.tf
        ├── secrets.tf
        └── variables.tf

modules/db/main.tf:

resource "aws_db_instance" "database"{
    #needs aws.db-provider
    ...
}

modules/db/secrets:

data "aws_secretsmanager_secret_version" "rds_pg_credentials" {
  #needs aws.secret-provider 
  secret_id = var.secret_id
}

Both providers are specified in environments/myenv/main.tf:

provider "aws" {
  alias = "db-provider"
  assume_role {
     role_arn = "arn:aws:iam::123:role/db-role"
  }
  ...
}

provider "aws" {
  alias = "secret-provider"
  assume_role {
     role_arn = "arn:aws:iam::123:role/secrets-role"
  }
  ...
}

Until now secrets had been defined in their own module

So I assigned the providers like this:

module "my-db" {
  source = ".//../../modules/db"
  providers = {
    aws = aws.db-provider
  }
  ...
}

module "secrets" {
  source = ".//../../modules/secrets"
  providers = {
    aws = aws.secret-provider
  }
  ...
}

But now that I move secrets into db, I somehow need to pass both in one provider block.
I believe both resources expect their provider to be called "aws" so I would guess that I just need to pass them under different names like

module "my-db" {
  source = ".//../../modules/db"
  providers = {
    aws1 = aws.db-provider
    aws2 = aws.secret-provider
  }
  ...
}

But then how do I configure the modules to use aws{1,2} instead of aws?


Solution

  • You would pass it in like this:

    module "my-db" {
      source = ".//../../modules/db"
      providers = {
        aws.db-provider = aws.db-provider
        aws.secret-provider = aws.secret-provider
      }
      ...
    }
    

    In your module my-db you would need proxy provider definitions like this:

    provider "aws" {
      alias = "db-provider"
    }
    
    provider "aws" {
      alias = "secret-provider"
    }
    

    Each resource in your module should then have its own provider attribute set to either aws.db-provider or aws.secret-provider to choose which of the two provider configurations to use.

    Documentation: Providers Within Modules