Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions docs/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
243 changes: 243 additions & 0 deletions docs/pages/database-access/guides/aws-cross-account.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
---
title: AWS Cross-Account Database Access
description: How to connect AWS databases in external AWS accounts to Teleport.
---

<Details
title="Version warning"
opened={true}
scope={["oss", "enterprise"]}
scopeOnly={true}
min="13.0"
>
AWS cross-account database access is available starting from Teleport `13.0`.
</Details>

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.

<Admonition type="note">
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).
</Admonition>

## 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.

<Tabs>
<TabItem label="AWS Discovery">
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.

<Admonition type="note">
The AWS IAM role used to discover a database will also be used by the Teleport
Database Service to provide access to that database.
</Admonition>

</TabItem>
<TabItem label="Static Config">
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.

</TabItem>
<TabItem label="Dynamic Config">
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).

</TabItem>
</Tabs>

## 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.

<Details title="Why are both required?">
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).
</Details>

(!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.
5 changes: 4 additions & 1 deletion docs/pages/includes/aws-credentials.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ Instance Metadata Service method. Otherwise, you must use environment variables:
<TabItem label="Instance Metadata Service">

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).

</TabItem>
<TabItem label="Environment Variables">
Expand Down
37 changes: 31 additions & 6 deletions docs/pages/includes/database-access/aws-bootstrap.mdx
Original file line number Diff line number Diff line change
@@ -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:
Expand All @@ -8,16 +10,14 @@ 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:

<Tabs>
<TabItem label="Automatic / IAM User">
Use this command to bootstrap the permissions automatically when
your Teleport Database Service runs as an IAM user (for example, uses an AWS
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 }}
```
</TabItem>

Expand All @@ -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 }}
```
</TabItem>

<TabItem label="Manual / IAM User">
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 }}
```
</TabItem>

<TabItem label="Manual">
<TabItem label="Manual / IAM Role">
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 }}
```
</TabItem>
</Tabs>

<Details title="Bootstrapping with assume_role_arn in config">
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`.
</Details>

See the full `bootstrap` command
[reference](../../database-access/reference/cli.mdx#teleport-db-configure-bootstrap).
1 change: 1 addition & 0 deletions docs/pages/includes/database-access/guides.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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.