terraform icon indicating copy to clipboard operation
terraform copied to clipboard

s3 backend role chaining permission failure

Open Folling opened this issue 9 months ago • 4 comments
trafficstars

Terraform Version

Terraform v1.10.5
on darwin_arm64

Terraform Configuration Files

This works:

backend "s3" {
  bucket  = "redacted"
  region  = "redacted"
  key     = "redacted.tfstate"
  encrypt = true

  assume_role = {
    role_arn = "arn:aws:iam::1234567890:role/redacted"
  }
}

This fails:

backend "s3" {
  bucket  = "redacted"
  region  = "redacted"
  key     = "redacted.tfstate"
  encrypt = true

  assume_role = {
    role_arn = "arn:aws:iam::0987654321:role/redacted"
  }

  assume_role = {
    role_arn = "arn:aws:iam::1234567890:role/redacted"
  }
}

Debug Output

The first example initialises fine, the second fails with:

│ Error: Error loading state:
│     Unable to access object "redacted.tfstate" in S3 bucket "redacted": operation error S3: HeadObject, https response error StatusCode: 403, RequestID: redacted, HostID: redacted, api error Forbidden: Forbidden
│
│ Terraform failed to load the default state from the "s3" backend.
│ State migration cannot occur unless the state can be loaded. Backend
│ modification and state migration has been aborted. The state in both the
│ source and the destination remain unmodified. Please resolve the
│ above error and try again.

Expected Behavior

The request should work with chained role assumptions.

Actual Behavior

It fails with a role inbetween.

Steps to Reproduce

  1. terraform init

Additional Context

I have manually verified that

  1. The role has access (by assuming it directly)
  2. The chain is intact (assuming works on the CLI and the final role has access to S3 if role-chained)

I am also suspect that the roles are actually chained. The following configuration:

backend "s3" {
  bucket  = "redacted"
  region  = "redacted"
  key     = "redacted.tfstate"
  encrypt = true

  assume_role = {
    role_arn = "arn:aws:iam::0987654321:role/redacted"
  }

  assume_role = {
    role_arn = "gibberish_arn"
  }
}

Still yields the "403" error, instead of a "invalid ARN" error, as I would have expected.

The documentation is a bit iffy as well. It just says "multiple values can be specified", but isn't clear about whether that means

  1. passing an array of objects
  2. passing multiple role_arn properties in the object
  3. passing multiple blocks, like in the provider config.

I tried all of these and more, but looking at the source code I believe my above code is what would be intended.

References

  • #36506

Generative AI / LLM assisted development?

No response

Folling avatar Feb 13 '25 20:02 Folling

Hi @Folling,

This looks like an error in the configuration, you can't assign different things to the same attribute and the above configuration returns an Attribute redefined error during decoding so you shouldn't be able to get past initialization. Can you show how you are getting to the point of receiving a response from AWS with the given configuration?

jbardin avatar Feb 14 '25 13:02 jbardin

The attribute explicitly is supposed to allow for multiple values to allow for AWS role chaining.

This is supposed to provide parity with the AWS provider, which supports this feature here.

#36454 also talks about this feature, where they were able to get it running somehow. Which is confusing to me because: The feature was implemented in #35720 but was reverted in #35827.

Looking at https://github.com/hashicorp/terraform/blob/eb02c6538fd32c7f58008706cdc23208312379f5/internal/backend/remote-state/s3/backend.go#L297 it doesn't seem like it was ever re-renabled again.

But that conflicts with the documentation here and with the discussion in #36454.

Folling avatar Feb 14 '25 13:02 Folling

Yeah, I also don't understand what was going on in #36454, but you're correct about the configuration, the schema is explicitly a single attribute. I suspect it's a discrepancy in the documentation, but I'll wait for the AWS developers to chime in on the actual intent here.

jbardin avatar Feb 14 '25 13:02 jbardin

Just ran into this exact same issue today, docs say you can chain but it seems like you cannot.

syntastical avatar May 08 '25 14:05 syntastical