> For the complete documentation index, see [llms.txt](https://docs.release.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.release.com/cli/cli-usage-example.md).

# CLI usage example

### Overview

We can use the Release CLI to create, manage, and interact with ephemeral environments. The example voting application is a Dockerized application that contains three services: Vote, Result, and Worker, along with a Postgres database and Redis. We can use it to illustrate how to work with the Release CLI.

To get started using Release CLI, make sure you have a [Release account](/getting-started/create-an-account.md) and have worked through the [CLI quickstart guide](/cli/getting-started.md#quickstart).

Get [the code for the example voting application](https://github.com/awesome-release/release-example-voting-app), and follow the [guide to configure it as a Release application](/guides-and-examples/common-setup-examples/example-voting-app.md).

### Creating an environment

By using the `release environments create` command, we can spin up an environment from the Release CLI. This is often used in automation tasks in CI to create ephemeral environments programmatically.

If we have configured our application correctly in the above step, we should be able to list all our applications using `release apps list`:

```jsx
% release apps list
ID    NAME
1921  example-voting-app-1
```

***Note:*** *The `ID` and `NAME` of an application can be used interchangeably in commands that require the `--app` flag.*

As arguments to the `create` command, we pass in the app we want to deploy, the branch we want to track related to that application, and optionally any image overrides that are present.

We can also provide the `--wait` flag, which specifies that the command should wait for the deployment of the environment to complete before exiting. Additionally, the `--verbose` flag can be used to give us more detailed log output.

Before creating an environment for an application, we need to ensure that we have configured it to be able to be built automatically, or we need to have manually created a build for the branch we want to specify, through the UI.

```jsx
% release environments create --app example-voting-app-1 --branch main --wait --verbose
2022/05/20 00:01:20 Task [1526048] started as part of Task Chain [421859]!
2022/05/20 00:01:21 Task [1526047] started as part of Task Chain [421859]!
2022/05/20 00:01:22 Applying: registry-secrets
2022/05/20 00:01:22 Applying: example-voting-app-1-ingress
2022/05/20 00:01:22 Creating example-voting-app-1-ingress.
...
2022/05/20 00:03:06 Task Chain [421858] done as part of Pipeline Stage [511267]! End State is [done]!
2022/05/20 00:03:06 SpaceStage [511267] finished successfully as part of Space Pipeline [153125]!
2022/05/20 00:03:06 Space Pipeline [153125] finished successfully!
Created Environment: 36470
Created Deploy: 153125
```

Once we’ve run the command, it will create the environment and wait for the deployment. We should see output from the build and deploy logs in our terminal. This output replicates what we might see in the Release UI under the environment deploys page.

![Release UI Deployment](https://585411240-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1neGLLQ0sDXeK6ooSo%2Fuploads%2Fgit-blob-55c9acd416feba050e7b162fe685c65995238eb8%2Frelease-client-deploy.png?alt=media\&token=fb370724-b992-41ae-9009-c1e7e4b88ab1)

We can also optionally provide the `-o json` flag to the above command, so that the command output is JSON formatted. This is useful in CI and automation tasks.

We can now list the environments for our app with the `environments list` command:

```jsx
% release environments list --app example-voting-app-1
ID     HANDLE   NAME                 STATE     BRANCH  TYPE       VERSION  LAST DEPLOYED         EXPIRES
36470  tede739  awesome-release-main  deployed  main ephemeral  v2.1     2022-05-19T22:02:48Z  2022-05-26T22:02:48Z
```

Additionally, we can view the `deploys` for our environment using the `release deploys list` command. This command gives us the details of the deploy that was initiated when our environment was created, including how long it took, and the name of the environment it was against.

```jsx
% release deploys list --app 1921
ID      NAME    ENV NAME             STATE  STARTED AT                         TOTAL DURATION
154371  Deploy  awesome-release-main    done   2022-05-23 17:54:25.366 +0000 UTC  1m55s
```

### Interacting with instances

In a similar vein to the capabilities provided by the UI, the Release CLI lets us interact with the instances in an environment.

We can:

* Stream logs from an instance deployed in an environment.
* `exec` into a terminal in an instance to run commands in the container.

Using the environment we created in the above section, we can `exec` into a terminal in the pod our application is running in.

To `exec` into a terminal from the CLI, we can run the `instances terminal` command. This command automatically downloads the Kubernetes configuration for the environment to our development machine and sets us up with a terminal running whatever shell is installed on the pod.

```
release instances terminal --app backend
```

If we don’t specify an environment name, the Release CLI will provide a fuzzy search interactive prompt to allow us to select the environment we want.

![CLI environment search](https://585411240-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1neGLLQ0sDXeK6ooSo%2Fuploads%2Fgit-blob-057e772259577b4b496870fad9b7bf8cc9ddeccf%2Ffuzzy-environment-search.png?alt=media\&token=380858fc-11cb-4031-a2dc-4c4f6d0aeb01)

Additionally, we will be prompted to choose the instance we want to create a terminal for.

![CLI instance search](https://585411240-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1neGLLQ0sDXeK6ooSo%2Fuploads%2Fgit-blob-c42c8ce4d3b44a7381fa2940189187e5d2de251c%2Ffuzzy-instance-search.png?alt=media\&token=27e30298-d80f-4c4d-84d4-e21f2e77ad80)

After running the command, we should be able to interact with a shell running in the pod:

```jsx
<shell output>
```

Similarly, we can stream logs from a pod by running the `instances logs` command:

```
release instances logs --app example-voting-app-1
```

This command will connect to the pod in a specific environment that corresponds to the app, and stream the logs to the terminal.

```jsx
% release instances logs --app example-voting-app-1
vote-7d65b9959f-b255h/vote: * Serving Flask app "app" (lazy loading)
vote-7d65b9959f-b255h/vote: * Environment: production
vote-7d65b9959f-b255h/vote: WARNING: This is a development server. Do not use it in a production deployment.
vote-7d65b9959f-b255h/vote: Use a production WSGI server instead.
vote-7d65b9959f-b255h/vote: * Debug mode: on
vote-7d65b9959f-b255h/vote: * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
vote-7d65b9959f-b255h/vote: * Restarting with stat
vote-7d65b9959f-b255h/vote: * Debugger is active!
vote-7d65b9959f-b255h/vote: * Debugger PIN: 152-459-136
vote-7d65b9959f-b255h/vote: 10.8.108.167 - - [19/May/2022 22:02:58] "HEAD / HTTP/1.1" 200 -
```

### Interacting directly with an underlying cluster

{% hint style="info" %}
To use `clusters` commands, make sure you have configured a cluster in the Account Settings page of the Release UI.
{% endhint %}

Should we need to interact with the cluster, we can do this through the `clusters exec` command. The `clusters exec` command will run the provided Kubernetes client command with the following environment variables set:

* `KUBECONFIG`, set to a temporary file containing the cluster's Kubernetes config.
* `AWS_ACCESS_KEY` and `AWS_SECRET_KEY`, set to the credentials with access to the AWS account.

The command will download the configuration for the cluster and inject it locally through the above environment variables.

We can use `clusters exec` to run any Kubernetes client command that respects the above variables, such as `kubectl`, `k9s`, `aws`, and many others.

The temporary environment variables are cleaned up as soon as the command completes.

There are a few ways to specify the cluster you want to `exec` against:

* We can specify the cluster context directly via the `--cluster` flag.
* We can specify the `--app` and `--environment` flags. This will point to the cluster to the environment containing the app and set the Kubernetes namespace to the namespace containing the app, for example, `release clusters exec --app backend --environment training -- kubectl get pods`. This command tells the CLI to access the cluster the backend app is using in the training environment and run `kubectl get pods`.

A related command is `clusters shell`. Instead of running a provided command, this command will give us a new shell with the Kubernetes configuration set (the namespace and cluster for the environment). This allows us to run multiple commands against that cluster.

Exiting the created shell will clear the configuration in a similar way to the `clusters exec` command and return to the regular terminal.

### Streamlining Release configuration via GitOps

{% hint style="info" %}
This is still a relatively new feature. Should you wish to use `gitops`, please contact the Release team to have it enabled on your account. You can still commit and download the configuration, but the integration needs to be turned on.
{% endhint %}

We can use the `release gitops` commands to ease the process of migrating an application that was configured via the Release UI, but isn’t currently using GitOps.

By running the `release gitops init` command in an application's repo, we can automatically download the required configuration for the app. The following configuration files will be downloaded:

* A `.release.yaml` file, containing the default configuration for the application.
* A directory called `.release/`, containing the application template and environment variable configuration for the app.

```jsx
% release gitops init --app example-voting-app-1

⣾ Downloading existing configs...
Copying existing application template to .release/application_template.yaml
⣽ Downloading existing configs...
Copying existing environment variables config to .release/environment_variables.yaml
```

When we update any of our configuration, we can ensure that it is sane and valid by running `release gitops validate`. The output of this command will inform us of any errors in the configuration, and make suggestions for how it can be fixed. This is especially useful if the Release CLI is being used as part of CI/CD, and we need to validate any configuration errors *before* running other commands. It's useful to set this up as a Git pre-commit hook to catch any errors up front.

```jsx
% release gitops validate
⣟ Validating GitOps config...

✅ GitOps config is valid
```

### Deleting an environment

Although ephemeral environments will automatically be deleted after a specific amount of time, we might want to delete an environment before then. To do this, we can use the `environments delete` command.

Run the following command, specifying the app (by ID or by name) and the environment you want to delete (by ID or by name).

```jsx
% release environments delete --app example-voting-app-1 36470
⣾ Deleting environment...
```

In the above command, `example-voting-app-1` is the name of the application, and `36470` is the ID of the environment we want to delete.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.release.com/cli/cli-usage-example.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
