From ca0cf2e6cd7dbb5ec9eac3da9db2e4b7195e56dc Mon Sep 17 00:00:00 2001
From: Sebastian Poxhofer <secustor@users.noreply.github.com>
Date: Sun, 28 Mar 2021 07:50:27 +0200
Subject: [PATCH] fix(terraform): do not abort search after first block (#9302)

---
 lib/manager/terraform/__fixtures__/1.tf       | 24 +++++++++++++++++++
 .../__snapshots__/extract.spec.ts.snap        |  8 ++++++-
 lib/manager/terraform/extract.spec.ts         |  2 +-
 lib/manager/terraform/providers.ts            | 22 +++++++++++++----
 4 files changed, 50 insertions(+), 6 deletions(-)

diff --git a/lib/manager/terraform/__fixtures__/1.tf b/lib/manager/terraform/__fixtures__/1.tf
index fa7accbc19..0ddcab51ea 100644
--- a/lib/manager/terraform/__fixtures__/1.tf
+++ b/lib/manager/terraform/__fixtures__/1.tf
@@ -79,6 +79,30 @@ module "vote_service_sg" {
   ]
 }
 
+module "addons_aws" {
+
+  providers = {
+    helm       = helm.core
+    kubectl    = kubectl.core
+    kubernetes = kubernetes.core
+  }
+
+  cluster-name = data.aws_eks_cluster.core_cluster.id
+
+  aws-ebs-csi-driver = {
+    enabled          = true
+    is_default_class = true
+  }
+
+
+  source  = "particuleio/addons/kubernetes//modules/aws"
+  version = "1.28.3"
+
+  aws-load-balancer-controller = {
+    enabled = true
+  }
+}
+
 module "consul" {
   source  = "app.terraform.io/example-corp/k8s-cluster/azurerm"
   version = "~> 1.1.0"
diff --git a/lib/manager/terraform/__snapshots__/extract.spec.ts.snap b/lib/manager/terraform/__snapshots__/extract.spec.ts.snap
index 5c3eebb6fb..645e3106b8 100644
--- a/lib/manager/terraform/__snapshots__/extract.spec.ts.snap
+++ b/lib/manager/terraform/__snapshots__/extract.spec.ts.snap
@@ -137,6 +137,12 @@ Object {
       "depName": "terraform-aws-modules/security-group/aws",
       "depType": "terraform",
     },
+    Object {
+      "currentValue": "1.28.3",
+      "datasource": "terraform-module",
+      "depName": "particuleio/addons/kubernetes",
+      "depType": "terraform",
+    },
     Object {
       "currentValue": "~> 1.1.0",
       "datasource": "terraform-module",
@@ -264,7 +270,7 @@ Object {
       "datasource": "github-tags",
       "depName": "hashicorp/terraform",
       "extractVersion": "v(?<version>.*)$",
-      "lineNumber": 205,
+      "lineNumber": 229,
     },
     Object {
       "currentValue": "2.7.2",
diff --git a/lib/manager/terraform/extract.spec.ts b/lib/manager/terraform/extract.spec.ts
index b7647c943f..339957e368 100644
--- a/lib/manager/terraform/extract.spec.ts
+++ b/lib/manager/terraform/extract.spec.ts
@@ -16,7 +16,7 @@ describe('lib/manager/terraform/extract', () => {
     it('extracts', () => {
       const res = extractPackageFile(tf1);
       expect(res).toMatchSnapshot();
-      expect(res.deps).toHaveLength(45);
+      expect(res.deps).toHaveLength(46);
       expect(res.deps.filter((dep) => dep.skipReason)).toHaveLength(8);
     });
     it('returns null if only local deps', () => {
diff --git a/lib/manager/terraform/providers.ts b/lib/manager/terraform/providers.ts
index ef3b9193b5..f49240b2e9 100644
--- a/lib/manager/terraform/providers.ts
+++ b/lib/manager/terraform/providers.ts
@@ -1,5 +1,6 @@
 import is from '@sindresorhus/is';
 import * as datasourceTerraformProvider from '../../datasource/terraform-provider';
+import { logger } from '../../logger';
 import { SkipReason } from '../../types';
 import type { PackageDependency } from '../types';
 import {
@@ -16,7 +17,6 @@ export function extractTerraformProvider(
   moduleName: string
 ): ExtractionResult {
   let lineNumber = startingLine;
-  let line: string;
   const deps: PackageDependency[] = [];
   const dep: PackageDependency = {
     managerData: {
@@ -24,9 +24,19 @@ export function extractTerraformProvider(
       terraformDependencyType: TerraformDependencyTypes.provider,
     },
   };
+  let braceCounter = 0;
   do {
-    lineNumber += 1;
-    line = lines[lineNumber];
+    // istanbul ignore if
+    if (lineNumber > lines.length - 1) {
+      logger.debug(`Malformed Terraform file detected.`);
+    }
+
+    const line = lines[lineNumber];
+    // `{` will be counted wit +1 and `}` with -1. Therefore if we reach braceCounter == 0. We have found the end of the terraform block
+    const openBrackets = (line.match(/\{/g) || []).length;
+    const closedBrackets = (line.match(/\}/g) || []).length;
+    braceCounter = braceCounter + openBrackets - closedBrackets;
+
     const kvMatch = keyValueExtractionRegex.exec(line);
     if (kvMatch) {
       if (kvMatch.groups.key === 'version') {
@@ -36,8 +46,12 @@ export function extractTerraformProvider(
         dep.managerData.sourceLine = lineNumber;
       }
     }
-  } while (line.trim() !== '}');
+    lineNumber += 1;
+  } while (braceCounter !== 0);
   deps.push(dep);
+
+  // remove last lineNumber addition to not skip a line after the last bracket
+  lineNumber -= 1;
   return { lineNumber, dependencies: deps };
 }
 
-- 
GitLab