mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
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:
committed by
GitHub
parent
288df75686
commit
419eba5fb6
@@ -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.
|
||||
@@ -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
|
||||
|
||||

|
||||
|
||||
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 user’s 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`.**
|
||||
|
||||

|
||||
|
||||
On the “Okta User to {Your Application}” tab, map a `roles` or `groups`
|
||||
attribute you have configured to the application.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
@@ -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.
|
||||
@@ -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'
|
||||
```
|
||||
@@ -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?
|
||||
|
||||

|
||||
|
||||
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.
|
||||
@@ -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:
|
||||
|
||||

|
||||
|
||||
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.
|
||||
@@ -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>
|
||||
```
|
||||
@@ -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>
|
||||
@@ -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).
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||
## 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.
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
Copy the session token into the clipboard:
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
### Next steps
|
||||
|
||||
- [Setting up templates](../admin/templates/index.md)
|
||||
- [Customizing templates](../admin/templates/extending-templates/index.md)
|
||||
- [Troubleshooting template](../admin/templates/troubleshooting.md)
|
||||
@@ -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:
|
||||
|
||||

|
||||
|
||||
From there, you can manage the name, icon, description, users, and groups:
|
||||
|
||||

|
||||
|
||||
## 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.
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
### 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.
|
||||
|
||||

|
||||
|
||||
### 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.
|
||||
|
||||

|
||||
|
||||
## 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.
|
||||
Reference in New Issue
Block a user