Skip to main content
Knowledge Base

Terragrunt, assume_role and multi-region modules: NoCredentialProviders

Answer

A customer asked: > I am using your iam_access_analyzer module, that is multiregion, creating and passing the different aws alias providers, one for each region. It was working until we had to use assume_role for authentication: ``` generate "providers" { path = "providers.tf" if_exists = "overwrite" contents = <<EOF %{for region in local.all_aws_regions} provider "aws" { region = "${region}" alias = "${replace(region, "-", "_")}" assume_role { role_arn = "${local.aws_role_arn}" } # Skip credential validation and account ID retrieval for disabled or restricted regions skip_credentials_validation = contains(coalesce(var.iam_access_analyzer_opt_in_regions, []), "${region}") ? false : true skip_requesting_account_id = contains(coalesce(var.iam_access_analyzer_opt_in_regions, []), "${region}") ? false : true } %{endfor} EOF } ``` We have only two opt-in regions: ``` opt_in_regions = ["eu-west-1", "eu-central-1"] ``` The error occuring for each region: ``` Error: error configuring Terraform AWS Provider: IAM Role (arn:aws:iam::<xxxxxx>:role/<xxxxxx>) cannot be assumed. There are a number of possible causes of this - the most common are: * The credentials used in order to assume the role are invalid * The credentials do not have appropriate permission to assume the role * The role ARN is not valid Error: NoCredentialProviders: no valid providers in chain. Deprecated. For verbose messaging see aws.Config.CredentialsChainVerboseErrors with provider["registry.terraform.io/hashicorp/aws"].af_south_1, on providers.tf line 3, in provider "aws": 3: provider "aws" { ```

The issue here is that the assume_role block will always be processed on the provider even when the region is disabled. This is indicated by the error arising for the provider block for af_south_1, which is not in your opt in list. `af-south-1` is one of those regions you must also "opt-in" to within AWS. You probably have that disabled in your account and the provider is failing the assume role. To fix this, you need to update that generate block to use the if directive (https://www.terraform.io/docs/language/expressions/strings.html#directives) to only render out the assume_role block for the opt in regions. ``` generate "providers" { path = "providers.tf" if_exists = "overwrite" contents = <<EOF %{for region in local.all_aws_regions} provider "aws" { region = "${region}" alias = "${replace(region, "-", "_")}" %{ if contains(local.opt_in_regions, region) } assume_role { role_arn = "${local.aws_role_arn}" } %{ endif } # Skip credential validation and account ID retrieval for disabled or restricted regions skip_credentials_validation = contains(coalesce(var.iam_access_analyzer_opt_in_regions, []), "${region}") ? false : true skip_requesting_account_id = contains(coalesce(var.iam_access_analyzer_opt_in_regions, []), "${region}") ? false : true } %{endfor} EOF } ```