support cross-account AWS db access#23680
Conversation
| // Use full identity string as the semaphore name, since two roles | ||
| // may have the same name in different AWS accounts. | ||
| SemaphoreName: configurator.cfg.identity.String(), |
There was a problem hiding this comment.
@smallinsky the comment explains why I did this, but I just want to make sure this is ok
|
I'll test out I should be able to use an |
|
@greedy52 Yes you can use any assume role arn, even the same account as the agent identity. And thank you for testing those other protocols! |
mdwn
left a comment
There was a problem hiding this comment.
From a code perspective this looks good to me. Surprisingly straightforward given the size. :-) But I haven't actually gone and tested any of this myself -- I just wanted to make sure that if you're waiting for code reviews you're not blocked on me.
greedy52
left a comment
There was a problem hiding this comment.
first pass. good job tracking a millions places that need to be updated. I've tested elasticache/memorydb/rdsproxy with auto discovery and they worked out of the box. Really love this feature that now I can have separates roles for holding permissions for different database types.
|
may want to use the account from assume role arn for db user matcher here. Lines 2178 to 2179 in f238c1b |
998d3e2 to
1df39cc
Compare
|
I decided to refactor this and it's still WIP to fix tests, but should be ready again tomorrow. Implementation itself should be working for all protocols still, although the discovery PR stacked on this one will have to be updated as well. TODO:
|
0023a9c to
b62d5dd
Compare
On closer look I don't think this needs to be changed. Database AccountID must match the account ID for the assumed role. If there is no assumed role, then the account ID must not be blank. DynamoDB and Cassandra both return error from CheckAndSetDefaults if account ID is empty, Redshift Serverless checks for empty account ID and sets it from the parsed endpoint uri, and ValidateDatabase verifies that the account ID matches assume_role_arn account ID for all databases. And if account ID is blank, servicecfg.Database.CheckAndSetDefaults will set the account ID by parsing assume_role_arn. |
b62d5dd to
b9ee156
Compare
6fa8821 to
7e631b1
Compare
* update aws cloud clients, engines, metadata * base64 encode semaphor * update tests for refactored cloud clients
7e631b1 to
9a34bc7
Compare
This PR is a follow-up for #23158 as part of the larger issue: #21872
The database agent will now assume a configured AWS role for a database when connecting to it, fetching metadata, or setting up IAM permissions.
I split out the implementation for database discovery separately for a follow-up PR; this PR is just for individual db config.
Note:
assume_role_arnshould be in the same account as the configured database, so that when the db agent assumes that role it will be able to access the database.Testing
I have tested that this works with
RDSandAurora(MySQL and Postgres),Keyspaces,DynamoDB,Redshift Serverless.I have not tested:
MemoryDB,ElastiCache,RDS Proxy, orRedshift. Working on doing those next, but it's time consuming to setup all these different databases.Special Cases
Three protocols that use IAM roles for
--db-userare: AWS DynamoDB, Keyspaces, and Redshift Serverless. These protocols will assume the configured role (assume_role_arn) before assuming the role from--db-user. If there is noassume_role_arnin the database config, it will attempt to assume the--db-userrole directly (prior behavior), except that now all 3 protocols will useexternal_id, if it's available. So technically, these protocols don't need a configuredassume_role_arn, but we should advise customers to use that, as I explain below:Cross-account AWS requires a bit more setup than assuming a role within the same account, namely:
sts:AssumeRolepermission allowed for the role it will assume.For these reasons, in the doc guide update PR I will advise customers to use a configured
assume_role_arnandexternal_idto access an external account, which can then be used to assume other roles within that account for DynamoDB, Keyspaces, or Redshift Serverless (from--db-user). This is a simpler setup than configuring cross-account access for multiple roles; instead we only need to configure one role for cross-account access.Example setup
Example permissions attached to an identity in AWS account "111111111111":
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::222222222222:role/some-role" } ] }Example trust policy for "some-role" in AWS account "222222222222":
{ "Sid": "ExternalAccess", "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::111111111111:root", ] }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:ExternalId": "someUniqueID" } } }Example configuration for RDS postgres for a database agent running with credentials in account "111111111111":