docs: restructure docs (#14421)

Closes #13434 
Supersedes #14182

---------

Co-authored-by: Ethan <39577870+ethanndickson@users.noreply.github.com>
Co-authored-by: Ethan Dickson <ethan@coder.com>
Co-authored-by: Ben Potter <ben@coder.com>
Co-authored-by: Stephen Kirby <58410745+stirby@users.noreply.github.com>
Co-authored-by: Stephen Kirby <me@skirby.dev>
Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
Co-authored-by: Edward Angert <EdwardAngert@users.noreply.github.com>
This commit is contained in:
Muhammad Atif Ali
2024-10-05 08:52:04 -07:00
committed by GitHub
parent 288df75686
commit 419eba5fb6
298 changed files with 5009 additions and 3889 deletions
+131
View File
@@ -0,0 +1,131 @@
# Federating Coder's control plane to Azure
<div>
<a href="https://github.com/ericpaulsen" style="text-decoration: none; color: inherit;">
<span style="vertical-align:middle;">Eric Paulsen</span>
<img src="https://github.com/ericpaulsen.png" width="24px" height="24px" style="vertical-align:middle; margin: 0px;"/>
</a>
</div>
January 26, 2024
---
This guide will walkthrough how to authenticate a Coder Provisioner to Microsoft
Azure, using a Service Principal with a client certificate. You can use this
guide for authenticating Coder to Azure, regardless of where Coder is run,
either on-premise or in a non-Azure cloud. This method is one of several
[recommended by Terraform](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs#authenticating-to-azure).
## Step 1: Generate Client Certificate & PKCS bundle
We'll need to create the certificate Coder will use for authentication. Run the
below command to generate a private key and self-signed certificate:
```console
openssl req -subj '/CN=myclientcertificate/O=MyCompany, Inc./ST=CA/C=US' \
-new -newkey rsa:4096 -sha256 -days 730 -nodes -x509 -keyout client.key -out client.crt
```
Next, generate a `.pfx` file to be used by Coder's Provisioner to authenticate
the AzureRM provider:
```console
openssl pkcs12 -export -password pass:"Pa55w0rd123" -out client.pfx -inkey client.key -in client.crt
```
## Step 2: Create Azure Application & Service Principal
Navigate to the Azure portal, and into the Microsoft Entra ID section. Select
the App Registration blade, and register a new application. Fill in the
following fields:
- **Name**: this is a friendly identifier and can be anything (e.g. "Coder")
- **Supported Account Types**: - set to "Accounts in this organizational
directory only (single-tenant)"
The **Redirect URI** field does not need to be set in this case. Take note of
the `Application (client) ID` and `Directory (tenant) ID` values, which will be
used by Coder.
## Step 3: Assign Client Certificate to the Azure Application
To upload the certificate we created in Step 1, select **Certificates &
secrets** on the left-hand side, and select **Upload Certificate**. Upload the
public key file, which is `service-principal.crt` from the example above.
## Step 4: Set Permissions on the Service Principal
Now that the Application is created in Microsoft Entra ID, we need to assign
permissions to the Service Principal so it can provision Azure resources for
Coder users. Navigate to the Subscriptions blade in the Azure Portal, select the
**Subscription > Access Control (IAM) > Add > Add role assignment**.
Set the **Role** that grants the appropriate permissions to create the Azure
resources you need for your Coder workspaces. `Contributor` will provide
Read/Write on all Subscription resources. For more information on the available
roles, see the
[Microsoft documentation](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles).
## Step 5: Configure Coder to use the Client Certificate
Now that the client certificate is uploaded to Azure, we need to mount the
certificate files into the Coder deployment. If running Coder on Kubernetes, you
will need to create the `.pfx` file as a Kubernetes secret, and mount it into
the Helm chart.
Run the below command to create the secret:
```console
kubectl create secret generic -n coder azure-client-cert-secret --from-file=client.pfx=/path/to/your/client.pfx
```
In addition, create secrets for each of the following values from your Azure
Application:
- Client ID
- Tenant ID
- Subscription ID
- Certificate password
Next, set the following values in Coder's Helm chart:
```yaml
coder:
env:
- name: ARM_CLIENT_ID
valueFrom:
secretKeyRef:
key: id
name: arm-client-id
- name: ARM_CLIENT_CERTIFICATE_PATH
value: /home/coder/az/
- name: ARM_CLIENT_CERTIFICATE_PASSWORD
valueFrom:
secretKeyRef:
key: password
name: arm-client-cert-password
- name: ARM_TENANT_ID
valueFrom:
secretKeyRef:
key: id
name: arm-tenant-id
- name: ARM_SUBSCRIPTION_ID
valueFrom:
secretKeyRef:
key: id
name: arm-subscription-id
volumes:
- name: "azure-client-cert"
secret:
secretName: "azure-client-cert-secret"
volumeMounts:
- name: "azure-client-cert"
mountPath: "/home/coder/az/"
readOnly: true
```
Upgrade the Coder deployment using the following `helm` command:
```console
helm upgrade coder coder-v2/coder -n coder -f values.yaml
```
@@ -0,0 +1,72 @@
# Cloning Git Repositories
<div style="padding: 0px; margin: 0px;">
<span style="vertical-align:middle;">Author: </span>
<a href="https://github.com/BrunoQuaresma" style="text-decoration: none; color: inherit; margin-bottom: 0px;">
<span style="vertical-align:middle;">Bruno Quaresma</span>
<img src="https://avatars.githubusercontent.com/u/3165839?v=4" width="24px" height="24px" style="vertical-align:middle; margin: 0px;"/>
</a>
</div>
August 06, 2024
---
When starting to work on a project, engineers usually need to clone a Git
repository. Even though this is often a quick step, it can be automated using
the [Coder Registry](https://registry.coder.com/) to make a seamless Git-first
workflow.
The first step to enable Coder to clone a repository is to provide
authorization. This can be achieved by using the Git provider, such as GitHub,
as an authentication method. If you don't know how to do that, we have written
documentation to help you:
- [GitHub](../admin/external-auth.md#github)
- [GitLab self-managed](../admin/external-auth.md#gitlab-self-managed)
- [Self-managed git providers](../admin/external-auth.md#self-managed-git-providers)
With the authentication in place, it is time to set up the template to use the
[Git Clone module](https://registry.coder.com/modules/git-clone) from the
[Coder Registry](https://registry.coder.com/) by adding it to our template's
Terraform configuration.
```tf
module "git-clone" {
source = "registry.coder.com/modules/git-clone/coder"
version = "1.0.12"
agent_id = coder_agent.example.id
url = "https://github.com/coder/coder"
}
```
> You can edit the template using an IDE or terminal of your preference, or by
> going into the
> [template editor UI](../admin/templates/creating-templates.md#web-ui).
You can also use
[template parameters](../admin/templates/extending-templates/parameters.md) to
customize the Git URL and make it dynamic for use cases where a template
supports multiple projects.
```tf
data "coder_parameter" "git_repo" {
name = "git_repo"
display_name = "Git repository"
default = "https://github.com/coder/coder"
}
module "git-clone" {
source = "registry.coder.com/modules/git-clone/coder"
version = "1.0.12"
agent_id = coder_agent.example.id
url = data.coder_parameter.git_repo.value
}
```
> If you need more customization, you can read the
> [Git Clone module](https://registry.coder.com/modules/git-clone) documentation
> to learn more about the module.
Don't forget to build and publish the template changes before creating a new
workspace. You can check if the repository is cloned by accessing the workspace
terminal and listing the directories.
+160
View File
@@ -0,0 +1,160 @@
# Configuring Custom Claims/Scopes with Okta for group/role
<div style="pad: 0px; margin: 0px;">
<span style="vertical-align:middle;">Author: </span>
<a href="https://github.com/Emyrk" style="text-decoration: none; color: inherit; margin-bottom: 0px;">
<span style="vertical-align:middle;">Steven Masley</span>
<img src="https://avatars.githubusercontent.com/u/5446298?v=4" width="24px" height="24px" style="vertical-align:middle; margin: 0px;"/>
</a>
</div>
December 13, 2023
---
> Okta is an identity provider that can be used for OpenID Connect (OIDC) Single
> Sign On (SSO) on Coder.
To configure custom claims in Okta to support syncing roles and groups with
Coder, you must first have setup an Okta application with
[OIDC working with Coder](https://coder.com/docs/admin/auth#openid-connect).
From here, we will add additional claims for Coder to use for syncing groups and
roles.
You may use a hybrid of the following approaches.
# (Easiest) Sync using Okta Groups
If the Coder roles & Coder groups can be inferred from
[Okta groups](https://help.okta.com/en-us/content/topics/users-groups-profiles/usgp-about-groups.htm),
Okta has a simple way to send over the groups as a `claim` in the `id_token`
payload.
In Okta, go to the application “Sign On” settings page.
Applications > Select Application > General > Sign On
In the “OpenID Connect ID Token” section, turn on “Groups Claim Type” and set
the “Claim name” to `groups`. Optionally configure a filter for which groups to
be sent.
> !! If the user does not belong to any groups, the claim will not be sent. Make
> sure the user authenticating for testing is in at least 1 group. Defer to
> [troubleshooting](https://coder.com/docs/admin/auth#troubleshooting) with
> issues
![Okta OpenID Connect ID Token](../images/guides/okta/oidc_id_token.png)
Configure Coder to use these claims for group sync. These claims are present in
the `id_token`. See all configuration options for group sync in the
[docs](https://coder.com/docs/admin/auth#group-sync-enterprise).
```bash
# Add the 'groups' scope.
CODER_OIDC_SCOPES=openid,profile,email,groups
# This name needs to match the "Claim name" in the configuration above.
CODER_OIDC_GROUP_FIELD=groups
```
These groups can also be used to configure role syncing based on group
membership.
```bash
# Requires the "groups" scope
CODER_OIDC_SCOPES=openid,profile,email,groups
# This name needs to match the "Claim name" in the configuration above.
CODER_OIDC_USER_ROLE_FIELD=groups
# Example configuration to map a group to some roles
CODER_OIDC_USER_ROLE_MAPPING='{"admin-group":["template-admin","user-admin"]}'
```
# (Easy) Mapping Okta profile attributes
If roles or groups cannot be completely inferred from Okta group memberships,
another option is to source them from a users attributes. The user attribute
list can be found in “Directory > Profile Editor > User (default)”.
Coder can query an Okta profile for the application from the `/userinfo` OIDC
endpoint. To pass attributes to Coder, create the attribute in your application,
then add a mapping from the Okta profile to the application.
“Directory > Profile Editor > {Your Application} > Add Attribute”
Create the attribute for the roles, groups, or both. **Make sure the attribute
is of type `string array`.**
![Okta Add Attribute view](../images/guides/okta/add_attribute.png)
On the “Okta User to {Your Application}” tab, map a `roles` or `groups`
attribute you have configured to the application.
![Okta Add Claim view](../images/guides/okta/add_claim.png)
Configure using these new attributes in Coder.
```bash
# This must be set to false. Coder uses this endpoint to grab the attributes.
CODER_OIDC_IGNORE_USERINFO=false
# No custom scopes are required.
CODER_OIDC_SCOPES=openid,profile,email
# Configure the group/role field using the attribute name in the application.
CODER_OIDC_USER_ROLE_FIELD=approles
# See our docs for mapping okta roles to coder roles.
CODER_OIDC_USER_ROLE_MAPPING='{"admin-group":["template-admin","user-admin"]}'
# If you added an attribute for groups, set that here.
# CODER_OIDC_GROUP_FIELD=...
```
# (Advanced) Custom scopes to retrieve custom claims
Okta does not support setting custom scopes and claims in the default
authorization server used by your application. If you require this
functionality, you must create (or modify) an authorization server.
To see your custom authorization servers go to “Security > API”. Note the
`default` authorization server **is not the authorization server your app is
using.** You can configure this default authorization server, or create a new
one specifically for your application.
Authorization servers also give more refined controls over things such as
token/session lifetimes.
![Okta API view](../images/guides/okta/api_view.png)
To get custom claims working, we should map them to a custom scope. Click the
authorization server you wish to use (likely just using the default).
Go to “Scopes”, and “Add Scope”. Feel free to create one for roles, groups, or
both.
![Okta Add Scope view](../images/guides/okta/add_scope.png)
Now create the claim to go with the said scope. Go to “Claims”, then “Add
Claim”. Make sure to select **ID Token** for the token type. The **Value**
expression is up to you based on where you are sourcing the role information.
Lastly, configure it to only be a claim with the requested scope. This is so if
other applications exist, we do not send them information they do not care
about.
![Okta Add Claim with Roles view](../images/guides/okta/add_claim_with_roles.png)
Now we have a custom scope + claim configured under an authorization server, we
need to configure coder to use this.
```bash
# Grab this value from the Authorization Server > Settings > Issuer
# DO NOT USE the application issuer URL. Make sure to use the newly configured
# authorization server.
CODER_OIDC_ISSUER_URL=https://dev-12222860.okta.com/oauth2/default
# Add the new scope you just configured
CODER_OIDC_SCOPES=openid,profile,email,roles
# Use the claim you just configured
CODER_OIDC_USER_ROLE_FIELD=roles
# See our docs for mapping okta roles to coder roles.
CODER_OIDC_USER_ROLE_MAPPING='{"admin-group":["template-admin","user-admin"]}'
```
You can use the “Token Preview” page to verify it has been correctly configured
and verify the `roles` is in the payload.
![Okta Token Preview](../images/guides/okta/token_preview.png)
+54
View File
@@ -0,0 +1,54 @@
# Guide Title (Only Visible in Github)
<div>
<a href="https://github.com/<your_github_handle>" style="text-decoration: none; color: inherit;">
<span style="vertical-align:middle;">Your Name</span>
<img src="https://github.com/ericpaulsen.png" width="24px" height="24px" style="vertical-align:middle; margin: 0px;"/>
</a>
</div>
December 13, 2023
---
This is a guide on how to make Coder guides, it is not listed on our
[official guides page](https://coder.com/docs/guides) in the docs. Intended for
those who don't frequently contribute documentation changes to the `coder/coder`
repository.
## Content
Defer to our
[Contributing/Documentation](https://coder.com/docs/contributing/documentation)
page for rules on technical writing.
### Adding Photos
Use relative imports in the markdown and store photos in
`docs/images/guides/<your_guide>/<image>.png`.
### Setting the author data
At the top of this example you will find a small html snippet that nicely
renders the author's name and photo, while linking to their Github profile.
Before submitting your guide in a PR, replace `your_github_handle`,
`your_github_profile_photo_url` and "Your Name". The entire `<img>` element can
be omitted.
## Setting up the routes
Once you've written your guide, you'll need to add its route to
`docs/manifest.json` under `Guides` > `"children"` at the bottom:
```json
{
// Overrides the "# Guide Title" at the top of this file
"title": "Contributing to Guides",
"description": "How to add a guide",
"path": "./guides/my-guide-file.md"
},
```
## Format before push
Before pushing your guide to github, run `make fmt` to format the files with
Prettier. Then, push your changes to a new branch and create a PR.
+92
View File
@@ -0,0 +1,92 @@
# Using Coder with an external database
## Recommendation
For production deployments, we recommend using an external
[PostgreSQL](https://www.postgresql.org/) database (version 13 or higher).
## Basic configuration
Before starting the Coder server, prepare the database server by creating a role
and a database. Remember that the role must have access to the created database.
With `psql`:
```sql
CREATE ROLE coder LOGIN SUPERUSER PASSWORD 'secret42';
```
With `psql -U coder`:
```sql
CREATE DATABASE coder;
```
Coder configuration is defined via
[environment variables](../admin/setup/index.md). The database client requires
the connection string provided via the `CODER_PG_CONNECTION_URL` variable.
```shell
export CODER_PG_CONNECTION_URL="postgres://coder:secret42@localhost/coder?sslmode=disable"
```
## Custom schema
For installations with elevated security requirements, it's advised to use a
separate [schema](https://www.postgresql.org/docs/current/ddl-schemas.html)
instead of the public one.
With `psql -U coder`:
```sql
CREATE SCHEMA myschema;
```
Once the schema is created, you can list all schemas with `\dn`:
```
List of schemas
Name | Owner
-----------+----------
myschema | coder
public | postgres
(2 rows)
```
In this case the database client requires the modified connection string:
```shell
export CODER_PG_CONNECTION_URL="postgres://coder:secret42@localhost/coder?sslmode=disable&search_path=myschema"
```
The `search_path` parameter determines the order of schemas in which they are
visited while looking for a specific table. The first schema named in the search
path is called the current schema. By default `search_path` defines the
following schemas:
```sql
SHOW search_path;
search_path
--------------
"$user", public
```
Using the `search_path` in the connection string corresponds to the following
`psql` command:
```sql
ALTER ROLE coder SET search_path = myschema;
```
## Troubleshooting
### Coder server fails startup with "current_schema: converting NULL to string is unsupported"
Please make sure that the schema selected in the connection string
`...&search_path=myschema` exists and the role has granted permissions to access
it. The schema should be present on this listing:
```shell
psql -U coder -c '\dn'
```
+537
View File
@@ -0,0 +1,537 @@
# FAQs
Frequently asked questions on Coder OSS and Enterprise deployments. These FAQs
come from our community and enterprise customers, feel free to
[contribute to this page](https://github.com/coder/coder/edit/main/docs/tutorials/faqs.md).
For other community resources, see our
[Github discussions](https://github.com/coder/coder/discussions), or join our
[Discord server](https://discord.gg/coder).
### How do I add a Premium trial license?
Visit https://coder.com/trial or contact
[sales@coder.com](mailto:sales@coder.com?subject=License) to get a trial key.
You can add a license through the UI or CLI.
In the UI, click the Deployment tab -> Licenses and upload the `jwt` license
file.
> To add the license with the CLI, first
> [install the Coder CLI](../install/cli.md) and server to the latest release.
If the license is a text string:
```sh
coder licenses add -l 1f5...765
```
If the license is in a file:
```sh
coder licenses add -f <path/filename>
```
### I'm experiencing networking issues, so want to disable Tailscale, STUN, Direct connections and force use of websocket
The primary developer use case is a local IDE connecting over SSH to a Coder
workspace.
Coder's networking stack has intelligence to attempt a peer-to-peer or
[Direct connection](../admin/networking/index.md#direct-connections) between the
local IDE and the workspace. However, this requires some additional protocols
like UDP and being able to reach a STUN server to echo the IP addresses of the
local IDE machine and workspace, for sharing using a Wireguard Coordination
Server. By default, Coder assumes Internet and attempts to reach Google's STUN
servers to perform this IP echo.
Operators experimenting with Coder may run into networking issues if UDP (which
STUN requires) or the STUN servers are unavailable, potentially resulting in
lengthy local IDE and SSH connection times as the Coder control plane attempts
to establish these direct connections.
Setting the following flags as shown disables this logic to simplify
troubleshooting.
| Flag | Value | Meaning |
| --------------------------------------------------------------------------------------------- | ----------- | ------------------------------------- |
| [`CODER_BLOCK_DIRECT`](../reference/cli/server.md#--block-direct-connections) | `true` | Blocks direct connections |
| [`CODER_DERP_SERVER_STUN_ADDRESSES`](../reference/cli/server.md#--derp-server-stun-addresses) | `"disable"` | Disables STUN |
| [`CODER_DERP_FORCE_WEBSOCKETS`](../reference/cli/server.md#--derp-force-websockets) | `true` | Forces websockets over Tailscale DERP |
### How do I configure NGINX as the reverse proxy in front of Coder?
[This doc](https://github.com/coder/coder/tree/main/examples/web-server/nginx#configure-nginx)
in our repo explains in detail how to configure NGINX with Coder so that our
Tailscale Wireguard networking functions properly.
### How do I hide some of the default icons in a workspace like VS Code Desktop, Terminal, SSH, Ports?
The visibility of Coder apps is configurable in the template. To change the
default (shows all), add this block inside the
[`coder_agent`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent)
of a template and configure as needed:
```tf
display_apps {
vscode = false
vscode_insiders = false
ssh_helper = false
port_forwarding_helper = false
web_terminal = true
}
```
This example will hide all built-in
[`coder_app`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app)
icons except the web terminal.
### I want to allow code-server to be accessible by other users in my deployment.
> It is **not** recommended to share a web IDE, but if required, the following
> deployment environment variable settings are required.
Set deployment (Kubernetes) to allow path app sharing
```yaml
# allow authenticated users to access path-based workspace apps
- name: CODER_DANGEROUS_ALLOW_PATH_APP_SHARING
value: "true"
# allow Coder owner roles to access path-based workspace apps
- name: CODER_DANGEROUS_ALLOW_PATH_APP_SITE_OWNER_ACCESS
value: "true"
```
In the template, set
[`coder_app`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app)
[`share`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app#share)
option to `authenticated` and when a workspace is built with this template, the
pretty globe shows up next to path-based `code-server`:
```tf
resource "coder_app" "code-server" {
...
share = "authenticated"
...
}
```
### I installed Coder and created a workspace but the icons do not load.
An important concept to understand is that Coder creates workspaces which have
an agent that must be able to reach the `coder server`.
If the [`CODER_ACCESS_URL`](../admin/setup/index.md#access-url) is not
accessible from a workspace, the workspace may build, but the agent cannot reach
Coder, and thus the missing icons. e.g., Terminal, IDEs, Apps.
> By default, `coder server` automatically creates an Internet-accessible
> reverse proxy so that workspaces you create can reach the server.
If you are doing a standalone install, e.g., on a MacBook and want to build
workspaces in Docker Desktop, everything is self-contained and workspaces
(containers in Docker Desktop) can reach the Coder server.
```sh
coder server --access-url http://localhost:3000 --address 0.0.0.0:3000
```
> Even `coder server` which creates a reverse proxy, will let you use
> http://localhost to access Coder from a browser.
### I updated a template, and an existing workspace based on that template fails to start.
When updating a template, be aware of potential issues with input variables. For
example, if a template prompts users to choose options like a
[code-server](https://github.com/coder/code-server)
[VS Code](https://code.visualstudio.com/) IDE release, a
[container image](https://hub.docker.com/u/codercom), or a
[VS Code extension](https://marketplace.visualstudio.com/vscode), removing any
of these values can lead to existing workspaces failing to start. This issue
occurs because the Terraform state will not be in sync with the new template.
However, a lesser-known CLI sub-command,
[`coder update`](../reference/cli/update.md), can resolve this issue. This
command re-prompts users to re-enter the input variables, potentially saving the
workspace from a failed status.
```sh
coder update --always-prompt <workspace name>
```
### I'm running coder on a VM with systemd but latest release installed isn't showing up.
Take, for example, a Coder deployment on a VM with a 2 shared vCPU systemd
service. In this scenario, it's necessary to reload the daemon and then restart
the Coder service. This prevents the `systemd` daemon from trying to reference
the previous Coder release service since the unit file has changed.
The following commands can be used to update Coder and refresh the service:
```sh
curl -fsSL https://coder.com/install.sh | sh
sudo systemctl daemon-reload
sudo systemctl restart coder.service
```
### I'm using the built-in Postgres database and forgot admin email I set up.
1. Run the `coder server` command below to retrieve the `psql` connection URL
which includes the database user and password.
2. `psql` into Postgres, and do a select query on the `users` table.
3. Restart the `coder server`, pull up the Coder UI and log in (you will still
need your password)
```sh
coder server postgres-builtin-url
psql "postgres://coder@localhost:53737/coder?sslmode=disable&password=I2S...pTk"
```
### How to find out Coder's latest Terraform provider version?
[Coder is on the HashiCorp's Terraform registry](https://registry.terraform.io/providers/coder/coder/latest).
Check this frequently to make sure you are on the latest version.
Sometimes, the version may change and `resource` configurations will either
become deprecated or new ones will be added when you get warnings or errors
creating and pushing templates.
### How can I set up TLS for my deployment and not create a signed certificate?
Caddy is an easy-to-configure reverse proxy that also automatically creates
certificates from Let's Encrypt.
[Install docs here](https://caddyserver.com/docs/quick-starts/reverse-proxy) You
can start Caddy as a `systemd` service.
The Caddyfile configuration will appear like this where `127.0.0.1:3000` is your
`CODER_ACCESS_URL`:
```text
coder.example.com {
reverse_proxy 127.0.0.1:3000
tls {
issuer acme {
email user@example.com
}
}
}
```
### I'm using Caddy as my reverse proxy in front of Coder. How do I set up a wildcard domain for port forwarding?
Caddy requires your DNS provider's credentials to create wildcard certificates.
This involves building the Caddy binary
[from source](https://github.com/caddyserver/caddy) with the DNS provider plugin
added. e.g.,
[Google Cloud DNS provider here](https://github.com/caddy-dns/googleclouddns)
To compile Caddy, the host running Coder requires Go. Once installed, replace
the existing Caddy binary in `usr/bin` and restart the Caddy service.
The updated Caddyfile configuration will look like this:
```text
*.coder.example.com, coder.example.com {
reverse_proxy 127.0.0.1:3000
tls {
issuer acme {
email user@example.com
dns googleclouddns {
gcp_project my-gcp-project
}
}
}
}
```
### Can I use local or remote Terraform Modules in Coder templates?
One way is to reference a Terraform module from a GitHub repo to avoid
duplication and then just extend it or pass template-specific
parameters/resources:
```tf
# template1/main.tf
module "central-coder-module" {
source = "github.com/org/central-coder-module"
myparam = "custom-for-template1"
}
resource "ebs_volume" "custom_template1_only_resource" {
}
```
```tf
# template2/main.tf
module "central-coder-module" {
source = "github.com/org/central-coder-module"
myparam = "custom-for-template2"
myparam2 = "bar"
}
resource "aws_instance" "custom_template2_only_resource" {
}
```
Another way using local modules is to symlink the module directory inside the
template directory and then `tar` the template.
```sh
ln -s modules template_1/modules
tar -cvh -C ./template_1 | coder templates <push|create> -d - <name>
```
References:
- [Public Github Issue 6117](https://github.com/coder/coder/issues/6117)
- [Public Github Issue 5677](https://github.com/coder/coder/issues/5677)
- [Coder docs: Templates/Change Management](../admin/templates/managing-templates/change-management.md)
### Can I run Coder in an air-gapped or offline mode? (no Internet)?
Yes, Coder can be deployed in
[air-gapped or offline mode](../install/offline.md).
Our product bundles with the Terraform binary so assume access to terraform.io
during installation. The docs outline rebuilding the Coder container with
Terraform built-in as well as any required Terraform providers.
Direct networking from local SSH to a Coder workspace needs a STUN server. Coder
defaults to Google's STUN servers, so you can either create your STUN server in
your network or disable and force all traffic through the control plane's DERP
proxy.
### Create a randomized computer_name for an Azure VM
Azure VMs have a 15 character limit for the `computer_name` which can lead to
duplicate name errors.
This code produces a hashed value that will be difficult to replicate.
```tf
locals {
concatenated_string = "${data.coder_workspace.me.name}+${data.coder_workspace_owner.me.name}"
hashed_string = md5(local.concatenated_string)
truncated_hash = substr(local.hashed_string, 0, 16)
}
```
### Do you have example JetBrains Gateway templates?
In August 2023, JetBrains certified the Coder plugin signifying enhanced
stability and reliability.
The Coder plugin will appear in the Gateway UI when opened.
Selecting the most suitable template depends on how the deployment manages
JetBrains IDE versions. If downloading from
[jetbrains.com](https://www.jetbrains.com/remote-development/gateway/) is
acceptable, see the example templates below which specifies the product code,
IDE version and build number in the
[`coder_app`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app#share)
resource. This will present an icon in the workspace dashboard which when
clicked, will look for a locally installed Gateway, and open it. Alternatively,
the IDE can be baked into the container image and manually open Gateway (or
IntelliJ which has Gateway built-in), using a session token to Coder and then
open the IDE.
- [IntelliJ IDEA](https://github.com/sharkymark/v2-templates/tree/main/src/pod-idea)
- [IntelliJ IDEA with Icon](https://github.com/sharkymark/v2-templates/tree/main/src/pod-idea-icon)
### What options do I have for adding VS Code extensions into code-server, VS Code Desktop or Microsoft's Code Server?
Coder has an open-source project called
[`code-marketplace`](https://github.com/coder/code-marketplace) which is a
private VS Code extension marketplace. There is even integration with JFrog
Artifactory.
- [Blog post](https://coder.com/blog/running-a-private-vs-code-extension-marketplace)
- [OSS project](https://github.com/coder/code-marketplace)
[See this example template](https://github.com/sharkymark/v2-templates/blob/main/src/code-marketplace/main.tf#L229C1-L232C12)
where the agent specifies the URL and config environment variables which
code-server picks up and points the developer to.
Another option is to use Microsoft's code-server - which is like Coder's, but it
can connect to Microsoft's extension marketplace so Copilot and chat can be
retrieved there.
Another option is to use VS Code Desktop (local) and that connects to
Microsoft's marketplace.
> Note: these are example templates with no SLAs on them and are not guaranteed
> for long-term support.
### I want to run Docker for my workspaces but not install Docker Desktop.
[Colima](https://github.com/abiosoft/colima) is a Docker Desktop alternative.
This example is meant for a users who want to try out Coder on a macOS device.
Install Colima and docker with:
```sh
brew install colima
brew install docker
```
Start Colima:
```sh
colima start
```
Start Colima with specific compute options:
```sh
colima start --cpu 4 --memory 8
```
Starting Colima on a M3 MacBook Pro:
```sh
colima start --arch x86_64 --cpu 4 --memory 8 --disk 10
```
Colima will show the path to the docker socket so we have a
[community template](https://github.com/sharkymark/v2-templates/tree/main/src/docker-code-server)
that prompts the Coder admin to enter the docker socket as a Terraform variable.
### How to make a `coder_app` optional?
An example use case is the user should decide if they want a browser-based IDE
like code-server when creating the workspace.
1. Add a `coder_parameter` with type `bool` to ask the user if they want the
code-server IDE
```tf
data "coder_parameter" "code_server" {
name = "Do you want code-server in your workspace?"
description = "Use VS Code in a browser."
type = "bool"
default = false
mutable = true
icon = "/icon/code.svg"
order = 6
}
```
2. Add conditional logic to the `startup_script` to install and start
code-server depending on the value of the added `coder_parameter`
```sh
# install and start code-server, VS Code in a browser
if [ ${data.coder_parameter.code_server.value} = true ]; then
echo "🧑🏼‍💻 Downloading and installing the latest code-server IDE..."
curl -fsSL https://code-server.dev/install.sh | sh
code-server --auth none --port 13337 >/dev/null 2>&1 &
fi
```
3. Add a Terraform meta-argument
[`count`](https://developer.hashicorp.com/terraform/language/meta-arguments/count)
in the `coder_app` resource so it will only create the resource if the
`coder_parameter` is `true`
```tf
# code-server
resource "coder_app" "code-server" {
count = data.coder_parameter.code_server.value ? 1 : 0
agent_id = coder_agent.coder.id
slug = "code-server"
display_name = "code-server"
icon = "/icon/code.svg"
url = "http://localhost:13337?folder=/home/coder"
subdomain = false
share = "owner"
healthcheck {
url = "http://localhost:13337/healthz"
interval = 3
threshold = 10
}
}
```
### Why am I getting this "remote host doesn't meet VS Code Server's prerequisites" error when opening up VSCode remote in a Linux environment?
![VS Code Server prerequisite](https://github.com/coder/coder/assets/10648092/150c5996-18b1-4fae-afd0-be2b386a3239)
It is because, more than likely, the supported OS of either the container image
or VM/VPS doesn't have the proper C libraries to run the VS Code Server. For
instance, Alpine is not supported at all. If so, you need to find a container
image or supported OS for the VS Code Server. For more information on OS
prerequisites for Linux, please look at the VSCode docs.
https://code.visualstudio.com/docs/remote/linux#_local-linux-prerequisites
### How can I resolve disconnects when connected to Coder via JetBrains Gateway?
If your JetBrains IDE is disconnected for a long period of time due to a network
change (for example turning off a VPN), you may find that the IDE will not
reconnect once the network is re-established (for example turning a VPN back
on). When this happens a persistent message will appear similar to the below:
```console
No internet connection. Changes in the document might be lost. Trying to reconnect…
```
To resolve this, add this entry to your SSH config file on your local machine:
```console
Host coder-jetbrains--*
ServerAliveInterval 5
```
This will make SSH check that it can contact the server every five seconds. If
it fails to do so `ServerAliveCountMax` times (3 by default for a total of 15
seconds) then it will close the connection which forces JetBrains to recreate
the hung session. You can tweak `ServerAliveInterval` and `ServerAliveCountMax`
to increase or decrease the total timeout.
Note that the JetBrains Gateway configuration blocks for each host in your SSH
config file will be overwritten by the JetBrains Gateway client when it
re-authenticates to your Coder deployment so you must add the above config as a
separate block and not add it to any existing ones.
### How can I restrict inbound/outbound file transfers from Coder workspaces?
In certain environments, it is essential to keep confidential files within
workspaces and prevent users from uploading or downloading resources using tools
like `scp` or `rsync`.
To achieve this, template admins can use the environment variable
`CODER_AGENT_BLOCK_FILE_TRANSFER` to enable additional SSH command controls.
This variable allows the system to check if the executed application is on the
block list, which includes `scp`, `rsync`, `ftp`, and `nc`.
```tf
resource "docker_container" "workspace" {
...
env = [
"CODER_AGENT_TOKEN=${coder_agent.main.token}",
"CODER_AGENT_BLOCK_FILE_TRANSFER=true",
...
]
}
```
#### Important Notice
This control operates at the `ssh-exec` level or during `sftp` sessions. While
it can help prevent automated file transfers using the specified tools, users
can still SSH into the workspace and manually initiate file transfers. The
primary purpose of this feature is to warn and discourage users from downloading
confidential resources to their local machines.
For more advanced security needs, consider adopting an endpoint security
solution.
+195
View File
@@ -0,0 +1,195 @@
# Federating a Google Cloud service account to AWS
<div>
<a href="https://github.com/ericpaulsen" style="text-decoration: none; color: inherit;">
<span style="vertical-align:middle;">Eric Paulsen</span>
<img src="https://github.com/ericpaulsen.png" width="24px" height="24px" style="vertical-align:middle; margin: 0px;"/>
</a>
</div>
January 4, 2024
---
This guide will walkthrough how to use a Google Cloud service account to
authenticate the Coder control plane to AWS and create an EC2 workspace. The
below steps assume your Coder control plane is running in Google Cloud and has
the relevant service account assigned.
> For steps on assigning a service account to a resource like Coder,
> [see the Google documentation here](https://cloud.google.com/iam/docs/attach-service-accounts#attaching-new-resource)
## 1. Get your Google service account OAuth Client ID
Navigate to the Google Cloud console, and select **IAM & Admin** > **Service
Accounts**. View the service account you want to use, and copy the **OAuth 2
Client ID** value shown on the right-hand side of the row.
> (Optional): If you do not yet have a service account,
> [here is the Google IAM documentation on creating a service account](https://cloud.google.com/iam/docs/service-accounts-create).
## 2. Create AWS role
Create an AWS role that is configured for Web Identity Federation, with Google
as the identity provider, as shown below:
![AWS Create Role](../images/guides/gcp-to-aws/aws-create-role.png)
Once created, edit the **Trust Relationship** section to look like the
following:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "accounts.google.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"accounts.google.com:aud": "<enter-OAuth-client-ID-here"
}
}
}
]
}
```
## 3. Assign permissions to the AWS role
In this example, Coder will need permissions to create the EC2 instance. Add the
following policy to the role:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ec2:GetDefaultCreditSpecification",
"ec2:DescribeIamInstanceProfileAssociations",
"ec2:DescribeTags",
"ec2:DescribeInstances",
"ec2:DescribeInstanceTypes",
"ec2:CreateTags",
"ec2:RunInstances",
"ec2:DescribeInstanceCreditSpecifications",
"ec2:DescribeImages",
"ec2:ModifyDefaultCreditSpecification",
"ec2:DescribeVolumes"
],
"Resource": "*"
},
{
"Sid": "CoderResources",
"Effect": "Allow",
"Action": [
"ec2:DescribeInstanceAttribute",
"ec2:UnmonitorInstances",
"ec2:TerminateInstances",
"ec2:StartInstances",
"ec2:StopInstances",
"ec2:DeleteTags",
"ec2:MonitorInstances",
"ec2:CreateTags",
"ec2:RunInstances",
"ec2:ModifyInstanceAttribute",
"ec2:ModifyInstanceCreditSpecification"
],
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/Coder_Provisioned": "true"
}
}
}
]
}
```
## 4. Generate the identity token for the service account
Run the following `gcloud` command to generate the service account identity
token. This is a JWT token with a payload that includes the service account
email, audience, issuer, and expiration.
```console
gcloud auth print-identity-token --audiences=https://aws.amazon.com --impersonate-service-account 12345-compute@de
veloper.gserviceaccount.com --include-email
```
> Note: Your `gcloud` client may needed elevated permissions to run this
> command.
## 5. Set identity token in Coder control plane
You will need to set the token created in the previous step on a location in the
Coder control plane. Follow the below steps for your specific deployment type:
### VM control plane
- Write the token to a file on the host, preferably inside the `/home/coder`
directory:
```console
/home/coder/.aws/gcp-identity-token
```
### Kubernetes control plane
- Create the Kubernetes secret to house the token value:
```console
kubectl create secret generic gcp-identity-token -n coder --from-literal=token=<enter-token-here>
```
Make sure the secret is created inside the same namespace where Coder is
running.
- Mount the token file into the Coder pod using the values below:
```yaml
coder:
volumes:
- name: "gcp-identity-mount"
secret:
secretName: "gcp-identity-token"
volumeMounts:
- name: "gcp-identity-mount"
mountPath: "/home/coder/.aws/gcp-identity-token"
readOnly: true
```
## 6. Configure the AWS Terraform provider
Navigate to your EC2 workspace template in Coder, and configure the AWS provider
using the block below:
```tf
provider "aws" {
assume_role_with_web_identity {
# enter role ARN here - copy from AWS console
role_arn = "arn:aws:iam::123456789:role/gcp-to-aws"
# arbitrary value for logging
session_name = "coder-session"
# define location of token file on control plane here
web_identity_token_file = "/home/coder/.aws/gcp-identity-token"
}
}
```
This provider block is equivalent to running this `aws` CLI command:
```console
aws sts assume-role-with-web-identity \
--role-arn arn:aws:iam::123456789:role/gcp-to-aws \
--role-session-name coder-session \
--web-identity-token xxx
```
You can run this command with the identity token string to validate or
troubleshoot the call to AWS.
+100
View File
@@ -0,0 +1,100 @@
# Defining ImagePullSecrets for Coder workspaces
<div>
<a href="https://github.com/ericpaulsen" style="text-decoration: none; color: inherit;">
<span style="vertical-align:middle;">Eric Paulsen</span>
<img src="https://github.com/ericpaulsen.png" width="24px" height="24px" style="vertical-align:middle; margin: 0px;"/>
</a>
</div>
January 12, 2024
---
Coder workspaces are commonly run as Kubernetes pods. When run inside of an
enterprise, the pod image is typically pulled from a private image registry.
This guide walks through creating an ImagePullSecret to use for authenticating
to your registry, and defining it in your workspace template.
## 1. Create Docker Config JSON File
Create a Docker configuration JSON file containing your registry credentials.
Replace `<your-registry>`, `<your-username>`, and `<your-password>` with your
actual Docker registry URL, username, and password.
```json
{
"auths": {
"<your-registry>": {
"username": "<your-username>",
"password": "<your-password>"
}
}
}
```
## 2. Create Kubernetes Secret
Run the below `kubectl` command in the K8s cluster where you intend to run your
Coder workspaces:
```console
kubectl create secret generic regcred \
--from-file=.dockerconfigjson=<path-to-docker-config.json> \
--type=kubernetes.io/dockerconfigjson \
--namespace=<workspaces-namespace>
```
Inspect the secret to confirm its contents:
```console
kubectl get secret -n <workspaces-namespace> regcred --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode
```
The output should look similar to this:
```json
{
"auths": {
"your.private.registry.com": {
"username": "ericpaulsen",
"password": "xxxx",
"auth": "c3R...zE2"
}
}
}
```
## 3. Define ImagePullSecret in Terraform template
With the ImagePullSecret now created, we can add the secret into the workspace
template. In the example below, we define the secret via the
`image_pull_secrets` argument. Note that this argument is nested at the same
level as the `container` argument:
```tf
resource "kubernetes_pod" "dev" {
metadata {
# this must be the same namespace where workspaces will be deployed
namespace = "workspaces-namespace"
}
spec {
image_pull_secrets {
name = "regcred"
}
container {
name = "dev"
image = "your-image:latest"
}
}
}
```
## 4. Push New Template Version
Update your template by running the following commands:
```console
coder login <access-url>
coder templates push <template-name>
```
+10
View File
@@ -0,0 +1,10 @@
# Guides and Tutorials
Here you can find a list of employee-written guides on Coder for OSS and
Enterprise. These tutorials are hosted on our
[Github](https://github.com/coder/coder/) where you can leave feedback or
request new topics to be covered.
<children>
This page is rendered on https://coder.com/docs/guides. Refer to the other documents in the `guides/` directory for specific employee-written guides.
</children>
+77
View File
@@ -0,0 +1,77 @@
# Configure Coder to connect to PostgreSQL using SSL
<div>
<a href="https://github.com/ericpaulsen" style="text-decoration: none; color: inherit;">
<span style="vertical-align:middle;">Eric Paulsen</span>
<img src="https://github.com/ericpaulsen.png" width="24px" height="24px" style="vertical-align:middle; margin: 0px;"/>
</a>
</div>
February 24, 2024
---
Your organization may require connecting to the database instance over SSL. To
supply Coder with the appropriate certificates, and have it connect over SSL,
follow the steps below:
## Client verification (server verifies the client)
1. Create the certificate as a secret in your Kubernetes cluster, if not already
present:
```shell
kubectl create secret tls postgres-certs -n coder --key="postgres.key" --cert="postgres.crt"
```
1. Define the secret volume and volumeMounts in the Helm chart:
```yaml
coder:
volumes:
- name: "pg-certs-mount"
secret:
secretName: "postgres-certs"
volumeMounts:
- name: "pg-certs-mount"
mountPath: "$HOME/.postgresql"
readOnly: true
```
1. Lastly, your PG connection URL will look like:
```shell
postgres://<user>:<password>@databasehost:<port>/<db-name>?sslmode=require&sslcert="$HOME/.postgresql/postgres.crt&sslkey=$HOME/.postgresql/postgres.key"
```
## Server verification (client verifies the server)
1. Download the CA certificate chain for your database instance, and create it
as a secret in your Kubernetes cluster, if not already present:
```shell
kubectl create secret tls postgres-certs -n coder --key="postgres-root.key" --cert="postgres-root.crt"
```
1. Define the secret volume and volumeMounts in the Helm chart:
```yaml
coder:
volumes:
- name: "pg-certs-mount"
secret:
secretName: "postgres-certs"
volumeMounts:
- name: "pg-certs-mount"
mountPath: "$HOME/.postgresql/postgres-root.crt"
readOnly: true
```
1. Lastly, your PG connection URL will look like:
```shell
postgres://<user>:<password>@databasehost:<port>/<db-name>?sslmode=verify-full&sslrootcert="/home/coder/.postgresql/postgres-root.crt"
```
> More information on connecting to PostgreSQL databases using certificates can
> be found
> [here](https://www.postgresql.org/docs/current/libpq-ssl.html#LIBPQ-SSL-CLIENTCERT).
+87
View File
@@ -0,0 +1,87 @@
# Generate and upload a Support Bundle to Coder Support
When you engage with Coder support to diagnose an issue with your deployment,
you may be asked to generate and upload a "Support Bundle" for offline analysis.
This document explains the contents of a support bundle and the steps to submit
a support bundle to Coder staff.
## What is a Support Bundle?
A support bundle is an archive containing a snapshot of information about your
Coder deployment.
It contains information about the workspace, the template it uses, running
agents in the workspace, and other detailed information useful for
troubleshooting.
It is primarily intended for troubleshooting connectivity issues to workspaces,
but can be useful for diagnosing other issues as well.
**While we attempt to redact sensitive information from support bundles, they
may contain information deemed sensitive by your organization and should be
treated as such.**
A brief overview of all files contained in the bundle is provided below:
> Note: detailed descriptions of all the information available in the bundle is
> out of scope, as support bundles are primarily intended for internal use.
| Filename | Description |
| --------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `agent/agent.json` | The agent used to connect to the workspace with environment variables stripped. |
| `agent/agent_magicsock.html` | The contents of the HTTP debug endpoint of the agent's Tailscale connection. |
| `agent/client_magicsock.html` | The contents of the HTTP debug endpoint of the client's Tailscale connection. |
| `agent/listening_ports.json` | The listening ports detected by the selected agent running in the workspace. |
| `agent/logs.txt` | The logs of the selected agent running in the workspace. |
| `agent/manifest.json` | The manifest of the selected agent with environment variables stripped. |
| `agent/startup_logs.txt` | Startup logs of the workspace agent. |
| `agent/prometheus.txt` | The contents of the agent's Prometheus endpoint. |
| `cli_logs.txt` | Logs from running the `coder support bundle` command. |
| `deployment/buildinfo.json` | Coder version and build information. |
| `deployment/config.json` | Deployment [configuration](../reference/api/general.md#get-deployment-config), with secret values removed. |
| `deployment/experiments.json` | Any [experiments](../reference/cli/server.md#--experiments) currently enabled for the deployment. |
| `deployment/health.json` | A snapshot of the [health status](../admin/monitoring/health-check.md) of the deployment. |
| `logs.txt` | Logs from the `codersdk.Client` used to generate the bundle. |
| `network/connection_info.json` | Information used by workspace agents used to connect to Coder (DERP map etc.) |
| `network/coordinator_debug.html` | Peers currently connected to each Coder instance and the tunnels established between peers. |
| `network/netcheck.json` | Results of running `coder netcheck` locally. |
| `network/tailnet_debug.html` | Tailnet coordinators, their heartbeat ages, connected peers, and tunnels. |
| `workspace/build_logs.txt` | Build logs of the selected workspace. |
| `workspace/workspace.json` | Details of the selected workspace. |
| `workspace/parameters.json` | Build parameters of the selected workspace. |
| `workspace/template.json` | The template currently in use by the selected workspace. |
| `workspace/template_file.zip` | The source code of the template currently in use by the selected workspace. |
| `workspace/template_version.json` | The template version currently in use by the selected workspace. |
## How do I generate a Support Bundle?
1. Ensure your deployment is up and running. Generating a support bundle
requires the Coder deployment to be available.
2. Ensure you have the Coder CLI installed on a local machine. See
[installation](../install/index.md) for steps on how to do this.
> Note: It is recommended to generate a support bundle from a location
> experiencing workspace connectivity issues.
3. Ensure you are [logged in](../reference/cli/login.md#login) to your Coder
deployment as a user with the Owner privilege.
4. Run `coder support bundle [owner/workspace]`, and respond `yes` to the
prompt. The support bundle will be generated in the current directory with
the filename `coder-support-$TIMESTAMP.zip`.
> While support bundles can be generated without a running workspace, it is
> recommended to specify one to maximize troubleshooting information.
5. (Recommended) Extract the support bundle and review its contents, redacting
any information you deem necessary.
6. Coder staff will provide you a link where you can upload the bundle along
with any other necessary supporting files.
> Note: It is helpful to leave an informative message regarding the nature of
> supporting files.
Coder support will then review the information you provided and respond to you
with next steps.
+420
View File
@@ -0,0 +1,420 @@
# A guided tour of a template
This guided tour introduces you to the different parts of a Coder template by
showing you how to create a template from scratch.
You'll write a simple template that provisions a workspace as a Docker container
with Ubuntu.
## Before you start
To follow this guide, you'll need:
- A computer or cloud computing instance with both
[Docker](https://docs.docker.com/get-docker/) and [Coder](../install/index.md)
installed on it.
> When setting up your computer or computing instance, make sure to install
> Docker first, then Coder. Otherwise, you'll need to add the `coder` user to
> the `docker` group.
- The URL for your Coder instance. If you're running Coder locally, the default
URL is [http://127.0.0.1:3000](http://127.0.0.1:3000).
- A text editor. For this tour, we use [GNU nano](https://nano-editor.org/).
> Haven't written Terraform before? Check out Hashicorp's
> [Getting Started Guides](https://developer.hashicorp.com/terraform/tutorials).
## What's in a template
The main part of a Coder template is a [Terraform](https://terraform.io) `tf`
file. A Coder template often has other files to configure the other resources
that the template needs. In this tour you'll also create a `Dockerfile`.
Coder can provision all Terraform modules, resources, and properties. The Coder
server essentially runs a `terraform apply` every time a workspace is created,
started, or stopped.
Here's a simplified diagram that shows the main parts of the template we'll
create.
![Template architecture](../images/templates/template-architecture.png)
## 1. Create template files
On your local computer, create a directory for your template and create the
`Dockerfile`.
```sh
mkdir template-tour
cd template-tour
mkdir build
nano build/Dockerfile
```
You'll enter a simple `Dockerfile` that starts with the
[official Ubuntu image](https://hub.docker.com/_/ubuntu/). In the editor, enter
and save the following text in `Dockerfile` then exit the editor:
```dockerfile
FROM ubuntu
RUN apt-get update \
&& apt-get install -y \
sudo \
curl \
&& rm -rf /var/lib/apt/lists/*
ARG USER=coder
RUN useradd --groups sudo --no-create-home --shell /bin/bash ${USER} \
&& echo "${USER} ALL=(ALL) NOPASSWD:ALL" >/etc/sudoers.d/${USER} \
&& chmod 0440 /etc/sudoers.d/${USER}
USER ${USER}
WORKDIR /home/${USER}
```
Notice how `Dockerfile` adds a few things to the parent `ubuntu` image, which
your template needs later:
- It installs the `sudo` and `curl` packages.
- It adds a `coder` user, including a home directory.
## 2. Set up template providers
Now you can edit the Terraform file, which provisions the workspace's resources.
```shell
nano main.tf
```
We'll start by setting up our providers. At a minimum, we need the `coder`
provider. For this template, we also need the `docker` provider:
```tf
terraform {
required_providers {
coder = {
source = "coder/coder"
version = "~> 0.8.3"
}
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0.1"
}
}
}
provider "coder" {
}
provider "docker" {
}
locals {
username = data.coder_workspace.me.owner
}
data "coder_provisioner" "me" {
}
data "coder_workspace" "me" {
}
```
Notice that the `provider` blocks for `coder` and `docker` are empty. In a more
practical template, you would add arguments to these blocks to configure the
providers, if needed.
The
[`coder_workspace`](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/workspace)
data source provides details about the state of a workspace, such as its name,
owner, and so on. The data source also lets us know when a workspace is being
started or stopped. We'll take advantage of this information in later steps to
do these things:
- Set some environment variables based on the workspace owner.
- Manage ephemeral and persistent storage.
## 3. coder_agent
All templates need to create and run a
[Coder agent](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent).
This lets developers connect to their workspaces. The `coder_agent` resource
runs inside the compute aspect of your workspace, typically a VM or container.
In our case, it will run in Docker.
You do not need to have any open ports on the compute aspect, but the agent
needs `curl` access to the Coder server. Remember that we installed `curl` in
`Dockerfile`, earlier.
This snippet creates the agent:
```tf
resource "coder_agent" "main" {
arch = data.coder_provisioner.me.arch
os = "linux"
startup_script_timeout = 180
startup_script = <<-EOT
set -e
# install and start code-server
curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/tmp/code-server --version 4.11.0
/tmp/code-server/bin/code-server --auth none --port 13337 >/tmp/code-server.log 2>&1 &
EOT
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}"
}
metadata {
display_name = "CPU Usage"
key = "0_cpu_usage"
script = "coder stat cpu"
interval = 10
timeout = 1
}
metadata {
display_name = "RAM Usage"
key = "1_ram_usage"
script = "coder stat mem"
interval = 10
timeout = 1
}
}
```
Because Docker is running locally in the Coder server, there is no need to
authenticate `coder_agent`. But if your `coder_agent` were running on a remote
host, your template would need
[authentication credentials](../admin/external-auth.md).
This template's agent also runs a startup script, sets environment variables,
and provides metadata.
The
[`startup script`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script)
installs [code-server](https://coder.com/docs/code-server), a browser-based
[VS Code](https://code.visualstudio.com/) app that runs in the workspace. We'll
give users access to code-server through `coder_app`, later.
The
[`env`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#env)
block sets environments variables for the workspace. We use the data source from
`coder_workspace` to set the environment variables based on the workspace's
owner. This way, the owner can make git commits immediately without any manual
configuration.
Your template can use metadata to show information to the workspace owner. Coder
displays this metadata in the Coder dashboard. Our template has
[`metadata`](../admin/templates/extending-templates/agent-metadata.md) blocks
for CPU and RAM usage.
## 4. coder_app
A
[`coder_app`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app)
resource lets a developer use an app from the workspace's Coder dashboard.
![Apps in a Coder workspace](../images/templates/workspace-apps.png)
This is commonly used for
[web IDEs](../user-guides/workspace-access/web-ides.md) such as
[code-server](https://coder.com/docs/code-server), RStudio, and JupyterLab.
To install and code-server in the workspace, remember that we installed it in
the `startup_script` argument in `coder_agent`. We make it available from a
workspace with a `coder_app` resource. See
[web IDEs](../user-guides/workspace-access/web-ides.md) for more examples.
```tf
resource "coder_app" "code-server" {
agent_id = coder_agent.main.id
slug = "code-server"
display_name = "code-server"
url = "http://localhost:13337/?folder=/home/${local.username}"
icon = "/icon/code.svg"
subdomain = false
share = "owner"
healthcheck {
url = "http://localhost:13337/healthz"
interval = 5
threshold = 6
}
}
```
You can also use a `coder_app` resource to link to external apps, such as links
to wikis or cloud consoles.
```tf
resource "coder_app" "coder-server-doc" {
agent_id = coder_agent.main.id
icon = "/emojis/1f4dd.png"
slug = "getting-started"
url = "https://coder.com/docs/code-server"
external = true
}
```
## 5. Persistent and ephemeral resources
Managing the lifecycle of template resources is important. We want to make sure
that workspaces use computing, storage, and other services efficiently.
We want our workspace's home directory to persist after the workspace is stopped
so that a developer can continue their work when they start the workspace again.
We do this in 2 parts:
- Our `docker_volume` resource uses the `lifecycle` block with the
`ignore_changes = all` argument to prevent accidental deletions.
- To prevent Terraform from destroying persistent Docker volumes in case of a
workspace name change, we use an immutable parameter, like
`data.coder_workspace.me.id`.
You'll see later that we make sure that our Docker container is ephemeral with
the Terraform
[count](https://developer.hashicorp.com/terraform/language/meta-arguments/count)
meta-argument.
```tf
resource "docker_volume" "home_volume" {
name = "coder-${data.coder_workspace.me.id}-home"
# Protect the volume from being deleted due to changes in attributes.
lifecycle {
ignore_changes = all
}
}
```
For details, see
[Resource persistence](../admin/templates/extending-templates/resource-persistence.md).
## 6. Set up the Docker container
To set up our Docker container, our template has a `docker_image` resource that
uses `build/Dockerfile`, which we created earlier.
```tf
resource "docker_image" "main" {
name = "coder-${data.coder_workspace.me.id}"
build {
context = "./build"
build_args = {
USER = local.username
}
}
triggers = {
dir_sha1 = sha1(join("", [for f in fileset(path.module, "build/*") : filesha1(f)]))
}
}
```
Our `docker_container` resource uses `coder_workspace` `start_count` to start
and stop the Docker container:
```tf
resource "docker_container" "workspace" {
count = data.coder_workspace.me.start_count
image = docker_image.main.name
# Uses lower() to avoid Docker restriction on container names.
name = "coder-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}"
# Hostname makes the shell more user friendly: coder@my-workspace:~$
hostname = data.coder_workspace.me.name
# Use the docker gateway if the access URL is 127.0.0.1
entrypoint = ["sh", "-c", replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal")]
env = [
"CODER_AGENT_TOKEN=${coder_agent.main.token}",
]
host {
host = "host.docker.internal"
ip = "host-gateway"
}
volumes {
container_path = "/home/${local.username}"
volume_name = docker_volume.home_volume.name
read_only = false
}
}
```
## 7. Create the template in Coder
Save `main.tf` and exit the editor.
Now that we've created the files for our template, we can add them to our Coder
deployment.
We can do this with the Coder CLI or the Coder dashboard. For this tour, we'll
use the Coder CLI.
First, you'll need to log in to your Coder deployment from the CLI. This is
where you need the URL for your deployment:
```sh
$ coder login https://coder.example.com
Your browser has been opened to visit:
https://coder.example.com/cli-auth
> Paste your token here:
```
In your web browser, enter your credentials:
![Logging in to your Coder deployment](../images/templates/coder-login-web.png)
Copy the session token into the clipboard:
![Logging in to your Coder deployment](../images/templates/coder-session-token.png)
And paste it into the CLI:
```sh
> Welcome to Coder, marc! You're authenticated.
$
```
Now you can add your template files to your Coder deployment:
```sh
$ pwd
/home/marc/template-tour
$ coder templates create
> Upload "."? (yes/no) yes
```
The Coder CLI tool gives progress information then prompts you to confirm:
```sh
> Confirm create? (yes/no) yes
The template-tour template has been created! Developers can provision a workspace with this template using:
coder create --template="template-tour" [workspace name]
```
In your web browser, log in to your Coder dashboard, select **Templates**. Your
template is ready to use for new workspaces.
![Your new template, ready to use](../images/templates/template-tour.png)
### Next steps
- [Setting up templates](../admin/templates/index.md)
- [Customizing templates](../admin/templates/extending-templates/index.md)
- [Troubleshooting template](../admin/templates/troubleshooting.md)
+135
View File
@@ -0,0 +1,135 @@
# Using Organizations
> Note: Organizations is still under active development and requires a
> non-standard enterprise license to use. Do not use organizations on your
> production instance!
>
> For more details, [contact your account team](https://coder.com/contact).
Organizations allow you to run a Coder deployment with multiple platform teams,
all with uniquely scoped templates, provisioners, users, groups, and workspaces.
## Prerequisites
- Coder deployment with non-standard license with Organizations enabled
([contact your account team](https://coder.com/contact))
- User with `Owner` role
- Coder CLI installed on local machine
## Switch to the preview image and enable the experiment
To try the latest organizations features, switch to a preview image in your Helm
chart and enable the
[experimental flag](../reference/cli/server.md#--experiments).
For example, with Kubernetes, set the following in your `values.yaml`:
```yaml
coderd:
image:
repo: ghcr.io/coder/coder-preview
tag: orgs-preview-aug-16
env:
- name: CODER_EXPERIMENTS
value: multi-organization
```
> See all
> [preview images](https://github.com/coder/coder/pkgs/container/coder-preview)
> in GitHub. Preview images prefixed with `main-` expire after a week.
Then, upgrade your deployment:
```sh
helm upgrade coder coder-v2/coder -f values.yaml
```
## The default organization
All Coder deployments start with one organization called `Default`.
To edit the organization details, navigate to `Deployment -> Organizations` in
the top bar:
![Organizations Menu](../images/guides/using-organizations/deployment-organizations.png)
From there, you can manage the name, icon, description, users, and groups:
![Organization Settings](../images/guides/using-organizations/default-organization.png)
## Guide: Your first organization
### 1. Create the organization
Within the sidebar, click `New organization` to create an organization. In this
example, we'll create the `data-platform` org.
![New Organization](../images/guides/using-organizations/new-organization.png)
From there, let's deploy a provisioner and template for this organization.
### 2. Deploy a provisioner
[Provisioners](../admin/provisioners.md) are organization-scoped and are
responsible for executing Terraform/OpenTofu to provision the infrastructure for
workspaces and testing templates. Before creating templates, we must deploy at
least one provisioner as the built-in provisioners are scoped to the default
organization.
using Coder CLI, run the following command to create a key that will be used to
authenticate the provisioner:
```sh
coder provisioner keys create data-cluster-key --org data-platform
Successfully created provisioner key data-cluster! Save this authentication token, it will not be shown again.
< key omitted >
```
Next, start the provisioner with the key on your desired platform. In this
example, we'll start it using the Coder CLI on a host with Docker. For
instructions on using other platforms like Kubernetes, see our
[provisioner documentation](../admin/provisioners.md).
```sh
export CODER_URL=https://<your-coder-url>
export CODER_PROVISIONER_DAEMON_KEY=<key>
coder provisionerd start --org <org-name>
```
### 3. Create a template
Once you've started a provisioner, you can create a template. You'll notice the
"Create Template" screen now has an organization dropdown:
![Template Org Picker](../images/guides/using-organizations/template-org-picker.png)
### 5. Add members
Navigate to `Deployment->Organizations` to add members to your organization.
Once added, they will be able to see the organization-specific templates.
![Add members](../images/guides/using-organizations/organization-members.png)
### 6. Create a workspace
Now, users in the data platform organization will see the templates related to
their organization. Users can be in multiple organizations.
![Workspace List](../images/guides/using-organizations/workspace-list.png)
## Planned work
Organizations is under active development. The work is planned before
organizations is generally available:
- View provisioner health via the Coder UI
- Custom Role support in Coder UI
- Per-organization quotas
- Improved visibility of organization-specific resources throughout the UI
- Sync OIDC claims to auto-assign users to organizations / roles + SCIM support
## Support & Feedback
[Contact your account team](https://coder.com/contact) if you have any questions
or feedback.