Skip to content

Commit

Permalink
Add MariaDB to AWS RDS auto discovery (#10994)
Browse files Browse the repository at this point in the history
Add support for MariaDB AWS RDS with IAM authentication version 10.6+.

Backport #10333

Co-authored-by: Paul Gottschling <[email protected]>
Co-authored-by: Alan Parra <[email protected]>
Co-authored-by: Roman Tkachenko <[email protected]>
  • Loading branch information
4 people authored Mar 9, 2022
1 parent acbfe78 commit 81f2a9e
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 13 deletions.
16 changes: 9 additions & 7 deletions docs/pages/database-access/guides/rds.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
title: Database Access with AWS RDS and Aurora for PostgreSQL and MySQL
description: How to configure Teleport Database Access with AWS RDS and Aurora for PostgreSQL and MySQL.
title: Database Access with AWS RDS and Aurora
h1: Database Access with AWS RDS and Aurora for PostgreSQL, MySQL and MariaDB
description: How to configure Teleport Database Access with AWS RDS and Aurora for PostgreSQL, MySQL and MariaDB.
---

This guide will help you to:
Expand All @@ -9,9 +10,10 @@ This guide will help you to:
- Set up Teleport to access your RDS instances and Aurora clusters.
- Connect to your databases through Teleport.

<Admonition type="note" title="Aurora Serverless">
Aurora Serverless does not support IAM authentication at the time of this
writing so it can't be used with Database Access.
<Admonition type="note" title="Supported versions">
The following products are not compatible with Database Access as they don't support IAM authentication:
- Aurora Serverless.
- RDS MariaDB versions lower than 10.6.
</Admonition>

## Prerequisites
Expand Down Expand Up @@ -318,8 +320,8 @@ Access for RDS. See below how to enable it for your database engine.
GRANT rds_iam TO alice;
```
</TabItem>
<TabItem label="MySQL">
MySQL users must have RDS authentication plugin enabled:
<TabItem label="MySQL/MariaDB">
MySQL and MariaDB users must have the RDS authentication plugin enabled:

```sql
CREATE USER alice IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';
Expand Down
32 changes: 28 additions & 4 deletions lib/services/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/aws/aws-sdk-go/service/rds"
"github.com/aws/aws-sdk-go/service/redshift"

"github.com/coreos/go-semver/semver"
"github.com/gravitational/trace"
log "github.com/sirupsen/logrus"
)
Expand All @@ -49,7 +50,7 @@ type Databases interface {
DatabaseGetter
// CreateDatabase creates a new database resource.
CreateDatabase(context.Context, types.Database) error
// UpdateDatabse updates an existing database resource.
// UpdateDatabase updates an existing database resource.
UpdateDatabase(context.Context, types.Database) error
// DeleteDatabase removes the specified database resource.
DeleteDatabase(ctx context.Context, name string) error
Expand Down Expand Up @@ -290,7 +291,7 @@ func engineToProtocol(engine string) string {
switch engine {
case RDSEnginePostgres, RDSEngineAuroraPostgres:
return defaults.ProtocolPostgres
case RDSEngineMySQL, RDSEngineAurora, RDSEngineAuroraMySQL:
case RDSEngineMySQL, RDSEngineAurora, RDSEngineAuroraMySQL, RDSEngineMariaDB:
return defaults.ProtocolMySQL
}
return ""
Expand Down Expand Up @@ -369,6 +370,27 @@ func rdsTagsToLabels(tags []*rds.Tag) map[string]string {
return labels
}

// IsRDSInstanceSupported returns true if database supports IAM authentication.
// Currently, only MariaDB is being checked.
func IsRDSInstanceSupported(instance *rds.DBInstance) bool {
// TODO(jakule): Check other engines.
if aws.StringValue(instance.Engine) != RDSEngineMariaDB {
return true
}

// MariaDB follows semver schema: https://mariadb.org/about/
ver, err := semver.NewVersion(aws.StringValue(instance.EngineVersion))
if err != nil {
log.Errorf("Failed to parse RDS MariaDB version: %s", aws.StringValue(instance.EngineVersion))
return false
}

// Min supported MariaDB version that supports IAM is 10.6
// https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html
minIAMSupportedVer := semver.New("10.6.0")
return !ver.LessThan(*minIAMSupportedVer)
}

// IsRDSClusterSupported checks whether the aurora cluster is supported and logs
// related info if not.
func IsRDSClusterSupported(cluster *rds.DBCluster) bool {
Expand Down Expand Up @@ -536,6 +558,8 @@ const (
RDSEngineMySQL = "mysql"
// RDSEnginePostgres is RDS engine name for Postgres instances.
RDSEnginePostgres = "postgres"
// RDSEngineMariaDB is RDS engine name for MariaDB instances.
RDSEngineMariaDB = "mariadb"
// RDSEngineAurora is RDS engine name for Aurora MySQL 5.6 compatible clusters.
RDSEngineAurora = "aurora"
// RDSEngineAuroraMySQL is RDS engine name for Aurora MySQL 5.7 compatible clusters.
Expand All @@ -553,9 +577,9 @@ const (
// RDSEndpointTypeReader is the endpoint that load-balances connections across the Aurora Replicas that are
// available in a RDS cluster.
RDSEndpointTypeReader RDSEndpointType = "reader"
// RDSEndpointTypeCustom is the endpoint that specifieds one of the custom endpoints associated with the RDS cluster.
// RDSEndpointTypeCustom is the endpoint that specifies one of the custom endpoints associated with the RDS cluster.
RDSEndpointTypeCustom RDSEndpointType = "custom"
// RDSEndpointTypeInstance is the endpoint of a RDS DB instance.
// RDSEndpointTypeInstance is the endpoint of an RDS DB instance.
RDSEndpointTypeInstance RDSEndpointType = "instance"
)

Expand Down
51 changes: 50 additions & 1 deletion lib/services/database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,57 @@ func TestIsRDSClusterSupported(t *testing.T) {
EngineVersion: aws.String(test.engineVersion),
}

require.Equal(t, test.isSupported, IsRDSClusterSupported(cluster))
got, want := IsRDSClusterSupported(cluster), test.isSupported
require.Equal(t, want, got, "IsRDSClusterSupported = %v, want = %v", got, want)
})
}
}

func TestIsRDSInstanceSupported(t *testing.T) {
tests := []struct {
name string
engine string
engineVersion string
isSupported bool
}{
{
name: "non-MariaDB engine",
engine: RDSEnginePostgres,
engineVersion: "13.3",
isSupported: true,
},
{
name: "unsupported MariaDB",
engine: RDSEngineMariaDB,
engineVersion: "10.3.28",
isSupported: false,
},
{
name: "min supported version",
engine: RDSEngineMariaDB,
engineVersion: "10.6.2",
isSupported: true,
},
{
name: "supported version",
engine: RDSEngineMariaDB,
engineVersion: "10.8.0",
isSupported: true,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
cluster := &rds.DBInstance{
DBInstanceArn: aws.String("arn:aws:rds:us-east-1:1234567890:instance:test"),
DBClusterIdentifier: aws.String(test.name),
DbiResourceId: aws.String(uuid.New().String()),
Engine: aws.String(test.engine),
EngineVersion: aws.String(test.engineVersion),
}

got, want := IsRDSInstanceSupported(cluster), test.isSupported
require.Equal(t, want, got, "IsRDSInstanceSupported = %v, want = %v", got, want)
})
}
}
Expand Down
11 changes: 10 additions & 1 deletion lib/srv/db/cloud/watchers/rds.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,14 @@ func (f *rdsDBInstancesFetcher) getRDSDatabases(ctx context.Context) (types.Data
}
databases := make(types.Databases, 0, len(instances))
for _, instance := range instances {
if !services.IsRDSInstanceSupported(instance) {
f.log.Debugf("RDS instance %q (engine mode %v, engine version %v) doesn't support IAM authentication. Skipping.",
aws.StringValue(instance.DBInstanceIdentifier),
aws.StringValue(instance.Engine),
aws.StringValue(instance.EngineVersion))
continue
}

if !services.IsRDSInstanceAvailable(instance) {
f.log.Debugf("The current status of RDS instance %q is %q. Skipping.",
aws.StringValue(instance.DBInstanceIdentifier),
Expand Down Expand Up @@ -275,7 +283,8 @@ func rdsFilters() []*rds.Filter {
Name: aws.String("engine"),
Values: aws.StringSlice([]string{
services.RDSEnginePostgres,
services.RDSEngineMySQL}),
services.RDSEngineMySQL,
services.RDSEngineMariaDB}),
}}
}

Expand Down

0 comments on commit 81f2a9e

Please sign in to comment.