From 0f3faff278973082722071052c636d3d4597a5fc Mon Sep 17 00:00:00 2001 From: Sebastian Poxhofer Date: Sun, 4 Apr 2021 14:48:52 +0200 Subject: [PATCH] feat(terraform): rework dep types (#9116) Improves the `depType` values returned by the terraform manager. Closes #8792 BREAKING CHANGE: Values for extracted `depType` in terraform manager have changed, please see the `terraform` manager readme for details. --- .../__snapshots__/extract.spec.ts.snap | 87 ++++++++++--------- lib/manager/terraform/extract.ts | 7 +- lib/manager/terraform/modules.ts | 6 +- lib/manager/terraform/providers.ts | 2 +- lib/manager/terraform/readme.md | 41 ++++++--- lib/manager/terraform/required-providers.ts | 8 ++ lib/manager/terraform/required-version.ts | 1 + lib/manager/terraform/resources.ts | 5 +- 8 files changed, 98 insertions(+), 59 deletions(-) diff --git a/lib/manager/terraform/__snapshots__/extract.spec.ts.snap b/lib/manager/terraform/__snapshots__/extract.spec.ts.snap index a7c0567b1cf466..1fba3faa42c84d 100644 --- a/lib/manager/terraform/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/terraform/__snapshots__/extract.spec.ts.snap @@ -7,7 +7,7 @@ Object { "currentValue": "1.0.1", "datasource": "helm", "depName": "redis", - "depType": "helm", + "depType": "helm_release", "registryUrls": Array [ "https://charts.helm.sh/stable", ], @@ -15,7 +15,7 @@ Object { Object { "datasource": "helm", "depName": "redis", - "depType": "helm", + "depType": "helm_release", "registryUrls": Array [ "https://charts.helm.sh/stable", ], @@ -23,7 +23,7 @@ Object { Object { "datasource": "helm", "depName": "./charts/example", - "depType": "helm", + "depType": "helm_release", "registryUrls": Array [ undefined, ], @@ -33,7 +33,7 @@ Object { "currentValue": "4.0.1", "datasource": "helm", "depName": undefined, - "depType": "helm", + "depType": "helm_release", "registryUrls": Array [ "https://charts.helm.sh/stable", ], @@ -43,7 +43,7 @@ Object { "currentValue": "5.0.1", "datasource": "helm", "depName": "redis", - "depType": "helm", + "depType": "helm_release", "registryUrls": Array [ "https://charts.helm.sh/stable", ], @@ -52,7 +52,7 @@ Object { "currentValue": "6.0.1", "datasource": "helm", "depName": "redis", - "depType": "helm", + "depType": "helm_release", "registryUrls": Array [ undefined, ], @@ -68,86 +68,86 @@ Object { "currentValue": "v1.0.0", "datasource": "github-tags", "depName": "github.com/hashicorp/example", - "depType": "github", + "depType": "module", "lookupName": "hashicorp/example", }, Object { "currentValue": "next", "datasource": "github-tags", "depName": "github.com/hashicorp/example", - "depType": "github", + "depType": "module", "lookupName": "hashicorp/example", }, Object { "currentValue": "tfmodule_one-v0.0.9", "datasource": "github-tags", "depName": "github.com/githubuser/myrepo", - "depType": "github", + "depType": "module", "lookupName": "githubuser/myrepo", }, Object { "currentValue": "v1.0.0", "datasource": "github-tags", "depName": "github.com/hashicorp/example.2.3", - "depType": "github", + "depType": "module", "lookupName": "hashicorp/example.2.3", }, Object { "currentValue": "v1.0.0", "datasource": "github-tags", "depName": "github.com/hashicorp/example.2.3", - "depType": "github", + "depType": "module", "lookupName": "hashicorp/example.2.3", }, Object { "currentValue": "0.1.0", "datasource": "terraform-module", "depName": "hashicorp/consul/aws", - "depType": "terraform", + "depType": "module", }, Object { "currentValue": "v0.1.0", "datasource": "github-tags", "depName": "github.com/tieto-cem/terraform-aws-ecs-task-definition", - "depType": "github", + "depType": "module", "lookupName": "tieto-cem/terraform-aws-ecs-task-definition", }, Object { "currentValue": "v0.1.0", "datasource": "github-tags", "depName": "github.com/tieto-cem/terraform-aws-ecs-task-definition", - "depType": "github", + "depType": "module", "lookupName": "tieto-cem/terraform-aws-ecs-task-definition", }, Object { "currentValue": "v2.0.0", "datasource": "github-tags", "depName": "github.com/hashicorp/example", - "depType": "github", + "depType": "module", "lookupName": "hashicorp/example", }, Object { "datasource": "terraform-module", "depName": "terraform-aws-modules/security-group/aws", - "depType": "terraform", + "depType": "module", }, Object { "currentValue": "<= 2.4.0", "datasource": "terraform-module", "depName": "terraform-aws-modules/security-group/aws", - "depType": "terraform", + "depType": "module", }, Object { "currentValue": "1.28.3", "datasource": "terraform-module", "depName": "particuleio/addons/kubernetes", - "depType": "terraform", + "depType": "module", }, Object { "currentValue": "~> 1.1.0", "datasource": "terraform-module", "depName": "app.terraform.io/example-corp/k8s-cluster/azurerm", - "depType": "terraform", + "depType": "module", "registryUrls": Array [ "https://app.terraform.io", ], @@ -156,7 +156,7 @@ Object { "currentValue": "~> 1.1", "datasource": "terraform-module", "depName": "app.terraform.io/example-corp/k8s-cluster/azurerm", - "depType": "terraform", + "depType": "module", "registryUrls": Array [ "https://app.terraform.io", ], @@ -165,7 +165,7 @@ Object { "currentValue": "~~ 1.1", "datasource": "terraform-module", "depName": "app.terraform.io/example-corp/k8s-cluster/azurerm", - "depType": "terraform", + "depType": "module", "registryUrls": Array [ "https://app.terraform.io", ], @@ -174,7 +174,7 @@ Object { "currentValue": ">= 1.0.0, <= 2.0.0", "datasource": "terraform-module", "depName": "hashicorp/consul/aws", - "depType": "terraform", + "depType": "module", }, Object { "skipReason": "local", @@ -186,89 +186,90 @@ Object { "currentValue": "1.36.1", "datasource": "terraform-provider", "depName": "azurerm", - "depType": "terraform", + "depType": "provider", }, Object { "currentValue": "=2.4", "datasource": "terraform-provider", "depName": "gitlab", - "depType": "terraform", + "depType": "provider", }, Object { "currentValue": "=1.3", "datasource": "terraform-provider", "depName": "gitlab", - "depType": "terraform", + "depType": "provider", }, Object { "datasource": "terraform-provider", "depName": "helm", - "depType": "terraform", + "depType": "provider", }, Object { "currentValue": "V1.9", "datasource": "terraform-provider", "depName": "newrelic", - "depType": "terraform", + "depType": "provider", }, Object { "currentValue": "v1.0.0", "datasource": "git-tags", "depName": "bitbucket.com/hashicorp/example", - "depType": "gitTags", + "depType": "module", "lookupName": "https://bitbucket.com/hashicorp/example", }, Object { "currentValue": "v1.0.0", "datasource": "git-tags", "depName": "bitbucket.com/hashicorp/example", - "depType": "gitTags", + "depType": "module", "lookupName": "https://bitbucket.com/hashicorp/example", }, Object { "currentValue": "next", "datasource": "git-tags", "depName": "bitbucket.com/hashicorp/example", - "depType": "gitTags", + "depType": "module", "lookupName": "https://bitbucket.com/hashicorp/example", }, Object { "currentValue": "v1.0.1", "datasource": "git-tags", "depName": "bitbucket.com/hashicorp/example", - "depType": "gitTags", + "depType": "module", "lookupName": "https://bitbucket.com/hashicorp/example", }, Object { "currentValue": "v1.0.2", "datasource": "git-tags", "depName": "bitbucket.com/hashicorp/example", - "depType": "gitTags", + "depType": "module", "lookupName": "http://bitbucket.com/hashicorp/example", }, Object { "currentValue": "v1.0.3", "datasource": "git-tags", "depName": "bitbucket.com/hashicorp/example", - "depType": "gitTags", + "depType": "module", "lookupName": "ssh://git@bitbucket.com/hashicorp/example", }, Object { "currentValue": ">= 2.7.0", "datasource": "terraform-provider", "depName": "aws", - "depType": "terraform", + "depType": "required_provider", }, Object { "currentValue": ">= 2.0.0", "datasource": "terraform-provider", "depName": "azurerm", - "depType": "terraform", + "depType": "required_provider", }, Object { "currentValue": ">= 0.13", "datasource": "github-tags", "depName": "hashicorp/terraform", + "depType": "required_version", "extractVersion": "v(?.*)$", "lineNumber": 230, }, @@ -276,7 +277,7 @@ Object { "currentValue": "2.7.2", "datasource": "terraform-provider", "depName": "docker", - "depType": "terraform", + "depType": "required_provider", "registryUrls": Array [ "https://releases.hashicorp.com", ], @@ -285,34 +286,34 @@ Object { "currentValue": "2.7.0", "datasource": "terraform-provider", "depName": "aws", - "depType": "terraform", + "depType": "required_provider", "lookupName": "aws", }, Object { "currentValue": "=2.27.0", "datasource": "terraform-provider", "depName": "azurerm", - "depType": "terraform", + "depType": "required_provider", }, Object { "currentValue": "1.2.4", "datasource": "terraform-provider", "depName": "invalid", - "depType": "terraform", + "depType": "required_provider", "skipReason": "unsupported-url", }, Object { "currentValue": "1.2.4", "datasource": "terraform-provider", "depName": "helm", - "depType": "terraform", + "depType": "required_provider", "lookupName": "hashicorp/helm", }, Object { "currentValue": ">= 1.0", "datasource": "terraform-provider", "depName": "kubernetes", - "depType": "terraform", + "depType": "required_provider", "lookupName": "hashicorp/kubernetes", "registryUrls": Array [ "https://terraform.example.com", @@ -324,6 +325,7 @@ Object { "currentValue": "1.7.8", "datasource": "docker", "depName": "nginx", + "depType": "docker_image", "replaceString": "nginx:1.7.8", }, Object { @@ -332,6 +334,7 @@ Object { Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", "datasource": "docker", + "depType": "docker_image", "replaceString": "\${data.docker_registry_image.ubuntu.name}", "skipReason": "contains-variable", }, @@ -341,6 +344,7 @@ Object { "currentValue": "1.7.8", "datasource": "docker", "depName": "nginx", + "depType": "docker_container", "replaceString": "nginx:1.7.8", }, Object { @@ -352,6 +356,7 @@ Object { "currentValue": "v1", "datasource": "docker", "depName": "repo.mycompany.com:8080/foo-service", + "depType": "docker_service", "replaceString": "repo.mycompany.com:8080/foo-service:v1", }, Object { diff --git a/lib/manager/terraform/extract.ts b/lib/manager/terraform/extract.ts index 4658a80336cbe7..0048bde408dc4a 100644 --- a/lib/manager/terraform/extract.ts +++ b/lib/manager/terraform/extract.ts @@ -5,7 +5,10 @@ import { analyzeTerraformProvider, extractTerraformProvider, } from './providers'; -import { extractTerraformRequiredProviders } from './required-providers'; +import { + analyzeTerraformRequiredProvider, + extractTerraformRequiredProviders, +} from './required-providers'; import { analyseTerraformVersion, extractTerraformRequiredVersion, @@ -98,6 +101,8 @@ export function extractPackageFile(content: string): PackageFile | null { deps.forEach((dep) => { switch (dep.managerData.terraformDependencyType) { case TerraformDependencyTypes.required_providers: + analyzeTerraformRequiredProvider(dep); + break; case TerraformDependencyTypes.provider: analyzeTerraformProvider(dep); break; diff --git a/lib/manager/terraform/modules.ts b/lib/manager/terraform/modules.ts index f3336a1ab7ff09..692c120328e77f 100644 --- a/lib/manager/terraform/modules.ts +++ b/lib/manager/terraform/modules.ts @@ -30,12 +30,12 @@ export function analyseTerraformModule(dep: PackageDependency): void { /* eslint-disable no-param-reassign */ if (githubRefMatch) { dep.lookupName = githubRefMatch.groups.project.replace(/\.git$/, ''); - dep.depType = 'github'; + dep.depType = 'module'; dep.depName = 'github.com/' + dep.lookupName; dep.currentValue = githubRefMatch.groups.tag; dep.datasource = datasourceGithubTags.id; } else if (gitTagsRefMatch) { - dep.depType = 'gitTags'; + dep.depType = 'module'; if (gitTagsRefMatch.groups.path.includes('//')) { logger.debug('Terraform module contains subdirectory'); dep.depName = gitTagsRefMatch.groups.path.split('//')[0]; @@ -56,7 +56,7 @@ export function analyseTerraformModule(dep: PackageDependency): void { if (hostnameMatch) { dep.registryUrls = [`https://${hostnameMatch.groups.hostname}`]; } - dep.depType = 'terraform'; + dep.depType = 'module'; dep.depName = moduleParts.join('/'); dep.datasource = datasourceTerraformModule.id; } diff --git a/lib/manager/terraform/providers.ts b/lib/manager/terraform/providers.ts index 7be0e7653a3889..aa06ad0d73609c 100644 --- a/lib/manager/terraform/providers.ts +++ b/lib/manager/terraform/providers.ts @@ -61,7 +61,7 @@ export function extractTerraformProvider( export function analyzeTerraformProvider(dep: PackageDependency): void { /* eslint-disable no-param-reassign */ - dep.depType = 'terraform'; + dep.depType = 'provider'; dep.depName = dep.managerData.moduleName; dep.datasource = datasourceTerraformProvider.id; diff --git a/lib/manager/terraform/readme.md b/lib/manager/terraform/readme.md index 4dd83219332888..9d3138c89cb327 100644 --- a/lib/manager/terraform/readme.md +++ b/lib/manager/terraform/readme.md @@ -1,21 +1,38 @@ -Currently Terraform support is limited to Terraform registry sources and GitHub sources that include SemVer refs, e.g. like `github.com/hashicorp/example?ref=v1.0.0`. +Currently, Terraform supports renovating the following dependencies, where sub points represent hosting options of the dependencies: -Fixed versions like the following will receive a PR whenever there is a newer version available: +- modules + - GitTags + - GithubTags + - TerraformRegistry ( Public and Private ) +- providers ( deprecated in Terraform 0.13.0 ) + - TerraformRegistry ( Public and Private ) +- required_providers block ( Terraform >= 0.13.0) + - TerraformRegistry ( Public and Private ) +- required_version +- helm_release + - chart repository ( Public and Private ) +- docker\_\* + - Docker registry ( Public and Private ) -``` -module "consul" { - source = "hashicorp/consul/aws" - version = "0.0.5" - servers = 3 -} -``` - -The following _range_ constraints are also supported: +Terraform range constraints are supported: - `>= 1.2.0`: version 1.2.0 or newer - `<= 1.2.0`: version 1.2.0 or older - `~> 1.2.0`: any non-beta version >= 1.2.0 and < 1.3.0, e.g. 1.2.X - `~> 1.2`: any non-beta version >= 1.2.0 and < 2.0.0, e.g. 1.X.Y -- `>= 1.0.0`, <= 2.0.0`: any version between 1.0.0 and 2.0.0 inclusive +- `>= 1.0.0, <= 2.0.0`: any version between 1.0.0 and 2.0.0 inclusive + +For fine-grained control, e.g. to turn off only parts of this manager, there are following `depTypes` provided: + +| 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 | 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/manager/terraform/required-providers.ts b/lib/manager/terraform/required-providers.ts index 9319737a69c94f..44b1186210c23e 100644 --- a/lib/manager/terraform/required-providers.ts +++ b/lib/manager/terraform/required-providers.ts @@ -1,4 +1,5 @@ import type { PackageDependency } from '../types'; +import { analyzeTerraformProvider } from './providers'; import { ExtractionResult, TerraformDependencyTypes, @@ -72,3 +73,10 @@ export function extractTerraformRequiredProviders( } while (line.trim() !== '}'); return { lineNumber, dependencies: deps }; } + +export function analyzeTerraformRequiredProvider(dep: PackageDependency): void { + /* eslint-disable no-param-reassign */ + analyzeTerraformProvider(dep); + dep.depType = `required_provider`; + /* eslint-enable no-param-reassign */ +} diff --git a/lib/manager/terraform/required-version.ts b/lib/manager/terraform/required-version.ts index f5deb89a8b87fd..c8bb1e4dad6f32 100644 --- a/lib/manager/terraform/required-version.ts +++ b/lib/manager/terraform/required-version.ts @@ -48,6 +48,7 @@ export function extractTerraformRequiredVersion( export function analyseTerraformVersion(dep: PackageDependency): void { /* eslint-disable no-param-reassign */ + dep.depType = 'required_version'; dep.datasource = datasourceGithubTags.id; dep.depName = 'hashicorp/terraform'; dep.extractVersion = 'v(?.*)$'; diff --git a/lib/manager/terraform/resources.ts b/lib/manager/terraform/resources.ts index 62c986261c8806..4937a8e98ef4d6 100644 --- a/lib/manager/terraform/resources.ts +++ b/lib/manager/terraform/resources.ts @@ -73,6 +73,7 @@ export function analyseTerraformResource( case TerraformResourceTypes.docker_container: if (dep.managerData.image) { applyDockerDependency(dep, dep.managerData.image); + dep.depType = 'docker_container'; } else { dep.skipReason = SkipReason.InvalidDependencySpecification; } @@ -81,6 +82,7 @@ export function analyseTerraformResource( case TerraformResourceTypes.docker_image: if (dep.managerData.name) { applyDockerDependency(dep, dep.managerData.name); + dep.depType = 'docker_image'; } else { dep.skipReason = SkipReason.InvalidDependencySpecification; } @@ -89,6 +91,7 @@ export function analyseTerraformResource( case TerraformResourceTypes.docker_service: if (dep.managerData.image) { applyDockerDependency(dep, dep.managerData.image); + dep.depType = 'docker_service'; } else { dep.skipReason = SkipReason.InvalidDependencySpecification; } @@ -100,7 +103,7 @@ export function analyseTerraformResource( } else if (checkIfStringIsPath(dep.managerData.chart)) { dep.skipReason = SkipReason.LocalChart; } - dep.depType = 'helm'; + dep.depType = 'helm_release'; dep.registryUrls = [dep.managerData.repository]; dep.depName = dep.managerData.chart; dep.datasource = datasourceHelm.id;