# End-to-End Walkthrough: Destinations with Rudder CLI


> Step-by-step tutorial to define, validate, and apply a destination with Rudder CLI.



This tutorial shows you how to use [Rudder CLI](https://www.rudderstack.com/docs/rudder-cli/) to:

- Authenticate against your RudderStack workspace
- Create a project directory and define an Amazon S3 destination in YAML
- Validate and deploy the destination to your workspace

For feature overview and supported types, see [Manage Destinations using Rudder CLI](https://www.rudderstack.com/docs/rudder-cli/destinations/). To wire the destination to a source, continue with the [Connections walkthrough](https://www.rudderstack.com/docs/rudder-cli/connections-walkthrough/).

## Prerequisites

- Rudder CLI tool (`rudder-cli`) [installed locally](https://www.rudderstack.com/docs/rudder-cli/installation/), **v0.25.0 or later**.
- In your RudderStack workspace, create a [workspace-level Service Access Token](https://www.rudderstack.com/docs/access-management/service-access-tokens/#workspace-sat) with the following [permissions](https://www.rudderstack.com/docs/access-management/policies-overview/#resource-permissions) to manage destinations:

| Resource | Permissions | <div>Description</div> |
| :----| :-----| :----|
| Destinations | **Create & Delete** | Create or delete destinations in the workspace |
| Destinations | **Edit** | Change destination configuration |
| Destinations | **Connect** | Connect a destination to a source or a transformation |

- **If you're on Free or self-hosted plan, or for testing and development only**: Generate a [Personal Access Token](https://www.rudderstack.com/docs/access-management/personal-access-tokens/) with **Read-Write** role
**Warning:** Any action authenticated by a Personal Access Token will break if the user generating the token is removed from the organization or there is a breaking change to their permissions.

**Token permissions for legacy RBAC system**

If you are on the [legacy Permissions Management (RBAC) system](https://www.rudderstack.com/docs/archive/dashboard-guides/user-management/), your workspace-level Service Access Token should have minimum **Admin** permissions.

See [Generate a workspace-level Service Access Token](https://www.rudderstack.com/docs/archive/dashboard-guides/service-access-tokens/#generate-service-access-token) for steps to create the token.

![workspace-level Service Access Token with Admin permission](/docs/images/access-management/permissions/legacy/admin.webp)

## 1. Authenticate the CLI tool

Run the following command and enter your [access token](#prerequisites) when prompted:

```shell
rudder-cli auth login
```

## 2. Create a project directory

Create a project directory to store your destination YAML files:

```shell
mkdir ~/tutorial-destinations
```

**Info:** If you already manage Event Stream sources or other CLI resources, add the destination file to the same project directory. Rudder CLI processes all YAML files in the directory recursively.

This tutorial uses Amazon S3. See [Supported destinations](https://www.rudderstack.com/docs/rudder-cli/yaml-destinations/#supported-destination-types) for the destinations you can define with Rudder CLI.

If you use access-key authentication, see [How to Use Variable Substitution in Rudder CLI](https://www.rudderstack.com/docs/rudder-cli/variable-substitution/). This tutorial uses IAM role authentication, so you don't need a var file.

## 3. Review the YAML reference

Before you define the destination, review the [Destination YAML Reference](https://www.rudderstack.com/docs/rudder-cli/yaml-destinations/) for:

- The `destination` spec envelope (`id`, `display_name`, `type`, `definition_version`, `enabled`, `config`)
- Amazon S3 `config` keys, including role-based vs access-key authentication
- How `display_name` uniqueness and `type` immutability work

## 4. Define an Amazon S3 destination

Create `~/tutorial-destinations/s3.yaml`:

```yaml
version: rudder/v1
kind: destination
metadata:
  name: s3
spec:
  id: s3
  display_name: "S3 Destination"
  type: s3
  definition_version: 1
  enabled: true
  config:
    bucket_name: "my-rudder-bucket"
    prefix: "rudder-events"
    role_based_auth: true
    iam_role_arn: "arn:aws:iam::<AWS_ACCOUNT_ID>:role/<ROLE_NAME>"
```

Replace `<AWS_ACCOUNT_ID>` and `<ROLE_NAME>` with values from your AWS account. `role_based_auth` is required. When it is `true`, you must set `iam_role_arn` and must not set access keys.

**Info:** `id` is the project identifier other specs use in `#destination:s3` references. `display_name` is what the dashboard shows and must be unique among destinations in the project.

## 5. Validate and deploy

1. Validate your files:

```shell
rudder-cli validate -l ~/tutorial-destinations
```

2. **Optional**: Preview the workspace changes:

```shell
rudder-cli apply -l ~/tutorial-destinations --dry-run
```

3. Deploy the destination:

```shell
rudder-cli apply -l ~/tutorial-destinations
```

## See more

- [Manage Destinations using Rudder CLI](https://www.rudderstack.com/docs/rudder-cli/destinations/)
- [Destination YAML Reference](https://www.rudderstack.com/docs/rudder-cli/yaml-destinations/)
- [How to Use Variable Substitution in Rudder CLI](https://www.rudderstack.com/docs/rudder-cli/variable-substitution/)
- [End-to-End Walkthrough: Connections with Rudder CLI](https://www.rudderstack.com/docs/rudder-cli/connections-walkthrough/)
- [GitHub Actions for Rudder CLI](https://www.rudderstack.com/docs/rudder-cli/github-actions/)

