Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Terraform S3 Backend does not recognize multiple AWS credentials #18774

Closed
KevinKirkpatrick opened this issue Aug 31, 2018 · 10 comments · Fixed by #25134
Closed

Terraform S3 Backend does not recognize multiple AWS credentials #18774

KevinKirkpatrick opened this issue Aug 31, 2018 · 10 comments · Fixed by #25134
Assignees
Milestone

Comments

@KevinKirkpatrick
Copy link

I've trying to store terraform state in an S3 bucket in a non default AWS account. When initializing the terraform S3 backend I get an access denied error. I enabled debugging on an found that terraform s3 backend was using the default account in my shared aws credentials file. The terraform backend should really honor what I'm defining in my aws provider profile.

terraform_version 0.11.8

provider "aws" { region = "us-east-1" profile = "non-default aws account" }

terraform { backend "s3" { bucket = "TF-S3-Bucket" key = "folder/statefile" } }

terraform init
Initializing modules...

  • module.mine

Initializing the backend...
Error inspecting states in the "s3" backend:
AccessDenied: Access Denied
status code: 403, request id: 37C678457C37B5FD, host id: +zQJP6lg11NEvpMPkqNNy3AAgb8rxOs+G2Jf+RpT405CUABwEkeN2xi4Se0t2v1H8E7OPjLSCFk=

~/.aws/credentials
[default]
aws_access_key_id = xxxx
aws_secret_access_key = xxxxxx

[non-default aws account]
aws_access_key_id = xxxx
aws_secret_access_key = xxxxxx

Relates to #13589

@troyfontaine
Copy link

troyfontaine commented Oct 13, 2018

I'm seeing this too. Only work around I've found is in this comment

EDIT: @KevinKirkpatrick I just installed boto into my general Python environment and that fixed the profile issue for me. So there is a dependency on Boto for the profile feature to function.

@useafterfree
Copy link

useafterfree commented Oct 16, 2018

aws.provider.profile will; be ignored if AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY is set.
Issuing: unset AWS_ACCESS_KEY_ID; unset AWS_SECRET_ACCESS_KEY worked for me!

@robzr
Copy link

robzr commented Nov 15, 2018

The backend will not use the provider configuration. If you are using profiles or roles in your backend, you must put profile = and/or role_arn = directly into the backend {...} block. And yes, this means you cannot use any interpolation in there. HC recommends you use Backend Partial Configuration, which runs at init time only.

So good luck sharing remote state in an environment where AWS permissioning profiles/roles may vary (ie: multi-account CI/CD with state stored in a consistent account). I guess HC wants to sell you Terraform Enterprise for this.

@useafterfree
Copy link

As a workaround, I use this:

for var in AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_ACCOUNT_ID AWS_DEFAULT_REGION AWS_REGION; do
  if [ -n "${!var}" ] ; then
    echo "$var is set, unsetting" # to ${!var}"
    eval "unset $var"
  fi
done

Right before terraform plan

@dwiest
Copy link

dwiest commented Dec 4, 2018

@useafterfree Still not working for me. I have to set either AWS_PROFILE or AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.

$ set | grep AWS
$ ~/bin/terraform plan
Failed to load backend: 
Error configuring the backend "s3": 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

Please update the configuration in your Terraform files to fix this error.
If you'd like to update the configuration interactively without storing
the values in your configuration, run "terraform init".
$ export AWS_PROFILE=terraform
$ ~/bin/terraform plan
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.


------------------------------------------------------------------------

No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.

I'm using the latest Terraform release,

$ ~/bin/terraform version
Terraform v0.11.10
+ provider.aws v1.50.0

boto libs are current,

$ pip list | grep boto
boto3           1.9.59 
botocore        1.12.59

The profile attribute is being ignored.

$ cat *.tf
terraform {
  backend "s3" {}
}

provider "aws" {
  version = "~> 1.50"
  region  = "us-east-1"
  profile = "terraform"
}

@lostick
Copy link

lostick commented Aug 14, 2019

The issue is still happening with terraform 0.12.6.

If AWS_PROFILE, AWS_ACCESS_KEY_ID andAWS_SECRET_ACCESS_KEY env vars are set, terraform fails to init multiple backends.

Using multple profiles with AWS CLI works fine:

$ cat ~/.aws/credentials
[default]
region=eu-west-2

[ops]
aws_access_key_id=xxx
aws_secret_access_key=xxx

[dev]
aws_access_key_id=xxx
aws_secret_access_key=xxx

----------------------------

$ aws s3 ls --profile ops
2019-07-09 10:38:26 terraform-ops-state-xxx

$ aws s3 ls --profile dev
2019-06-12 10:32:55 terraform-dev-state-xxx

However, if i add an additional s3 backend, terraform will fail to authenticate.

$ cat  backends.tf
provider "aws" {
  alias = "dev"

  region  = "eu-west-2
  version = "~> 2.21"
  profile = "dev"
}

data "aws_caller_identity" "dev_peer" {
  provider = "aws.dev"
}

data "terraform_remote_state" "dev_base_networking" {
  backend = "s3"
  config = {
    bucket  = format("terraform-%s-state-xxx", "dev")
    key     = "base-networking/terraform.tfstate"
    region  = "eu-west-2"
    profile = "dev"
  }
}

----------------------------

$ terraform plan
...
data.aws_caller_identity.dev_peer: Refreshing state...

Error: Error loading state error
  on backend.tf line 16, in data "terraform_remote_state" "dev_base_networking":
  16:   backend = "s3"

error loading the remote state: AccessDenied: Access Denied

The only way to make it work is to unset both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY

@shurrman
Copy link

shurrman commented May 8, 2020

This is true for #metoo on v0.12.21. :-(
Workaround is to run
AWS_PROFILE= terraform apply

@lnxslck
Copy link

lnxslck commented May 26, 2020

This is still happening on Terraform 0.12.25, only way to do it is using the AWS_PROFILE=profile_name before calling terraform

@bflad bflad self-assigned this Jun 2, 2020
@bflad bflad added this to the v0.13.0 milestone Jun 2, 2020
bflad added a commit that referenced this issue Jun 4, 2020
Reference: #13410
Reference: #18774
Reference: #19482
Reference: #20062
Reference: #20599
Reference: #22103
Reference: #22161
Reference: #22601
Reference: #22992
Reference: #24252
Reference: #24253
Reference: #24480
Reference: #25056

Changes:

```
NOTES

* backend/s3: Deprecated `lock_table`, `skip_get_ec2_platforms`, `skip_requesting_account_id` arguments have been removed
* backend/s3: Credential ordering has changed from static, environment, shared credentials, EC2 metadata, default AWS Go SDK (shared configuration, web identity, ECS, EC2 Metadata) to static, environment, shared credentials, default AWS Go SDK (shared configuration, web identity, ECS, EC2 Metadata)
* The `AWS_METADATA_TIMEOUT` environment variable no longer has any effect as we now depend on the default AWS Go SDK EC2 Metadata client timeout of one second with two retries

ENHANCEMENTS

* backend/s3: Always enable shared configuration file support (no longer require `AWS_SDK_LOAD_CONFIG` environment variable)
* backend/s3: Automatically expand `~` prefix for home directories in `shared_credentials_file` argument
* backend/s3: Add `assume_role_duration_seconds`, `assume_role_policy_arns`, `assume_role_tags`, and `assume_role_transitive_tag_keys` arguments

BUG FIXES

* backend/s3: Ensure configured profile is used
* backend/s3: Ensure configured STS endpoint is used during AssumeRole API calls
* backend/s3: Prefer AWS shared configuration over EC2 metadata credentials
* backend/s3: Prefer ECS credentials over EC2 metadata credentials
* backend/s3: Remove hardcoded AWS Provider messaging
```

Output from acceptance testing:

```
--- PASS: TestBackend (16.32s)
--- PASS: TestBackendConfig (0.58s)
--- PASS: TestBackendConfig_AssumeRole (0.02s)
--- PASS: TestBackendConfig_conflictingEncryptionSchema (0.00s)
--- PASS: TestBackendConfig_invalidKey (0.00s)
--- PASS: TestBackendConfig_invalidSSECustomerKeyEncoding (0.00s)
--- PASS: TestBackendConfig_invalidSSECustomerKeyLength (0.00s)
--- PASS: TestBackendExtraPaths (13.21s)
--- PASS: TestBackendLocked (28.98s)
--- PASS: TestBackendPrefixInWorkspace (5.65s)
--- PASS: TestBackendSSECustomerKey (17.60s)
--- PASS: TestBackend_impl (0.00s)
--- PASS: TestForceUnlock (17.50s)
--- PASS: TestKeyEnv (50.25s)
--- PASS: TestRemoteClient (4.78s)
--- PASS: TestRemoteClientLocks (16.85s)
--- PASS: TestRemoteClient_clientMD5 (12.08s)
--- PASS: TestRemoteClient_impl (0.00s)
--- PASS: TestRemoteClient_stateChecksum (17.92s)
```
bflad added a commit that referenced this issue Jun 5, 2020
* deps: Update github.com/hashicorp/aws-sdk-go-base@v0.5.0

Updated via:

```
$ go get github.com/hashicorp/aws-sdk-go-base@v0.5.0
$ go mod tidy
$ go mod vendor
```

* backend/s3: Updates for Terraform v0.13.0

Reference: #13410
Reference: #18774
Reference: #19482
Reference: #20062
Reference: #20599
Reference: #22103
Reference: #22161
Reference: #22601
Reference: #22992
Reference: #24252
Reference: #24253
Reference: #24480
Reference: #25056

Changes:

```
NOTES

* backend/s3: Deprecated `lock_table`, `skip_get_ec2_platforms`, `skip_requesting_account_id` arguments have been removed
* backend/s3: Credential ordering has changed from static, environment, shared credentials, EC2 metadata, default AWS Go SDK (shared configuration, web identity, ECS, EC2 Metadata) to static, environment, shared credentials, default AWS Go SDK (shared configuration, web identity, ECS, EC2 Metadata)
* The `AWS_METADATA_TIMEOUT` environment variable no longer has any effect as we now depend on the default AWS Go SDK EC2 Metadata client timeout of one second with two retries

ENHANCEMENTS

* backend/s3: Always enable shared configuration file support (no longer require `AWS_SDK_LOAD_CONFIG` environment variable)
* backend/s3: Automatically expand `~` prefix for home directories in `shared_credentials_file` argument
* backend/s3: Add `assume_role_duration_seconds`, `assume_role_policy_arns`, `assume_role_tags`, and `assume_role_transitive_tag_keys` arguments

BUG FIXES

* backend/s3: Ensure configured profile is used
* backend/s3: Ensure configured STS endpoint is used during AssumeRole API calls
* backend/s3: Prefer AWS shared configuration over EC2 metadata credentials
* backend/s3: Prefer ECS credentials over EC2 metadata credentials
* backend/s3: Remove hardcoded AWS Provider messaging
```

Output from acceptance testing:

```
--- PASS: TestBackend (16.32s)
--- PASS: TestBackendConfig (0.58s)
--- PASS: TestBackendConfig_AssumeRole (0.02s)
--- PASS: TestBackendConfig_conflictingEncryptionSchema (0.00s)
--- PASS: TestBackendConfig_invalidKey (0.00s)
--- PASS: TestBackendConfig_invalidSSECustomerKeyEncoding (0.00s)
--- PASS: TestBackendConfig_invalidSSECustomerKeyLength (0.00s)
--- PASS: TestBackendExtraPaths (13.21s)
--- PASS: TestBackendLocked (28.98s)
--- PASS: TestBackendPrefixInWorkspace (5.65s)
--- PASS: TestBackendSSECustomerKey (17.60s)
--- PASS: TestBackend_impl (0.00s)
--- PASS: TestForceUnlock (17.50s)
--- PASS: TestKeyEnv (50.25s)
--- PASS: TestRemoteClient (4.78s)
--- PASS: TestRemoteClientLocks (16.85s)
--- PASS: TestRemoteClient_clientMD5 (12.08s)
--- PASS: TestRemoteClient_impl (0.00s)
--- PASS: TestRemoteClient_stateChecksum (17.92s)
```
@bflad
Copy link
Member

bflad commented Jun 5, 2020

Multiple fixes for credential ordering, automatically using the AWS shared configuration file if present, and profile configuration handling of the S3 Backend have been merged and will release with version 0.13.0-beta2 of Terraform.

mildwonkey pushed a commit that referenced this issue Jun 12, 2020
* deps: Update github.com/hashicorp/aws-sdk-go-base@v0.5.0

Updated via:

```
$ go get github.com/hashicorp/aws-sdk-go-base@v0.5.0
$ go mod tidy
$ go mod vendor
```

* backend/s3: Updates for Terraform v0.13.0

Reference: #13410
Reference: #18774
Reference: #19482
Reference: #20062
Reference: #20599
Reference: #22103
Reference: #22161
Reference: #22601
Reference: #22992
Reference: #24252
Reference: #24253
Reference: #24480
Reference: #25056

Changes:

```
NOTES

* backend/s3: Deprecated `lock_table`, `skip_get_ec2_platforms`, `skip_requesting_account_id` arguments have been removed
* backend/s3: Credential ordering has changed from static, environment, shared credentials, EC2 metadata, default AWS Go SDK (shared configuration, web identity, ECS, EC2 Metadata) to static, environment, shared credentials, default AWS Go SDK (shared configuration, web identity, ECS, EC2 Metadata)
* The `AWS_METADATA_TIMEOUT` environment variable no longer has any effect as we now depend on the default AWS Go SDK EC2 Metadata client timeout of one second with two retries

ENHANCEMENTS

* backend/s3: Always enable shared configuration file support (no longer require `AWS_SDK_LOAD_CONFIG` environment variable)
* backend/s3: Automatically expand `~` prefix for home directories in `shared_credentials_file` argument
* backend/s3: Add `assume_role_duration_seconds`, `assume_role_policy_arns`, `assume_role_tags`, and `assume_role_transitive_tag_keys` arguments

BUG FIXES

* backend/s3: Ensure configured profile is used
* backend/s3: Ensure configured STS endpoint is used during AssumeRole API calls
* backend/s3: Prefer AWS shared configuration over EC2 metadata credentials
* backend/s3: Prefer ECS credentials over EC2 metadata credentials
* backend/s3: Remove hardcoded AWS Provider messaging
```

Output from acceptance testing:

```
--- PASS: TestBackend (16.32s)
--- PASS: TestBackendConfig (0.58s)
--- PASS: TestBackendConfig_AssumeRole (0.02s)
--- PASS: TestBackendConfig_conflictingEncryptionSchema (0.00s)
--- PASS: TestBackendConfig_invalidKey (0.00s)
--- PASS: TestBackendConfig_invalidSSECustomerKeyEncoding (0.00s)
--- PASS: TestBackendConfig_invalidSSECustomerKeyLength (0.00s)
--- PASS: TestBackendExtraPaths (13.21s)
--- PASS: TestBackendLocked (28.98s)
--- PASS: TestBackendPrefixInWorkspace (5.65s)
--- PASS: TestBackendSSECustomerKey (17.60s)
--- PASS: TestBackend_impl (0.00s)
--- PASS: TestForceUnlock (17.50s)
--- PASS: TestKeyEnv (50.25s)
--- PASS: TestRemoteClient (4.78s)
--- PASS: TestRemoteClientLocks (16.85s)
--- PASS: TestRemoteClient_clientMD5 (12.08s)
--- PASS: TestRemoteClient_impl (0.00s)
--- PASS: TestRemoteClient_stateChecksum (17.92s)
```
@ghost
Copy link

ghost commented Jul 6, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators Jul 6, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants