# Enable a New Service on an Agent

A single Teleport Agent can run multiple services. This guide shows you how to adjust the services that a Teleport Agent runs so you can proxy different resources in your infrastructure.

## How it works

When a Teleport Agent joins a cluster, it presents a **join token** to the Teleport Auth Service in order to authenticate itself. A join token is a dynamic resource stored on the Teleport Auth Service backend. It contains a time to live (TTL), name, and a list of Teleport services that the token authorizes to run on the agent.

When a Teleport Agent joins a cluster, the Teleport Auth Service issues a certificate for the agent. The certificate contains the Teleport services that it authorizes the agent to run. To run new services on an agent, you must repeat the initial join procedure for those services. The agent needs to re-join the cluster with the new token and receive a new certificate.

## Prerequisites

- A Teleport cluster
- At least one Teleport Agent running in your cluster, either on a Linux server or a Kubernetes pod
- To check that you can connect to your Teleport cluster, sign in with `tsh login`, then verify that you can run `tctl` commands using your current credentials. For example, run the following command, assigning teleport.example.com to the domain name of the Teleport Proxy Service in your cluster and email\@example.com to your Teleport username:
  ```
  $ tsh login --proxy=teleport.example.com --user=email@example.com
  $ tctl status
  Cluster  teleport.example.com
  Version  17.7.20
  CA pin   sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678
  ```
  If you can connect to the cluster and run the `tctl status` command, you can use your current credentials to run subsequent `tctl` commands from your workstation. If you host your own Teleport cluster, you can also run `tctl` commands on the computer that hosts the Teleport Auth Service for full permissions.

As an example, this guide shows you how to add a service to an agent using the token join method. This is one of multiple available join methods. Read the [Using Teleport Agents overview](https://goteleport.com/docs/ver/17.x/enroll-resources/agents.md) for a complete list.

## Step 1/3. Generate a new join token

Generate a new join token for all services running on an agent, including any new services you want to run.

For example, if an agent runs the Teleport Kubernetes Service, and you want it to run the Teleport Application Service as well, create a join token for the Teleport Kubernetes Service and Teleport Application Service. To do so, specify the two services in the `--type` flag of `tctl tokens add`:

```
$ tctl tokens add --type=kube,app --ttl=5m
```

You can specify the following token types:

| Role             | Teleport Service                |
| ---------------- | ------------------------------- |
| `app`            | Application Service             |
| `auth`           | Auth Service                    |
| `bot`            | Machine & Workload Identity Bot |
| `db`             | Database Service                |
| `discovery`      | Discovery Service               |
| `kube`           | Kubernetes Service              |
| `node`           | SSH Service                     |
| `proxy`          | Proxy Service                   |
| `windowsdesktop` | Windows Desktop Service         |
| `mdm`            | Jamf Service                    |

If you are running your Teleport Agent using the `teleport-kube-agent` Helm chart, once you know your token types, update your values file so the `roles` field includes your required roles.

For example, this change adds the `app` role to enable the Teleport Application Service:

```
- roles: kube,db
+ roles: kube,app,db

```

See the `teleport-kube-agent` [chart reference](https://goteleport.com/docs/ver/17.x/reference/helm-reference/teleport-kube-agent.md#roles) for the roles and token types that the chart supports.

## Step 2/3. Edit your agent configuration

All Teleport Agent services run concurrently on the same `teleport` process. When the `teleport` daemon starts, it loads its configuration file (`/etc/teleport.yaml` by default) and determines which services to run. The configuration file also contains a reference to the join token the agent presents to the Teleport Auth Service in order to authenticate.

### Enable the new service

In the Teleport configuration file, top-level configuration fields that include the substring `_service` indicate whether to run a given Teleport service.

To enable a service, add the configuration field for your service with the `enabled` field set to `true`. The following configuration snippets are examples of enabling each Teleport Agent service in the configuration file:

**Application Service**

If the Teleport Agent runs on a Linux server, edit the configuration file to enable the new service:

```
app_service:
  enabled: true

```

If the Teleport Agent runs using the `teleport-kube-agent` chart, edit the values file to add an entry to `apps`:

```
apps:
  - name: myapp
    # ...

```

**Database Service**

If the Teleport Agent runs on a Linux server, edit the configuration file to enable the new service:

```
db_service:
  enabled: true

```

If the Teleport Agent runs using the `teleport-kube-agent` chart, edit the values file to add an entry to `databases`:

```
databases:
  - name: mydb
    # ...

```

**Kubernetes Service**

If the Teleport Agent runs on a Linux server, edit the configuration file to enable the new service:

```
kubernetes_service:
  enabled: true

```

If the Teleport Agent runs using the `teleport-kube-agent` chart, edit the values file to add the `kubeClusterName` field:

```
kubeClusterName: mycluster

```

**SSH Service**

If the Teleport Agent runs on a Linux server, edit the configuration file to enable the new service:

```
ssh_service:
  enabled: true

```

The Teleport SSH Service is not available for the `teleport-kube-agent` chart.

**Windows Desktop Service**

If the Teleport Agent runs on a Linux server, edit the configuration file to enable the new service:

```
windows_desktop_service:
  enabled: true

```

The Windows Desktop Service is not available for the `teleport-kube-agent` chart.

Note that while the examples above enable a new service, they do not configure it to proxy any resources. Read a [guide to enrolling resources](https://goteleport.com/docs/ver/17.x/enroll-resources.md) for how to configure the new Teleport service.

### Update the join token

Make sure the agent's configuration file refers to the new join token.

1. Find the name of the join token you created:

   ```
   $ tctl tokens ls
   Token                            Type        Labels Expiry Time (UTC)
   -------------------------------- ----------- ------ -------------------------------
   abcd123-insecure-do-not-use-this Node,Db,App        10 Aug 23 19:49 UTC (4m11s)
   ```

   In this case, the name of the token is `abcd123-insecure-do-not-use-this`.

2. In the agent's configuration file, update `teleport.join_params` or `teleport.auth_token`:

   ```
     teleport:
       join_params:
   -     token_name: efgh456-insecure-do-not-use-this
   +     token_name: abcd123-insecure-do-not-use-this
         method: token

   ```

   If the value of this field is a file path, edit the file at that path to refer to the name of the new token. For example, if the value of the field is `/var/lib/teleport/token`, run the following command:

   ```
   $ echo abcd123-insecure-do-not-use-this > /var/lib/teleport/token
   ```

   If you are using the `teleport-kube-agent` Helm chart to deploy an Agent, check your values file for either the `authToken` field or the `joinParams.tokenName` field instead.

## Step 3/3. Start Teleport Agents with the new join tokens

Restart your Teleport Agent so it rejoins the cluster with the new token and receives a certificate that authorizes the additional service you want to run.

### Linux server

If your Teleport Agent runs on a Linux server:

1. Delete the agent's state directory, which is `/var/lib/teleport` by default. (Check the `teleport.data_dir` field of the Agent's configuration file.) With no data directory, the agent will obtain its initial credentials from the Auth Service instead of reading existing credentials.

2. Restart the agent:

   ```
   $ sudo systemctl reload teleport
   ```

### Helm chart

Upgrade your Helm release:

```
$ helm upgrade teleport-agent teleport-kube-agent
```

## Further reading: manage tokens as code

While this guide shows you how to create a token using `tctl`, you can also manage tokens using the Teleport Terraform provider or Kubernetes operator. See the following documentation for information on the token resource:

- [Terraform provider](https://goteleport.com/docs/ver/17.x/reference/terraform-provider/resources/provision_token.md)
- [Kubernetes operator](https://goteleport.com/docs/ver/17.x/reference/operator-resources/resources-teleport-dev-provisiontokens.md)

You can set up a system to automate the process of assigning join tokens to agents, ensuring that all Teleport services you run have the correct join token permissions. Here are examples in the documentation:

- [Enroll Infrastructure with Terraform](https://goteleport.com/docs/ver/17.x/zero-trust-access/infrastructure-as-code/terraform-starter/enroll-resources.md): Using Terraform to launch Teleport Agent instances that depend on join token resources.
- [Automatically Register Resources with Teleport](https://goteleport.com/docs/ver/17.x/zero-trust-access/api/automatically-register-agents.md): Writing a compute platform client that automatically creates join tokens and launches Teleport Agents with them.
