mirror of
https://github.com/coder/coder.git
synced 2025-07-15 22:20:27 +00:00
chore(docs): add recommendations for dependency management (#13400)
This commit is contained in:
4
docs/images/icons/dependency.svg
Normal file
4
docs/images/icons/dependency.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Do not edit this file with editors other than draw.io -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="242px" height="242px" viewBox="-0.5 -0.5 242 242" content="<mxfile host="app.diagrams.net" modified="2024-05-29T15:42:32.513Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" etag="b2GWNkOVRrYg_N6W6w9m" version="24.0.5" type="device" scale="1" border="0"> <diagram name="Page-1" id="ze-s_6qxPxK6-2NziO6e"> <mxGraphModel dx="1509" dy="1147" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0"> <root> <mxCell id="0" /> <mxCell id="1" parent="0" /> <mxCell id="hO5YA4T3fkVWsWNRnRbz-4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;curved=1;strokeWidth=20;endArrow=block;endFill=1;" edge="1" parent="1" source="hO5YA4T3fkVWsWNRnRbz-1" target="hO5YA4T3fkVWsWNRnRbz-2"> <mxGeometry relative="1" as="geometry" /> </mxCell> <mxCell id="hO5YA4T3fkVWsWNRnRbz-1" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#000000;" vertex="1" parent="1"> <mxGeometry x="240" y="1000" width="80" height="80" as="geometry" /> </mxCell> <mxCell id="hO5YA4T3fkVWsWNRnRbz-5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;curved=1;strokeWidth=20;endArrow=block;endFill=1;" edge="1" parent="1" source="hO5YA4T3fkVWsWNRnRbz-2" target="hO5YA4T3fkVWsWNRnRbz-1"> <mxGeometry relative="1" as="geometry" /> </mxCell> <mxCell id="hO5YA4T3fkVWsWNRnRbz-2" value="" style="ellipse;whiteSpace=wrap;html=1;fillColor=#000000;" vertex="1" parent="1"> <mxGeometry x="400" y="1161" width="80" height="80" as="geometry" /> </mxCell> </root> </mxGraphModel> </diagram> </mxfile> "><defs/><g><g><path d="M 80 40.05 Q 200.05 40.05 200.02 112.64" fill="none" stroke="rgb(0, 0, 0)" stroke-width="20" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 200.01 138.64 L 187.02 112.63 L 213.02 112.65 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="20" stroke-miterlimit="10" pointer-events="all"/></g><g><ellipse cx="40" cy="40" rx="39.99999999999999" ry="39.99999999999999" fill="#000000" stroke="rgb(0, 0, 0)" pointer-events="all"/></g><g><path d="M 160 201 Q 40.05 201 40.02 128.36" fill="none" stroke="rgb(0, 0, 0)" stroke-width="20" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 40.01 102.36 L 53.02 128.35 L 27.02 128.37 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="20" stroke-miterlimit="10" pointer-events="all"/></g><g><ellipse cx="200" cy="201" rx="39.99999999999999" ry="39.99999999999999" fill="#000000" stroke="rgb(0, 0, 0)" pointer-events="all"/></g></g></svg>
|
After Width: | Height: | Size: 3.9 KiB |
@ -143,6 +143,12 @@
|
||||
"description": "Best practices for writing templates",
|
||||
"path": "./templates/best-practices.md",
|
||||
"children": [
|
||||
{
|
||||
"title": "Template Dependencies",
|
||||
"description": "Manage dependencies of your templates",
|
||||
"path": "./templates/dependencies.md",
|
||||
"icon_path": "./images/icons/dependency.svg"
|
||||
},
|
||||
{
|
||||
"title": "Change management",
|
||||
"description": "Versioning templates with git and CI",
|
||||
|
113
docs/templates/dependencies.md
vendored
Normal file
113
docs/templates/dependencies.md
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
# Template Dependencies
|
||||
|
||||
When creating Coder templates, it is unlikely that you will just be using
|
||||
built-in providers. Part of Terraform's flexibility stems from its rich plugin
|
||||
ecosystem, and it makes sense to take advantage of this.
|
||||
|
||||
That having been said, here are some recommendations to follow, based on the
|
||||
[Terraform documentation](https://developer.hashicorp.com/terraform/tutorials/configuration-language/provider-versioning).
|
||||
|
||||
Following these recommendations will:
|
||||
|
||||
- **Prevent unexpected changes:** Your templates will use the same versions of
|
||||
Terraform providers each build. This will prevent issues related to changes in
|
||||
providers.
|
||||
- **Improve build performance:** Coder caches provider versions on each build.
|
||||
If the same provider version can be re-used on subsequent builds, Coder will
|
||||
simply re-use the cached version if it is available.
|
||||
- **Improve build reliability:** As some providers are hundreds of megabytes in
|
||||
size, interruptions in connectivity to the Terraform registry during a
|
||||
workspace build can result in a failed build. If Coder is able to re-use a
|
||||
cached provider version, the likelihood of this is greatly reduced.
|
||||
|
||||
## Lock your provider and module versions
|
||||
|
||||
If you add a Terraform provider to `required_providers` without specifying a
|
||||
version requirement, Terraform will always fetch the latest version on each
|
||||
invocation:
|
||||
|
||||
```terraform
|
||||
terraform {
|
||||
required_providers {
|
||||
coder = {
|
||||
source = "coder/coder"
|
||||
}
|
||||
frobnicate = {
|
||||
source = "acme/frobnicate"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Any new releases of the `coder` or `frobnicate` providers will be picked up upon
|
||||
the next time a workspace is built using this template. This may include
|
||||
breaking changes.
|
||||
|
||||
To prevent this, add a
|
||||
[version constraint](https://developer.hashicorp.com/terraform/language/expressions/version-constraints)
|
||||
to each provider in the `required_providers` block:
|
||||
|
||||
```terraform
|
||||
terraform {
|
||||
required_providers {
|
||||
coder = {
|
||||
source = "coder/coder"
|
||||
version = ">= 0.2, < 0.3"
|
||||
}
|
||||
frobnicate = {
|
||||
source = "acme/frobnicate"
|
||||
version = "~> 1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In the above example, the `coder/coder` provider will be limited to all versions
|
||||
above or equal to `0.2.0` and below `0.3.0`, while the `acme/frobnicate`
|
||||
provider will be limited to all versions matching `1.0.x`.
|
||||
|
||||
The above also applies to Terraform modules. In the below example, the module
|
||||
`razzledazzle` is locked to version `1.2.3`.
|
||||
|
||||
```terraform
|
||||
module "razzledazzle" {
|
||||
source = "registry.example.com/modules/razzle/dazzle"
|
||||
version = "1.2.3"
|
||||
foo = "bar"
|
||||
}
|
||||
```
|
||||
|
||||
## Use a Dependency Lock File
|
||||
|
||||
Terraform allows creating a
|
||||
[dependency lock file](https://developer.hashicorp.com/terraform/language/files/dependency-lock)
|
||||
to track which provider versions were selected previously. This allows you to
|
||||
ensure that the next workspace build uses the same provider versions as with the
|
||||
last build.
|
||||
|
||||
To create a new Terraform lock file, run the
|
||||
[`terraform init` command](https://developer.hashicorp.com/terraform/cli/commands/init)
|
||||
inside a folder containing the Terraform source code for a given template.
|
||||
|
||||
This will create a new file named `.terraform.lock.hcl` in the current
|
||||
directory. When you next run [`coder templates push`](../cli/templates_push.md),
|
||||
the lock file will be stored alongside with the other template source code.
|
||||
|
||||
> Note: Terraform best practices also recommend checking in your
|
||||
> `.terraform.lock.hcl` into Git or other VCS.
|
||||
|
||||
The next time a workspace is built from that template, Coder will make sure to
|
||||
use the same versions of those providers as specified in the lock file.
|
||||
|
||||
If, at some point in future, you need to update the providers and versions you
|
||||
specified within the version constraints of the template, run
|
||||
|
||||
```console
|
||||
terraform init -upgrade
|
||||
```
|
||||
|
||||
This will check each provider, check the newest satisfiable version based on the
|
||||
version constraints you specified, and update the `.terraform.lock.hcl` with
|
||||
those new versions. When you next run `coder templates push`, again, the updated
|
||||
lock file will be stored and used to determine the provider versions to use for
|
||||
subsequent workspace builds.
|
Reference in New Issue
Block a user