terragrunt icon indicating copy to clipboard operation
terragrunt copied to clipboard

Add support for AssumeRoleWithWebIdentity

Open partcyborg opened this issue 11 months ago • 7 comments

Description

Add support for STS AssumeRoleWithWebIdentity.

Includes new config option iam_web_identity_token which takes either a WebIdentity token (designed to be passed in with get_env()), or a path to a file containing a WebIdentity token.

Fixes #2585.

TODOs

Read the Gruntwork contribution guidelines.

  • [x] Update the docs.
  • [x] Run the relevant tests successfully, including pre-commit checks.
  • [x] Ensure any 3rd party code adheres with our license policy or delete this line if its not applicable.
  • [x] Include release notes. If this PR is backward incompatible, include a migration guide.

Release Notes (draft)

Added attribute iam_web_identity_token to support AssumeRoleWithWebIdentity

Migration Guide

partcyborg avatar Mar 13 '24 00:03 partcyborg

FYI: I also tested this using gitlab's OIDC integration and it worked correctly, both with iam_web_identity_token set to the value of a token (using get_env()) and with it set to the path to a token on disk.

partcyborg avatar Mar 13 '24 01:03 partcyborg

Sorry, I have no idea how this got closed. I certainly did not intend to.

partcyborg avatar Mar 13 '24 17:03 partcyborg

aws_helper/config.go:5:2: SA1019: "io/ioutil" has been deprecated since Go 1.19: As of Go 1.16, the same functionality is now provided by package [io] or package [os], and those implementations should be preferred in new code. See the specific function documentation for details. (staticcheck)
        "io/ioutil"
        ^

denis256 avatar Mar 18 '24 17:03 denis256

aws_helper/config.go:5:2: SA1019: "io/ioutil" has been deprecated since Go 1.19: As of Go 1.16, the same functionality is now provided by package [io] or package [os], and those implementations should be preferred in new code. See the specific function documentation for details. (staticcheck)
        "io/ioutil"
        ^

Thanks for the review! I have replaced calls to ioutil.ReadFile with calls to os.ReadFile.

partcyborg avatar Mar 18 '24 23:03 partcyborg

@denis256 any chance I could get a followup review? I addressed the comments you left previously. Thanks in advance!

partcyborg avatar Apr 01 '24 21:04 partcyborg

Hi, returning to this PR, looks like there are conflicts with master

cli/app_test.go
cli/commands/flags.go

denis256 avatar Apr 16 '24 17:04 denis256

Hi @denis256 thanks for picking this up again.

I have resolved the merge conflicts (and updated the new flag name per the new naming convention).

Please take another look.

partcyborg avatar Apr 16 '24 19:04 partcyborg

Synced this branch against master again, resolving a small merge conflict.

Hey @denis256 I would really appreciate a followup review so I don't have to keep checking syncing this to avoid merge conflicts. Please and thank you!

partcyborg avatar May 06 '24 20:05 partcyborg

It is possible to implement integration tests to track that this functionality will work over time?

denis256 avatar May 14 '24 15:05 denis256

It is possible to implement integration tests to track that this functionality will work over time?

Yes, depending on your CI environment. For example, we will be using this functionality to replace shell script calls to aws sts assume-role-with-web-identity in our CI/CD environment.

Do you have integration tests for the current iam_role functionality? I would happily modify them for this, but I don't see anything in the repo that uses it.

In order to do this, you need to

  • Setup an AWS IAM OpenID Connect provider in the account
  • Setup an IAM role for your terragrunt to execute under
  • Grant AssumeRole permission to the OpenID Connect provider using an AssumeRolePolicyDocument entry that looks like this
{
    "Effect": "Allow",
    "Principal": {
        "Federated": "arn:aws:iam::<account>:oidc-provider/<name>"
    },
    "Action": "sts:AssumeRoleWithWebIdentity",
    "Condition": {
        "StringLike": {
            "<OIDC provider>:sub": "<repo path from your provider documentation>"
        }
    }
}

Then point iam_role at the above IAM role, and iam_web_identity_token at the either environment variable or filepath provided by the provider.

Here are the docs for setting this up in gitlab: https://docs.gitlab.com/ee/ci/cloud_services/aws/

Here are the docs for setting this up in github: https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services

Here are the docs for setting this up in circleci: https://circleci.com/docs/openid-connect-tokens/

partcyborg avatar May 21 '24 00:05 partcyborg

Hello, then this PR should be extended with integration tests which will use AssumeRoleWithWebIdentity, in the minimal implementation, required IAM role can be read from environment variables, similar to TestTerragruntAssumeRoleDuration.

In CircleCI we can add later required env variable.

denis256 avatar May 22 '24 20:05 denis256

To be clear, @partcyborg , we don't need these tests to be running in our CircleCI configuration for this pull request.

This integration test only has to work in the context of your CI system. Run it there, show the configurations you used (masking any account identifiers, etc), and share the test output with us so that we can consider this functionality tested.

They should require the minimum set of dependencies like an environment variable and an IAM role. It should also be accompanied with example CI setups in the docs that we can share with the community.

Once we have these, we can independently verify the tests, then merge this PR. In a subsequent PR, we can setup the integration tests into the CI configurations for this repository.

yhakbar avatar May 23 '24 12:05 yhakbar

To be clear, @partcyborg , we don't need these tests to be running in our CircleCI configuration for this pull request.

This integration test only has to work in the context of your CI system. Run it there, show the configurations you used (masking any account identifiers, etc), and share the test output with us so that we can consider this functionality tested.

They should require the minimum set of dependencies like an environment variable and an IAM role. It should also be accompanied with example CI setups in the docs that we can share with the community.

Once we have these, we can independently verify the tests, then merge this PR. In a subsequent PR, we can setup the integration tests into the CI configurations for this repository.

Thanks for the more detailed explanation @yhakbar

Just to be sure I understand, you want me to

  • Create a new integration test (in the test directory) that makes use of iam_role with iam_web_identity_token
  • Setup a CI pipeline in our CI infrastructure that runs this test

Is this correct?

partcyborg avatar May 23 '24 21:05 partcyborg

To be clear, @partcyborg , we don't need these tests to be running in our CircleCI configuration for this pull request. This integration test only has to work in the context of your CI system. Run it there, show the configurations you used (masking any account identifiers, etc), and share the test output with us so that we can consider this functionality tested. They should require the minimum set of dependencies like an environment variable and an IAM role. It should also be accompanied with example CI setups in the docs that we can share with the community. Once we have these, we can independently verify the tests, then merge this PR. In a subsequent PR, we can setup the integration tests into the CI configurations for this repository.

Thanks for the more detailed explanation @yhakbar

Just to be sure I understand, you want me to

* Create a new integration test (in the `test` directory) that makes use of `iam_role` with `iam_web_identity_token`

* Setup a CI pipeline in our CI infrastructure that runs this test

Is this correct?

That's basically it! If you could also provide some documentation updates to help other users set up their usage of the feature, with example workflows, etc that would be great.

yhakbar avatar May 24 '24 14:05 yhakbar

Hello @yhakbar and @denis256

I have added two integration tests for iam_web_identity_token:

  • TestTerragruntAssumeRoleWebIdentityEnv tests the functionality when the token is provided as input from an environment variable
  • TestTerragruntAssumeRoleWebIdentityFile tests the functionality when the token is provided as a local file on disk

I also updated the documentation to include instructions for how to set this up in GitHub, GitLab, and CircleCI.

To run the tests, I uploaded my fork of the terragrunt repo to my company's private gitlab project. I was then able to successfully execute both integration tests using an IAM role configured for web identity using the documentation referenced in my changes to the terragrunt documentation in this pull request.

I have included the GitLab pipeline config config used to run both tests, along with the pipeline's output (showing that the tests passed) in the following gist: https://gist.github.com/partcyborg/370d66dfea927052e27fa00f2e378019

One thing I will point out however is that I had to add support for using the given IAM role ARN and WebIdentity token to the deleteS3Bucket functionality in the integration test suite, otherwise the call would fail as our CI pipelines do not run with any static AWS credentials. I do not know if your pipelines need this or not, but it should work as written as long as the configured IAM role for the integration tests has sufficient AWS permissions.

Please let me know if there is anything else I can do here. While I can easily help with configuring GitLab pipelines in this manner, unfortunately I do not have experience with configuring GitHub Actions or CircleCI in this manner.

partcyborg avatar Jun 05 '24 01:06 partcyborg

docs/_docs/04_reference/config-blocks-and-attributes.md:1350 MD032/blanks-around-lists Lists should be surrounded by blank lines [Context: "- GitLab: [Configure OpenID Co..."]

Exited with code exit status 1

denis256 avatar Jun 05 '24 20:06 denis256

I was wondering why the integration test passed with WebIdentityFile

--- PASS: TestTerragruntAssumeRoleWebIdentityFile (13.67s)

I also found in internal tests that usage of WebIdentity file fails:

time=2024-06-05T18:11:01Z level=error msg=Error finding AWS credentials (did you set the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables?): NoCredentialProviders: no valid providers in chain. Deprecated.
	For verbose messaging see aws.Config.CredentialsChainVerboseErrors
time=2024-06-05T[18](https://github.com/gruntwork-test/testing-terragrunt-with-web-identity/actions/runs/9389092410/job/25855946545#step:6:19):11:01Z level=error msg=Unable to determine underlying exit code, so Terragrunt will exit with error code 1time=2024-06-05T18:11:01Z level=error msg=Error finding AWS credentials (did you set the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables?): NoCredentialProviders: no valid providers in chain. Deprecated.
	For verbose messaging see aws.Config.CredentialsChainVerboseErrors
time=2024-06-05T[18](https://github.com/gruntwork-test/testing-terragrunt-with-web-identity/actions/runs/9389092410/job/25855946545#step:6:19):11:01Z level=error msg=Unable to determine underlying exit code, so Terragrunt will exit with error code 1

Added fix in https://github.com/partcyborg/terragrunt/pull/1

denis256 avatar Jun 05 '24 20:06 denis256

I was wondering why the integration test passed with WebIdentityFile

--- PASS: TestTerragruntAssumeRoleWebIdentityFile (13.67s)

I also found in internal tests that usage of WebIdentity file fails:

time=2024-06-05T18:11:01Z level=error msg=Error finding AWS credentials (did you set the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables?): NoCredentialProviders: no valid providers in chain. Deprecated.
	For verbose messaging see aws.Config.CredentialsChainVerboseErrors
time=2024-06-05T[18](https://github.com/gruntwork-test/testing-terragrunt-with-web-identity/actions/runs/9389092410/job/25855946545#step:6:19):11:01Z level=error msg=Unable to determine underlying exit code, so Terragrunt will exit with error code 1time=2024-06-05T18:11:01Z level=error msg=Error finding AWS credentials (did you set the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables?): NoCredentialProviders: no valid providers in chain. Deprecated.
	For verbose messaging see aws.Config.CredentialsChainVerboseErrors
time=2024-06-05T[18](https://github.com/gruntwork-test/testing-terragrunt-with-web-identity/actions/runs/9389092410/job/25855946545#step:6:19):11:01Z level=error msg=Unable to determine underlying exit code, so Terragrunt will exit with error code 1

Added fix in partcyborg#1

Interesting that it works in our environment but not yours, as when initially setting up our CI environment to run these tests I was able to execute a static rendering of test/fixture-assume-role-web-identity/file-path using the same input vars as the test.

Regardless, I accepted the PR and updated our private fork and the tests still pass, so the change LGTM

partcyborg avatar Jun 06 '24 20:06 partcyborg

docs/_docs/04_reference/config-blocks-and-attributes.md:1350 MD032/blanks-around-lists Lists should be surrounded by blank lines [Context: "- GitLab: [Configure OpenID Co..."]

Exited with code exit status 1

Added a blank line before the start of the list.

Can you point me at instructions on how to run this test? A google search for "MD032/blanks-around-lists" points me at markdownlint, but running that against the docs returns a lot of unrelated issues.

partcyborg avatar Jun 06 '24 20:06 partcyborg

Can you point me at instructions on how to run this test? A google search for "MD032/blanks-around-lists" points me at markdownlint, but running that against the docs returns a lot of unrelated issues.

Different markdownlint.

It looks good to me!

$ markdownlint --disable 'MD013' -- docs

I will circle back to this tomorrow to review if Denis doesn't beat me to it. I think we're close to merging this!

yhakbar avatar Jun 06 '24 21:06 yhakbar

This would be an awesome addition. Mind taking a look @denis256 so it can be released? 🤞🏼

GeertWille avatar Jun 10 '24 18:06 GeertWille

@denis256 I responded to all of your review feedback. Mind taking another look?

Thanks!

partcyborg avatar Jun 12 '24 21:06 partcyborg

This change has been helpful, thanks, but I have to point out there's a typo in one of the env var names

TERRRAGRUNT_IAM_ASSUME_ROLE_WEB_IDENTITY_TOKEN

You've got too many Rs in TERRRAGRUNT.

dhmw avatar Jul 17 '24 14:07 dhmw

This change has been helpful, thanks, but I have to point out there's a typo in one of the env var names

TERRRAGRUNT_IAM_ASSUME_ROLE_WEB_IDENTITY_TOKEN

You've got too many Rs in TERRRAGRUNT.

It's an angry environment variable 😂 . Thanks for reporting. We'll look to address it.

yhakbar avatar Jul 17 '24 14:07 yhakbar