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

Add assume role with web identity support for the S3 backend #31276

Conversation

bschaatsbergen
Copy link
Member

@bschaatsbergen bschaatsbergen commented Jun 19, 2022

This pull request implements the feature requested in #31244.

Summary

Currently the S3 Backend does not support assuming a role with web identity. As we already support assuming a different role as part of the S3 backend this seems like a valid request.

Next to that I think that it's also right to have feature parity with the Terraform AWS provider as they added the OpenID Connect (OIDC) support too recently.

OIDC allows GitHub Actions and other CI/CD pipelines to access resources in Amazon Web Services (AWS), without needing to store the AWS credentials as long-lived GitHub secrets. Security wise this seems like a huge win for those that assume a different role for the S3 backend.

A little heads-up

There seems to be no support yet for AssumeRoleWithWebIdentity in the awsbase go package we're using. As support for AssumeRoleWithWebIdentity through awsbase is only added to the awsbase/v2 package.

I've refactored a part of the S3 backend code to be compatible with the awsbase/v2 package.

Next to that, to separate the assume role and assume role through web identity configurations I've offloaded the existing attributes to 2 different configuration blocks. assume_role and assume_role_with_web_identity. For both a cleaner and simpler interface as well as to be inline with the existing configuration blocks coming from the Terraform AWS provder.

For example the below existing Terraform configuration

terraform {
  backend "s3" {
    region     = "us-west-2"
    bucket     = "example-bucket"
    key        = "example/state.tfstate"
    role_arn = "arn:aws:iam::837424938642:role/example-role"
    assume_role_duration_seconds = 600
  }
}

Becomes as following:

terraform {
  backend "s3" {
    region     = "us-west-2"
    bucket     = "example-bucket"
    key        = "example/state.tfstate"
    
    assume_role {
      role_arn = "arn:aws:iam::837424938642:role/example-role"
      duration_seconds = 600
    }
  }
}

Similar to the new assume_role block, a assume_role_with_web_identity block has been added to support the feature request.

terraform {
  backend "s3" {
    region     = "us-west-2"
    bucket     = "example-bucket"
    key        = "example/state.tfstate"
    
    assume_role_with_web_identity {
      role_arn = "arn:aws:iam::837424938642:role/example-role"
      web_identity_token_file = "/example/tokenfile"
      duration_seconds = 600
    }
  }
}

(Optional) backwards compatible - if we want no breaking changes

This doesn't have to be a breaking change, even though existing assume role related attributes are moved to a nested attribute and renamed. We could make the change backwards compatible, the old attributes can still be provided and override the assume_role block and a deprecation warning is shown to the user.

Implementation

Due to the S3 backend code being fairly outdated, I was forced to refactor a portion of the code to be compatible with the awsbase/v2. Which isn't a bad thing as this helped to stay inline with the Terraform AWS provider, most of the code was years old and up for a refactor nevertheless.

I've created 2 new configuration blocks, assume_role and assume_role_with_web_identity_provider. I've also added a new parameter duration to the assume_role block to be inline with the assume_role_with_web_identity_provider block.

To be done

Here some points that I'm still working on:

(if we plan on having backwards compatible)

  • Add support for backwards compatibility
  • Deprecation warning if old attributes are set

Tests

To be added..

Example usage

To be added..

terraform {
  backend "s3" {
    key            = "25335/test.tfstate"
    bucket         = "tf-state-837424938642-eu-central-1"
    region         = "eu-central-1"
    encrypt        = true
    dynamodb_table = "tf-state-837424938642-eu-central-1"

    assume_role_with_web_identity {
      role_arn = "arn:aws:iam::837424938642:role/example-role"
      web_identity_token_file = "/example/tokenfile"
    }
  }
}

@hashicorp-cla
Copy link

hashicorp-cla commented Jun 19, 2022

CLA assistant check
All committers have signed the CLA.

@bschaatsbergen bschaatsbergen changed the title Add assume role with web identity support for the S3 backend [WIP] - Add assume role with web identity support for the S3 backend Jun 19, 2022
@bschaatsbergen
Copy link
Member Author

I'm going to wait for some feedback on this PR, whether it fits the roadmap, etc. before finalizing this.

@IrmantasMarozas
Copy link

Can't wait <3

@IskanderNovena
Copy link

@bschaatsbergen I don't know how long you are planning on waiting, but you might want to set the PR to 'Ready for review' to get it reviewed by one of the reviewers.

@bschaatsbergen
Copy link
Member Author

@bschaatsbergen I don't know how long you are planning on waiting, but you might want to set the PR to 'Ready for review' to get it reviewed by one of the reviewers.

I'll have to dive into the PR again to sort a few things out. I'll see if I can spend some time on this over the weekend.

@bschaatsbergen
Copy link
Member Author

@gdavison and I plan on revisiting this PR soon 👍🏼

@haakond
Copy link

haakond commented Feb 21, 2023

This capability would be really useful and could reduce a lot of complexity.

Any new information to share? Thanks, guys!

@oxypwn
Copy link

oxypwn commented Apr 17, 2023

When can we get this functionality in?

@thobalose
Copy link

Looking forward to this! Thanks @bschaatsbergen 🥇

@MattPalladino
Copy link

Hey @bschaatsbergen , thanks for taking the time to develop this, it will be incredibly handy for setting up secure s3 backends : )

Are there any updates on the state of this PR? From my understanding of the feature, it should be ready to review?

@bschaatsbergen
Copy link
Member Author

Thanks for reaching out @MattPalladino, I've internally flagged this feature PR within Hashicorp and it's on the list of things to pick up - I believe that the S3 backend is part of the team that maintains the AWS Provider, which is currently busy working on their 5.0.0 release.

Tagging @breathingdust for visibility on this.

@alencar
Copy link

alencar commented Jul 11, 2023

Given AWS Provider 5.x is out for almost 2 months now, is there any news on this been released in next coming weeks/months? It would improve security and reduce operational complexity immensely.

@bschaatsbergen
Copy link
Member Author

@breathingdust ☝🏼

@breathingdust
Copy link
Member

breathingdust commented Jul 12, 2023

Hi @bschaatsbergen! We have just begun work on our S3 backend maintenance work in which this is included so we should have some movement on this very soon 🚀

@bschaatsbergen
Copy link
Member Author

Ah that's amazing @breathingdust, thanks for the update 👍🏼

@gdavison gdavison self-requested a review August 22, 2023 22:00
@gdavison gdavison force-pushed the 31244-add-assume-role-with-web-identity-support branch from f4fe0ac to 56e1363 Compare August 23, 2023 01:02
Copy link
Contributor

@gdavison gdavison left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for submitting, @bschaatsbergen. Looks good! 🚀

I've rebased this onto our dev branch, s3/modernization. If you could either create a new PR on this branch onto s3/modernization or point this PR at s3/modernization, we can get it merged into our dev work

@bschaatsbergen bschaatsbergen changed the title [WIP] - Add assume role with web identity support for the S3 backend Add assume role with web identity support for the S3 backend Aug 23, 2023
@bschaatsbergen bschaatsbergen changed the base branch from main to s3/modernization August 23, 2023 07:53
@bschaatsbergen bschaatsbergen marked this pull request as ready for review August 23, 2023 07:53
@bschaatsbergen bschaatsbergen requested a review from a team as a code owner August 23, 2023 07:53
@bschaatsbergen
Copy link
Member Author

Ah great to hear, @gdavison fixed! 👍🏼

  • Removed WIP from title
  • Moved from Draft to Ready for Review
  • Changed the base branch to s3/modernization

@jar-b jar-b force-pushed the 31244-add-assume-role-with-web-identity-support branch from 56e1363 to 28f0381 Compare August 23, 2023 14:29
Copy link
Member

@jar-b jar-b left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🚀

% TF_ACC=1 go test -count=1 ./internal/backend/remote-state/s3/...
ok      github.com/hashicorp/terraform/internal/backend/remote-state/s3 98.630s

@jar-b jar-b merged commit 7c9f6d3 into hashicorp:s3/modernization Aug 23, 2023
5 of 6 checks passed
@github-actions
Copy link

Reminder for the merging maintainer: if this is a user-visible change, please update the changelog on the appropriate release branch.

@jar-b
Copy link
Member

jar-b commented Aug 23, 2023

Thanks for your contribution, @bschaatsbergen!

The s3/modernization branch will be merged back onto main in the near future, targeting release with Terraform 1.6.0.

@bschaatsbergen bschaatsbergen deleted the 31244-add-assume-role-with-web-identity-support branch August 23, 2023 15:09
@manobi
Copy link

manobi commented Sep 1, 2023

@jar-b I'm trying to test it with IRSA, using the docker build hashicorp/terraform:1.6.0-beta1.
Unfortunately still receiving the same error as 1.5.0, where it's trying to use the node (EC2) IAM role instead of pod's role injected via service account:

╷
│ Error: No valid credential sources found
│ 
│ Please see https://www.terraform.io/docs/language/settings/backends/s3.html
│ for more information about providing credentials.
│ 
│ Error: failed to refresh cached credentials, operation error STS:
│ AssumeRole, https response error StatusCode: 403, RequestID:
│ 1bb41fc4-9cd0-4e05-9897-34ff7615786f, api error AccessDenied: User:
│ arn:aws:sts::REDACTED:assumed-role/REDACTED-eks-node-group-REDACTED
│ is not authorized to perform: sts:AssumeRole on resource:
│ arn:aws:iam::REDACTED:role/gitlab-runner-rule-REDACTED

Which is the same problem describe in hashicorp/go-getter#313

AWS_ROLE_ARN and AWS_WEB_IDENTITY_TOKEN_FILE env vars have correctly injected (validated with aws cli). Is this case covered by this PR and available in 1.6.0-beta1?

When I try to use the explicit configurations block:

assume_role_with_web_identity {
  role_arn = "arn:aws:iam::837424938642:role/example-role"
  web_identity_token_file = "/example/tokenfile"
}

I've the following error:

╷
│ Error: Unsupported block type
│ 
│   on dev.tfbackend line 11:
│   11: assume_role_with_web_identity {
│ 
│ Blocks of type "assume_role_with_web_identity" are not expected here.
╵

@jar-b
Copy link
Member

jar-b commented Sep 5, 2023

Hi @manobi - Thanks for the report! It appears the initial implementation in the 1.6 beta is not checking for the presence of the AWS_ROLE_ARN and AWS_WEB_IDENTITY_TOKEN_FILE. We will address this for the next beta release.

The explicit configuration should work with a minor adjustment in syntax (= { instead of {):

assume_role_with_web_identity = {
  role_arn = "arn:aws:iam::837424938642:role/example-role"
  web_identity_token_file = "/example/tokenfile"
}

Please let us know if you continue to see issues with an explicit backend configuration, and thanks again for the bug report.

@manobi
Copy link

manobi commented Sep 6, 2023

Thanks you @jar-b
I've made some progress by changing to the syntax you recommended.

Looking forward for the #33803, as soon as it get merged I'll come back here to report my tests.

Copy link

I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active contributions.
If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 10, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet