Skip to content

Commit

Permalink
Use raw string instead of token path
Browse files Browse the repository at this point in the history
  • Loading branch information
mattwilder committed Mar 12, 2024
1 parent 1363712 commit a6dae29
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 30 deletions.
23 changes: 12 additions & 11 deletions aws_helper/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package aws_helper

import (
"fmt"
"io/ioutil"
"time"

"github.com/aws/aws-sdk-go/aws/request"
Expand Down Expand Up @@ -96,7 +95,7 @@ func CreateAwsSessionFromConfig(config *AwsSessionConfig, terragruntOptions *opt
)
}

if iamRoleOptions.WebIdentityTokenPath != "" && iamRoleOptions.RoleARN != "" {
if iamRoleOptions.WebIdentityToken != "" && iamRoleOptions.RoleARN != "" {
sess.Config.Credentials = getWebIdentityCredentialsFromIAMRoleOptions(sess, iamRoleOptions)
return sess, nil
}
Expand All @@ -113,14 +112,20 @@ func CreateAwsSessionFromConfig(config *AwsSessionConfig, terragruntOptions *opt
return sess, nil
}

type rawTokenFetcher string

func (f rawTokenFetcher) FetchToken(ctx credentials.Context) ([]byte, error) {
return []byte(f), nil
}

func getWebIdentityCredentialsFromIAMRoleOptions(sess *session.Session, iamRoleOptions options.IAMRoleOptions) *credentials.Credentials {
roleSessionName := iamRoleOptions.AssumeRoleSessionName
if roleSessionName == "" {
// Set a unique session name in the same way it is done in the SDK
roleSessionName = fmt.Sprintf("%d", time.Now().UTC().UnixNano())
}
svc := sts.New(sess)
p := stscreds.NewWebIdentityRoleProviderWithOptions(svc, iamRoleOptions.RoleARN, roleSessionName, stscreds.FetchTokenPath(iamRoleOptions.WebIdentityTokenPath))
p := stscreds.NewWebIdentityRoleProviderWithOptions(svc, iamRoleOptions.RoleARN, roleSessionName, rawTokenFetcher(iamRoleOptions.WebIdentityToken))
if iamRoleOptions.AssumeRoleDuration > 0 {
p.Duration = time.Second * time.Duration(iamRoleOptions.AssumeRoleDuration)
} else {
Expand Down Expand Up @@ -161,8 +166,8 @@ func CreateAwsSession(config *AwsSessionConfig, terragruntOptions *options.Terra
}
sess.Handlers.Build.PushFrontNamed(addUserAgent)
if terragruntOptions.IAMRoleOptions.RoleARN != "" {
if terragruntOptions.IAMRoleOptions.WebIdentityTokenPath != "" {
terragruntOptions.Logger.Debugf("Assuming role %s with WebIdentity token %s", terragruntOptions.IAMRoleOptions.RoleARN, terragruntOptions.IAMRoleOptions.WebIdentityTokenPath)
if terragruntOptions.IAMRoleOptions.WebIdentityToken != "" {
terragruntOptions.Logger.Debugf("Assuming role %s with WebIdentity token %s", terragruntOptions.IAMRoleOptions.RoleARN, terragruntOptions.IAMRoleOptions.WebIdentityToken)
sess.Config.Credentials = getWebIdentityCredentialsFromIAMRoleOptions(sess, terragruntOptions.IAMRoleOptions)
} else {
terragruntOptions.Logger.Debugf("Assuming role %s", terragruntOptions.IAMRoleOptions.RoleARN)
Expand Down Expand Up @@ -215,15 +220,11 @@ func AssumeIamRole(iamRoleOpts options.IAMRoleOptions) (*sts.Credentials, error)
sessionDurationSeconds = iamRoleOpts.AssumeRoleDuration
}

if iamRoleOpts.WebIdentityTokenPath != "" {
webToken, err := ioutil.ReadFile(iamRoleOpts.WebIdentityTokenPath)
if err != nil {
return nil, err
}
if iamRoleOpts.WebIdentityToken != "" {
input := sts.AssumeRoleWithWebIdentityInput{
RoleArn: aws.String(iamRoleOpts.RoleARN),
RoleSessionName: aws.String(sessionName),
WebIdentityToken: aws.String(string(webToken)),
WebIdentityToken: aws.String(iamRoleOpts.WebIdentityToken),
DurationSeconds: aws.Int64(sessionDurationSeconds),
}
req, resp := stsClient.AssumeRoleWithWebIdentityRequest(&input)
Expand Down
8 changes: 4 additions & 4 deletions cli/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ func TestParseTerragruntOptionsFromArgs(t *testing.T) {
},

{
[]string{doubleDashed(commands.FlagNameTerragruntIAMWebIdentityToken), "/tmp/web-identity-token"},
mockOptionsWithIamWebIdentityToken(t, util.JoinPath(workingDir, config.DefaultTerragruntConfigPath), workingDir, []string{}, false, "", false, "/tmp/web-identity-token"),
[]string{doubleDashed(commands.FlagNameTerragruntIAMWebIdentityToken), "web-identity-token"},
mockOptionsWithIamWebIdentityToken(t, util.JoinPath(workingDir, config.DefaultTerragruntConfigPath), workingDir, []string{}, false, "", false, "web-identity-token"),
nil,
},

Expand Down Expand Up @@ -255,8 +255,8 @@ func mockOptionsWithIamAssumeRoleSessionName(t *testing.T, terragruntConfigPath

func mockOptionsWithIamWebIdentityToken(t *testing.T, terragruntConfigPath string, workingDir string, terraformCliArgs []string, nonInteractive bool, terragruntSource string, ignoreDependencyErrors bool, webIdentityToken string) *options.TerragruntOptions {
opts := mockOptions(t, terragruntConfigPath, workingDir, terraformCliArgs, nonInteractive, terragruntSource, ignoreDependencyErrors, false, defaultLogLevel, false)
opts.OriginalIAMRoleOptions.WebIdentityTokenPath = webIdentityToken
opts.IAMRoleOptions.WebIdentityTokenPath = webIdentityToken
opts.OriginalIAMRoleOptions.WebIdentityToken = webIdentityToken
opts.IAMRoleOptions.WebIdentityToken = webIdentityToken
return opts
}

Expand Down
4 changes: 2 additions & 2 deletions cli/commands/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,9 @@ func NewGlobalFlags(opts *options.TerragruntOptions) cli.Flags {
},
&cli.GenericFlag[string]{
Name: FlagNameTerragruntIAMWebIdentityToken,
Destination: &opts.IAMRoleOptions.WebIdentityTokenPath,
Destination: &opts.IAMRoleOptions.WebIdentityToken,
EnvVar: "TERRRAGRUNT_IAM_ASSUME_ROLE_WEB_IDENTITY_TOKEN",
Usage: "For AssumeRoleWithWebIdentity, the path to the WebIdentity token on disk. Can also be set via TERRRAGRUNT_IAM_ASSUME_ROLE_WEB_IDENTITY_TOKEN environment variable",
Usage: "For AssumeRoleWithWebIdentity, the WebIdentity token. Can also be set via TERRRAGRUNT_IAM_ASSUME_ROLE_WEB_IDENTITY_TOKEN environment variable",
},
&cli.BoolFlag{
Name: FlagNameTerragruntIgnoreDependencyErrors,
Expand Down
2 changes: 1 addition & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ func (conf *TerragruntConfig) GetIAMRoleOptions() options.IAMRoleOptions {
configIAMRoleOptions := options.IAMRoleOptions{
RoleARN: conf.IamRole,
AssumeRoleSessionName: conf.IamAssumeRoleSessionName,
WebIdentityTokenPath: conf.IamWebIdentityToken,
WebIdentityToken: conf.IamWebIdentityToken,
}
if conf.IamAssumeRoleDuration != nil {
configIAMRoleOptions.AssumeRoleDuration = *conf.IamAssumeRoleDuration
Expand Down
6 changes: 3 additions & 3 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,9 @@ func TestParseIamAssumeRoleSessionName(t *testing.T) {

func TestParseIamWebIdentity(t *testing.T) {
t.Parallel()
tokenPath := "/tmp/web-identity-token"
token := "test-token"

config := fmt.Sprintf(`iam_web_identity_token = "%s"`, tokenPath)
config := fmt.Sprintf(`iam_web_identity_token = "%s"`, token)

ctx := NewParsingContext(context.Background(), mockOptionsForTest(t))
terragruntConfig, err := ParseConfigString(ctx, DefaultTerragruntConfigPath, config, nil)
Expand All @@ -299,7 +299,7 @@ func TestParseIamWebIdentity(t *testing.T) {
assert.Nil(t, terragruntConfig.Dependencies)
assert.Nil(t, terragruntConfig.RetryableErrors)
assert.Empty(t, terragruntConfig.IamRole)
assert.Equal(t, tokenPath, terragruntConfig.IamWebIdentityToken)
assert.Equal(t, token, terragruntConfig.IamWebIdentityToken)
}

func TestParseTerragruntConfigDependenciesOnePath(t *testing.T) {
Expand Down
15 changes: 10 additions & 5 deletions config/include_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,19 @@ func TestMergeConfigIntoIncludedConfig(t *testing.T) {
&TerragruntConfig{IamRole: "role2"},
},
{
&TerragruntConfig{IamWebIdentityToken: "/tmp/token"},
&TerragruntConfig{IamWebIdentityToken: "/tmp/token"},
&TerragruntConfig{IamWebIdentityToken: "/tmp/token"},
&TerragruntConfig{IamWebIdentityToken: "token"},
&TerragruntConfig{IamWebIdentityToken: "token"},
&TerragruntConfig{IamWebIdentityToken: "token"},
},
{
&TerragruntConfig{IamWebIdentityToken: "token"},
&TerragruntConfig{IamWebIdentityToken: "token2"},
&TerragruntConfig{IamWebIdentityToken: "token2"},
},
{
&TerragruntConfig{},
&TerragruntConfig{IamWebIdentityToken: "/tmp/token"},
&TerragruntConfig{IamWebIdentityToken: "/tmp/token"},
&TerragruntConfig{IamWebIdentityToken: "token"},
&TerragruntConfig{IamWebIdentityToken: "token"},
},
}

Expand Down
8 changes: 4 additions & 4 deletions options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,8 @@ type IAMRoleOptions struct {
// The ARN of an IAM Role to assume. Used when accessing AWS, both internally and through terraform.
RoleARN string

// Path to the WebIdentity token on disk
WebIdentityTokenPath string
// The Web identity token. Used when RoleArn is also set to use AssumeRoleWithWebIdentity instead of AssumeRole.
WebIdentityToken string

// Duration of the STS Session when assuming the role.
AssumeRoleDuration int64
Expand All @@ -298,8 +298,8 @@ func MergeIAMRoleOptions(target IAMRoleOptions, source IAMRoleOptions) IAMRoleOp
out.AssumeRoleSessionName = source.AssumeRoleSessionName
}

if source.WebIdentityTokenPath != "" {
out.WebIdentityTokenPath = source.WebIdentityTokenPath
if source.WebIdentityToken != "" {
out.WebIdentityToken = source.WebIdentityToken
}

return out
Expand Down

0 comments on commit a6dae29

Please sign in to comment.