terraform-provider-aws: AWS assume role not working

This issue was originally opened by @hkalyana as hashicorp/terraform#11270. It was migrated here as part of the provider split. The original body of the issue is below.


Hi there,

Thank you for opening an issue. Please note that we try to keep the Terraform issue tracker reserved for bug reports and feature requests. For general usage questions, please see: https://www.terraform.io/community.html.

Terraform Version -0.8.0

Run terraform -v to show the version. If you are not running the latest version of Terraform, please upgrade because your issue may have already been fixed.

Affected Resource(s)

Please list the resources as a list, for example:

  • aws_provider

Copy-paste your Terraform configurations here - for large Terraform configs,

provider "aws"
{
    region = "${var.region}"
    assume_role {
    role_arn = "arn:aws:iam::<trustedaccount>:role/trustedrole"
    }
 }

Expected Behavior

Expected the resources to be created on the trusting account

Actual Behavior

Received error The role “arn:aws:iam::<aws acct>:role/trustedrole” 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

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. Created iam role in the trusting account with the necessary permission .
  2. Created a policy on the trusted account with sts assume role permission and pointing the arm of the trusting account in the resource 3)Attached the policy to the user 4)Used the same role ARN of the trusting account in the terraform assume role

Important Factoids

The procedure I followed is working for me when I try to switch the roles in AWS GUI and I am able to create resources on the trusting account .

References

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 2
  • Comments: 22 (3 by maintainers)

Most upvoted comments

@catsby Could you please reopen this again? It’s clearly not fixed (satisfactory)…

The terraform files in my opinion should not be specifying anything to do with authentication. Role names are different and if it’s an admin with an admin role or a developer with a developer role running a terraform file they should not have to edit it to specify the profile/role/etc to use. This should be input to terraform.

Currently, the only way I can, as an admin with MFA on my role/profile, give credentials properly to a terraform file is to have an external script issue sts assume role calls and then set environment variables to the temporary access key and secret. This is not an efficient way to pass in credentials. The GO SDK fully supports MFA + assume role style profiles (with role_arn and source_profile) so terraform should delegate authentication calls to the GO SDK.

I hoped there would be a --profile option to terraform but barring that setting the env var AWS_PROFILE to my profile name should be the only thing I need to do on the cli prior to calling terraform.

In my opinion.

Same issue here. Our IAM users are managed through a central account, requiring MFA. Users have barely any permissions in the central account, but can assume roles in other accounts managed through AWS Organisations. I think this is a pretty common setup, especially at larger companies, and is the recommended best practice by AWS themselves.

Even if I avoid using the aws credentials and config files by embedding my credentials straight into the tf file like this:

provider "aws" {
  region = "eu-west-1"
  access_key = "REDACTED" # Central account
  secret_key = "REDACTED" # Central account
  token = "arn:REDACTED" # Central account
  assume_role {
    role_arn = "arn:REDACTED" # Satellite account
  }
}

I get the following error:


2017/07/05 10:22:19 [DEBUG] plugin: terraform: aws-provider (internal) 2017/07/05 10:22:19 [DEBUG] plugin: waiting for all plugin processes to complete...
* provider.aws: The role "arn:REDACTED" 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

My guess is that this is because the MFA code isn’t being requested and sent before trying to assume the role (the trust policy on the role requires that the user is MFA authenticated).

This is a real blocker for us. Let me know if there’s anything else I can provide to help.

It works for non-MFA roles, yes. For roles enforcing MFA-protected access something like https://github.com/hashicorp/terraform/pull/11734 (which hasn’t been migrated?) is needed.

Happy New Year! Anyone… anyone… Bueller?

This is clearly not fixed as other mentioned. Does not work at all with MFA!

This doesn’t work at all for me.

Files

~/.aws/credentials

[root]
# Account: <account_id0>
aws_access_key_id = SOMETHING
aws_secret_access_key = SECRET

[core]
aws_access_key_id = SOMETHING_ELSE
aws_secret_access_key = OTHER_SECRET

#[test]
# Account: <account_id1>
#aws_access_key_id = YET_ANOTHER
#aws_secret_access_key = MORE_SECRETS

The test profile here disabled, so that TF don’t accidentally pick it up somehow. But with that enabled, and a different entry in the profile.tf file for that, it works. But that’s not doing assume_role

remote.tf

data "terraform_remote_state" "base" {
  backend   = "s3"
  config {
    bucket  = "my-root-account-bucket"
    key     = "terraform-base.tfstate"
    region  = "eu-west-1"
    profile = "root"
  }
}

data "terraform_remote_state" "core" {
  backend   = "s3"
  config {
    bucket  = "my-root-account-bucket"
    key     = "terraform-core.tfstate"
    region  = "eu-west-1"
    profile = "root"
  }
}

data "terraform_remote_state" "test" {
  backend   = "s3"
  config {
    bucket  = "my-root-account-bucket"
    key     = "terraform-test.tfstate"
    region  = "eu-west-1"
    profile = "root"
  }
}

provider.tf

provider "aws" {
  region  = "eu-west-1"
  profile = "core"
  alias   = "core"
}

provider "aws" {
  region  = "eu-west-1"
#  profile = "test"
  assume_role {
    role_arn = "arn:aws:iam::<account_id1>:role/Cross_Account"
  }
}

The second provider will then be the “default” one and the first being referenced in certain places as provider = "aws.core"

This gives me:

[Turbo-Fredrikssons-MacBook-Pro]$ terraform plan -no-color
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

data.terraform_remote_state.test: Refreshing state...
data.terraform_remote_state.core: Refreshing state...
data.terraform_remote_state.base: Refreshing state...
data.aws_caller_identity.core: Refreshing state...
Error refreshing state: 1 error(s) occurred:

* provider.aws: No valid credential sources found for AWS Provider.
  Please see https://terraform.io/docs/providers/aws/index.html for more information on
  providing credentials for the AWS Provider

I had wanted this to work:

~/.aws/credentials

[root]
# Account: <account_id0>
aws_access_key_id = SOMETHING
aws_secret_access_key = SECRET

[test]
role_arn = arn:aws:iam::<account_id1>:role/Cross_Account
source_profile = core
mfa_serial = arn:aws:iam::<account_id0>:mfa/turbo

but that don’t work either… Not even if I disable MFA and remove the mfa_serialline.

@choppedpork so how do we get this to happen?

I spent some time trying to get Terraform to assume roles in a cross-account setup, trying various workarounds.

The real solution in the end was to use Terragrunt, which worked first time using this feature - Terragrunt does the assume-role, bypassing the Terraform issues in this area - just give Terragrunt a role ARN.

@et304383 @FransUrbo https://github.com/terraform-providers/terraform-provider-aws/pull/1608 might be of interest. If my understanding of the latest comments is correct, this will require a release of the provider for aws resources but also a release of terraform for remote state kept in aws s3.

@drsolaris Could you, temporarily, disable MFA on the satellite account role and see if that makes any difference?

The reason for this, is that I suspect that there’s TWO problems here - TF can’t assume remote roles AND it have problems with MFA. But I’m not sure…