From 7cc96f5d40f206e4edca811a4046785bf48a0deb Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Thu, 30 May 2024 10:17:26 +0100 Subject: [PATCH] chore(docs): add recommendations for dependency management (#13400) --- docs/images/icons/dependency.svg | 4 ++ docs/manifest.json | 6 ++ docs/templates/dependencies.md | 113 +++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 docs/images/icons/dependency.svg create mode 100644 docs/templates/dependencies.md diff --git a/docs/images/icons/dependency.svg b/docs/images/icons/dependency.svg new file mode 100644 index 0000000000..1d41f51c88 --- /dev/null +++ b/docs/images/icons/dependency.svg @@ -0,0 +1,4 @@ + + + + diff --git a/docs/manifest.json b/docs/manifest.json index 5925417528..067aecac8e 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -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", diff --git a/docs/templates/dependencies.md b/docs/templates/dependencies.md new file mode 100644 index 0000000000..a3949f1c0e --- /dev/null +++ b/docs/templates/dependencies.md @@ -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.