From 5b7407516225cb857afdcee2f020a86ffb70d357 Mon Sep 17 00:00:00 2001 From: Zoltan Mezei Date: Wed, 30 Oct 2024 19:15:54 +0100 Subject: [PATCH 1/5] feat: Add support for assuming an AWS IAM role from the provider. This commit proposes a solution for https://github.com/cyrilgdn/terraform-provider-postgresql/issues/263 --- postgresql/provider.go | 40 ++++++++++++++++++++++++++++++-- website/docs/index.html.markdown | 1 + 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/postgresql/provider.go b/postgresql/provider.go index af2b435f..f4c05a9a 100644 --- a/postgresql/provider.go +++ b/postgresql/provider.go @@ -3,6 +3,8 @@ package postgresql import ( "context" "fmt" + "github.com/aws/aws-sdk-go-v2/credentials" + "github.com/aws/aws-sdk-go-v2/service/sts" "os" "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" @@ -90,6 +92,13 @@ func Provider() *schema.Provider { Description: "AWS region to use for IAM auth", }, + "aws_rds_iam_provider_role_arn": { + Type: schema.TypeString, + Optional: true, + Default: "", + Description: "AWS IAM role to assume for IAM auth", + }, + "azure_identity_auth": { Type: schema.TypeBool, Optional: true, @@ -227,7 +236,7 @@ func validateExpectedVersion(v interface{}, key string) (warnings []string, erro return } -func getRDSAuthToken(region string, profile string, username string, host string, port int) (string, error) { +func getRDSAuthToken(region string, profile string, role string, username string, host string, port int) (string, error) { endpoint := fmt.Sprintf("%s:%d", host, port) ctx := context.Background() @@ -246,6 +255,32 @@ func getRDSAuthToken(region string, profile string, username string, host string return "", err } + if role != "" { + stsClient := sts.NewFromConfig(awscfg) + roleInput := &sts.AssumeRoleInput{ + RoleArn: aws.String(role), + RoleSessionName: aws.String("TerraformSession"), + } + + roleOutput, err := stsClient.AssumeRole(ctx, roleInput) + if err != nil { + return "", err + } + + awscfg, err = awsConfig.LoadDefaultConfig(ctx, + awsConfig.WithCredentialsProvider( + aws.NewCredentialsCache(credentials.NewStaticCredentialsProvider( + *roleOutput.Credentials.AccessKeyId, + *roleOutput.Credentials.SecretAccessKey, + *roleOutput.Credentials.SessionToken, + )), + ), + ) + if err != nil { + return "", err + } + } + token, err := auth.BuildAuthToken(ctx, endpoint, awscfg.Region, username, awscfg.Credentials) return token, err @@ -312,8 +347,9 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) { if d.Get("aws_rds_iam_auth").(bool) { profile := d.Get("aws_rds_iam_profile").(string) region := d.Get("aws_rds_iam_region").(string) + role := d.Get("aws_rds_iam_provider_role_arn").(string) var err error - password, err = getRDSAuthToken(region, profile, username, host, port) + password, err = getRDSAuthToken(region, profile, role, username, host, port) if err != nil { return nil, err } diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown index 30959d90..ce178fbc 100644 --- a/website/docs/index.html.markdown +++ b/website/docs/index.html.markdown @@ -183,6 +183,7 @@ The following arguments are supported: from the environment (or the given profile, see `aws_rds_iam_profile`) * `aws_rds_iam_profile` - (Optional) The AWS IAM Profile to use while using AWS RDS IAM Auth. * `aws_rds_iam_region` - (Optional) The AWS region to use while using AWS RDS IAM Auth. +* `aws_rds_iam_provider_role_arn` - (Optional) AWS IAM role to assume while using AWS RDS IAM Auth. * `azure_identity_auth` - (Optional) If set to `true`, call the Azure OAuth token endpoint for temporary token * `azure_tenant_id` - (Optional) (Required if `azure_identity_auth` is `true`) Azure tenant ID [read more](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config.html) From 0c5fea3170872c7296519afba26f55cc2636f96f Mon Sep 17 00:00:00 2001 From: Zoltan Mezei <59565282+zizzencs@users.noreply.github.com> Date: Mon, 4 Nov 2024 18:44:22 +0100 Subject: [PATCH 2/5] Update postgresql/provider.go Change RoleSessionName to be more descriptive. Co-authored-by: Cyril Gaudin --- postgresql/provider.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/postgresql/provider.go b/postgresql/provider.go index f4c05a9a..6f304200 100644 --- a/postgresql/provider.go +++ b/postgresql/provider.go @@ -259,7 +259,7 @@ func getRDSAuthToken(region string, profile string, role string, username string stsClient := sts.NewFromConfig(awscfg) roleInput := &sts.AssumeRoleInput{ RoleArn: aws.String(role), - RoleSessionName: aws.String("TerraformSession"), + RoleSessionName: aws.String("TerraformPostgresqlProvider"), } roleOutput, err := stsClient.AssumeRole(ctx, roleInput) From d7992e1aece59523565de382dd110ae0cf031100 Mon Sep 17 00:00:00 2001 From: Zoltan Mezei <59565282+zizzencs@users.noreply.github.com> Date: Mon, 4 Nov 2024 18:45:04 +0100 Subject: [PATCH 3/5] Update postgresql/provider.go More descriptive wrapper for the error message. Co-authored-by: Cyril Gaudin --- postgresql/provider.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/postgresql/provider.go b/postgresql/provider.go index 6f304200..f8a80bf9 100644 --- a/postgresql/provider.go +++ b/postgresql/provider.go @@ -264,7 +264,7 @@ func getRDSAuthToken(region string, profile string, role string, username string roleOutput, err := stsClient.AssumeRole(ctx, roleInput) if err != nil { - return "", err + return "", fmt.Errorf("could not assume AWS role: %w", err) } awscfg, err = awsConfig.LoadDefaultConfig(ctx, From e3c33a9ccd29ffcd3bfca42bc6831f801ad5ab0d Mon Sep 17 00:00:00 2001 From: Zoltan Mezei <59565282+zizzencs@users.noreply.github.com> Date: Mon, 4 Nov 2024 18:45:14 +0100 Subject: [PATCH 4/5] Update postgresql/provider.go More descriptive wrapper for the error message. Co-authored-by: Cyril Gaudin --- postgresql/provider.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/postgresql/provider.go b/postgresql/provider.go index f8a80bf9..91b2bb2a 100644 --- a/postgresql/provider.go +++ b/postgresql/provider.go @@ -277,7 +277,7 @@ func getRDSAuthToken(region string, profile string, role string, username string ), ) if err != nil { - return "", err + return "", fmt.Errorf("could not load AWS default config", err) } } From 58e64f010e944e5283bb3f2362772e506e2974f5 Mon Sep 17 00:00:00 2001 From: Cyril Gaudin Date: Thu, 7 Nov 2024 08:31:20 +0100 Subject: [PATCH 5/5] Apply suggestions from code review --- postgresql/provider.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/postgresql/provider.go b/postgresql/provider.go index 91b2bb2a..f0df3ea9 100644 --- a/postgresql/provider.go +++ b/postgresql/provider.go @@ -277,7 +277,7 @@ func getRDSAuthToken(region string, profile string, role string, username string ), ) if err != nil { - return "", fmt.Errorf("could not load AWS default config", err) + return "", fmt.Errorf("could not load AWS default config: %w", err) } }