diff --git a/lib/modules/manager/terraform/__fixtures__/tfeWorkspace.tf b/lib/modules/manager/terraform/__fixtures__/tfeWorkspace.tf new file mode 100644 index 00000000000000..17477f65cba7d6 --- /dev/null +++ b/lib/modules/manager/terraform/__fixtures__/tfeWorkspace.tf @@ -0,0 +1,11 @@ +resource "tfe_workspace" "test_workspace" { + name = "test-workspace" + organization = "renovate-fixtures" + + terraform_version = "1.1.6" +} + +resource "tfe_workspace" "test_workspace" { + name = "test-workspace" + organization = "renovate-fixtures" +} diff --git a/lib/modules/manager/terraform/__snapshots__/extract.spec.ts.snap b/lib/modules/manager/terraform/__snapshots__/extract.spec.ts.snap index a93787e6cb678f..bc2084b3ff85bd 100644 --- a/lib/modules/manager/terraform/__snapshots__/extract.spec.ts.snap +++ b/lib/modules/manager/terraform/__snapshots__/extract.spec.ts.snap @@ -447,6 +447,23 @@ Object { } `; +exports[`modules/manager/terraform/extract extractPackageFile() extracts terraform_version for tfe_workspace and ignores missing terraform_version keys 1`] = ` +Object { + "deps": Array [ + Object { + "currentValue": "1.1.6", + "datasource": "github-tags", + "depName": "hashicorp/terraform", + "depType": "tfe_workspace", + "extractVersion": "v(?.*)$", + }, + Object { + "skipReason": "no-version", + }, + ], +} +`; + exports[`modules/manager/terraform/extract extractPackageFile() test terraform block with only requirement_terraform_version 1`] = ` Object { "deps": Array [ diff --git a/lib/modules/manager/terraform/common.ts b/lib/modules/manager/terraform/common.ts index e66d74fad011a1..8e168d7d02b884 100644 --- a/lib/modules/manager/terraform/common.ts +++ b/lib/modules/manager/terraform/common.ts @@ -30,4 +30,8 @@ export enum TerraformResourceTypes { * https://www.terraform.io/docs/providers/helm/r/release.html */ helm_release = 'helm_release', + /** + * https://registry.terraform.io/providers/hashicorp/tfe/latest/docs/resources/workspace + */ + tfe_workspace = 'tfe_workspace', } diff --git a/lib/modules/manager/terraform/extract.spec.ts b/lib/modules/manager/terraform/extract.spec.ts index e7defaabdf129d..801f82f6a652af 100644 --- a/lib/modules/manager/terraform/extract.spec.ts +++ b/lib/modules/manager/terraform/extract.spec.ts @@ -17,6 +17,7 @@ const helm = loadFixture('helm.tf'); const lockedVersion = loadFixture('lockedVersion.tf'); const lockedVersionLockfile = loadFixture('rangeStrategy.hcl'); const terraformBlock = loadFixture('terraformBlock.tf'); +const tfeWorkspaceBlock = loadFixture('tfeWorkspace.tf'); const adminConfig: RepoGlobalConfig = { // `join` fixes Windows CI @@ -99,5 +100,16 @@ describe('modules/manager/terraform/extract', () => { expect(res.deps.filter((dep) => dep.skipReason)).toHaveLength(0); expect(res).toMatchSnapshot(); }); + + it('extracts terraform_version for tfe_workspace and ignores missing terraform_version keys', async () => { + const res = await extractPackageFile( + tfeWorkspaceBlock, + 'tfeWorkspace.tf', + {} + ); + expect(res).toMatchSnapshot(); + expect(res.deps).toHaveLength(2); + expect(res.deps.filter((dep) => dep.skipReason)).toHaveLength(1); + }); }); }); diff --git a/lib/modules/manager/terraform/extract.ts b/lib/modules/manager/terraform/extract.ts index 5998458c2f68db..ce2580c55f3cf8 100644 --- a/lib/modules/manager/terraform/extract.ts +++ b/lib/modules/manager/terraform/extract.ts @@ -37,6 +37,7 @@ const contentCheckList = [ ' "helm_release" ', ' "docker_image" ', 'required_version', + 'terraform_version', // part of tfe_workspace ]; export async function extractPackageFile( diff --git a/lib/modules/manager/terraform/readme.md b/lib/modules/manager/terraform/readme.md index 50c204b2300a3a..d158f3e0803592 100644 --- a/lib/modules/manager/terraform/readme.md +++ b/lib/modules/manager/terraform/readme.md @@ -13,6 +13,7 @@ Currently, Terraform supports renovating the following dependencies, where sub p - chart repository ( Public and Private ) - docker\_\* - Docker registry ( Public and Private ) +- [tfe_workspace](https://registry.terraform.io/providers/hashicorp/tfe/latest/docs/resources/workspace) ( `terraform_version` argument ) Terraform range constraints are supported: @@ -24,15 +25,16 @@ Terraform range constraints are supported: For fine-grained control, e.g. to turn off only parts of this manager, you can use the following `depTypes`: -| resource | depType | -| --------------------------- | :-----------------: | -| Terraform provider | `provider` | -| required Terraform provider | `required_provider` | -| required Terraform version | `required_version` | -| Terraform module | `module` | -| Helm release | `helm_release` | -| Docker container | `docker_container` | -| Docker image | `docker_image` | -| Docker service | `docker_service` | +| resource | depType | Notes | +| --------------------------- | :-----------------: | :------------------------------------------------------------------------: | +| Terraform provider | `provider` | | +| required Terraform provider | `required_provider` | | +| required Terraform version | `required_version` | This handles the `required_version` in terraform blocks | +| TFE workspace | `tfe_workspace` | This handles the `terraform_version` argument in `tfe_workspace` resources | +| Terraform module | `module` | | +| Helm release | `helm_release` | | +| Docker container | `docker_container` | | +| Docker image | `docker_image` | | +| Docker service | `docker_service` | | If you need to change the versioning format, read the [versioning](https://docs.renovatebot.com/modules/versioning/) documentation to learn more. diff --git a/lib/modules/manager/terraform/resources.ts b/lib/modules/manager/terraform/resources.ts index 7f3f618c0b281d..26762dcb7dea65 100644 --- a/lib/modules/manager/terraform/resources.ts +++ b/lib/modules/manager/terraform/resources.ts @@ -2,6 +2,7 @@ import { HelmDatasource } from '../../datasource/helm'; import { getDep } from '../dockerfile/extract'; import type { PackageDependency } from '../types'; import { TerraformDependencyTypes, TerraformResourceTypes } from './common'; +import { analyseTerraformVersion } from './required-version'; import type { ExtractionResult, ResourceManagerData } from './types'; import { checkIfStringIsPath, @@ -32,10 +33,15 @@ export function extractTerraformResource( const typeMatch = resourceTypeExtractionRegex.exec(line); + // Sets the resourceType, e.g. "helm_release" 'resource "helm_release" "test_release"' dep.managerData.resourceType = TerraformResourceTypes[typeMatch?.groups?.type] ?? TerraformResourceTypes.unknown; + /** + * Iterates over all lines of the resource to extract the relevant key value pairs, + * e.g. the chart name for helm charts or the terraform_version for tfe_workspace + */ do { lineNumber += 1; line = lines[lineNumber]; @@ -49,6 +55,7 @@ export function extractTerraformResource( dep.managerData[kvMatch.groups.key] = kvMatch.groups.value; break; case 'version': + case 'terraform_version': dep.currentValue = kvMatch.groups.value; break; default: @@ -104,6 +111,15 @@ export function analyseTerraformResource( dep.datasource = HelmDatasource.id; break; + case TerraformResourceTypes.tfe_workspace: + if (dep.currentValue) { + analyseTerraformVersion(dep); + dep.depType = 'tfe_workspace'; + } else { + dep.skipReason = 'no-version'; + } + break; + default: dep.skipReason = 'invalid-value'; break;