From 75883586992b26d42b37c770210de4de6e978cbc Mon Sep 17 00:00:00 2001 From: Rudra Gupta Date: Sat, 21 Oct 2023 08:44:04 -0400 Subject: [PATCH 1/3] feat: adds strike for checking automated backups against a db instance --- cmd/root.go | 2 +- go.mod | 4 ++ go.sum | 31 ++++++++++ strikes/AutomatedBackups.go | 99 ++++++++++++++++++++++++++++++++ strikes/AutomatedBackups_test.go | 32 +++++++++++ strikes/SQLFeatures.go | 20 +------ strikes/common.go | 47 +++++++++++++-- 7 files changed, 210 insertions(+), 25 deletions(-) create mode 100644 strikes/AutomatedBackups.go create mode 100644 strikes/AutomatedBackups_test.go diff --git a/cmd/root.go b/cmd/root.go index 328b8db..d8c94f9 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -24,10 +24,10 @@ var ( AvailableStrikes = map[string][]raidengine.Strike{ "CCC-Taxonomy": { Strikes.SQLFeatures, + Strikes.AutomatedBackups, // Strikes.VerticalScaling, // Strikes.Replication, // Strikes.MultiRegion, - // Strikes.AutomatedBackup, // Strikes.BackupRecovery, // Strikes.Encryption, // Strikes.RBAC, diff --git a/go.mod b/go.mod index c79709a..48428dd 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,10 @@ module github.com/krumIO/raid-rds go 1.14 require ( + github.com/aws/aws-sdk-go-v2 v1.21.2 + github.com/aws/aws-sdk-go-v2/config v1.19.0 + github.com/aws/aws-sdk-go-v2/credentials v1.13.43 + github.com/aws/aws-sdk-go-v2/service/rds v1.57.0 github.com/hashicorp/go-hclog v1.2.0 github.com/privateerproj/privateer-sdk v0.0.6 github.com/spf13/cobra v1.4.0 diff --git a/go.sum b/go.sum index 0bb7800..a325b97 100644 --- a/go.sum +++ b/go.sum @@ -397,6 +397,32 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV github.com/armon/go-metrics v0.4.0/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aws/aws-sdk-go-v2 v1.21.2 h1:+LXZ0sgo8quN9UOKXXzAWRT3FWd4NxeXWOZom9pE7GA= +github.com/aws/aws-sdk-go-v2 v1.21.2/go.mod h1:ErQhvNuEMhJjweavOYhxVkn2RUx7kQXVATHrjKtxIpM= +github.com/aws/aws-sdk-go-v2/config v1.19.0 h1:AdzDvwH6dWuVARCl3RTLGRc4Ogy+N7yLFxVxXe1ClQ0= +github.com/aws/aws-sdk-go-v2/config v1.19.0/go.mod h1:ZwDUgFnQgsazQTnWfeLWk5GjeqTQTL8lMkoE1UXzxdE= +github.com/aws/aws-sdk-go-v2/credentials v1.13.43 h1:LU8vo40zBlo3R7bAvBVy/ku4nxGEyZe9N8MqAeFTzF8= +github.com/aws/aws-sdk-go-v2/credentials v1.13.43/go.mod h1:zWJBz1Yf1ZtX5NGax9ZdNjhhI4rgjfgsyk6vTY1yfVg= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13 h1:PIktER+hwIG286DqXyvVENjgLTAwGgoeriLDD5C+YlQ= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13/go.mod h1:f/Ib/qYjhV2/qdsf79H3QP/eRE4AkVyEf6sk7XfZ1tg= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43 h1:nFBQlGtkbPzp/NjZLuFxRqmT91rLJkgvsEQs68h962Y= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43/go.mod h1:auo+PiyLl0n1l8A0e8RIeR8tOzYPfZZH/JNlrJ8igTQ= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37 h1:JRVhO25+r3ar2mKGP7E0LDl8K9/G36gjlqca5iQbaqc= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37/go.mod h1:Qe+2KtKml+FEsQF/DHmDV+xjtche/hwoF75EG4UlHW8= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45 h1:hze8YsjSh8Wl1rYa1CJpRmXP21BvOBuc76YhW0HsuQ4= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45/go.mod h1:lD5M20o09/LCuQ2mE62Mb/iSdSlCNuj6H5ci7tW7OsE= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.37 h1:WWZA/I2K4ptBS1kg0kV1JbBtG/umed0vwHRrmcr9z7k= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.37/go.mod h1:vBmDnwWXWxNPFRMmG2m/3MKOe+xEcMDo1tanpaWCcck= +github.com/aws/aws-sdk-go-v2/service/rds v1.57.0 h1:kUCf6QowN4v8Jz1LRCr9ar3vcrKJu5YtbAbdXUGvvF4= +github.com/aws/aws-sdk-go-v2/service/rds v1.57.0/go.mod h1:NNx09yR8B7z4I5xTt2rUq+5h2lmA9T9bbm7NME/74Ac= +github.com/aws/aws-sdk-go-v2/service/sso v1.15.2 h1:JuPGc7IkOP4AaqcZSIcyqLpFSqBWK32rM9+a1g6u73k= +github.com/aws/aws-sdk-go-v2/service/sso v1.15.2/go.mod h1:gsL4keucRCgW+xA85ALBpRFfdSLH4kHOVSnLMSuBECo= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3 h1:HFiiRkf1SdaAmV3/BHOFZ9DjFynPHj8G/UIO1lQS+fk= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3/go.mod h1:a7bHA82fyUXOm+ZSWKU6PIoBxrjSprdLoM8xPYvzYVg= +github.com/aws/aws-sdk-go-v2/service/sts v1.23.2 h1:0BkLfgeDjfZnZ+MhB3ONb01u9pwFYTCZVhlsSSBvlbU= +github.com/aws/aws-sdk-go-v2/service/sts v1.23.2/go.mod h1:Eows6e1uQEsc4ZaHANmsPRzAKcVDrcmjjWiih2+HUUQ= +github.com/aws/smithy-go v1.15.0 h1:PS/durmlzvAFpQHDs4wi4sNNP9ExsqZh6IlfdHXgKK8= +github.com/aws/smithy-go v1.15.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -596,6 +622,10 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -1319,6 +1349,7 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/strikes/AutomatedBackups.go b/strikes/AutomatedBackups.go new file mode 100644 index 0000000..30055f9 --- /dev/null +++ b/strikes/AutomatedBackups.go @@ -0,0 +1,99 @@ +package strikes + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/rds" + "github.com/privateerproj/privateer-sdk/raidengine" + "github.com/privateerproj/privateer-sdk/utils" + "github.com/spf13/viper" +) + +// Todo/Roadmap: Features to evaluate implementing +// AutomatedBackup.go - AWS CLI - check backup interval + +// This creates a database table +func (a *Strikes) AutomatedBackups() (strikeName string, result raidengine.StrikeResult) { + strikeName = "AutomatedBackups" + result = raidengine.StrikeResult{ + Passed: false, + Description: "Check for automated backups against the specified RDS instance", + DocsURL: "https://www.github.com/krumIO/raid-rds", + ControlID: "CCC-Taxonomy-1", + Movements: make(map[string]raidengine.MovementResult), + } + + // Movement + cfg, err := getAWSConfig() + if err != nil { + result.Message = err.Error() + return + } + + rdsInstanceMovement := checkRDSInstanceMovement(cfg) + result.Movements["CheckForDBInstance"] = rdsInstanceMovement + if !rdsInstanceMovement.Passed { + result.Message = rdsInstanceMovement.Message + return + } + + autmatedBackupsMovement := checkRDSAutomatedBackupMovement(cfg) + result.Movements["CheckForDBInstanceAutomatedBackups"] = autmatedBackupsMovement + if !autmatedBackupsMovement.Passed { + result.Message = autmatedBackupsMovement.Message + return + } + + result.Passed = true + result.Message = "Completed Successfully" + return +} + +func checkRDSInstanceMovement(cfg aws.Config) (result raidengine.MovementResult) { + // check if the instance is available + result = raidengine.MovementResult{ + Description: "Check if the instance is available/exists", + Function: utils.CallerPath(0), + } + + rdsClient := rds.NewFromConfig(cfg) + input := &rds.DescribeDBInstancesInput{ + DBInstanceIdentifier: aws.String(viper.GetString("raids.RDS.config.aws_db_instance_identifier")), + } + + instances, err := rdsClient.DescribeDBInstances(context.TODO(), input) + if err != nil { + // Handle error + result.Message = err.Error() + result.Passed = false + return + } + result.Passed = len(instances.DBInstances) > 0 + return +} + +func checkRDSAutomatedBackupMovement(cfg aws.Config) (result raidengine.MovementResult) { + + result = raidengine.MovementResult{ + Description: "Check if the instance has automated backups enabled", + Function: utils.CallerPath(0), + } + + rdsClient := rds.NewFromConfig(cfg) + input := &rds.DescribeDBInstanceAutomatedBackupsInput{ + DBInstanceIdentifier: aws.String(viper.GetString("raids.RDS.config.aws_db_instance_identifier")), + } + + backups, err := rdsClient.DescribeDBInstanceAutomatedBackups(context.TODO(), input) + if err != nil { + // Handle error + result.Message = err.Error() + result.Passed = false + return + } + + // Loop through the instances and print information + result.Passed = len(backups.DBInstanceAutomatedBackups) > 0 + return +} diff --git a/strikes/AutomatedBackups_test.go b/strikes/AutomatedBackups_test.go new file mode 100644 index 0000000..5fd0741 --- /dev/null +++ b/strikes/AutomatedBackups_test.go @@ -0,0 +1,32 @@ +package strikes + +import ( + "encoding/json" + "fmt" + "testing" + + "github.com/spf13/viper" +) + +func TestAutomatedBackup(t *testing.T) { + viper.AddConfigPath("../") + viper.SetConfigName("config") + viper.SetConfigType("yaml") + err := viper.ReadInConfig() + + if err != nil { + fmt.Println("Config file not found...") + return + } + + strikes := Strikes{} + strikeName, result := strikes.AutomatedBackups() + + fmt.Println(strikeName) + b, err := json.MarshalIndent(result, "", " ") + if err != nil { + fmt.Println(err) + } + fmt.Print(string(b)) + fmt.Println() +} diff --git a/strikes/SQLFeatures.go b/strikes/SQLFeatures.go index 54782f1..b0183ed 100644 --- a/strikes/SQLFeatures.go +++ b/strikes/SQLFeatures.go @@ -24,10 +24,6 @@ import ( // Monitoring.go - check for enabled, req API/CLI // Alerting.go - check for enabled, req API/CLI -func (a *Strikes) SetLogger(loggerName string) { - a.Log = raidengine.GetLogger(loggerName, false) -} - // This creates a database table func (a *Strikes) SQLFeatures() (strikeName string, result raidengine.StrikeResult) { strikeName = "SQLFeatures" @@ -61,26 +57,12 @@ func (a *Strikes) SQLFeatures() (strikeName string, result raidengine.StrikeResu return } -func connectToDb() (result raidengine.MovementResult) { - result = raidengine.MovementResult{ - Description: "The database host must be available and accepting connections", - Function: utils.CallerPath(0), - } - _, err := getConfig() - if err != nil { - result.Message = err.Error() - return - } - result.Passed = true - return -} - func createTable() (result raidengine.MovementResult) { result = raidengine.MovementResult{ Description: "A table can be created in the database", Function: utils.CallerPath(0), } - name, err := getConfig() + name, err := getDBConfig() if err != nil { result.Message = err.Error() return diff --git a/strikes/common.go b/strikes/common.go index fe80726..870a892 100644 --- a/strikes/common.go +++ b/strikes/common.go @@ -1,9 +1,15 @@ package strikes import ( + "context" "errors" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/credentials" hclog "github.com/hashicorp/go-hclog" + "github.com/privateerproj/privateer-sdk/raidengine" + "github.com/privateerproj/privateer-sdk/utils" "github.com/spf13/viper" ) @@ -15,12 +21,43 @@ type Movement struct { Strike string } -func getConfig() (string, error) { - if viper.IsSet("raids.RDS.config") && viper.IsSet("raids.RDS.config.database") { +func (a *Strikes) SetLogger(loggerName string) { + a.Log = raidengine.GetLogger(loggerName, false) +} - // Todo: return full config - // return viper.GetString("raids.RDS.config.database.host"), nil +func getDBConfig() (string, error) { + if viper.IsSet("raids.RDS.config") && viper.IsSet("raids.RDS.config.database") { return "database_host_placeholder", nil } - return "", errors.New("Database URL must be set in the config file (raids.RDS.config.database.host)") + return "", errors.New("database url must be set in the config file") +} + +func getAWSConfig() (cfg aws.Config, err error) { + if viper.IsSet("raids.RDS.config") && + viper.IsSet("raids.RDS.config.aws_access_key") && + viper.IsSet("raids.RDS.config.aws_secret_key") { + + access_key := viper.GetString("raids.RDS.config.aws_access_key") + secret_key := viper.GetString("raids.RDS.config.aws_secret_key") + session_key := viper.GetString("raids.RDS.config.aws_session_key") + region := viper.GetString("raids.RDS.config.aws_region") + + creds := credentials.NewStaticCredentialsProvider(access_key, secret_key, session_key) + cfg, err = config.LoadDefaultConfig(context.TODO(), config.WithCredentialsProvider(creds), config.WithRegion(region)) + } + return +} + +func connectToDb() (result raidengine.MovementResult) { + result = raidengine.MovementResult{ + Description: "The database host must be available and accepting connections", + Function: utils.CallerPath(0), + } + _, err := getDBConfig() + if err != nil { + result.Message = err.Error() + return + } + result.Passed = true + return } From b387992f211cf22af8cf78b9222448fa41cb2a19 Mon Sep 17 00:00:00 2001 From: Rudra Gupta Date: Sat, 21 Oct 2023 08:46:22 -0400 Subject: [PATCH 2/3] chore: updates exampe-config --- example-config.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/example-config.yml b/example-config.yml index 3d6b93f..aedcf0d 100644 --- a/example-config.yml +++ b/example-config.yml @@ -3,6 +3,11 @@ WriteDirectory: test_output raids: RDS: config: + aws_access_key: access_key + aws_secret_key: supersecret + aws_session_key: "" + aws_region: region + aws_db_instance_identifier: instance_identifier database: test host: localhost password: password From b342a63c38d539c7dc686b1515aba6b16ccc2bec Mon Sep 17 00:00:00 2001 From: Rudra Gupta Date: Sat, 21 Oct 2023 10:13:58 -0400 Subject: [PATCH 3/3] feat: updates yml structure --- example-config.yml | 26 +++++++++++++++----------- strikes/AutomatedBackups.go | 10 ++++++---- strikes/common.go | 25 ++++++++++++++++--------- 3 files changed, 37 insertions(+), 24 deletions(-) diff --git a/example-config.yml b/example-config.yml index aedcf0d..66597a0 100644 --- a/example-config.yml +++ b/example-config.yml @@ -2,16 +2,20 @@ loglevel: Debug WriteDirectory: test_output raids: RDS: - config: - aws_access_key: access_key - aws_secret_key: supersecret - aws_session_key: "" - aws_region: region - aws_db_instance_identifier: instance_identifier - database: test - host: localhost - password: password - port: 3306 - user: root + aws: + creds: + aws_access_key: access + aws_secret_key: supersecret + aws_session_key: "" + aws_region: us-east-1 + config: + instance_identifier: unique-id-name + database: test + host: localhost + password: password + port: 3306 + user: root + # google + # azure tactics: - CCC-Taxonomy \ No newline at end of file diff --git a/strikes/AutomatedBackups.go b/strikes/AutomatedBackups.go index 30055f9..967f1f3 100644 --- a/strikes/AutomatedBackups.go +++ b/strikes/AutomatedBackups.go @@ -7,7 +7,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/rds" "github.com/privateerproj/privateer-sdk/raidengine" "github.com/privateerproj/privateer-sdk/utils" - "github.com/spf13/viper" ) // Todo/Roadmap: Features to evaluate implementing @@ -58,8 +57,10 @@ func checkRDSInstanceMovement(cfg aws.Config) (result raidengine.MovementResult) } rdsClient := rds.NewFromConfig(cfg) + identifier, _ := getDBInstanceIdentifier() + input := &rds.DescribeDBInstancesInput{ - DBInstanceIdentifier: aws.String(viper.GetString("raids.RDS.config.aws_db_instance_identifier")), + DBInstanceIdentifier: aws.String(identifier), } instances, err := rdsClient.DescribeDBInstances(context.TODO(), input) @@ -81,13 +82,14 @@ func checkRDSAutomatedBackupMovement(cfg aws.Config) (result raidengine.Movement } rdsClient := rds.NewFromConfig(cfg) + identifier, _ := getDBInstanceIdentifier() + input := &rds.DescribeDBInstanceAutomatedBackupsInput{ - DBInstanceIdentifier: aws.String(viper.GetString("raids.RDS.config.aws_db_instance_identifier")), + DBInstanceIdentifier: aws.String(identifier), } backups, err := rdsClient.DescribeDBInstanceAutomatedBackups(context.TODO(), input) if err != nil { - // Handle error result.Message = err.Error() result.Passed = false return diff --git a/strikes/common.go b/strikes/common.go index 870a892..0530851 100644 --- a/strikes/common.go +++ b/strikes/common.go @@ -26,21 +26,28 @@ func (a *Strikes) SetLogger(loggerName string) { } func getDBConfig() (string, error) { - if viper.IsSet("raids.RDS.config") && viper.IsSet("raids.RDS.config.database") { + if viper.IsSet("raids.RDS.aws.config.host") && viper.IsSet("raids.RDS.aws.config.database") { return "database_host_placeholder", nil } return "", errors.New("database url must be set in the config file") } +func getDBInstanceIdentifier() (string, error) { + if viper.IsSet("raids.RDS.aws.config.instance_identifier") { + return viper.GetString("raids.RDS.aws.config.instance_identifier"), nil + } + return "", errors.New("database instance identifier must be set in the config file") +} + func getAWSConfig() (cfg aws.Config, err error) { - if viper.IsSet("raids.RDS.config") && - viper.IsSet("raids.RDS.config.aws_access_key") && - viper.IsSet("raids.RDS.config.aws_secret_key") { - - access_key := viper.GetString("raids.RDS.config.aws_access_key") - secret_key := viper.GetString("raids.RDS.config.aws_secret_key") - session_key := viper.GetString("raids.RDS.config.aws_session_key") - region := viper.GetString("raids.RDS.config.aws_region") + if viper.IsSet("raids.RDS.aws.creds") && + viper.IsSet("raids.RDS.aws.creds.aws_access_key") && + viper.IsSet("raids.RDS.aws.creds.aws_secret_key") { + + access_key := viper.GetString("raids.RDS.aws.creds.aws_access_key") + secret_key := viper.GetString("raids.RDS.aws.creds.aws_secret_key") + session_key := viper.GetString("raids.RDS.aws.creds.aws_session_key") + region := viper.GetString("raids.RDS.aws.creds.aws_region") creds := credentials.NewStaticCredentialsProvider(access_key, secret_key, session_key) cfg, err = config.LoadDefaultConfig(context.TODO(), config.WithCredentialsProvider(creds), config.WithRegion(region))