Skip to content

Don't use parameters to pass secrets to GCP or AWS #2039

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 36 additions & 2 deletions docs/templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ vim <template-name>/main.tf
coder templates <create/update> <template-name>
```

> We recommend source controlling your templates.

## Persistent and ephemeral resources

Coder supports both ephemeral and persistent resources in workspaces. Ephemeral
Expand Down Expand Up @@ -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.
Comment on lines +84 to +88
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Appreciate the detail here 👍🏼


---

Next: [Workspaces](./workspaces.md)
7 changes: 7 additions & 0 deletions examples/templates/aws-linux/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Comment on lines +13 to +18
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, this isn't really be visible when creating a template via coder templates init. I added a mock "variable" in the Docker example, but I'm not really happy with this.

Any ideas? Perhaps it's also fair to rely on the default Terraform errors (+ these docs) to warn users.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I don't like the idea of hijacking parameters to guide end users. If we can't expect users to read the README in the examples, and want do do some handholding, we should build out a guided template init


## Required permissions / policy

This example policy allows Coder to create EC2 instances and modify instances provisioned by Coder.
Expand Down
24 changes: 1 addition & 23 deletions examples/templates/aws-linux/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,6 @@ terraform {
}
}

variable "access_key" {
description = <<EOT
Create an AWS access key to provision resources with Coder:
- https://console.aws.amazon.com/iam/home#/users

See the template README for an example permissions policy,
if needed.

AWS Access Key ID
EOT
sensitive = true
}

variable "secret_key" {
description = <<EOT
AWS Secret Key
EOT
sensitive = true
}

# Last updated 2022-05-31
# aws ec2 describe-regions | jq -r '[.Regions[].RegionName] | sort'
variable "region" {
Expand Down Expand Up @@ -70,9 +50,7 @@ variable "disk_size" {
}

provider "aws" {
region = var.region
access_key = var.access_key
secret_key = var.secret_key
region = var.region
}

data "coder_workspace" "me" {
Expand Down
66 changes: 66 additions & 0 deletions examples/templates/aws-windows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,69 @@ name: Develop in Windows on AWS
description: Get started with Windows development on AWS.
tags: [cloud, aws]
---

# aws-windows

## Getting started

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.

```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ec2:GetDefaultCreditSpecification",
"ec2:DescribeIamInstanceProfileAssociations",
"ec2:DescribeTags",
"ec2:CreateTags",
"ec2:RunInstances",
"ec2:DescribeInstanceCreditSpecifications",
"ec2:DescribeImages",
"ec2:ModifyDefaultCreditSpecification",
"ec2:DescribeVolumes"
],
"Resource": "*"
},
{
"Sid": "CoderResouces",
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances",
"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"
}
}
}
]
}
```

21 changes: 1 addition & 20 deletions examples/templates/aws-windows/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,6 @@ terraform {
}
}

variable "access_key" {
description = <<EOT
Create an AWS access key to provision resources with Coder:
- https://console.aws.amazon.com/iam/home#/users

AWS Access Key
EOT
sensitive = true
}

variable "secret_key" {
description = <<EOT
AWS Secret Key
EOT
sensitive = true
}

# Last updated 2022-05-31
# aws ec2 describe-regions | jq -r '[.Regions[].RegionName] | sort'
variable "region" {
Expand Down Expand Up @@ -54,9 +37,7 @@ variable "region" {
}

provider "aws" {
region = var.region
access_key = var.access_key
secret_key = var.secret_key
region = var.region
}

data "coder_workspace" "me" {
Expand Down
19 changes: 19 additions & 0 deletions examples/templates/gcp-linux/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,22 @@ name: Develop in Linux on Google Cloud
description: Get started with Linux development on Google Cloud.
tags: [cloud, google]
---

# gcp-linux

## Getting started

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 Google Cloud. For example, run `gcloud auth application-default login` 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/google/latest/docs/guides/getting_started#adding-credentials).

## Required permissions / policy

The user or service account used by the Terraform provisioner should have the following roles

- Compute Admin
21 changes: 4 additions & 17 deletions examples/templates/gcp-linux/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,8 @@ terraform {
}
}

variable "service_account" {
description = <<EOF
Coder requires a Google Cloud Service Account to provision workspaces.

1. Create a service account:
https://console.cloud.google.com/projectselector/iam-admin/serviceaccounts/create
2. Add the roles:
- Compute Admin
- Service Account User
3. Click on the created key, and navigate to the "Keys" tab.
4. Click "Add key", then "Create new key".
5. Generate a JSON private key, and paste the contents below.
EOF
sensitive = true
variable "project_id" {
description = "Which Google Compute Project should your workspace live in?"
}

variable "zone" {
Expand All @@ -37,9 +25,8 @@ variable "zone" {
}

provider "google" {
zone = var.zone
credentials = var.service_account
project = jsondecode(var.service_account).project_id
zone = var.zone
project = var.project_id
}

data "google_compute_default_service_account" "default" {
Expand Down
19 changes: 19 additions & 0 deletions examples/templates/gcp-vm-container/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,22 @@ name: Develop in a container on a Google Cloud VM
description: Get started with Linux development on Google Cloud.
tags: [cloud, google, container]
---

# gcp-vm-container

## Getting started

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 Google Cloud. For example, run `gcloud auth application-default login` 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/google/latest/docs/guides/getting_started#adding-credentials).

## Required permissions / policy

The user or service account used by the Terraform provisioner should have the following roles

- Compute Admin
21 changes: 4 additions & 17 deletions examples/templates/gcp-vm-container/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,8 @@ terraform {
}
}

variable "service_account" {
description = <<EOF
Coder requires a Google Cloud Service Account to provision workspaces.

1. Create a service account:
https://console.cloud.google.com/projectselector/iam-admin/serviceaccounts/create
2. Add the roles:
- Compute Admin
- Service Account User
3. Click on the created key, and navigate to the "Keys" tab.
4. Click "Add key", then "Create new key".
5. Generate a JSON private key, and paste the contents below.
EOF
sensitive = true
variable "project_id" {
description = "Which Google Compute Project should your workspace live in?"
}

variable "zone" {
Expand All @@ -37,9 +25,8 @@ variable "zone" {
}

provider "google" {
zone = var.zone
credentials = var.service_account
project = jsondecode(var.service_account).project_id
zone = var.zone
project = var.project_id
}

data "google_compute_default_service_account" "default" {
Expand Down
19 changes: 19 additions & 0 deletions examples/templates/gcp-windows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,22 @@ name: Develop in Windows on Google Cloud
description: Get started with Windows development on Google Cloud.
tags: [cloud, google]
---

# gcp-windows

## Getting started

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 Google Cloud. For example, run `gcloud auth application-default login` 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/google/latest/docs/guides/getting_started#adding-credentials).

## Required permissions / policy

The user or service account used by the Terraform provisioner should have the following roles

- Compute Admin
21 changes: 4 additions & 17 deletions examples/templates/gcp-windows/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,8 @@ terraform {
}
}

variable "service_account" {
description = <<EOF
Coder requires a Google Cloud Service Account to provision workspaces.

1. Create a service account:
https://console.cloud.google.com/projectselector/iam-admin/serviceaccounts/create
2. Add the roles:
- Compute Admin
- Service Account User
3. Click on the created key, and navigate to the "Keys" tab.
4. Click "Add key", then "Create new key".
5. Generate a JSON private key, and paste the contents below.
EOF
sensitive = true
variable "project_id" {
description = "Which Google Compute Project should your workspace live in?"
}

variable "zone" {
Expand All @@ -37,9 +25,8 @@ variable "zone" {
}

provider "google" {
zone = var.zone
credentials = var.service_account
project = jsondecode(var.service_account).project_id
zone = var.zone
project = var.project_id
}

data "coder_workspace" "me" {
Expand Down