From 30893bf7c09634acf3c3e1519fa4ee5b67454d28 Mon Sep 17 00:00:00 2001 From: Spike Curtis Date: Fri, 3 Jun 2022 11:13:17 -0700 Subject: [PATCH 1/3] Don't use parameters to pass secrets to GCP or AWS Signed-off-by: Spike Curtis --- docs/templates.md | 38 ++++++++++- examples/templates/aws-linux/README.md | 7 ++ examples/templates/aws-linux/main.tf | 22 ------- examples/templates/aws-windows/README.md | 66 +++++++++++++++++++ examples/templates/aws-windows/main.tf | 19 ------ examples/templates/gcp-linux/README.md | 19 ++++++ examples/templates/gcp-linux/main.tf | 19 +----- examples/templates/gcp-vm-container/README.md | 19 ++++++ examples/templates/gcp-vm-container/main.tf | 19 +----- examples/templates/gcp-windows/README.md | 19 ++++++ examples/templates/gcp-windows/main.tf | 19 +----- 11 files changed, 175 insertions(+), 91 deletions(-) diff --git a/docs/templates.md b/docs/templates.md index 9fac5e542f761..6c4651be64e0c 100644 --- a/docs/templates.md +++ b/docs/templates.md @@ -23,8 +23,6 @@ vim /main.tf coder templates ``` -> We recommend source controlling your templates. - ## Persistent and ephemeral resources Coder supports both ephemeral and persistent resources in workspaces. Ephemeral @@ -53,6 +51,42 @@ Templates often contain *parameters*. In Coder, there are two types of parameter each workspace, often personalization settings such as "preferred region" or "workspace image". + +## Best Practices + +### Template Changes + +We recommend source controlling your templates. + +### Authenticating with Cloud Providers + +Coder's provisioner process needs to authenticate with cloud provider APIs to provision +workspaces. We strongly advise against including credentials directly in your templates. You +can either pass credentials to the provisioner as parameters, or execute Coder +in an environment that is authenticated with the cloud provider. + +We encourage the latter where supported. This approach simplifies the template, keeps cloud +provider credentials out of Coder's database (making it a less valuable target for attackers), +and is compatible with agent-based authentication schemes (that handle credential rotation +and/or ensure the credentials are not written to disk). + +Cloud providers for which the Terraform provider supports authenticated environments include + + * [Google Cloud](https://registry.terraform.io/providers/hashicorp/google/latest/docs) + * [Amazon Web Services](https://registry.terraform.io/providers/hashicorp/aws/latest/docs) + * [Microsoft Azure](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs) + * [Kubernetes](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs) + +Additional providers may be supported; check the +[documentation of the Terraform provider](https://registry.terraform.io/browse/providers) for +details. + +The way these generally work is via the credentials being available to Coder either in some +well-known location on disk (e.g. `~/.aws/credentials` for AWS on posix systems), or via +environment variables. It is usually sufficient to authenticate using the CLI or SDK for the +cloud provider before running Coder for this to work, but check the Terraform provider +documentation for details. + --- Next: [Workspaces](./workspaces.md) diff --git a/examples/templates/aws-linux/README.md b/examples/templates/aws-linux/README.md index bf50e661334bc..ab012d0f31b68 100644 --- a/examples/templates/aws-linux/README.md +++ b/examples/templates/aws-linux/README.md @@ -10,6 +10,13 @@ tags: [cloud, aws] Pick this template in `coder templates init` and follow instructions. +## Authentication + +This template assumes that coderd is run in an environment that is authenticated +with AWS. For example, run `aws configure import` to import credentials on the +system and user running coderd. For other ways to authenticate [consult the +Terraform docs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication-and-configuration). + ## Required permissions / policy This example policy allows Coder to create EC2 instances and modify instances provisioned by Coder. diff --git a/examples/templates/aws-linux/main.tf b/examples/templates/aws-linux/main.tf index 2a9d625c2634e..10c4990883a6c 100644 --- a/examples/templates/aws-linux/main.tf +++ b/examples/templates/aws-linux/main.tf @@ -7,26 +7,6 @@ terraform { } } -variable "access_key" { - description = < Date: Fri, 3 Jun 2022 11:16:31 -0700 Subject: [PATCH 2/3] Fix fmt Signed-off-by: Spike Curtis --- examples/templates/aws-linux/main.tf | 2 +- examples/templates/aws-windows/main.tf | 2 +- examples/templates/gcp-linux/main.tf | 4 ++-- examples/templates/gcp-vm-container/main.tf | 4 ++-- examples/templates/gcp-windows/main.tf | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/templates/aws-linux/main.tf b/examples/templates/aws-linux/main.tf index 10c4990883a6c..3d6666345658b 100644 --- a/examples/templates/aws-linux/main.tf +++ b/examples/templates/aws-linux/main.tf @@ -50,7 +50,7 @@ variable "disk_size" { } provider "aws" { - region = var.region + region = var.region } data "coder_workspace" "me" { diff --git a/examples/templates/aws-windows/main.tf b/examples/templates/aws-windows/main.tf index a1d31d9f10f03..9b82bbdad0dcc 100644 --- a/examples/templates/aws-windows/main.tf +++ b/examples/templates/aws-windows/main.tf @@ -37,7 +37,7 @@ variable "region" { } provider "aws" { - region = var.region + region = var.region } data "coder_workspace" "me" { diff --git a/examples/templates/gcp-linux/main.tf b/examples/templates/gcp-linux/main.tf index a76b44f1b1458..a53a29127bf2c 100644 --- a/examples/templates/gcp-linux/main.tf +++ b/examples/templates/gcp-linux/main.tf @@ -25,8 +25,8 @@ variable "zone" { } provider "google" { - zone = var.zone - project = var.project_id + zone = var.zone + project = var.project_id } data "google_compute_default_service_account" "default" { diff --git a/examples/templates/gcp-vm-container/main.tf b/examples/templates/gcp-vm-container/main.tf index 65cd9368368c7..e79cc85343fd5 100644 --- a/examples/templates/gcp-vm-container/main.tf +++ b/examples/templates/gcp-vm-container/main.tf @@ -25,8 +25,8 @@ variable "zone" { } provider "google" { - zone = var.zone - project = var.project_id + zone = var.zone + project = var.project_id } data "google_compute_default_service_account" "default" { diff --git a/examples/templates/gcp-windows/main.tf b/examples/templates/gcp-windows/main.tf index aefd15836e9df..a12426e3da898 100644 --- a/examples/templates/gcp-windows/main.tf +++ b/examples/templates/gcp-windows/main.tf @@ -25,8 +25,8 @@ variable "zone" { } provider "google" { - zone = var.zone - project = var.project_id + zone = var.zone + project = var.project_id } data "coder_workspace" "me" { From 2e009f773111ad9e1c1bf0b9bf0d6df7c8afcceb Mon Sep 17 00:00:00 2001 From: Spike Curtis Date: Fri, 3 Jun 2022 14:30:03 -0700 Subject: [PATCH 3/3] Digital Ocean example uses environment variable auth Signed-off-by: Spike Curtis --- examples/templates/do-linux/README.md | 10 +++++++++- examples/templates/do-linux/main.tf | 28 +++++++++------------------ 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/examples/templates/do-linux/README.md b/examples/templates/do-linux/README.md index 398b18501ba63..5829af5d246c3 100644 --- a/examples/templates/do-linux/README.md +++ b/examples/templates/do-linux/README.md @@ -10,8 +10,16 @@ This is an example for deploying workspaces as Digital Ocean Droplets. ## Requirements -- Digital Ocean Personal Access Token (PAT) - Digital Ocean Project ID (e.g. `doctl projects list`) - Remove `variable "step2_do_project_id"` and `resource "digitalocean_project_resources" "project"` if you don't want project association. - (Optional) Digital Ocean SSH key ID (e.g. `doctl compute ssh-key list`) - Only required for Fedora images to work. + +## Authentication + +This template assumes that coderd is run in an environment that is authenticated +with Digital Ocean. Obtain a +[Digital Ocean Personal Access Token](https://cloud.digitalocean.com/account/api/tokens) and set +the environment variable `DIGITALOCEAN_TOKEN` to the access token before starting coderd. For +other ways to authenticate +[consult the Terraform docs](https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs). diff --git a/examples/templates/do-linux/main.tf b/examples/templates/do-linux/main.tf index e9d611dddcde8..7710138bd5e3b 100644 --- a/examples/templates/do-linux/main.tf +++ b/examples/templates/do-linux/main.tf @@ -11,18 +11,7 @@ terraform { } } -variable "step1_do_token" { - type = string - description = "Enter token (see documentation at https://docs.digitalocean.com/reference/api/create-personal-access-token/)" - sensitive = true - - validation { - condition = length(var.step1_do_token) == 71 && substr(var.step1_do_token, 0, 4) == "dop_" - error_message = "Invalid Digital Ocean Personal Access Token." - } -} - -variable "step2_do_project_id" { +variable "step1_do_project_id" { type = string description = <<-EOF Enter project ID @@ -32,17 +21,17 @@ variable "step2_do_project_id" { sensitive = true validation { - condition = length(var.step2_do_project_id) == 36 + condition = length(var.step1_do_project_id) == 36 error_message = "Invalid Digital Ocean Project ID." } } -variable "step3_do_admin_ssh_key" { +variable "step2_do_admin_ssh_key" { type = number description = <<-EOF Enter admin SSH key ID (some Droplet images require an SSH key to be set): - Can be set to zero. + Can be set to "0" for no key. Note: Setting this to zero will break Fedora images and notify root passwords via email. @@ -51,7 +40,7 @@ variable "step3_do_admin_ssh_key" { sensitive = true validation { - condition = var.step3_do_admin_ssh_key >= 0 + condition = var.step2_do_admin_ssh_key >= 0 error_message = "Invalid Digital Ocean SSH key ID, a number is required." } } @@ -98,7 +87,8 @@ variable "region" { # Configure the DigitalOcean Provider provider "digitalocean" { - token = var.step1_do_token + # Recommended: use environment variable DIGITALOCEAN_TOKEN with your personal access token when starting coderd + # alternatively, you can pass the token via a variable. } data "coder_workspace" "me" {} @@ -130,12 +120,12 @@ resource "digitalocean_droplet" "workspace" { coder_agent_token = coder_agent.dev.token }) # Required to provision Fedora. - ssh_keys = var.step3_do_admin_ssh_key > 0 ? [var.step3_do_admin_ssh_key] : [] + ssh_keys = var.step2_do_admin_ssh_key > 0 ? [var.step2_do_admin_ssh_key] : [] } # Temporarily disabled because it breaks SSH. (https://github.com/coder/coder/issues/1750) # resource "digitalocean_project_resources" "project" { -# project = var.step2_do_project_id +# project = var.step1_do_project_id # # Workaround for terraform plan when using count. # resources = length(digitalocean_droplet.workspace) > 0 ? [ # digitalocean_volume.home_volume.urn,