2022-04-26 17:10:50 +00:00
# Templates
2022-06-21 20:17:07 +00:00
Templates are written in standard Terraform and describe the infrastructure for
workspaces (e.g., aws_instance, kubernetes_pod, or both).
2022-04-26 17:10:50 +00:00
2022-06-21 20:17:07 +00:00
In most cases, a small group of users (Coder admins) manage templates. Then,
other users provision their development workspaces from templates.
2022-04-26 17:10:50 +00:00
2022-06-21 20:17:07 +00:00
## Add a template
2022-04-26 17:10:50 +00:00
2022-06-21 20:17:07 +00:00
Before users can create workspaces, you'll need at least one template in Coder.
2022-04-26 17:10:50 +00:00
```sh
2022-06-21 20:17:07 +00:00
# create a local directory to store templates
mkdir -p $HOME/coder/templates
cd $HOME/coder/templates
2022-04-26 17:10:50 +00:00
# start from an example
coder templates init
# optional: modify the template
vim < template-name > /main.tf
# add the template to Coder deployment
coder templates < create / update > < template-name >
```
2022-06-21 20:17:07 +00:00
> See the documentation and source code for each example in the
> [examples/](https://github.com/coder/coder/tree/main/examples/templates)
> directory in the repo.
## Customize templates
Example templates are not designed to support every use (e.g [examples/aws-linux ](https://github.com/coder/coder/tree/main/examples/templates/aws-linux ) does
not support custom VPCs). You can add these features by editing the Terraform
code once you run `coder templates init` (new) or `coder templates pull`
(existing).
- See [Creating and troubleshooting templates ](#creating--troubleshooting-templates ) for
more info
## Concepts in templates
While templates are written with standard Terraform, the
2022-07-19 18:24:06 +00:00
[Coder Terraform Provider ](https://registry.terraform.io/providers/coder/coder/latest/docs ) is
2022-06-21 20:17:07 +00:00
used to define the workspace lifecycle and establish a connection from resources
to Coder.
Below is an overview of some key concepts in templates (and workspaces). For all
2022-09-10 21:20:28 +00:00
template options, reference [Coder Terraform provider docs ](https://registry.terraform.io/providers/coder/coder/latest/docs ).
2022-06-21 20:17:07 +00:00
### Resource
2022-07-19 18:24:06 +00:00
Resources in Coder are simply [Terraform resources ](https://www.terraform.io/language/resources ).
2022-06-21 20:17:07 +00:00
If a Coder agent is attached to a resource, users can connect directly to the resource over
SSH or web apps.
### Coder agent
Once a Coder workspace is created, the Coder agent establishes a connection
between a resource (docker_container) and Coder, so that a user can connect to
their workspace from the web UI or CLI. A template can have multiple agents to
2022-07-19 18:24:06 +00:00
allow users to connect to multiple resources in their workspace.
2022-06-21 20:17:07 +00:00
> Resources must download and start the Coder agent binary to connect to Coder.
> This means the resource must be able to reach your Coder URL.
2022-07-19 18:24:06 +00:00
Use the Coder agent's init script to
2022-06-21 20:17:07 +00:00
```hcl
data "coder_workspace" "me" {
}
resource "coder_agent" "pod1" {
os = "linux"
arch = "amd64"
}
resource "kubernetes_pod" "pod1" {
spec {
...
container {
command = ["sh", "-c", coder_agent.pod1.init_script]
env {
name = "CODER_AGENT_TOKEN"
value = coder_agent.dev.token
}
}
}
}
```
2022-07-19 18:24:06 +00:00
The `coder_agent` resource can be configured as described in the
[documentation for the `coder` Terraform provider. ](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent )
For example, you can use the `env` property to set environment variables that will be
inherited by all child processes of the agent, including SSH sessions.
2022-07-30 22:57:16 +00:00
#### startup_script
Use the Coder agent's `startup_script` to run additional commands like
2022-08-10 22:56:21 +00:00
installing IDEs, [cloning dotfiles ](./dotfiles.md#templates ), and cloning project repos.
2022-07-30 22:57:16 +00:00
```hcl
resource "coder_agent" "coder" {
os = "linux"
arch = "amd64"
dir = "/home/coder"
startup_script = < < EOT
#!/bin/bash
# install code-server
2022-07-31 20:06:05 +00:00
curl -fsSL https://code-server.dev/install.sh | sh
# The & prevents the startup_script from blocking so the
# next commands can run.
2022-07-30 22:57:16 +00:00
code-server --auth none --port &
2022-07-31 20:06:05 +00:00
# var.repo and var.dotfiles_uri is specified
# elsewhere in the Terraform code as input
# variables.
2022-07-30 22:57:16 +00:00
# clone repo
ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
git clone --progress git@github.com:${var.repo}
# use coder CLI to clone and install dotfiles
coder dotfiles -y ${var.dotfiles_uri}
2022-07-31 20:06:05 +00:00
EOT
2022-07-30 22:57:16 +00:00
}
```
2022-06-21 20:17:07 +00:00
### Parameters
2022-04-26 17:10:50 +00:00
2022-06-21 20:17:07 +00:00
Templates often contain _parameters_ . These are defined by `variable` blocks in
Terraform. There are two types of parameters:
2022-04-26 17:10:50 +00:00
2022-06-21 20:17:07 +00:00
- **Admin/template-wide parameters** are set when a template is created/updated. These values
are often cloud configuration, such as a `VPC` , and are annotated
2022-06-16 17:47:10 +00:00
with `sensitive = true` in the template code.
2022-06-21 20:17:07 +00:00
- **User/workspace parameters** are set when a user creates a workspace. These
values are often personalization settings such as "preferred region"
2022-06-16 16:22:14 +00:00
or "workspace image".
2022-06-03 21:29:22 +00:00
2022-07-22 14:59:19 +00:00
The template sample below uses _admin and user parameters_ to allow developers to
2022-06-21 20:17:07 +00:00
create workspaces from any image as long as it is in the proper registry:
```hcl
variable "image_registry_url" {
2022-07-22 14:59:19 +00:00
description = "The image registry developers can select"
default = "artifactory1.organization.com"
2022-06-21 20:17:07 +00:00
sensitive = true # admin (template-wide) parameter
}
variable "docker_image_name" {
description = "The image your workspace will start from"
default = "base_image"
sensitive = false # user (workspace) parameter
}
resource "docker_image" "workspace" {
# ... other config
name = "${var.image_registry_url}/${var.docker_image_name}"
}
```
### Persistent vs. ephemeral resources
2022-09-10 06:07:51 +00:00
You can use the workspace state to ensure some resources in Coder are
2022-06-21 20:17:07 +00:00
persistent, while others are ephemeral.
#### Start/stop
Coder workspaces can be started/stopped. This is often used to save on cloud costs or enforce
ephemeral workflows. When a workspace is started or stopped, the Coder server
runs an additional
[terraform apply ](https://www.terraform.io/cli/commands/apply ), informing the
Coder provider that the workspace has a new transition state.
2022-10-05 14:50:56 +00:00
This template sample has one persistent resource (docker volume) and one ephemeral resource
(docker image).
2022-06-21 20:17:07 +00:00
```sh
data "coder_workspace" "me" {
}
resource "docker_volume" "home_volume" {
# persistent resource (remains a workspace is stopped)
count = 1
name = "coder-${data.coder_workspace.me.owner}-${data.coder_workspace.me.name}-root"
}
resource "docker_container" "workspace" {
# ephemeral resource (deleted when workspace is stopped, created when started)
count = data.coder_workspace.me.start_count # 0 (stopped), 1 (started)
volumes {
container_path = "/home/coder/"
volume_name = docker_volume.home_volume.name
read_only = false
}
# ... other config
}
```
2022-06-28 19:06:54 +00:00
#### Using updated images when rebuilding a workspace
To ensure that Coder uses an updated image when rebuilding a workspace, we
suggest that admins update the tag in the template (e.g., `my-image:v0.4.2` ->
`my-image:v0.4.3` ) or digest (`my-image@sha256:[digest]` ->
`my-image@sha256:[new_digest]` ).
Alternatively, if you're willing to wait for longer start times from Coder, you
can set the `imagePullPolicy` to `Always` in your Terraform template; when set,
Coder will check `image:tag` on every build and update if necessary:
```tf
resource "kubernetes_pod" "podName" {
spec {
container {
image_pull_policy = "Always"
}
}
}
```
2022-09-13 15:51:50 +00:00
### Delete templates
You can delete a template using both the coder CLI and UI. Only
[template admins and owners ](./admin/users.md ) can delete a template, and the template
must not have any running workspaces associated to it.
Using the CLI, login to Coder and run the following command to delete a template:
```console
coder templates delete < template-name >
```
In the UI, navigate to the template you want to delete, and select the dropdown in
the right-hand corner of the page to delete the template.
![delete-template ](./images/delete-template.png )
2022-06-21 20:17:07 +00:00
#### Delete workspaces
When a workspace is deleted, the Coder server essentially runs a
[terraform destroy ](https://www.terraform.io/cli/commands/destroy ) to remove all
resources associated with the workspace.
> Terraform's
> [prevent-destroy](https://www.terraform.io/language/meta-arguments/lifecycle#prevent_destroy)
> and
> [ignore-changes](https://www.terraform.io/language/meta-arguments/lifecycle#ignore_changes)
2022-06-28 19:06:54 +00:00
> meta-arguments can be used to accidental data loss.
2022-06-21 20:17:07 +00:00
### Coder apps
By default, all templates allow developers to connect over SSH and a web
2022-08-10 01:10:09 +00:00
terminal. See [Configuring Web IDEs ](./ides/web-ides.md ) to
2022-06-21 20:17:07 +00:00
learn how to give users access to additional web applications.
2022-07-19 18:24:06 +00:00
### Data source
When a workspace is being started or stopped, the `coder_workspace` data source provides
some useful parameters. See the [documentation for the `coder` Terraform provider ](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/workspace )
for more information.
For example, the [Docker quick-start template ](https://github.com/coder/coder/tree/main/examples/templates/docker )
sets a few environment variables based on the username and email address of the workspace's owner, so
that you can make Git commits immediately without any manual configuration:
```tf
2022-07-23 20:26:56 +00:00
resource "coder_agent" "main" {
2022-07-19 18:24:06 +00:00
# ...
env = {
GIT_AUTHOR_NAME = "${data.coder_workspace.me.owner}"
GIT_COMMITTER_NAME = "${data.coder_workspace.me.owner}"
GIT_AUTHOR_EMAIL = "${data.coder_workspace.me.owner_email}"
GIT_COMMITTER_EMAIL = "${data.coder_workspace.me.owner_email}"
}
}
```
You can add these environment variable definitions to your own templates, or customize them however
you like.
2022-06-21 20:17:07 +00:00
## Creating & troubleshooting templates
You can use any Terraform resources or modules with Coder! When working on
templates, we recommend you refer to the following resources:
- this document
- [example templates ](https://github.com/coder/coder/tree/main/examples/templates ) code
- [Coder Terraform provider ](https://registry.terraform.io/providers/coder/coder/latest/docs )
documentation
Occasionally, you may run into scenarios where the agent is not able to connect.
This means the start script has failed.
```sh
$ coder ssh myworkspace
Waiting for [agent] to connect...
```
While troubleshooting steps vary by resource, here are some general best
practices:
- Ensure the resource has `curl` installed
- Ensure the resource can reach your Coder URL
- Manually connect to the resource (e.g., `docker exec` or AWS console)
2022-07-22 14:59:19 +00:00
- The Coder agent logs are typically stored in `/var/log/coder-agent.log`
- The Coder agent startup script logs are typically stored in `/var/log/coder-startup-script.log`
2022-06-21 20:17:07 +00:00
2022-06-16 17:47:10 +00:00
## Change Management
2022-06-03 21:29:22 +00:00
2022-06-16 17:47:10 +00:00
We recommend source controlling your templates as you would other code.
2022-06-03 21:29:22 +00:00
2022-08-16 14:52:31 +00:00
CI is as simple as running `coder templates push` with the appropriate
2022-06-16 17:47:10 +00:00
credentials.
2022-06-03 21:29:22 +00:00
2022-08-25 15:26:04 +00:00
## Next Steps
2022-09-13 20:45:17 +00:00
2022-08-25 15:26:04 +00:00
- Learn about [Authentication & Secrets ](templates/authentication.md )
- Learn about [Workspaces ](workspaces.md )