boltops-tools / boltops-tools/terraspace_plugin_aws

client_assume_role_options doesn't recognize the S3 backend's newer nested assume_role block, only the deprecated flat role_arn

Open Beginner friendly
#29 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Ruby
Stars
1
Forks
4
PR merge metrics
No merged PRs in 30d

Description

### Summary

Terraform (since ~1.6) and OpenTofu deprecated the flat `role_arn` argument on the S3 `backend` block in favor of a nested `assume_role` object:

```hcl
# Deprecated, produces a warning:
terraform {
backend "s3" {
role_arn = "arn:aws:iam::123456789012:role/example"
bucket = "my-bucket"
...
}
}

# Current:
terraform {
backend "s3" {
assume_role = {
role_arn = "arn:aws:iam::123456789012:role/example"
}
bucket = "my-bucket"
...
}
}
```
(Reference: https://opentofu.org/docs/language/settings/backends/s3/#credentials-and-shared-configuration)

`client_options` in [`lib/terraspace_plugin_aws/clients/options.rb`](https://github.com/boltops-tools/terraspace_plugin_aws/blob/main/lib/terraspace_plugin_aws/clients/options.rb#L6) only checks the flat key:

```ruby
def client_options
return {} unless @info
if @info['role_arn']
client_assume_role_options
else
client_default_options
end
end
```

When `role_arn` is moved under the nested `assume_role` block (to silence the deprecation warning and stay current with Terraform/OpenTofu), `@info['role_arn']` is `nil`, so this silently falls through to `client_default_options` — meaning the plugin's own S3 bucket/DynamoDB-table existence checks (`Backend::Bucket#exist?`, `Backend::Table`) run with the ambient/default credentials instead of assuming the configured role.

### Impact

If the default credentials don't have direct access to the state bucket (a common setup — the whole point of `assume_role` is that the CI identity has no direct bucket access and must assume a separate role), this fails hard:

```
Aws::S3::Errors::Forbidden: Aws::S3::Errors::Forbidden
ERROR: Bucket is not available:
Bucket might be owned by someone else or is on another one of your AWS accounts.
```

This means there's currently no way to use the new, non-deprecated `assume_role` backend syntax with this plugin without breaking its bucket/table preflight checks — users are stuck choosing between a deprecation warning (flat `role_arn`, still works) or broken CI (nested `assume_role`, silently loses the role assumption).

Confirmed still present in the latest release, `v0.6.1`.

### Reproduction

1. Configure an S3 backend using the nested `assume_role` block (flat `role_arn` removed).
2. Run any Terraspace command that hits `Backend::Bucket#exist?` (e.g. `terraspace plan`) where the target bucket is only accessible via the assumed role, not the caller's default credentials.
3. Observe `Aws::S3::Errors::Forbidden` / "Bucket is not available", even though `terraform`/`tofu` itself would correctly assume the role for its own backend init.

### Suggested fix

`client_options` (and the `whitelist`/`assume_role_config` extraction in `client_assume_role_options`) should also check for and read from a nested `assume_role` key, e.g.:

```ruby
def client_options
return {} unless @info
if @info['role_arn'] || @info['assume_role']
client_assume_role_options
else
client_default_options
end
end
```

with `client_assume_role_options` merging `@info['assume_role']` (if present) on top of/instead of the flat keys, matching Terraform's own precedence.

Happy to submit a PR if a maintainer confirms this approach.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in lib/terraspace_plugin_aws/clients/options.rb at client_options and client_assume_role_options, and trace how @info supplies role settings to the S3 and DynamoDB preflight clients. Support the nested assume_role configuration while preserving flat role_arn behavior and precedence, then verify that bucket and table checks use the assumed role for the nested configuration.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, ruby
Domain
backend, cloud
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.