# Joining Services via AWS IAM Role

This guide explains how to use the **IAM join method** to configure Teleport processes to join your Teleport cluster without sharing any secrets when they are running in AWS.

There are two other AWS join methods available depending on your use case:

1. The **EC2 join method**, which is only available for self-hosted Teleport deployments (see [documentation](https://goteleport.com/docs/enroll-resources/agents/aws-ec2.md)). A Teleport process running on an EC2 instance requests a signed EC2 instance identity document and presents it to the Teleport Auth Service, which queries the EC2 API to verify that the instance is genuine. This method requires a self-hosted Teleport cluster and IAM credentials for the Teleport Auth Service.
2. **Tokens not signed by AWS:** You can configure Teleport processes running on AWS to join a cluster via [Teleport join tokens](https://goteleport.com/docs/enroll-resources/agents/join-token.md) or, for Teleport processes running on Kubernetes, [signed ServiceAccount tokens](https://goteleport.com/docs/enroll-resources/agents/kubernetes.md). These approaches allow you to join a Teleport process to a cluster when you don't want to rely on AWS-specific APIs, e.g., when adopting a cloud-agnostic approach.

## How it works

The IAM join method is available to any Teleport process running anywhere with access to IAM credentials, such as an EC2 instance with an attached IAM role. No specific permissions or IAM policy is required: an IAM role with no attached policies is sufficient. No IAM credentials are required on the Teleport Auth Service.

Teleport processes prove that they are running in your AWS account by sending a pre-signed `sts:GetCallerIdentity` request to the Teleport Auth Service. The service's identity must match an allow rule configured in your AWS service joining token.

## Prerequisites

- A running Teleport cluster. If you want to get started with Teleport, [sign up](https://goteleport.com/signup) for a free trial or [set up a demo environment](https://goteleport.com/docs/get-started/deploy-community.md).

- The `tctl` and `tsh` clients.

  Installing `tctl` and `tsh` clients

  1. Determine the version of your Teleport cluster. The `tctl` and `tsh` clients must be at most one major version behind your Teleport cluster version. Send a GET request to the Proxy Service at `/v1/webapi/find` and use a JSON query tool to obtain your cluster version. Replace teleport.example.com:443 with the web address of your Teleport Proxy Service:

     ```
     $ TELEPORT_DOMAIN=teleport.example.com:443
     $ TELEPORT_VERSION="$(curl -s https://$TELEPORT_DOMAIN/v1/webapi/find | jq -r '.server_version')"
     ```

  2. Follow the instructions for your platform to install `tctl` and `tsh` clients:

     **Mac**

     Download the signed macOS .pkg installer for Teleport, which includes the `tctl` and `tsh` clients:

     ```
     $ curl -O https://cdn.teleport.dev/teleport-${TELEPORT_VERSION?}.pkg
     ```

     In Finder double-click the `pkg` file to begin installation.

     ---

     DANGER

     Using Homebrew to install Teleport is not supported. The Teleport package in Homebrew is not maintained by Teleport and we can't guarantee its reliability or security.

     ---

     **Windows - Powershell**

     ```
     $ curl.exe -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-windows-amd64-bin.zip
     Unzip the archive and move the `tctl` and `tsh` clients to your %PATH%
     NOTE: Do not place the `tctl` and `tsh` clients in the System32 directory, as this can cause issues when using WinSCP.
     Use %SystemRoot% (C:\Windows) or %USERPROFILE% (C:\Users\<username>) instead.
     ```

     **Linux**

     All of the Teleport binaries in Linux installations include the `tctl` and `tsh` clients. For more options (including RPM/DEB packages and downloads for i386/ARM/ARM64) see our [installation page](https://goteleport.com/docs/installation.md).

     ```
     $ curl -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
     $ tar -xzf teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
     $ cd teleport
     $ sudo ./install
     Teleport binaries have been copied to /usr/local/bin
     ```

* An AWS EC2 instance to host a Teleport service, with the Teleport binary installed.

* One of the following client tools for managing Teleport resources:

  - The `tctl` CLI, which you can install along with Teleport on your workstation ([documentation](https://goteleport.com/docs/installation.md)) on your workstation.
  - [Teleport Terraform provider](https://goteleport.com/docs/zero-trust-access/infrastructure-as-code/terraform-provider.md)
  - [Teleport Kubernetes operator](https://goteleport.com/docs/zero-trust-access/infrastructure-as-code/terraform-provider.md)

## Step 1/5. Set up AWS IAM credentials

Every Teleport process using the IAM method to join your Teleport cluster needs AWS IAM credentials in order to call the `sts:GetCallerIdentity` API. No specific IAM policy or permissions are needed. Any IAM user or role can call this API.

If running Teleport on an EC2 instance, it is sufficient to attach any IAM role to the instance. To attach an IAM role from the EC2 dashboard, select `Actions > Security > Modify IAM role`. It is not necessary for the role to have any attached IAM policies at all. If your instance does not otherwise need AWS credentials, it is preferred to create and attach an empty role with no attached policies.

## Step 2/5. Create the AWS joining token

Create the following `token.yaml` with an `allow` rule specifying your AWS account and the ARN that the Teleport process's identity must match.

You can create the token with `tctl` as well as the Teleport Terraform provider or Kubernetes operator.

The token name `iam-token` is just an example and can be any value you want to use, as long as you use the same value for `join_params.token_name` in Step 3.

The optional `aws_arn` field in the allow rules supports wildcard characters:

- `*` to match any combination of characters
- `?` to match any single character

**tctl**

```
# token.yaml
kind: token
version: v2
metadata:
  # the token name is not a secret because instances must prove that they are
  # running in your AWS account to use this token
  name: iam-token
spec:
  # use the minimal set of roles required (e.g. Node, App, Kube, DB, WindowsDesktop)
  roles: [Node]
  
  # set the join method allowed for this token
  join_method: iam
  
  allow:
    # specify the AWS account which Teleport processes may join from
    - aws_account: "111111111111"
    # multiple allow rules are supported
    - aws_account: "222222222222"
    # aws_arn is optional and allows you to restrict the IAM role of joining
    # Teleport processes
    - aws_account: "333333333333"
      aws_arn: "arn:aws:sts::333333333333:assumed-role/teleport-node-role/i-*"

```

Run the following command to create the token:

```
$ tctl create -f token.yaml
```

**Terraform**

Add the following resource to your Terraform configuration, replacing values as indicated:

```
resource "teleport_provision_token" "iam-token" {
  version = "v2"
  metadata = {
    name = "iam-token"
  }

  labels = {
    // This label is added on the Teleport side by default
    "teleport.dev/origin" = "dynamic"
  }

  spec = {
    // use the minimal set of roles required (e.g. Node, Proxy, App, Kube, DB, WindowsDesktop)
    roles = ["Node"]

    join_method = "iam"

    allow = [
      {
        aws_account = "111111111111"             # your AWS account ID
        aws_regions = ["us-west-1", "us-west-2"] # use the minimal set of AWS regions required
      },
      {
        # multiple allow rules are supported
        aws_account = "222222222222"
      },
      {
        # aws_arn is optional and allows you to restrict the IAM role of joining
        # Teleport processes
        aws_account = "333333333333"
        aws_arn     = "arn:aws:sts::333333333333:assumed-role/teleport-node-role/i-*"
      },
    ]
  }
}

```

**Kubernetes**

Add the following Kubernetes resource manifest, replacing values as indicated:

```
# token.yaml
kind: token
version: v2
metadata:
  # the token name is not a secret because instances must prove that they are
  # running in your AWS account to use this token
  name: iam-token
spec:
  # use the minimal set of roles required (e.g. Node, App, Kube, DB, WindowsDesktop)
  roles: [Node]
  
  # set the join method allowed for this token
  join_method: iam
  
  allow:
    # specify the AWS account which Teleport processes may join from
    - aws_account: "111111111111"
    # multiple allow rules are supported
    - aws_account: "222222222222"
    # aws_arn is optional and allows you to restrict the IAM role of joining
    # Teleport processes
    - aws_account: "333333333333"
      aws_arn: "arn:aws:sts::333333333333:assumed-role/teleport-node-role/i-*"

```

## Step 3/5 Install Teleport

Install Teleport on your AWS EC2 instance.

To install a Teleport Agent on your Linux server:

The recommended installation method is the cluster install script. It will select the correct version, edition, and installation mode for your cluster.

1. Assign teleport.example.com:443 to your Teleport cluster hostname and port, but not the scheme (https\://).

2. Run your cluster's install script:

   ```
   $ curl "https://teleport.example.com:443/scripts/install.sh" | sudo bash
   ```

## Step 4/5. Configure your services

Configure your Teleport service with a custom `teleport.yaml` file. Use the `join_params` section with `token_name` matching your token created in Step 2 and `method: iam` as shown in the following example config:

```
# /etc/teleport.yaml
version: v3
teleport:
  join_params:
    token_name: iam-token
    method: iam
  proxy_server: teleport.example.com:443
ssh_service:
  enabled: true
auth_service:
  enabled: false
proxy_service:
  enabled: false

```

In the `teleport.proxy_server` field, replace the value with the host and web port of your Teleport Proxy Service or Teleport Enterprise Cloud tenant, e.g., `mytenant.teleport.sh:443`.

## Step 5/5. Launch your Teleport process

Grant your Teleport instance access to credentials that it can use to authenticate to AWS.

- If you are running your Teleport instance on an EC2 instance, you may use the EC2 Instance Metadata Service method
- If you are running your Teleport instance in Kubernetes, you can use IAM Roles for Service Accounts (IRSA)
- Otherwise, you must use environment variables

**Instance Metadata Service**

Teleport will detect when it is running on an EC2 instance and use the Instance 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).

**Kubernetes IRSA**

Refer to [IAM Roles for Service Accounts (IRSA)](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) to set up an OIDC provider in AWS and configure an AWS IAM role that allows the pod's service account to assume the role.

**Environment Variables**

Teleport's built-in AWS client reads credentials from the following environment variables:

- `AWS_ACCESS_KEY_ID`
- `AWS_SECRET_ACCESS_KEY`
- `AWS_DEFAULT_REGION`

When you start your Teleport instance, the service reads environment variables from a file at the path `/etc/default/teleport`. Obtain these credentials from your organization. Ensure that `/etc/default/teleport` has the following content, replacing the values of each variable:

```
AWS_ACCESS_KEY_ID=00000000000000000000
AWS_SECRET_ACCESS_KEY=0000000000000000000000000000000000000000
AWS_DEFAULT_REGION=<YOUR_REGION>

```

Have multiple sources of AWS credentials?

Teleport's AWS client loads credentials from different sources in the following order:

- Environment Variables
- Shared credentials file
- Shared configuration file (Teleport always enables shared configuration)
- EC2 Instance Metadata (credentials only)

While you can provide AWS credentials via a shared credentials file or shared configuration file, you will need to run your Teleport instance with the `AWS_PROFILE` environment variable assigned to the name of your profile of choice.

If you have a specific use case that the instructions above do not account for, consult the documentation for the [AWS SDK for Go](https://docs.aws.amazon.com/sdk-for-go/api/aws/session/) for a detailed description of credential loading behavior.

Configure your Teleport instance to start automatically when the host boots up by creating a systemd service for it. The instructions depend on how you installed your Teleport instance.

**Package Manager**

On the host where you will run your Teleport instance, enable and start Teleport:

```
$ sudo systemctl enable teleport
$ sudo systemctl start teleport
```

**TAR Archive**

On the host where you will run your Teleport instance, create a systemd service configuration for Teleport, enable the Teleport service, and start Teleport:

```
$ sudo teleport install systemd -o /etc/systemd/system/teleport.service
$ sudo systemctl enable teleport
$ sudo systemctl start teleport
```

You can check the status of your Teleport instance with `systemctl status teleport` and view its logs with `journalctl -fu teleport`.

Once you have started Teleport, confirm that your service is able to connect to and join your cluster.
