From 8d0306d81e33f0e8a98005e61383222ab5d64429 Mon Sep 17 00:00:00 2001 From: Gavin Frazar Date: Wed, 17 May 2023 10:26:37 -0700 Subject: [PATCH] add AWS cross-account db access guide --- docs/config.json | 8 +- .../guides/aws-cross-account.mdx | 243 ++++++++++++++++++ docs/pages/includes/aws-credentials.mdx | 5 +- .../database-access/aws-bootstrap.mdx | 37 ++- .../pages/includes/database-access/guides.mdx | 1 + 5 files changed, 285 insertions(+), 9 deletions(-) create mode 100644 docs/pages/database-access/guides/aws-cross-account.mdx diff --git a/docs/config.json b/docs/config.json index 2287bfa44e441..9c7a61b20484c 100644 --- a/docs/config.json +++ b/docs/config.json @@ -1147,8 +1147,12 @@ "slug": "/database-access/guides/", "entries": [ { - "title": "AWS DynamoDB", - "slug": "/database-access/guides/aws-dynamodb/" + "title": "AWS Cross-Account", + "slug": "/database-access/guides/aws-cross-account/" + }, + { + "title": "AWS DynamoDB", + "slug": "/database-access/guides/aws-dynamodb/" }, { "title": "AWS ElastiCache & MemoryDB", diff --git a/docs/pages/database-access/guides/aws-cross-account.mdx b/docs/pages/database-access/guides/aws-cross-account.mdx new file mode 100644 index 0000000000000..b9c9045f28bbb --- /dev/null +++ b/docs/pages/database-access/guides/aws-cross-account.mdx @@ -0,0 +1,243 @@ +--- +title: AWS Cross-Account Database Access +description: How to connect AWS databases in external AWS accounts to Teleport. +--- + +
+ AWS cross-account database access is available starting from Teleport `13.0`. +
+ +You can deploy the Teleport Database Service with AWS IAM credentials in one +AWS account and use an AWS IAM role to grant Teleport access to databases in +another AWS account. + +When the Teleport Database Service needs to discover, configure, or retrieve +short-lived authentication tokens for AWS databases, it uses credentials for an +AWS IAM identity to make requests to the AWS API. +To access resources across AWS accounts, you can configure the Teleport Database +Service to assume an AWS role in another account before it uses the AWS API +for further actions. + +This is not limited to a single AWS role: +the Teleport Database Service can be configured to connect databases in its own +AWS account and multiple external AWS accounts at the same time. + +You will need to configure the Teleport Database Service to assume an AWS IAM +role and ensure that AWS IAM permissions are configured to allow the +`AssumeRole` call. + + +You should also check that your network configuration in AWS allows the +Teleport Database Service to connect to the databases. + +This guide does not cover AWS network configuration, because it depends on your +specific AWS network setup and the kind(s) of AWS databases you wish to connect +to Teleport. For more information, see: +[how to connect your database](../guides.mdx#how-to-connect-your-database-to-teleport). + + +## Teleport configuration + +The Teleport Database Service must be configured to assume an external AWS IAM +role and, optionally, pass an external ID when it assumes that role. +The configured AWS IAM role will be assumed via an AWS STS `AssumeRole` call +before the Teleport Database Service uses the AWS API to discover, configure, or retrieve +short-lived authentication tokens for AWS databases. + +An "external ID" is used to address what AWS calls +[the confused deputy problem](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html). +When you configure the Teleport Database Service to use an external ID, it will +include that external ID when it calls AWS STS `AssumeRole`. +The external AWS IAM role's trust policy will be used to verify that the +correct external ID was provided in the `AssumeRole` call. +For information about when you should use an external ID, see: +[purpose of an AWS external ID](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html#external-id-purpose). + +AWS database discovery config, static database config, and dynamic database +config all support the `assume_role_arn` and `external_id` settings. + + + +Modify your Teleport Database Service configuration file to assume an external +AWS IAM role when it is discovering AWS databases. + +```yaml +# This example configuration will discover AWS RDS databases in us-west-1 +# within AWS account `222222222222` by assuming the external AWS IAM role +# "example-role". +db_service: + enabled: "yes" + aws: + - types: ["rds"] + regions: ["us-west-1"] + assume_role_arn: "arn:aws:iam::222222222222:role/example-role" + external_id: "example-external-id" +``` + +Restart the Teleport Database Service for the configuration file changes to take +effect. + + +The AWS IAM role used to discover a database will also be used by the Teleport +Database Service to provide access to that database. + + + + +Modify your Teleport Database Service configuration file to statically register +an AWS database in an external account and proxy connections to it. + +```yaml +# This example configuration will statically register an RDS PostgreSQL instance +# in us-west-1 within AWS account `222222222222` by assuming an external AWS +# IAM role "example-role". +db_service: + enabled: "yes" + databases: + - name: "rds-postgres" + protocol: "postgres" + uri: "rds-postgres.abcdef012345.us-west-1.rds.amazonaws.com:5432" + aws: + assume_role_arn: "arn:aws:iam::222222222222:role/example-role" + external_id: "example-external-id" +``` + +Restart the Teleport Database Service for the configuration file changes to take +effect. + + + +Create a dynamic database resource to dynamically register an AWS database +in an external account and proxy connections to it. + +```yaml +# This example configuration will dynamically register an RDS PostgreSQL instance +# in us-west-1 within AWS account `222222222222`. +# Teleport Database Service agents that match its labels with resource selectors +# will proxy the database by assuming the configured external AWS IAM role. +kind: db +version: v3 +metadata: + name: "rds-postgres" + description: "Example dynamic database resource" + labels: + env: "dev" +spec: + protocol: "postgres" + uri: "rds-postgres.abcdef012345.us-west-1.rds.amazonaws.com:5432" + aws: + # Note that account_id must match the AWS account ID in `assume_role_arn`. + # Dynamic database resources do not derive `account_id` from + # `assume_role_arn` automatically (unlike static configuration). + account_id: "222222222222" + assume_role_arn: "arn:aws:iam::222222222222:role/example-role" + external_id: "example-external-id" +``` + +Save the configuration to a file like `database.yaml` and create it with `tctl`: +```code +$ tctl create database.yaml +``` +For more information about database registration using dynamic database +resources, see: [Dynamic Registration](dynamic-registration.mdx). + + + + +## Teleport AWS IAM identity + +In order to assume an AWS IAM role, the Teleport Database Service will need +credentials for an AWS IAM identity of its own. + +(!docs/pages/includes/aws-credentials.mdx service="the Database Service"!) + +## AWS IAM permissions + +AWS IAM policies must be configured for both the Teleport Database Service's +AWS IAM identity and the external AWS IAM role: +- The Teleport Database Service's AWS IAM identity must have permission to + assume the external role. +- The external AWS IAM role's trust policy must trust the Teleport Database + Service's AWS IAM identity. + +
+ Unlike assuming a role within the same AWS account, when an AWS IAM role is + in a different AWS account than the IAM identity that attempts to assume it, + the role's trust policy alone is not sufficient to allow assuming the role. + + For more details, see: + [AWS cross-account policy evaluation](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic-cross-account.html#policy-eval-cross-account). +
+ +(!docs/pages/includes/database-access/aws-bootstrap.mdx attachToRole="teleport-db-service" attachToUser="teleport-db-service"!) + +Specifically, the Teleport Database Service's AWS IAM identity must be granted +`sts:AssumeRole` permission for the external AWS IAM role. For example: +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "sts:AssumeRole", + "Resource": "arn:aws:iam::222222222222:role/example-role" + } + ] +} +``` + +You will also need to configure permissions for the external AWS IAM role, +specific to the type of database(s) that it will be used to access. + +For example, suppose `assume_role_arn` is set to +`arn:aws:iam::222222222222:role/example-role` - +you can bootstrap permissions for it automatically by running the following +command with AWS credentials for account `222222222222` configured in your +shell: +```code +$ teleport db configure bootstrap \ + -c /etc/teleport.yaml \ + --attach-to-role "example-role" +``` + +## AWS IAM trust policy + +Modify the external AWS IAM role's trust policy to allow the Teleport Database +Service's AWS IAM identity as a trusted principal. If you require an external +ID, provide a condition in the statement that allows the action only when +the correct external ID is given. + +For example, if the Teleport Database Service will be deployed to an EC2 +instance with an attached role `teleport-db-service` in AWS account +`123456789012`, and you want to require an external ID to assume the external +role, then the trust policy might look like: +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "Statement1", + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam::123456789012:role/teleport-db-service" + }, + "Action": "sts:AssumeRole", + "Condition": { + "StringEquals": { + "sts:ExternalId": "example-external-id" + } + } + } + ] +} +``` + +## Next steps + +- Get started by [connecting](../guides.mdx) your database. diff --git a/docs/pages/includes/aws-credentials.mdx b/docs/pages/includes/aws-credentials.mdx index 0504c784fad7c..eea6a9c44c212 100644 --- a/docs/pages/includes/aws-credentials.mdx +++ b/docs/pages/includes/aws-credentials.mdx @@ -8,7 +8,10 @@ Instance Metadata Service method. Otherwise, you must use environment variables: Teleport will detect when it is running on an EC2 instance and use the Instance -Metadata Service to fetch credentials. +Metadata Service to fetch credentials. + +The EC2 instance should be configured to use an EC2 instance profile. For more +information, see: [Using Instance Profiles](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html). diff --git a/docs/pages/includes/database-access/aws-bootstrap.mdx b/docs/pages/includes/database-access/aws-bootstrap.mdx index 9b25f7ac7cc53..49c638d50c2fe 100644 --- a/docs/pages/includes/database-access/aws-bootstrap.mdx +++ b/docs/pages/includes/database-access/aws-bootstrap.mdx @@ -1,3 +1,5 @@ +{{ attachToRole="TeleportRole" attachToUser="TeleportUser" account="123456789012" }} + Teleport can bootstrap IAM permissions for the Database Service based on its configuration using the `teleport db configure bootstrap` command. You can use this command in automatic or manual mode: @@ -8,8 +10,6 @@ this command in automatic or manual mode: - In manual mode, Teleport will print required IAM policies. You can then create and attach them manually using the AWS management console. -Run one of the following commands on your Database Service node: - Use this command to bootstrap the permissions automatically when @@ -17,7 +17,7 @@ Run one of the following commands on your Database Service node: credentials file). ```code - $ teleport db configure bootstrap -c /etc/teleport.yaml --attach-to-user TeleportUser + $ teleport db configure bootstrap -c /etc/teleport.yaml --attach-to-user {{ attachToUser }} ``` @@ -27,18 +27,43 @@ Run one of the following commands on your Database Service node: instance with an attached IAM role). ```code - $ teleport db configure bootstrap -c /etc/teleport.yaml --attach-to-role TeleportRole + $ teleport db configure bootstrap -c /etc/teleport.yaml --attach-to-role {{ attachToRole }} + ``` + + + + Use this command to display required IAM policies which you will then create in your AWS console: + + ```code + $ teleport db configure bootstrap -c /etc/teleport.yaml --manual --attach-to-user arn:aws:iam::{{ account }}:user/{{ attachToUser }} ``` - + Use this command to display required IAM policies which you will then create in your AWS console: ```code - $ teleport db configure bootstrap -c /etc/teleport.yaml --manual + $ teleport db configure bootstrap -c /etc/teleport.yaml --manual --attach-to-role arn:aws:iam::{{ account }}:role/{{ attachToRole }} ``` +
+When `assume_role_arn` is configured for databases or AWS matchers, +`teleport db configure bootstrap` will determine permissions required for the +bootstrap target AWS IAM identity using the following logic: +- When the target does not match `assume_role_arn` in any database resource or + AWS matcher in the configuration file, the target is assumed to be the + Teleport Database Service's AWS IAM identity and permissions are bootstrapped + for all the configured static databases and AWS matchers. +- When an `--attach-to-role` target matches an `assume_role_arn` setting for + static databases or AWS matchers in the configuration file, permissions will + be bootstrapped only for those static databases or AWS matchers. + +You will need to run the bootstrap command once with the Teleport Database +Service's IAM identity as the policy attachment target, and once for each AWS +IAM role that is used for `assume_role_arn`. +
+ See the full `bootstrap` command [reference](../../database-access/reference/cli.mdx#teleport-db-configure-bootstrap). diff --git a/docs/pages/includes/database-access/guides.mdx b/docs/pages/includes/database-access/guides.mdx index 532000f88a04a..6bae54d8913bd 100644 --- a/docs/pages/includes/database-access/guides.mdx +++ b/docs/pages/includes/database-access/guides.mdx @@ -32,3 +32,4 @@ - [GUI clients](../../connect-your-client/gui-clients.mdx): Configure database graphical clients. - [Dynamic Registration](../../database-access/guides/dynamic-registration.mdx): Register/unregister databases without restarting Teleport. - [High Availability](../../database-access/guides/ha.mdx): Deploy database access in HA configuration. +- [AWS Cross-Account Access](../../database-access/guides/aws-cross-account.mdx): Connect AWS databases in external AWS accounts.